From 0c915c8fcfe6f61fd5adf3e8f73d03340038fe5d Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 2 Apr 2002 03:27:03 +0000 Subject: PEP 287: reStructuredText Standard Docstring Format As posted to the Doc-SIG 2002-03-26. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@7 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 677 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 docs/peps/pep-0287.txt diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt new file mode 100644 index 000000000..f19354587 --- /dev/null +++ b/docs/peps/pep-0287.txt @@ -0,0 +1,677 @@ +PEP: +Title: reStructuredText Standard Docstring Format +Version: $Revision$ +Last-Modified: $Date$ +Author: goodger@users.sourceforge.net (David Goodger) +Discussions-To: doc-sig@python.org +Status: Draft +Type: Informational +Created: 2002-03-25 +Post-History: + + +Abstract + + This PEP proposes that the reStructuredText [1]_ markup be adopted + as the standard markup format for plaintext documentation in + Python docstrings, and (optionally) for PEPs and ancillary + documents as well. reStructuredText is a rich and extensible yet + easy-to-read, what-you-see-is-what-you-get plaintext markup + syntax. + + Only the low-level syntax of docstrings is addressed here. This + PEP is not concerned with docstring semantics or processing at + all. + + +Goals + + These are the generally accepted goals for a docstring format, as + discussed in the Python Documentation Special Interest Group + (Doc-SIG) [2]_: + + 1. It must be easy to type with any standard text editor. + + 2. It must be readable to the casual observer. + + 3. It must not need to contain information which can be deduced + from parsing the module. + + 4. It must contain sufficient information (structure) so it can be + converted to any reasonable markup format. + + 5. It must be possible to write a module's entire documentation in + docstrings, without feeling hampered by the markup language. + + [[Are these in fact the goals of the Doc-SIG members? Anything to + add?]] + + reStructuredText meets and exceeds all of these goals, and sets + its own goals as well, even more stringent. See "Features" below. + + The goals of this PEP are as follows: + + 1. To establish a standard docstring format by attaining + "accepted" status (Python community consensus; BDFL + pronouncement). Once reStructuredText is a Python standard, all + effort can be focused on tools instead of arguing for a + standard. Python needs a standard set of documentation tools. + + 2. To address any related concerns raised by the Python community. + + 3. To encourage community support. As long as multiple competing + markups are out there, the development community remains + fractured. Once a standard exists, people will start to use + it, and momentum will inevitably gather. + + 4. To consolidate efforts from related auto-documentation + projects. It is hoped that interested developers will join + forces and work on a joint/merged/common implementation. + + 5. (Optional.) To adopt reStructuredText as the standard markup + for PEPs. One or both of the following strategies may be + applied: + + a) Keep the existing PEP section structure constructs (one-line + section headers, indented body text). Subsections can either + be forbidden or supported with underlined headers in the + indented body text. + + b) Replace the PEP section structure constructs with the + reStructuredText syntax. Section headers will require + underlines, subsections will be supported out of the box, and + body text need not be indented (except for block quotes). + + Support for RFC822 headers will be added to the + reStructuredText parser (unambiguous given a specific context: + the first contiguous block of a PEP document). It may be + desired to concretely specify what over/underline styles are + allowed for PEP section headers, for uniformity. + + 6. (Optional.) To adopt reStructuredText as the standard markup + for README-type files and other standalone documents in the + Python distribution. + + +Rationale + + The __doc__ attribute is called a documentation string, or + docstring. It is often used to summarize the interface of the + module, class or function. The lack of a standard syntax for + docstrings has hampered the development of standard tools for + extracting docstrings and transforming them into documentation in + standard formats (e.g., HTML, DocBook, TeX). There have been a + number of proposed markup formats and variations, and many tools + tied to these proposals, but without a standard docstring format + they have failed to gain a strong following and/or floundered + half-finished. + + The adoption of a standard will, at the very least, benefit + docstring processing tools by preventing further "reinventing the + wheel". + + Throughout the existence of the Doc-SIG, consensus on a single + standard docstring format has never been reached. A lightweight, + implicit markup has been sought, for the following reasons (among + others): + + 1. Docstrings written within Python code are available from within + the interactive interpreter, and can be 'print'ed. Thus the + use of plaintext for easy readability. + + 2. Programmers want to add structure to their docstrings, without + sacrificing raw docstring readability. Unadorned plaintext + cannot be transformed ('up-translated') into useful structured + formats. + + 3. Explicit markup (like XML or TeX) is widely considered + unreadable by the uninitiated. + + 4. Implicit markup is aesthetically compatible with the clean and + minimalist Python syntax. + + Proposed alternatives have included: + + - XML [3]_, SGML [4]_, DocBook [5]_, HTML [6]_, XHTML [7]_ + + XML and SGML are explicit, well-formed meta-languages suitable + for all kinds of documentation. XML is a variant of SGML. They + are best used behind the scenes, because they are verbose, + difficult to type, and too cluttered to read comfortably as + source. DocBook, HTML, and XHTML are all applications of SGML + and/or XML, and all share the same basic syntax and the same + shortcomings. + + - TeX [8]_ + + TeX is similar to XML/SGML in that it's explicit, not very easy + to write, and not easy for the uninitiated to read. + + - Perl POD [9]_ + + Most Perl modules are documented in a format called POD -- Plain + Old Documentation. This is an easy-to-type, very low level + format with strong integration with the Perl parser. Many tools + exist to turn POD documentation into other formats: info, HTML + and man pages, among others. However, the POD syntax takes + after Perl itself in terms of readability. + + - JavaDoc [10]_ + + Special comments before Java classes and functions serve to + document the code. A program to extract these, and turn them + into HTML documentation is called javadoc, and is part of the + standard Java distribution. However, the only output format + that is supported is HTML, and JavaDoc has a very intimate + relationship with HTML, using HTML tags for most markup. Thus + it shares the readability problems of HTML. + + - Setext [11]_, StructuredText [12]_ + + Early on, variants of Setext (Structure Enhanced Text), + including Zope Corp's StructuredText, were proposed for Python + docstring formatting. Hereafter these variants will + collectively be call 'STexts'. STexts have the advantage of + being easy to read without special knowledge, and relatively + easy to write. + + Although used by some (including in most existing Python + auto-documentation tools), until now STexts have failed to + become standard because: + + - STexts have been incomplete. Lacking "essential" constructs + that people want to use in their docstrings, STexts are + rendered less than ideal. Note that these "essential" + constructs are not universal; everyone has their own + requirements. + + - STexts have been sometimes surprising. Bits of text are + marked up unexpectedly, leading to user frustration. + + - SText implementations have been buggy. + + - Most STexts have have had no formal specification except for + the implementation itself. A buggy implementation meant a + buggy spec, and vice-versa. + + - There has been no mechanism to get around the SText markup + rules when a markup character is used in a non-markup context. + + Proponents of implicit STexts have vigorously opposed proposals + for explicit markup (XML, HTML, TeX, POD, etc.), and the debates + have continued off and on since 1996 or earlier. + + reStructuredText is a complete revision and reinterpretation of + the SText idea, addressing all of the problems listed above. + + +Features + + Rather than repeating or summarizing the extensive + reStructuredText spec, please read the originals available from + http://structuredtext.sourceforge.net/spec/ (.txt & .html files). + Reading the documents in following order is recommended: + + - An Introduction to reStructuredText [13]_ + + - Problems With StructuredText [14]_ (optional, if you've used + StructuredText; it explains many markup decisions made) + + - reStructuredText Markup Specification [15]_ + + - A Record of reStructuredText Syntax Alternatives [16]_ (explains + markup decisions made independently of StructuredText) + + - reStructuredText Directives [17]_ + + There is also a "Quick reStructuredText" user reference [18]_. + + A summary of features addressing often-raised docstring markup + concerns follows: + + - A markup escaping mechanism. + + Backslashes (``\``) are used to escape markup characters when + needed for non-markup purposes. However, the inline markup + recognition rules have been constructed in order to minimize the + need for backslash-escapes. For example, although asterisks are + used for *emphasis*, in non-markup contexts such as "*" or "(*)" + or "x * y", the asterisks are not interpreted as markup and are + left unchanged. For many non-markup uses of backslashes (e.g., + describing regular expressions), inline literals or literal + blocks are applicable; see the next item. + + - Markup to include Python source code and Python interactive + sessions: inline literals, literal blocks, and doctest blocks. + + Inline literals use ``double-backquotes`` to indicate program + I/O or code snippets. No markup interpretation (including + backslash-escape [``\``] interpretation) is done within inline + literals. + + Literal blocks (block-level literal text, such as code excerpts + or ASCII graphics) are indented, and indicated with a + double-colon ("::") at the end of the preceding paragraph (right + here -->):: + + if literal_block: + text = 'is left as-is' + spaces_and_linebreaks = 'are preserved' + markup_processing = None + + Doctest blocks begin with ">>> " and end with a blank line. + Neither indentation nor literal block double-colons are + required. For example:: + + Here's a doctest block: + + >>> print 'Python-specific usage examples; begun with ">>>"' + Python-specific usage examples; begun with ">>>" + >>> print '(cut and pasted from interactive sessions)' + (cut and pasted from interactive sessions) + + - Markup that isolates a Python identifier: interpreted text. + + Text enclosed in single backquotes is recognized as "interpreted + text", whose interpretation is application-dependent. In the + context of a Python docstring, the default interpretation of + interpreted text is as Python identifiers. The text will be + marked up with a hyperlink connected to the documentation for + the identifier given. Lookup rules are the same as in Python + itself: LGB namespace lookups (local, global, builtin). The + "role" of the interpreted text (identifying a class, module, + function, etc.) is determined implicitly from the namespace + lookup. For example:: + + class Keeper(Storer): + + """ + Extend `Storer`. Class attribute `instances` keeps track + of the number of `Keeper` objects instantiated. + """ + + instances = 0 + """How many `Keeper` objects are there?""" + + def __init__(self): + """ + Extend `Storer.__init__()` to keep track of + instances. Keep count in `self.instances` and data + in `self.data`. + """ + Storer.__init__(self) + self.instances += 1 + + self.data = [] + """Store data in a list, most recent last.""" + + def storedata(self, data): + """ + Extend `Storer.storedata()`; append new `data` to a + list (in `self.data`). + """ + self.data = data + + Each piece of interpreted text is looked up according to the + local namespace of the block containing its docstring. + + - Markup that isolates a Python identifier and specifies its type: + interpreted text with roles. + + Although the Python source context reader is designed not to + require explicit roles, they may be used. To classify + identifiers explicitly, the role is given along with the + identifier in either prefix or suffix form:: + + Use :method:`Keeper.storedata` to store the object's data in + `Keeper.data`:instance_attribute:. + + The syntax chosen for roles is verbose, but necessarily so (if + anyone has a better alternative, please post it to the Doc-SIG). + The intention of the markup is that there should be little need + to use explicit roles; their use is to be kept to an absolute + minimum. + + - Markup for "tagged lists" or "label lists": field lists. + + Field lists represent a mapping from field name to field body. + These are mostly used for extension syntax, such as + "bibliographic field lists" (representing document metadata such + as author, date, and version) and extension attributes for + directives (see below). They may be used to implement docstring + semantics, such as identifying parameters, exceptions raised, + etc.; such usage is beyond the scope of this PEP. + + A modified RFC822 syntax is used, with a colon *before* as well + as *after* the field name. Field bodies are more versatile as + well; they may contain multiple field bodies (even nested field + lists). For example:: + + :Date: 2002-03-22 + :Version: 1 + :Authors: + - Me + - Myself + - I + + Standard RFC822 header syntax cannot be used for this construct + because it is ambiguous. A word followed by a colon at the + beginning of a line is common in written text. However, with + the addition of a well-defined context, such as when a field + list invariably occurs at the beginning of a document (e.g., + PEPs and email messages), standard RFC822 header syntax can be + used. + + - Markup extensibility: directives and substitutions. + + Directives are used as an extension mechanism for + reStructuredText, a way of adding support for new block-level + constructs without adding new syntax. Directives for images, + admonitions (note, caution, etc.), and tables of contents + generation (among others) have been implemented. For example, + here's how to place an image:: + + .. image:: mylogo.png + + Substitution definitions allow the power and flexibility of + block-level directives to be shared by inline text. For + example:: + + The |biohazard| symbol must be used on containers used to + dispose of medical waste. + + .. |biohazard| image:: biohazard.png + + - Section structure markup. + + Section headers in reStructuredText use adornment via underlines + (and possibly overlines) rather than indentation. For example:: + + This is a Section Title + ======================= + + This is a Subsection Title + -------------------------- + + This paragraph is in the subsection. + + This is Another Section Title + ============================= + + This paragraph is in the second section. + + +Questions & Answers + + Q: Is reStructuredText rich enough? + + A: Yes, it is for most people. If it lacks some construct that is + require for a specific application, it can be added via the + directive mechansism. If a common construct has been + overlooked and a suitably readable syntax can be found, it can + be added to the specification and parser. + + Q: Is reStructuredText *too* rich? + + A: No. + + Since the very beginning, whenever a markup syntax has been + proposed on the Doc-SIG, someone has complained about the lack + of support for some construct or other. The reply was often + something like, "These are docstrings we're talking about, and + docstrings shouldn't have complex markup." The problem is that + a construct that seems superfluous to one person may be + absolutely essential to another. + + reStructuredText takes the opposite approach: it provides a + rich set of implicit markup constructs (plus a generic + extension mechanism for explicit markup), allowing for all + kinds of documents. If the set of constructs is too rich for a + particular application, the unused constructs can either be + removed from the parser (via application-specific overrides) or + simply omitted by convention. + + Q: Why not use indentation for section structure, like + StructuredText does? Isn't it more "Pythonic"? + + A: Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG + post: + + I still think that using indentation to indicate sectioning + is wrong. If you look at how real books and other print + publications are laid out, you'll notice that indentation + is used frequently, but mostly at the intra-section level. + Indentation can be used to offset lists, tables, + quotations, examples, and the like. (The argument that + docstrings are different because they are input for a text + formatter is wrong: the whole point is that they are also + readable without processing.) + + I reject the argument that using indentation is Pythonic: + text is not code, and different traditions and conventions + hold. People have been presenting text for readability for + over 30 centuries. Let's not innovate needlessly. + + See "Section Structure via Indentation" in "Problems With + StructuredText" [14 ]_ for further elaboration. + + Q: Why use reStructuredText for PEPs? What's wrong with the + existing standard? + + A: The existing standard for PEPs is very limited in terms of + general expressibility, and referencing is especially lacking + for such a reference-rich document type. PEPs are currently + converted into HTML, but the results (mostly monospaced text) + are less than attractive, and most of the value-added potential + of HTML is untapped. + + Making reStructuredText the standard markup for PEPs will + enable much richer expression, including support for section + structure, inline markup, graphics, and tables. In several + PEPs there are ASCII graphics diagrams, which are all that + plaintext documents can support. Since PEPs are made available + in HTML form, the ability to include proper diagrams would be + immediately useful. + + Current PEP practices allow for reference markers in the form + "[1]" in the text, and the footnotes/references themselves are + listed in a section toward the end of the document. There is + currently no hyperlinking between the reference marker and the + footnote/reference itself (it would be possible to add this to + pep2html.py, but the "markup" as it stands is ambiguous and + mistakes would be inevitable). A PEP with many references + (such as this one ;-) requires a lot of flipping back and + forth. When revising a PEP, often new references are added or + unused references deleted. It is painful to renumber the + references, since it has to be done in two places and can have + a cascading effect (insert a single new reference 1, and every + other reference has to be renumbered; always adding new + references to the end is suboptimal). It is easy for + references to go out of sync. + + PEPs use references for two purposes: simple URL references and + footnotes. reStructuredText differentiates between the two. A + PEP might contain references like this:: + + Abstract + + This PEP proposes a adding frungible doodads [1] to the + core. It extends PEP 9876 [2] via the BCA [3] + mechanism. + + References and Footnotes + + [1] http://www.doodads.org/frungible.html + + [2] PEP 9876, Let's Hope We Never Get Here + http://www.python.org/peps/pep-9876.html + + [3] "Bogus Complexity Addition" + + Reference 1 is a simple URL reference. Reference 2 is a + footnote containing text and a URL. Reference 3 is a footnote + containing text only. Rewritten using reStructuredText, this + PEP could look like this:: + + Abstract + ======== + + This PEP proposes a adding `frungible doodads`_ to the + core. It extends PEP 9876 [#pep9876] via the BCA [#] + mechanism. + + .. _frungible doodads: + http://www.doodads.org/frungible.html + + .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here + + __ http://www.python.org/peps/pep-9876.html + + .. [#] "Bogus Complexity Addition" + + URLs and footnotes can be defined close to their references if + desired, making them easier to read in the source text, and + making the PEPs easier to revise. The "References and + Footnotes" section can be auto-generated with a document tree + transform. Footnotes from throughout the PEP would be gathered + and displayed under a standard header. If URL references + should likewise be written out explicitly (in citation form), + another tree transform could be used. + + URL references can be named ("frungible doodads"), and can be + referenced from multiple places in the document without + additional definitions. When converted to HTML, references + will be replaced with inline hyperlinks (HTML tags). The + two footnotes are automatically numbered, so they will always + stay in sync. The first footnote also contains an internal + reference name, "pep9876", so it's easier to see the connection + between reference and footnote in the source text. Named + footnotes can be referenced multiple times, maintaining + consistent numbering. + + The "#pep9876" footnote could also be written in the form of a + citation:: + + It extends PEP 9876 [PEP9876]_ ... + + .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here + + Footnotes are numbered, whereas citations use text for their + references. + + Q: Wouldn't it be better to keep the docstring and PEP proposals + separate? + + A: The PEP markup proposal is an option to this PEP. It may be + removed if it is deemed that there is no need for PEP markup. + The PEP markup proposal could be made into a separate PEP if + necessary. If accepted, PEP 1, PEP Purpose and Guidelines [19]_, + and PEP 9, Sample PEP Template [20]_ will be updated. + + It seems natural to adopt a single consistent markup standard + for all uses of plaintext in Python. + + Q: The existing pep2html.py script converts the existing PEP + format to HTML. How will the new-format PEPs be converted to + HTML? + + A: One of the deliverables of the Docutils project [21]_ will be a + new version of pep2html.py with integrated reStructuredText + parsing. The Docutils project will support PEPs with a "PEP + Reader" component, including all functionality currently in + pep2html.py (auto-recognition of PEP & RFC references). + + Q: Who's going to convert the existing PEPs to reStructuredText? + + A: A call for volunteers will be put out to the Doc-SIG and + greater Python communities. If insufficient volunteers are + forthcoming, I (David Goodger) will convert the documents + myself, perhaps with some level of automation. A transitional + system whereby both old and new standards can coexist will be + easy to implement (and I pledge to implement it if necessary). + + Q: Why use reStructuredText for README and other ancillary files? + + A: The same reasoning used for PEPs above applies to README and + other ancillary files. By adopting a standard markup, these + files can be converted to attractive cross-referenced HTML and + put up on python.org. Developers of Python projects can also + take advantage of this facility for their own documentation. + + +References and Footnotes + + [1] http://structuredtext.sourceforge.net/ + + [2] http://www.python.org/sigs/doc-sig/ + + [3] http://www.w3.org/XML/ + + [4] http://www.oasis-open.org/cover/general.html + + [5] http://docbook.org/tdg/en/html/docbook.html + + [6] http://www.w3.org/MarkUp/ + + [7] http://www.w3.org/MarkUp/#xhtml1 + + [8] http://www.tug.org/interest.html + + [9] http://www.perldoc.com/perl5.6/pod/perlpod.html + + [10] http://java.sun.com/j2se/javadoc/ + + [11] http://docutils.sourceforge.net/mirror/setext.html + + [12] http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + + [13] An Introduction to reStructuredText + http://structuredtext.sourceforge.net/spec/introduction.txt + + [14] Problems with StructuredText + http://structuredtext.sourceforge.net/spec/problems.txt + + [15] reStructuredText Markup Specification + http://structuredtext.sourceforge.net/spec/reStructuredText.txt + + [16] A Record of reStructuredText Syntax Alternatives + http://structuredtext.sourceforge.net/spec/alternatives.txt + + [17] reStructuredText Directives + http://structuredtext.sourceforge.net/spec/directives.txt + + [18] Quick reStructuredText + http://structuredtext.sourceforge.net/docs/quickref.html + + [19] PEP 1, PEP Guidelines, Warsaw, Hylton + http://www.python.org/peps/pep-0001.html + + [20] PEP 9, Sample PEP Template, Warsaw + http://www.python.org/peps/pep-0009.html + + [21] http://docutils.sourceforge.net/ + + [22] PEP 216, Docstring Format, Zadka + http://www.python.org/peps/pep-0216.html + + +Copyright + + This document has been placed in the public domain. + + +Acknowledgements + + Some text is borrowed from PEP 216, Docstring Format, by Moshe + Zadka [22]_. + + Special thanks to all members past & present of the Python Doc-SIG. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +sentence-end-double-space: t +fill-column: 70 +End: -- cgit v1.2.1 From 8eb0cda78664e494cdd033e3cdaf8c5c51be9c81 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 2 Apr 2002 03:28:25 +0000 Subject: As checked in to Python CVS 2002-04-01. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@8 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index f19354587..0b12971e3 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -1,4 +1,4 @@ -PEP: +PEP: 287 Title: reStructuredText Standard Docstring Format Version: $Revision$ Last-Modified: $Date$ @@ -6,8 +6,9 @@ Author: goodger@users.sourceforge.net (David Goodger) Discussions-To: doc-sig@python.org Status: Draft Type: Informational -Created: 2002-03-25 +Created: 25-Mar-2002 Post-History: +Replaces: 216 Abstract @@ -53,8 +54,8 @@ Goals 1. To establish a standard docstring format by attaining "accepted" status (Python community consensus; BDFL - pronouncement). Once reStructuredText is a Python standard, all - effort can be focused on tools instead of arguing for a + pronouncement). Once reStructuredText is a Python standard, + all effort can be focused on tools instead of arguing for a standard. Python needs a standard set of documentation tools. 2. To address any related concerns raised by the Python community. @@ -73,16 +74,17 @@ Goals applied: a) Keep the existing PEP section structure constructs (one-line - section headers, indented body text). Subsections can either - be forbidden or supported with underlined headers in the - indented body text. + section headers, indented body text). Subsections can + either be forbidden or supported with underlined headers in + the indented body text. b) Replace the PEP section structure constructs with the reStructuredText syntax. Section headers will require - underlines, subsections will be supported out of the box, and - body text need not be indented (except for block quotes). + underlines, subsections will be supported out of the box, + and body text need not be indented (except for block + quotes). - Support for RFC822 headers will be added to the + Support for RFC 2822 headers will be added to the reStructuredText parser (unambiguous given a specific context: the first contiguous block of a PEP document). It may be desired to concretely specify what over/underline styles are @@ -342,10 +344,10 @@ Features semantics, such as identifying parameters, exceptions raised, etc.; such usage is beyond the scope of this PEP. - A modified RFC822 syntax is used, with a colon *before* as well - as *after* the field name. Field bodies are more versatile as - well; they may contain multiple field bodies (even nested field - lists). For example:: + A modified RFC 2822 syntax is used, with a colon *before* as + well as *after* the field name. Field bodies are more versatile + as well; they may contain multiple field bodies (even nested + field lists). For example:: :Date: 2002-03-22 :Version: 1 @@ -354,13 +356,13 @@ Features - Myself - I - Standard RFC822 header syntax cannot be used for this construct - because it is ambiguous. A word followed by a colon at the - beginning of a line is common in written text. However, with - the addition of a well-defined context, such as when a field - list invariably occurs at the beginning of a document (e.g., - PEPs and email messages), standard RFC822 header syntax can be - used. + Standard RFC 2822 header syntax cannot be used for this + construct because it is ambiguous. A word followed by a colon + at the beginning of a line is common in written text. However, + with the addition of a well-defined context, such as when a + field list invariably occurs at the beginning of a document + (e.g., PEPs and email messages), standard RFC 2822 header syntax + can be used. - Markup extensibility: directives and substitutions. @@ -407,7 +409,7 @@ Questions & Answers A: Yes, it is for most people. If it lacks some construct that is require for a specific application, it can be added via the - directive mechansism. If a common construct has been + directive mechanism. If a common construct has been overlooked and a suitably readable syntax can be found, it can be added to the specification and parser. -- cgit v1.2.1 From 489ce879407408f5a852347ff7561ccdafa393f1 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 2 Apr 2002 03:50:38 +0000 Subject: As posted to Python-Dev and comp.lang.python on 2002-04-02. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@9 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 570 ++++++++++++++++++++++++++++--------------------- 1 file changed, 326 insertions(+), 244 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 0b12971e3..a61a40253 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -7,33 +7,78 @@ Discussions-To: doc-sig@python.org Status: Draft Type: Informational Created: 25-Mar-2002 -Post-History: +Post-History: 02-Apr-2002 Replaces: 216 Abstract - This PEP proposes that the reStructuredText [1]_ markup be adopted - as the standard markup format for plaintext documentation in - Python docstrings, and (optionally) for PEPs and ancillary - documents as well. reStructuredText is a rich and extensible yet - easy-to-read, what-you-see-is-what-you-get plaintext markup - syntax. + When plaintext hasn't been expressive enough for inline + documentation, Python programmers have sought out a format for + docstrings. This PEP proposes that the reStructuredText markup + [1]_ be adopted as the standard markup format for structured + plaintext documentation in Python docstrings, and for PEPs and + ancillary documents as well. reStructuredText is a rich and + extensible yet easy-to-read, what-you-see-is-what-you-get + plaintext markup syntax. Only the low-level syntax of docstrings is addressed here. This PEP is not concerned with docstring semantics or processing at - all. + all. Nor is it an attempt to deprecate pure plaintext docstrings, + which are always going to be legitimate. The reStructuredText + markup is an alternative for those who want more expressive + docstrings. + + +Benefits + + Programmers are by nature a lazy breed. We reuse code with + functions, classes, modules, and subsystems. Through its + docstring syntax, Python allows us to document our code from + within. The "holy grail" of the Python Documentation Special + Interest Group (Doc-SIG) [2]_ has been a markup syntax and toolset + to allow auto-documentation, where the docstrings of Python + systems can be extracted in context and processed into useful, + high-quality documentation for multiple purposes. + + The proposed format (reStructuredText) is entirely readable in + plaintext format, and many of the markup forms match common usage + (e.g., ``*emphasis*``), so it reads quite naturally. Yet it is + rich enough to produce complex documents, and extensible so that + there are few limits. + + The reStructuredText parser is available now. The Docutils + project is at the point where standalone reStructuredText + documents can be converted to HTML; other output format writers + will become available over time. Work is progressing on a Python + source "Reader" which will implement auto-documentation. Authors + of existing auto-documentation tools are encouraged to integrate + the reStructuredText parser into their projects, or better yet, to + join forces to produce a world-class toolset for the Python + standard library. + + Tools will become available in the near future, which will allow + programmers to generate HTML for online help, XML for multiple + purposes, and perhaps eventually PDF/DocBook/LaTeX for printed + documentation, essentially "for free" from the existing + docstrings. The adoption of a standard will, at the very least, + benefit docstring processing tools by preventing further + "reinventing the wheel". + + Eventually PyDoc, the one existing standard auto-documentation + tool, could have reStructuredText support added. In the interim + it will have no problem with reStructuredText markup, since it + treats all docstrings as plaintext. Goals These are the generally accepted goals for a docstring format, as - discussed in the Python Documentation Special Interest Group - (Doc-SIG) [2]_: + discussed in the Doc-SIG: - 1. It must be easy to type with any standard text editor. + 1. It must be readable in source form by the casual observer. - 2. It must be readable to the casual observer. + 2. It must be easy to type with any standard text editor. 3. It must not need to contain information which can be deduced from parsing the module. @@ -44,18 +89,15 @@ Goals 5. It must be possible to write a module's entire documentation in docstrings, without feeling hampered by the markup language. - [[Are these in fact the goals of the Doc-SIG members? Anything to - add?]] - reStructuredText meets and exceeds all of these goals, and sets its own goals as well, even more stringent. See "Features" below. The goals of this PEP are as follows: - 1. To establish a standard docstring format by attaining - "accepted" status (Python community consensus; BDFL + 1. To establish reStructuredText as a standard docstring format by + attaining "accepted" status (Python community consensus; BDFL pronouncement). Once reStructuredText is a Python standard, - all effort can be focused on tools instead of arguing for a + effort can be focused on tools instead of arguing for a standard. Python needs a standard set of documentation tools. 2. To address any related concerns raised by the Python community. @@ -69,9 +111,8 @@ Goals projects. It is hoped that interested developers will join forces and work on a joint/merged/common implementation. - 5. (Optional.) To adopt reStructuredText as the standard markup - for PEPs. One or both of the following strategies may be - applied: + 5. To adopt reStructuredText as the standard markup for PEPs. One + or both of the following strategies may be applied: a) Keep the existing PEP section structure constructs (one-line section headers, indented body text). Subsections can @@ -90,27 +131,20 @@ Goals desired to concretely specify what over/underline styles are allowed for PEP section headers, for uniformity. - 6. (Optional.) To adopt reStructuredText as the standard markup - for README-type files and other standalone documents in the - Python distribution. + 6. To adopt reStructuredText as the standard markup for + README-type files and other standalone documents in the Python + distribution. Rationale - The __doc__ attribute is called a documentation string, or - docstring. It is often used to summarize the interface of the - module, class or function. The lack of a standard syntax for - docstrings has hampered the development of standard tools for - extracting docstrings and transforming them into documentation in - standard formats (e.g., HTML, DocBook, TeX). There have been a - number of proposed markup formats and variations, and many tools - tied to these proposals, but without a standard docstring format - they have failed to gain a strong following and/or floundered - half-finished. - - The adoption of a standard will, at the very least, benefit - docstring processing tools by preventing further "reinventing the - wheel". + The lack of a standard syntax for docstrings has hampered the + development of standard tools for extracting and converting + docstrings into documentation in standard formats (e.g., HTML, + DocBook, TeX). There have been a number of proposed markup + formats and variations, and many tools tied to these proposals, + but without a standard docstring format they have failed to gain a + strong following and/or floundered half-finished. Throughout the existence of the Doc-SIG, consensus on a single standard docstring format has never been reached. A lightweight, @@ -188,7 +222,8 @@ Rationale requirements. - STexts have been sometimes surprising. Bits of text are - marked up unexpectedly, leading to user frustration. + unexpectedly interpreted as being marked up, leading to user + frustration. - SText implementations have been buggy. @@ -216,8 +251,8 @@ Features - An Introduction to reStructuredText [13]_ - - Problems With StructuredText [14]_ (optional, if you've used - StructuredText; it explains many markup decisions made) + - Problems With StructuredText [14]_ (optional for those who have + used StructuredText; it explains many markup decisions made) - reStructuredText Markup Specification [15]_ @@ -288,6 +323,8 @@ Features class Keeper(Storer): """ + Keep data fresher longer. + Extend `Storer`. Class attribute `instances` keeps track of the number of `Keeper` objects instantiated. """ @@ -358,11 +395,7 @@ Features Standard RFC 2822 header syntax cannot be used for this construct because it is ambiguous. A word followed by a colon - at the beginning of a line is common in written text. However, - with the addition of a well-defined context, such as when a - field list invariably occurs at the beginning of a document - (e.g., PEPs and email messages), standard RFC 2822 header syntax - can be used. + at the beginning of a line is common in written text. - Markup extensibility: directives and substitutions. @@ -381,7 +414,7 @@ Features The |biohazard| symbol must be used on containers used to dispose of medical waste. - + .. |biohazard| image:: biohazard.png - Section structure markup. @@ -405,203 +438,249 @@ Features Questions & Answers - Q: Is reStructuredText rich enough? - - A: Yes, it is for most people. If it lacks some construct that is - require for a specific application, it can be added via the - directive mechanism. If a common construct has been - overlooked and a suitably readable syntax can be found, it can - be added to the specification and parser. - - Q: Is reStructuredText *too* rich? - - A: No. - - Since the very beginning, whenever a markup syntax has been - proposed on the Doc-SIG, someone has complained about the lack - of support for some construct or other. The reply was often - something like, "These are docstrings we're talking about, and - docstrings shouldn't have complex markup." The problem is that - a construct that seems superfluous to one person may be - absolutely essential to another. - - reStructuredText takes the opposite approach: it provides a - rich set of implicit markup constructs (plus a generic - extension mechanism for explicit markup), allowing for all - kinds of documents. If the set of constructs is too rich for a - particular application, the unused constructs can either be - removed from the parser (via application-specific overrides) or - simply omitted by convention. - - Q: Why not use indentation for section structure, like - StructuredText does? Isn't it more "Pythonic"? - - A: Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG - post: - - I still think that using indentation to indicate sectioning - is wrong. If you look at how real books and other print - publications are laid out, you'll notice that indentation - is used frequently, but mostly at the intra-section level. - Indentation can be used to offset lists, tables, - quotations, examples, and the like. (The argument that - docstrings are different because they are input for a text - formatter is wrong: the whole point is that they are also - readable without processing.) - - I reject the argument that using indentation is Pythonic: - text is not code, and different traditions and conventions - hold. People have been presenting text for readability for - over 30 centuries. Let's not innovate needlessly. - - See "Section Structure via Indentation" in "Problems With - StructuredText" [14 ]_ for further elaboration. - - Q: Why use reStructuredText for PEPs? What's wrong with the - existing standard? - - A: The existing standard for PEPs is very limited in terms of - general expressibility, and referencing is especially lacking - for such a reference-rich document type. PEPs are currently - converted into HTML, but the results (mostly monospaced text) - are less than attractive, and most of the value-added potential - of HTML is untapped. - - Making reStructuredText the standard markup for PEPs will - enable much richer expression, including support for section - structure, inline markup, graphics, and tables. In several - PEPs there are ASCII graphics diagrams, which are all that - plaintext documents can support. Since PEPs are made available - in HTML form, the ability to include proper diagrams would be - immediately useful. - - Current PEP practices allow for reference markers in the form - "[1]" in the text, and the footnotes/references themselves are - listed in a section toward the end of the document. There is - currently no hyperlinking between the reference marker and the - footnote/reference itself (it would be possible to add this to - pep2html.py, but the "markup" as it stands is ambiguous and - mistakes would be inevitable). A PEP with many references - (such as this one ;-) requires a lot of flipping back and - forth. When revising a PEP, often new references are added or - unused references deleted. It is painful to renumber the - references, since it has to be done in two places and can have - a cascading effect (insert a single new reference 1, and every - other reference has to be renumbered; always adding new - references to the end is suboptimal). It is easy for - references to go out of sync. - - PEPs use references for two purposes: simple URL references and - footnotes. reStructuredText differentiates between the two. A - PEP might contain references like this:: - - Abstract - - This PEP proposes a adding frungible doodads [1] to the - core. It extends PEP 9876 [2] via the BCA [3] - mechanism. - - References and Footnotes - - [1] http://www.doodads.org/frungible.html - - [2] PEP 9876, Let's Hope We Never Get Here - http://www.python.org/peps/pep-9876.html - - [3] "Bogus Complexity Addition" - - Reference 1 is a simple URL reference. Reference 2 is a - footnote containing text and a URL. Reference 3 is a footnote - containing text only. Rewritten using reStructuredText, this - PEP could look like this:: - - Abstract - ======== - - This PEP proposes a adding `frungible doodads`_ to the - core. It extends PEP 9876 [#pep9876] via the BCA [#] - mechanism. - - .. _frungible doodads: - http://www.doodads.org/frungible.html - - .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here - - __ http://www.python.org/peps/pep-9876.html - - .. [#] "Bogus Complexity Addition" - - URLs and footnotes can be defined close to their references if - desired, making them easier to read in the source text, and - making the PEPs easier to revise. The "References and - Footnotes" section can be auto-generated with a document tree - transform. Footnotes from throughout the PEP would be gathered - and displayed under a standard header. If URL references - should likewise be written out explicitly (in citation form), - another tree transform could be used. - - URL references can be named ("frungible doodads"), and can be - referenced from multiple places in the document without - additional definitions. When converted to HTML, references - will be replaced with inline hyperlinks (HTML tags). The - two footnotes are automatically numbered, so they will always - stay in sync. The first footnote also contains an internal - reference name, "pep9876", so it's easier to see the connection - between reference and footnote in the source text. Named - footnotes can be referenced multiple times, maintaining - consistent numbering. - - The "#pep9876" footnote could also be written in the form of a - citation:: - - It extends PEP 9876 [PEP9876]_ ... - - .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here - - Footnotes are numbered, whereas citations use text for their - references. - - Q: Wouldn't it be better to keep the docstring and PEP proposals - separate? - - A: The PEP markup proposal is an option to this PEP. It may be - removed if it is deemed that there is no need for PEP markup. - The PEP markup proposal could be made into a separate PEP if - necessary. If accepted, PEP 1, PEP Purpose and Guidelines [19]_, - and PEP 9, Sample PEP Template [20]_ will be updated. - - It seems natural to adopt a single consistent markup standard - for all uses of plaintext in Python. - - Q: The existing pep2html.py script converts the existing PEP - format to HTML. How will the new-format PEPs be converted to - HTML? + Q1: Is reStructuredText rich enough? + + A1: Yes, it is for most people. If it lacks some construct that + is required for a specific application, it can be added via + the directive mechanism. If a common construct has been + overlooked and a suitably readable syntax can be found, it can + be added to the specification and parser. + + Q2: Is reStructuredText *too* rich? + + A2: For specific applications or individuals, perhaps. In + general, no. + + Since the very beginning, whenever a markup syntax has been + proposed on the Doc-SIG, someone has complained about the lack + of support for some construct or other. The reply was often + something like, "These are docstrings we're talking about, and + docstrings shouldn't have complex markup." The problem is + that a construct that seems superfluous to one person may be + absolutely essential to another. + + reStructuredText takes the opposite approach: it provides a + rich set of implicit markup constructs (plus a generic + extension mechanism for explicit markup), allowing for all + kinds of documents. If the set of constructs is too rich for + a particular application, the unused constructs can either be + removed from the parser (via application-specific overrides) + or simply omitted by convention. + + Q3: Why not use indentation for section structure, like + StructuredText does? Isn't it more "Pythonic"? + + A3: Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG + post: + + I still think that using indentation to indicate + sectioning is wrong. If you look at how real books and + other print publications are laid out, you'll notice that + indentation is used frequently, but mostly at the + intra-section level. Indentation can be used to offset + lists, tables, quotations, examples, and the like. (The + argument that docstrings are different because they are + input for a text formatter is wrong: the whole point is + that they are also readable without processing.) + + I reject the argument that using indentation is Pythonic: + text is not code, and different traditions and conventions + hold. People have been presenting text for readability + for over 30 centuries. Let's not innovate needlessly. + + See "Section Structure via Indentation" in "Problems With + StructuredText" [14]_ for further elaboration. + + Q4: Why use reStructuredText for PEPs? What's wrong with the + existing standard? + + A4: The existing standard for PEPs is very limited in terms of + general expressibility, and referencing is especially lacking + for such a reference-rich document type. PEPs are currently + converted into HTML, but the results (mostly monospaced text) + are less than attractive, and most of the value-added + potential of HTML is untapped. + + Making reStructuredText the standard markup for PEPs will + enable much richer expression, including support for section + structure, inline markup, graphics, and tables. In several + PEPs there are ASCII graphics diagrams, which are all that + plaintext documents can support. Since PEPs are made + available in HTML form, the ability to include proper diagrams + would be immediately useful. + + Current PEP practices allow for reference markers in the form + "[1]" in the text, and the footnotes/references themselves are + listed in a section toward the end of the document. There is + currently no hyperlinking between the reference marker and the + footnote/reference itself (it would be possible to add this to + pep2html.py, but the "markup" as it stands is ambiguous and + mistakes would be inevitable). A PEP with many references + (such as this one ;-) requires a lot of flipping back and + forth. When revising a PEP, often new references are added or + unused references deleted. It is painful to renumber the + references, since it has to be done in two places and can have + a cascading effect (insert a single new reference 1, and every + other reference has to be renumbered; always adding new + references to the end is suboptimal). It is easy for + references to go out of sync. + + PEPs use references for two purposes: simple URL references + and footnotes. reStructuredText differentiates between the + two. A PEP might contain references like this:: + + Abstract + + This PEP proposes adding frungible doodads [1] to the + core. It extends PEP 9876 [2] via the BCA [3] + mechanism. + + References and Footnotes + + [1] http://www.example.org/ + + [2] PEP 9876, Let's Hope We Never Get Here + http://www.python.org/peps/pep-9876.html + + [3] "Bogus Complexity Addition" + + Reference 1 is a simple URL reference. Reference 2 is a + footnote containing text and a URL. Reference 3 is a footnote + containing text only. Rewritten using reStructuredText, this + PEP could look like this:: + + Abstract + ======== + + This PEP proposes adding `frungible doodads`_ to the + core. It extends PEP 9876 [#pep9876]_ via the BCA [#]_ + mechanism. + + .. _frungible doodads: http://www.example.org/ + + .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here + + __ http://www.python.org/peps/pep-9876.html + + .. [#] "Bogus Complexity Addition" + + URLs and footnotes can be defined close to their references if + desired, making them easier to read in the source text, and + making the PEPs easier to revise. The "References and + Footnotes" section can be auto-generated with a document tree + transform. Footnotes from throughout the PEP would be + gathered and displayed under a standard header. If URL + references should likewise be written out explicitly (in + citation form), another tree transform could be used. + + URL references can be named ("frungible doodads"), and can be + referenced from multiple places in the document without + additional definitions. When converted to HTML, references + will be replaced with inline hyperlinks (HTML tags). The + two footnotes are automatically numbered, so they will always + stay in sync. The first footnote also contains an internal + reference name, "pep9876", so it's easier to see the + connection between reference and footnote in the source text. + Named footnotes can be referenced multiple times, maintaining + consistent numbering. + + The "#pep9876" footnote could also be written in the form of a + citation:: + + It extends PEP 9876 [PEP9876]_ ... + + .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here + + Footnotes are numbered, whereas citations use text for their + references. + + Q5: Wouldn't it be better to keep the docstring and PEP proposals + separate? + + A5: The PEP markup proposal may be removed if it is deemed that + there is no need for PEP markup, or it could be made into a + separate PEP. If accepted, PEP 1, PEP Purpose and Guidelines + [19]_, and PEP 9, Sample PEP Template [20]_ will be updated. + + It seems natural to adopt a single consistent markup standard + for all uses of structured plaintext in Python, and to propose + it all in one place. + + Q6: The existing pep2html.py script converts the existing PEP + format to HTML. How will the new-format PEPs be converted to + HTML? + + A6: One of the deliverables of the Docutils project [21]_ will be + a new version of pep2html.py with integrated reStructuredText + parsing. The Docutils project will support PEPs with a "PEP + Reader" component, including all functionality currently in + pep2html.py (auto-recognition of PEP & RFC references). + + Q7: Who's going to convert the existing PEPs to reStructuredText? + + A7: A call for volunteers will be put out to the Doc-SIG and + greater Python communities. If insufficient volunteers are + forthcoming, I (David Goodger) will convert the documents + myself, perhaps with some level of automation. A transitional + system whereby both old and new standards can coexist will be + easy to implement (and I pledge to implement it if necessary). - A: One of the deliverables of the Docutils project [21]_ will be a - new version of pep2html.py with integrated reStructuredText - parsing. The Docutils project will support PEPs with a "PEP - Reader" component, including all functionality currently in - pep2html.py (auto-recognition of PEP & RFC references). + Q8: Why use reStructuredText for README and other ancillary files? - Q: Who's going to convert the existing PEPs to reStructuredText? + A8: The reasoning given for PEPs in A4 above also applies to + README and other ancillary files. By adopting a standard + markup, these files can be converted to attractive + cross-referenced HTML and put up on python.org. Developers of + Python projects can also take advantage of this facility for + their own documentation. - A: A call for volunteers will be put out to the Doc-SIG and - greater Python communities. If insufficient volunteers are - forthcoming, I (David Goodger) will convert the documents - myself, perhaps with some level of automation. A transitional - system whereby both old and new standards can coexist will be - easy to implement (and I pledge to implement it if necessary). - - Q: Why use reStructuredText for README and other ancillary files? - - A: The same reasoning used for PEPs above applies to README and - other ancillary files. By adopting a standard markup, these - files can be converted to attractive cross-referenced HTML and - put up on python.org. Developers of Python projects can also - take advantage of this facility for their own documentation. - - -References and Footnotes + Q9: Won't the superficial similarity to existing markup + conventions cause problems, and result in people writing + invalid markup (and not noticing, because the plaintext looks + natural)? How forgiving is reStructuredText of "not quite + right" markup? + + A9: There will be some mis-steps, as there would be when moving + from one programming language to another. As with any + language, proficiency grows with experience. Luckily, + reStructuredText is a very little language indeed. + + As with any syntax, there is the possibility of syntax errors. + It is expected that a user will run the processing system over + their input and check the output for correctness. + + In a strict sense, the reStructuredText parser is very + unforgiving (as it should be; "In the face of ambiguity, + refuse the temptation to guess" [22]_ applies to parsing + markup as well as computer languages). Here's a design goal + from "An Introduction to reStructuredText" [13]_: + + 3. Unambiguous. The rules for markup must not be open for + interpretation. For any given input, there should be + one and only one possible output (including error + output). + + While unforgiving, at the same time the parser does try to be + helpful by producing useful diagnostic output ("system + messages"). The parser reports problems, indicating their + level of severity (from least to most: debug, info, warning, + error, severe). The user or the client software can decide on + reporting thresholds; they can ignore low-level problems or + cause high-level problems to bring processing to an immediate + halt. Problems are reported during the parse as well as + included in the output, often with two-way links between the + source of the problem and the system message explaining it. + + Q10: Will the docstrings in the Python standard library modules be + converted to reStructuredText? + + A10: Over time, with the help of the developer community, many + modules will be converted. Some modules may never be + converted. A future toolset will have to allow for + incompleteness. + + +References & Footnotes [1] http://structuredtext.sourceforge.net/ @@ -653,7 +732,10 @@ References and Footnotes [21] http://docutils.sourceforge.net/ - [22] PEP 216, Docstring Format, Zadka + [22] From "The Zen of Python (by Tim Peters)", + http://www.python.org/doc/Humor.html#zen + + [23] PEP 216, Docstring Format, Zadka http://www.python.org/peps/pep-0216.html @@ -664,8 +746,8 @@ Copyright Acknowledgements - Some text is borrowed from PEP 216, Docstring Format, by Moshe - Zadka [22]_. + Some text is borrowed from PEP 216, Docstring Format [23]_, by + Moshe Zadka. Special thanks to all members past & present of the Python Doc-SIG. -- cgit v1.2.1 From 937dd4cba2a71f56d703dea76578f080cbc65ef8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 4 Apr 2002 05:55:26 +0000 Subject: responding to feedback git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@10 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index a61a40253..f886d94c2 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -166,22 +166,23 @@ Rationale 4. Implicit markup is aesthetically compatible with the clean and minimalist Python syntax. - Proposed alternatives have included: + Many alternative markups have been proposed on the Doc-SIG, + including: - XML [3]_, SGML [4]_, DocBook [5]_, HTML [6]_, XHTML [7]_ XML and SGML are explicit, well-formed meta-languages suitable for all kinds of documentation. XML is a variant of SGML. They - are best used behind the scenes, because they are verbose, - difficult to type, and too cluttered to read comfortably as - source. DocBook, HTML, and XHTML are all applications of SGML - and/or XML, and all share the same basic syntax and the same - shortcomings. + are best used behind the scenes, because to untrained eyes they + are verbose, difficult to type, and too cluttered to read + comfortably as source. DocBook, HTML, and XHTML are all + applications of SGML and/or XML, and all share the same basic + syntax and the same shortcomings. - TeX [8]_ - TeX is similar to XML/SGML in that it's explicit, not very easy - to write, and not easy for the uninitiated to read. + TeX is similar to XML/SGML in that it's explicit, but not very + easy to write, and not easy for the uninitiated to read. - Perl POD [9]_ @@ -197,10 +198,9 @@ Rationale Special comments before Java classes and functions serve to document the code. A program to extract these, and turn them into HTML documentation is called javadoc, and is part of the - standard Java distribution. However, the only output format - that is supported is HTML, and JavaDoc has a very intimate - relationship with HTML, using HTML tags for most markup. Thus - it shares the readability problems of HTML. + standard Java distribution. However, JavaDoc has a very + intimate relationship with HTML, using HTML tags for most + markup. Thus it shares the readability problems of HTML. - Setext [11]_, StructuredText [12]_ @@ -234,6 +234,10 @@ Rationale - There has been no mechanism to get around the SText markup rules when a markup character is used in a non-markup context. + (Please note that this is not an exclusive list of all existing + markup systems, just a sample of those seriously proposed for + docstring use, on the Doc-SIG.) + Proponents of implicit STexts have vigorously opposed proposals for explicit markup (XML, HTML, TeX, POD, etc.), and the debates have continued off and on since 1996 or earlier. @@ -679,6 +683,13 @@ Questions & Answers converted. A future toolset will have to allow for incompleteness. + Q11: I want to write all my strings in Unicode. Will anything + break? + + A11: The parser will fully support Unicode. It may not yet, but + only because nobody's gotten around to implementing or + testing Unicode support. Contributions are always welcome! + References & Footnotes -- cgit v1.2.1 From 6b6fa81523b8fd785994f7bf20dc3f12594d467c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 13 Apr 2002 17:17:35 +0000 Subject: Preliminary post-initial-posting edit; incomplete. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@11 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 150 +++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 61 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index f886d94c2..74496d412 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -16,7 +16,7 @@ Abstract When plaintext hasn't been expressive enough for inline documentation, Python programmers have sought out a format for docstrings. This PEP proposes that the reStructuredText markup - [1]_ be adopted as the standard markup format for structured + [1]_ be adopted as a standard markup format for structured plaintext documentation in Python docstrings, and for PEPs and ancillary documents as well. reStructuredText is a rich and extensible yet easy-to-read, what-you-see-is-what-you-get @@ -41,11 +41,19 @@ Benefits systems can be extracted in context and processed into useful, high-quality documentation for multiple purposes. - The proposed format (reStructuredText) is entirely readable in - plaintext format, and many of the markup forms match common usage - (e.g., ``*emphasis*``), so it reads quite naturally. Yet it is - rich enough to produce complex documents, and extensible so that - there are few limits. + Document markup languages have three groups of customers: the + authors who write the documents, the software systems that process + the data, and the readers, who are the final consumers and the + most important group. Most markups are designed for the authors + and software systems; readers are only meant to see the processed + form, either on paper or via browser software. ReStructuredText + is different: it is intended to be easily readable in source form, + without prior knowledge of the markup. ReStructuredText) is + entirely readable in plaintext format, and many of the markup + forms match common usage (e.g., ``*emphasis*``), so it reads quite + naturally. Yet it is rich enough to produce complex documents, + and extensible so that there are few limits. Of course, to write + reStructuredText documents prior knowledge is required. The reStructuredText parser is available now. The Docutils project is at the point where standalone reStructuredText @@ -94,13 +102,18 @@ Goals The goals of this PEP are as follows: - 1. To establish reStructuredText as a standard docstring format by - attaining "accepted" status (Python community consensus; BDFL - pronouncement). Once reStructuredText is a Python standard, - effort can be focused on tools instead of arguing for a - standard. Python needs a standard set of documentation tools. + 1. To establish reStructuredText as a standard structured + plaintext format for docstrings (inline documentation of Python + modules and packages), PEPs, README-type files and other + standalone documents. "Accepted" status will be sought through + Python community consensus and eventual BDFL pronouncement. - 2. To address any related concerns raised by the Python community. + Please note that reStructuredText is being proposed as *a* + standard, not *the only* standard. Its use will be entirely + optional. Those who don't want to use it need not. + + 2. To solicit and address any related concerns raised by the + Python community. 3. To encourage community support. As long as multiple competing markups are out there, the development community remains @@ -111,29 +124,29 @@ Goals projects. It is hoped that interested developers will join forces and work on a joint/merged/common implementation. - 5. To adopt reStructuredText as the standard markup for PEPs. One - or both of the following strategies may be applied: + Once reStructuredText is a Python standard, effort can be focused + on tools instead of arguing for a standard. Python needs a + standard set of documentation tools. - a) Keep the existing PEP section structure constructs (one-line - section headers, indented body text). Subsections can - either be forbidden or supported with underlined headers in - the indented body text. + With regard to PEPs, one or both of the following strategies may + be applied: - b) Replace the PEP section structure constructs with the - reStructuredText syntax. Section headers will require - underlines, subsections will be supported out of the box, - and body text need not be indented (except for block - quotes). + a) Keep the existing PEP section structure constructs (one-line + section headers, indented body text). Subsections can + either be forbidden or supported with underlined headers in + the indented body text. - Support for RFC 2822 headers will be added to the - reStructuredText parser (unambiguous given a specific context: - the first contiguous block of a PEP document). It may be - desired to concretely specify what over/underline styles are - allowed for PEP section headers, for uniformity. + b) Replace the PEP section structure constructs with the + reStructuredText syntax. Section headers will require + underlines, subsections will be supported out of the box, + and body text need not be indented (except for block + quotes). - 6. To adopt reStructuredText as the standard markup for - README-type files and other standalone documents in the Python - distribution. + Support for RFC 2822 headers will be added to the reStructuredText + parser for PEPs (unambiguous given a specific context: the first + contiguous block of the document). It may be desired to + concretely specify what over/underline styles are allowed for PEP + section headers, for uniformity. Rationale @@ -166,8 +179,12 @@ Rationale 4. Implicit markup is aesthetically compatible with the clean and minimalist Python syntax. - Many alternative markups have been proposed on the Doc-SIG, - including: + Many alternative markups for docstrings have been proposed on the + Doc-SIG over the years; a representative sample is listed below. + Each is briefly analyzed in terms of the goals stated above. + Please note that this is *not* intended to be an exclusive list of + all existing markup systems; there are many other markups + (Texinfo, Doxygen, TIM, YODL, AFT, ...) which are not mentioned. - XML [3]_, SGML [4]_, DocBook [5]_, HTML [6]_, XHTML [7]_ @@ -234,10 +251,6 @@ Rationale - There has been no mechanism to get around the SText markup rules when a markup character is used in a non-markup context. - (Please note that this is not an exclusive list of all existing - markup systems, just a sample of those seriously proposed for - docstring use, on the Doc-SIG.) - Proponents of implicit STexts have vigorously opposed proposals for explicit markup (XML, HTML, TeX, POD, etc.), and the debates have continued off and on since 1996 or earlier. @@ -248,24 +261,26 @@ Rationale Features - Rather than repeating or summarizing the extensive - reStructuredText spec, please read the originals available from - http://structuredtext.sourceforge.net/spec/ (.txt & .html files). - Reading the documents in following order is recommended: + The specification and user documentaton for reStructuredText is + quite extensive. Rather than repeating or summarizing it all + here, links to the originals are provided. - - An Introduction to reStructuredText [13]_ + Please first take a look at "A ReStructuredText Primer" []_, a + short and gentle introduction. The "Quick reStructuredText" user + reference [18]_ quickly summarizes all of the markup constructs. + For complete and extensive details, the following documents + contain the full specification itself: - - Problems With StructuredText [14]_ (optional for those who have - used StructuredText; it explains many markup decisions made) + - An Introduction to reStructuredText [13]_ - reStructuredText Markup Specification [15]_ - - A Record of reStructuredText Syntax Alternatives [16]_ (explains - markup decisions made independently of StructuredText) - - reStructuredText Directives [17]_ - There is also a "Quick reStructuredText" user reference [18]_. + In addition, "Problems With StructuredText" [14]_ explains many + markup decisions made with regards to StructuredText, and "A + Record of reStructuredText Syntax Alternatives" [16]_ records + markup decisions made independently. A summary of features addressing often-raised docstring markup concerns follows: @@ -622,12 +637,11 @@ Questions & Answers Q7: Who's going to convert the existing PEPs to reStructuredText? - A7: A call for volunteers will be put out to the Doc-SIG and - greater Python communities. If insufficient volunteers are - forthcoming, I (David Goodger) will convert the documents - myself, perhaps with some level of automation. A transitional - system whereby both old and new standards can coexist will be - easy to implement (and I pledge to implement it if necessary). + A7: PEP authors or volunteers may convert existing PEPs if they + like, but there is no requirement to do so. The + reStructuredText-based PEPs will coexist with the old PEP + standard. The pep2html.py mentioned in A6 will process both + old and new standards. Q8: Why use reStructuredText for README and other ancillary files? @@ -678,10 +692,12 @@ Questions & Answers Q10: Will the docstrings in the Python standard library modules be converted to reStructuredText? - A10: Over time, with the help of the developer community, many - modules will be converted. Some modules may never be - converted. A future toolset will have to allow for - incompleteness. + A10: No. Python's library reference documentation is maintained + separately from the source. Docstrings in the Python + standard library should not try to duplicate the library + reference documentation. The current policy for docstrings + in the Python standard library is that they should be no more + than concise hints. Q11: I want to write all my strings in Unicode. Will anything break? @@ -690,6 +706,15 @@ Questions & Answers only because nobody's gotten around to implementing or testing Unicode support. Contributions are always welcome! + Q12: Why does the community need a new structured text design? + What is wrong with existing markup methodologies? + + A12: The existing structured text designs are deficient. + @@@ + + For Python docstrings, there is no official standard. + @@@ + References & Footnotes @@ -717,6 +742,12 @@ References & Footnotes [12] http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + [] A ReStructuredText Primer + http://structuredtext.sourceforge.net/docs/quickstart.html + + [18] Quick reStructuredText + http://structuredtext.sourceforge.net/docs/quickref.html + [13] An Introduction to reStructuredText http://structuredtext.sourceforge.net/spec/introduction.txt @@ -732,9 +763,6 @@ References & Footnotes [17] reStructuredText Directives http://structuredtext.sourceforge.net/spec/directives.txt - [18] Quick reStructuredText - http://structuredtext.sourceforge.net/docs/quickref.html - [19] PEP 1, PEP Guidelines, Warsaw, Hylton http://www.python.org/peps/pep-0001.html -- cgit v1.2.1 From ae4f07d30c23b941eb03e5ad59fb6600e74012a2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 13 Apr 2002 17:18:52 +0000 Subject: Docstring Semantics -- notes initially git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@12 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/semantics.txt | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/dev/semantics.txt diff --git a/docs/dev/semantics.txt b/docs/dev/semantics.txt new file mode 100644 index 000000000..96d2d5644 --- /dev/null +++ b/docs/dev/semantics.txt @@ -0,0 +1,38 @@ +===================== + Docstring Semantics +===================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +These are notes for a possible future PEP providing the final piece of +the Python docstring puzzle. + +PythonDoc +========= + +A Python version of the JavaDoc semantics (not syntax). A set of +conventions which are understood by the Docutils. + +- Can we extract comments from parsed modules? Could be handy for + documenting function/method parameters:: + + def method(self, + source, # path of input file + dest # path of output file + ): + + This would save having to repeat parameter names in the docstring. + + Idea from Mark Hammond's 1998-06-23 Doc-SIG post, "Re: [Doc-SIG] + Documentation tool": + + it would be quite hard to add a new param to this method without + realising you should document it + +- Use field lists or definition lists for "tagged blocks". + +- Frederic Giacometti's "iPhrase Python documentation conventions" is + an attachment to his Doc-SIG post of 2001-05-30 + (http://mail.python.org/pipermail/doc-sig/2001-May/001840.html). -- cgit v1.2.1 From 3522fa4da8a8aec1e7da46cf4eb4a5239ed17bfd Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Apr 2002 02:50:09 +0000 Subject: More editing progress. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@16 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 73 +++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 74496d412..3f0536231 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -259,31 +259,31 @@ Rationale the SText idea, addressing all of the problems listed above. -Features +Specification The specification and user documentaton for reStructuredText is quite extensive. Rather than repeating or summarizing it all here, links to the originals are provided. - Please first take a look at "A ReStructuredText Primer" []_, a + Please first take a look at "A ReStructuredText Primer" [13]_, a short and gentle introduction. The "Quick reStructuredText" user - reference [18]_ quickly summarizes all of the markup constructs. + reference [14]_ quickly summarizes all of the markup constructs. For complete and extensive details, the following documents contain the full specification itself: - - An Introduction to reStructuredText [13]_ + - An Introduction to reStructuredText [15]_ - - reStructuredText Markup Specification [15]_ + - reStructuredText Markup Specification [16]_ - reStructuredText Directives [17]_ - In addition, "Problems With StructuredText" [14]_ explains many + In addition, "Problems With StructuredText" [18]_ explains many markup decisions made with regards to StructuredText, and "A - Record of reStructuredText Syntax Alternatives" [16]_ records + Record of reStructuredText Syntax Alternatives" [19]_ records markup decisions made independently. - A summary of features addressing often-raised docstring markup - concerns follows: + +Docstring-Significant Features - A markup escaping mechanism. @@ -396,9 +396,10 @@ Features These are mostly used for extension syntax, such as "bibliographic field lists" (representing document metadata such as author, date, and version) and extension attributes for - directives (see below). They may be used to implement docstring - semantics, such as identifying parameters, exceptions raised, - etc.; such usage is beyond the scope of this PEP. + directives (see below). They may be used to implement + methodologies (docstring semantics), such as identifying + parameters, exceptions raised, etc.; such usage is beyond the + scope of this PEP. A modified RFC 2822 syntax is used, with a colon *before* as well as *after* the field name. Field bodies are more versatile @@ -508,7 +509,7 @@ Questions & Answers for over 30 centuries. Let's not innovate needlessly. See "Section Structure via Indentation" in "Problems With - StructuredText" [14]_ for further elaboration. + StructuredText" [18 ]_ for further elaboration. Q4: Why use reStructuredText for PEPs? What's wrong with the existing standard? @@ -520,8 +521,8 @@ Questions & Answers are less than attractive, and most of the value-added potential of HTML is untapped. - Making reStructuredText the standard markup for PEPs will - enable much richer expression, including support for section + Making reStructuredText a standard markup for PEPs will enable + much richer expression, including support for section structure, inline markup, graphics, and tables. In several PEPs there are ASCII graphics diagrams, which are all that plaintext documents can support. Since PEPs are made @@ -619,7 +620,7 @@ Questions & Answers A5: The PEP markup proposal may be removed if it is deemed that there is no need for PEP markup, or it could be made into a separate PEP. If accepted, PEP 1, PEP Purpose and Guidelines - [19]_, and PEP 9, Sample PEP Template [20]_ will be updated. + [20]_, and PEP 9, Sample PEP Template [21]_ will be updated. It seems natural to adopt a single consistent markup standard for all uses of structured plaintext in Python, and to propose @@ -629,7 +630,7 @@ Questions & Answers format to HTML. How will the new-format PEPs be converted to HTML? - A6: One of the deliverables of the Docutils project [21]_ will be + A6: One of the deliverables of the Docutils project [22]_ will be a new version of pep2html.py with integrated reStructuredText parsing. The Docutils project will support PEPs with a "PEP Reader" component, including all functionality currently in @@ -669,9 +670,9 @@ Questions & Answers In a strict sense, the reStructuredText parser is very unforgiving (as it should be; "In the face of ambiguity, - refuse the temptation to guess" [22]_ applies to parsing + refuse the temptation to guess" [23]_ applies to parsing markup as well as computer languages). Here's a design goal - from "An Introduction to reStructuredText" [13]_: + from "An Introduction to reStructuredText" [15 ]_: 3. Unambiguous. The rules for markup must not be open for interpretation. For any given input, there should be @@ -742,39 +743,39 @@ References & Footnotes [12] http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage - [] A ReStructuredText Primer + [13] A ReStructuredText Primer http://structuredtext.sourceforge.net/docs/quickstart.html - [18] Quick reStructuredText + [14] Quick reStructuredText http://structuredtext.sourceforge.net/docs/quickref.html - [13] An Introduction to reStructuredText + [15] An Introduction to reStructuredText http://structuredtext.sourceforge.net/spec/introduction.txt - [14] Problems with StructuredText - http://structuredtext.sourceforge.net/spec/problems.txt - - [15] reStructuredText Markup Specification + [16] reStructuredText Markup Specification http://structuredtext.sourceforge.net/spec/reStructuredText.txt - [16] A Record of reStructuredText Syntax Alternatives - http://structuredtext.sourceforge.net/spec/alternatives.txt - [17] reStructuredText Directives http://structuredtext.sourceforge.net/spec/directives.txt - [19] PEP 1, PEP Guidelines, Warsaw, Hylton + [18] Problems with StructuredText + http://structuredtext.sourceforge.net/spec/problems.txt + + [19] A Record of reStructuredText Syntax Alternatives + http://structuredtext.sourceforge.net/spec/alternatives.txt + + [20] PEP 1, PEP Guidelines, Warsaw, Hylton http://www.python.org/peps/pep-0001.html - [20] PEP 9, Sample PEP Template, Warsaw + [21] PEP 9, Sample PEP Template, Warsaw http://www.python.org/peps/pep-0009.html - [21] http://docutils.sourceforge.net/ + [22] http://docutils.sourceforge.net/ - [22] From "The Zen of Python (by Tim Peters)", - http://www.python.org/doc/Humor.html#zen + [23] From "The Zen of Python (by Tim Peters)", + http://www.python.org/doc/Humor.html#zen (or ``import this``) - [23] PEP 216, Docstring Format, Zadka + [24] PEP 216, Docstring Format, Zadka http://www.python.org/peps/pep-0216.html @@ -785,7 +786,7 @@ Copyright Acknowledgements - Some text is borrowed from PEP 216, Docstring Format [23]_, by + Some text is borrowed from PEP 216, Docstring Format [24]_, by Moshe Zadka. Special thanks to all members past & present of the Python Doc-SIG. -- cgit v1.2.1 From 101671ae44e1686680c80cd07b452aabeb88fb63 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Apr 2002 03:01:52 +0000 Subject: Initial revision git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@18 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- COPYING.txt | 34 + HISTORY.txt | 52 + MANIFEST.in | 6 + README.txt | 147 ++ docs/dev/pysource.dtd | 212 ++ docs/dev/pysource.txt | 173 ++ docs/dev/rst/alternatives.txt | 1239 +++++++++++ docs/dev/rst/problems.txt | 761 +++++++ docs/dev/todo.txt | 385 ++++ docs/peps/pep-0256.txt | 253 +++ docs/peps/pep-0257.txt | 248 +++ docs/peps/pep-0258.txt | 662 ++++++ docs/ref/doctree.txt | 344 +++ docs/ref/docutils.dtd | 514 +++++ docs/ref/rst/directives.txt | 360 +++ docs/ref/rst/introduction.txt | 307 +++ docs/ref/rst/restructuredtext.txt | 2344 ++++++++++++++++++++ docs/ref/soextblx.dtd | 312 +++ docs/user/rst/images/ball1.gif | Bin 0 -> 4361 bytes docs/user/rst/images/biohazard.bmp | Bin 0 -> 406 bytes docs/user/rst/images/biohazard.gif | Bin 0 -> 949 bytes docs/user/rst/images/biohazard.png | Bin 0 -> 179 bytes docs/user/rst/images/title.png | Bin 0 -> 1171 bytes docs/user/rst/quickref.html | 1096 +++++++++ docs/user/rst/quickstart.txt | 301 +++ docutils/__init__.py | 51 + docutils/core.py | 85 + docutils/languages/__init__.py | 22 + docutils/languages/en.py | 58 + docutils/nodes.py | 1112 ++++++++++ docutils/parsers/__init__.py | 37 + docutils/parsers/rst/__init__.py | 68 + docutils/parsers/rst/directives/__init__.py | 88 + docutils/parsers/rst/directives/admonitions.py | 55 + docutils/parsers/rst/directives/components.py | 59 + docutils/parsers/rst/directives/html.py | 89 + docutils/parsers/rst/directives/images.py | 97 + docutils/parsers/rst/directives/misc.py | 39 + docutils/parsers/rst/languages/__init__.py | 23 + docutils/parsers/rst/languages/en.py | 38 + docutils/parsers/rst/states.py | 2115 ++++++++++++++++++ docutils/parsers/rst/tableparser.py | 313 +++ docutils/readers/__init__.py | 118 + docutils/readers/standalone.py | 34 + docutils/roman.py | 81 + docutils/statemachine.py | 1076 +++++++++ docutils/transforms/__init__.py | 62 + docutils/transforms/components.py | 85 + docutils/transforms/frontmatter.py | 375 ++++ docutils/transforms/references.py | 670 ++++++ docutils/transforms/universal.py | 149 ++ docutils/urischemes.py | 94 + docutils/utils.py | 373 ++++ docutils/writers/__init__.py | 104 + docutils/writers/html4css1.py | 759 +++++++ docutils/writers/pprint.py | 28 + install.py | 20 + setup.py | 24 + test/DocutilsTestSupport.py | 379 ++++ test/UnitTestFolder.py | 135 ++ test/alltests.py | 41 + test/difflib.py | 1089 +++++++++ test/test_nodes.py | 83 + test/test_parsers/test_rst/test_TableParser.py | 197 ++ test/test_parsers/test_rst/test_block_quotes.py | 124 ++ test/test_parsers/test_rst/test_bullet_lists.py | 181 ++ test/test_parsers/test_rst/test_citations.py | 139 ++ test/test_parsers/test_rst/test_comments.py | 238 ++ .../test_parsers/test_rst/test_definition_lists.py | 317 +++ .../test_rst/test_directives/test_admonitions.py | 117 + .../test_rst/test_directives/test_contents.py | 166 ++ .../test_rst/test_directives/test_figures.py | 286 +++ .../test_rst/test_directives/test_images.py | 233 ++ .../test_rst/test_directives/test_meta.py | 141 ++ .../test_directives/test_test_directives.py | 109 + .../test_rst/test_directives/test_unknown.py | 55 + test/test_parsers/test_rst/test_doctest_blocks.py | 74 + .../test_parsers/test_rst/test_enumerated_lists.py | 662 ++++++ test/test_parsers/test_rst/test_field_lists.py | 491 ++++ test/test_parsers/test_rst/test_footnotes.py | 332 +++ test/test_parsers/test_rst/test_functions.py | 37 + test/test_parsers/test_rst/test_inline_markup.py | 659 ++++++ test/test_parsers/test_rst/test_literal_blocks.py | 190 ++ test/test_parsers/test_rst/test_option_lists.py | 684 ++++++ test/test_parsers/test_rst/test_outdenting.py | 90 + test/test_parsers/test_rst/test_paragraphs.py | 79 + test/test_parsers/test_rst/test_section_headers.py | 555 +++++ test/test_parsers/test_rst/test_substitutions.py | 192 ++ test/test_parsers/test_rst/test_tables.py | 564 +++++ test/test_parsers/test_rst/test_targets.py | 429 ++++ test/test_parsers/test_rst/test_transitions.py | 144 ++ test/test_statemachine.py | 296 +++ test/test_transforms/test_contents2.py | 262 +++ test/test_transforms/test_docinfo.py | 327 +++ test/test_transforms/test_doctitle.py | 175 ++ test/test_transforms/test_final_checks.py | 47 + test/test_transforms/test_footnotes2.py | 521 +++++ test/test_transforms/test_hyperlinks.py | 441 ++++ test/test_transforms/test_messages.py | 67 + test/test_transforms/test_substitutions.py | 61 + test/test_utils.py | 324 +++ tools/html.py | 31 + tools/publish.py | 27 + tools/quicktest.py | 185 ++ tools/stylesheets/default.css | 157 ++ 105 files changed, 30284 insertions(+) create mode 100644 COPYING.txt create mode 100644 HISTORY.txt create mode 100644 MANIFEST.in create mode 100644 README.txt create mode 100644 docs/dev/pysource.dtd create mode 100644 docs/dev/pysource.txt create mode 100644 docs/dev/rst/alternatives.txt create mode 100644 docs/dev/rst/problems.txt create mode 100644 docs/dev/todo.txt create mode 100644 docs/peps/pep-0256.txt create mode 100644 docs/peps/pep-0257.txt create mode 100644 docs/peps/pep-0258.txt create mode 100644 docs/ref/doctree.txt create mode 100644 docs/ref/docutils.dtd create mode 100644 docs/ref/rst/directives.txt create mode 100644 docs/ref/rst/introduction.txt create mode 100644 docs/ref/rst/restructuredtext.txt create mode 100644 docs/ref/soextblx.dtd create mode 100644 docs/user/rst/images/ball1.gif create mode 100644 docs/user/rst/images/biohazard.bmp create mode 100644 docs/user/rst/images/biohazard.gif create mode 100644 docs/user/rst/images/biohazard.png create mode 100644 docs/user/rst/images/title.png create mode 100644 docs/user/rst/quickref.html create mode 100644 docs/user/rst/quickstart.txt create mode 100644 docutils/__init__.py create mode 100644 docutils/core.py create mode 100644 docutils/languages/__init__.py create mode 100644 docutils/languages/en.py create mode 100644 docutils/nodes.py create mode 100644 docutils/parsers/__init__.py create mode 100644 docutils/parsers/rst/__init__.py create mode 100644 docutils/parsers/rst/directives/__init__.py create mode 100644 docutils/parsers/rst/directives/admonitions.py create mode 100644 docutils/parsers/rst/directives/components.py create mode 100644 docutils/parsers/rst/directives/html.py create mode 100644 docutils/parsers/rst/directives/images.py create mode 100644 docutils/parsers/rst/directives/misc.py create mode 100644 docutils/parsers/rst/languages/__init__.py create mode 100644 docutils/parsers/rst/languages/en.py create mode 100644 docutils/parsers/rst/states.py create mode 100644 docutils/parsers/rst/tableparser.py create mode 100644 docutils/readers/__init__.py create mode 100644 docutils/readers/standalone.py create mode 100644 docutils/roman.py create mode 100644 docutils/statemachine.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/references.py create mode 100644 docutils/transforms/universal.py create mode 100644 docutils/urischemes.py create mode 100644 docutils/utils.py create mode 100644 docutils/writers/__init__.py create mode 100644 docutils/writers/html4css1.py create mode 100644 docutils/writers/pprint.py create mode 100755 install.py create mode 100755 setup.py create mode 100644 test/DocutilsTestSupport.py create mode 100644 test/UnitTestFolder.py create mode 100755 test/alltests.py create mode 100644 test/difflib.py create mode 100755 test/test_nodes.py create mode 100755 test/test_parsers/test_rst/test_TableParser.py create mode 100755 test/test_parsers/test_rst/test_block_quotes.py create mode 100755 test/test_parsers/test_rst/test_bullet_lists.py create mode 100755 test/test_parsers/test_rst/test_citations.py create mode 100755 test/test_parsers/test_rst/test_comments.py create mode 100755 test/test_parsers/test_rst/test_definition_lists.py create mode 100755 test/test_parsers/test_rst/test_directives/test_admonitions.py create mode 100755 test/test_parsers/test_rst/test_directives/test_contents.py create mode 100755 test/test_parsers/test_rst/test_directives/test_figures.py create mode 100755 test/test_parsers/test_rst/test_directives/test_images.py create mode 100755 test/test_parsers/test_rst/test_directives/test_meta.py create mode 100755 test/test_parsers/test_rst/test_directives/test_test_directives.py create mode 100755 test/test_parsers/test_rst/test_directives/test_unknown.py create mode 100755 test/test_parsers/test_rst/test_doctest_blocks.py create mode 100755 test/test_parsers/test_rst/test_enumerated_lists.py create mode 100755 test/test_parsers/test_rst/test_field_lists.py create mode 100755 test/test_parsers/test_rst/test_footnotes.py create mode 100755 test/test_parsers/test_rst/test_functions.py create mode 100755 test/test_parsers/test_rst/test_inline_markup.py create mode 100755 test/test_parsers/test_rst/test_literal_blocks.py create mode 100755 test/test_parsers/test_rst/test_option_lists.py create mode 100755 test/test_parsers/test_rst/test_outdenting.py create mode 100755 test/test_parsers/test_rst/test_paragraphs.py create mode 100755 test/test_parsers/test_rst/test_section_headers.py create mode 100755 test/test_parsers/test_rst/test_substitutions.py create mode 100755 test/test_parsers/test_rst/test_tables.py create mode 100755 test/test_parsers/test_rst/test_targets.py create mode 100755 test/test_parsers/test_rst/test_transitions.py create mode 100755 test/test_statemachine.py create mode 100755 test/test_transforms/test_contents2.py create mode 100755 test/test_transforms/test_docinfo.py create mode 100755 test/test_transforms/test_doctitle.py create mode 100755 test/test_transforms/test_final_checks.py create mode 100755 test/test_transforms/test_footnotes2.py create mode 100755 test/test_transforms/test_hyperlinks.py create mode 100755 test/test_transforms/test_messages.py create mode 100755 test/test_transforms/test_substitutions.py create mode 100755 test/test_utils.py create mode 100755 tools/html.py create mode 100755 tools/publish.py create mode 100755 tools/quicktest.py create mode 100644 tools/stylesheets/default.css diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 000000000..fb2c3f5ae --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,34 @@ +================== + Copying Docutils +================== + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Web-site: http://docutils.sourceforge.net/ + +Most of the files included in this project are in the public domain, +and therefore have no license requirement and no restrictions on +copying or usage. The two exceptions are: + +- docutils/roman.py, copyright 2001 by Mark Pilgrim, licensed under the + `Python 2.1.1 license`_. + +- test/difflib.py, copyright by the Python Software Foundation, + licensed under the `Python 2.2 license`_. This file is included for + compatibility with Python versions less than 2.2; if you have Python + 2.2 or higher, difflib.py is not needed and may be removed. (It's + only used to report test failures anyhow; it isn't installed + anywhere. The included file is a pre-generator version of the + difflib.py module included in Python 2.2.) + +(Disclaimer: I am not a lawyer.) The Python license is OSI-approved_ +and GPL-compatible_. Although complicated by multiple owners and lots +of legalese, it basically lets you copy, use, modify, and redistribute +files as long as you keep the copyright attribution intact, note any +changes you make, and don't use the owner's name in vain. + +.. _Python 2.1.1 license: http://www.python.org/2.1.1/license.html +.. _Python 2.2 license: http://www.python.org/2.2/license.html +.. _OSI-approved: http://opensource.org/licenses/ +.. _GPL-compatible: http://www.gnu.org/philosophy/license-list.html diff --git a/HISTORY.txt b/HISTORY.txt new file mode 100644 index 000000000..afbbaf41e --- /dev/null +++ b/HISTORY.txt @@ -0,0 +1,52 @@ +================== + Docutils History +================== + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Website: http://docutils.sourceforge.net/ + + +Acknowledgements +================ + +I would like to acknowledge the people who have made a direct impact +on the Docutils project, knowingly or not, in terms of encouragement, +suggestions, criticism, bug reports, code contributions, and related +projects: + + David Ascher, Fred Drake, Jim Fulton, Peter Funk, Doug Hellmann, + Juergen Hermann, Tony Ibbs, Richard Jones, Garth Kidd, Daniel + Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken + Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, + Mark Pilgrim, Tavis Rudd, Ueli Schlaepfer, Bob Tolbert, Laurence + Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping + Yee, Moshe Zadka + +(I'm still waiting for contributions of computer equipment and cold +hard cash :-).) Hopefully I haven't forgotten anyone or misspelled +any names; apologies (and please let me know!) if I have. + + +Release 0.1 (2002-04-??) +======================== + +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.txt`__ and +the `DPS HISTORY.txt`__ files. + +__ http://structuredtext.sourceforge.net/ +__ http://docstring.sourceforge.net/ +__ http://structuredtext.sourceforge.net/HISTORY.txt +__ http://docstring.sourceforge.net/HISTORY.txt + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000000000..04191d2dc --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include *.txt +include *.py +recursive-include docs * +recursive-include spec * +recursive-include test * +recursive-include tools * diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..8b823b28d --- /dev/null +++ b/README.txt @@ -0,0 +1,147 @@ +================== + README: Docutils +================== + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Website: http://docutils.sourceforge.net/ + +Thank you for downloading the Python Docutils project arhive. As this +is a work in progress, please check the project website for updated +working files. + +To run the code, Python 2.0 or later must already be installed. You +can get Python from http://www.python.org/. + + +Project Files & Directories +=========================== + +* README.txt: You're reading it. + +* COPYING.txt: Copyright details for non-public-domain files (most are + PD). + +* HISTORY.txt: Release notes for the current and previous project + releases. + +* setup.py: Installation script. See "Installation" below. + +* install.py: Quick & dirty installation script. + +* docutils: The project source directory, installed as a Python + package. + +* docs: The project user documentation directory. The docs/rest + directory contains reStructuredText user docs. + +* spec: The project specification directory. Contains PEPs (Python + Enhancement Proposals), XML DTDs (document type definitions), and + other documents. The spec/rest directory contains the + reStructuredText specification. + +* tools: Directory for standalone scripts that use reStructuredText. + + - quicktest.py: Input reStructuredText, output pretty-printed + pseudo-XML and various other forms. + + - publish.py: A minimal example of a complete Docutils system, using + the "standalone" reader and "pformat" writer. + + - html.py: Read standalone reStructuredText documents and write + HTML4/CSS1. Uses the default.css stylesheet. + +* test: Unit tests; ``test/alltests.py`` runs all the tests. Not + required to use the software, but very useful if you're planning to + modify it. + + +Installation +============ + +The first step is to expand the .tar.gz archive. It contains a +distutils setup file "setup.py". OS-specific installation +instructions follow. + +Linux, Unix, MacOS X +-------------------- + +1. Open a shell. + +2. Go to the directory created by expanding the archive:: + + cd + +3. Install the package:: + + 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. You may need + root permissions to complete this step. + +You can also just run install.py; it does the same thing. + +Windows +------- + +1. Open a DOS box (Command Shell, MSDOS Prompt, or whatever they're + calling it these days). + +2. Go to the directory created by expanding the archive:: + + cd + +3. Install the package:: + + \python setup.py install + +If your system is set up to run Python when you double-click on .py +files, you can run install.py to do the same as the above. + +MacOS +----- + +1. Open the folder containing the expanded archive. + +2. Double-click on the file "setup.py", which should be a "Python + module" file. + + If the file isn't a "Python module", the line endings are probably + also wrong, and you will need to set up your system to recognize + ".py" file extensions as Python files. See + http://gotools.sourceforge.net/mac/python.html for detailed + instructions. Once set up, it's easiest to start over by expanding + the archive again. + +3. The distutils options window will appear. From the "Command" popup + list choose "install", click "Add", then click "OK". + +If install.py is a "Python module" (see step 2 above if it isn't), you +can run it instead of the above. The distutils options window will +not appear. + + +Usage +===== + +Start with the html.py and publish.py front-ends from the unpacked +"tools" subdirectory. Both tools take up to two arguments, the source +path and destination path, with STDIN and STDOUT being the defaults. + +The package modules are continually growing and evolving. The +``docutils.statemachine`` module is usable independently. It contains +extensive inline documentation (in reStructuredText format). + +The specs, the package structure, and the skeleton modules may also be +of interest to you. Contributions are welcome! + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/dev/pysource.dtd b/docs/dev/pysource.dtd new file mode 100644 index 000000000..463844a68 --- /dev/null +++ b/docs/dev/pysource.dtd @@ -0,0 +1,212 @@ + + + + + + + + + + + + + +%docutils; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dev/pysource.txt b/docs/dev/pysource.txt new file mode 100644 index 000000000..a75fd1d4d --- /dev/null +++ b/docs/dev/pysource.txt @@ -0,0 +1,173 @@ +====================== + Python Source Reader +====================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +This document explores issues around extracting and processing +docstrings from Python modules. + +For definitive element hierarchy details, see the "Python Plaintext +Document Interface DTD" XML document type definition, pysource.dtd_ +(which modifies the generic docutils.dtd_). Descriptions below list +'DTD elements' (XML 'generic identifiers' or tag names) corresponding +to syntax constructs. + + +.. contents:: + + +Python Source Reader +==================== + +The Python Source Reader ("PySource") model that's evolving in my mind +goes something like this: + +1. Extract the docstring/namespace [#]_ tree from the module(s) and/or + package(s). + + .. [#] See `Docstring Extractor`_ above. + +2. Run the parser on each docstring in turn, producing a forest of + doctrees (per nodes.py). + +3. Join the docstring trees together into a single tree, running + transforms: + + - merge hyperlinks + - merge namespaces + - create various sections like "Module Attributes", "Functions", + "Classes", "Class Attributes", etc.; see spec/ppdi.dtd + - convert the above special sections to ordinary doctree nodes + +4. Run transforms on the combined doctree. Examples: resolving + cross-references/hyperlinks (including interpreted text on Python + identifiers); footnote auto-numbering; first field list -> + bibliographic elements. + + (Or should step 4's transforms come before step 3?) + +5. Pass the resulting unified tree to the writer/builder. + +I've had trouble reconciling the roles of input parser and output +writer with the idea of modes ("readers" or "directors"). Does the +mode govern the tranformation of the input, the output, or both? +Perhaps the mode should be split into two. + +For example, say the source of our input is a Python module. Our +"input mode" should be the "Python Source Reader". It discovers (from +``__docformat__``) that the input parser is "reStructuredText". If we +want HTML, we'll specify the "HTML" output formatter. But there's a +piece missing. What *kind* or *style* of HTML output do we want? +PyDoc-style, LibRefMan style, etc. (many people will want to specify +and control their own style). Is the output style specific to a +particular output format (XML, HTML, etc.)? Is the style specific to +the input mode? Or can/should they be independent? + +I envision interaction between the input parser, an "input mode" , and +the output formatter. The same intermediate data format would be used +between each of these, being transformed as it progresses. + + +Docstring Extractor +=================== + +We need code that scans a parsed Python module, and returns an ordered +tree containing the names, docstrings (including attribute and +additional docstrings), and additional info (in parentheses below) of +all of the following objects: + +- packages +- modules +- module attributes (+ values) +- classes (+ inheritance) +- class attributes (+ values) +- instance attributes (+ values) +- methods (+ formal parameters & defaults) +- functions (+ formal parameters & defaults) + +(Extract comments too? For example, comments at the start of a module +would be a good place for bibliographic field lists.) + +In order to evaluate interpreted text cross-references, namespaces for +each of the above will also be required. + +See python-dev/docstring-develop thread "AST mining", started on +2001-08-14. + + +Interpreted Text +================ + +DTD elements: package, module, class, method, function, +module_attribute, class_attribute, instance_attribute, variable, +parameter, type, exception_class, warning_class. + +In Python docstrings, interpreted text is used to classify and mark up +program identifiers, such as the names of variables, functions, +classes, and modules. If the identifier alone is given, its role is +inferred implicitly according to the Python namespace lookup rules. +For functions and methods (even when dynamically assigned), +parentheses ('()') may be included:: + + This function uses `another()` to do its work. + +For class, instance and module attributes, dotted identifiers are used +when necessary:: + + class Keeper(Storer): + + """ + Extend `Storer`. Class attribute `instances` keeps track of + the number of `Keeper` objects instantiated. + """ + + instances = 0 + """How many `Keeper` objects are there?""" + + def __init__(self): + """ + Extend `Storer.__init__()` to keep track of instances. + + Keep count in `self.instances` and data in `self.data`. + """ + Storer.__init__(self) + self.instances += 1 + + self.data = [] + """Store data in a list, most recent last.""" + + def storedata(self, data): + """ + Extend `Storer.storedata()`; append new `data` to a list + (in `self.data`). + """ + self.data = data + +To classify identifiers explicitly, the role is given along with the +identifier in either prefix or suffix form:: + + Use :method:`Keeper.storedata` to store the object's data in + `Keeper.data`:instance_attribute:. + +The role may be one of 'package', 'module', 'class', 'method', +'function', 'module_attribute', 'class_attribute', +'instance_attribute', 'variable', 'parameter', 'type', +'exception_class', 'exception', 'warning_class', or 'warning'. Other +roles may be defined. + +.. _reStructuredText Markup Specification: + http://docutils.sourceforge.net/spec/rst/reStructuredText.html +.. _Docutils: http://docutils.sourceforge.net/ +.. _pysource.dtd: http://docutils.sourceforge.net/spec/pysource.dtd +.. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + fill-column: 70 + End: diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt new file mode 100644 index 000000000..9bbe9a2f1 --- /dev/null +++ b/docs/dev/rst/alternatives.txt @@ -0,0 +1,1239 @@ +================================================== + A Record of reStructuredText Syntax Alternatives +================================================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +The following are ideas, alternatives, and justifications that were +considered for reStructuredText syntax, which did not originate with +Setext_ or StructuredText_. For an analysis of constructs which *did* +originate with StructuredText or Setext, please see `Problems With +StructuredText`_. See the `reStructuredText Markup Specification`_ +for full details of the established syntax. + +.. _Setext: http://docutils.sourceforge.net/mirror/setext.html +.. _StructuredText: + http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage +.. _Problems with StructuredText: problems.html +.. _reStructuredText Markup Specification: reStructuredText.html + + +.. contents:: + + +... Or Not To Do? +================= + +This is the realm of the possible but questionably probable. These +ideas are kept here as a record of what has been proposed, for +posterity and in case any of them prove to be useful. + + +Compound Enumerated Lists +------------------------- + +Allow for compound enumerators, such as '1.1.' or '1.a.' or '1(a)', to +allow for nested enumerated lists without indentation? + + +Auto-Numbered Enumerated Lists +------------------------------ + +Add these? Example:: + + #. Item 1. + #. Item 2. + #. Item 3. + +Arabic numerals only, or any sequence if first initialized? For +example:: + + a) Item a. + #) Item b. + #) Item c. + + +Sloppy Indentation of List Items +-------------------------------- + +Perhaps the indentation shouldn't be so strict. Currently, this is +required:: + + 1. First line, + second line. + +Anything wrong with this? :: + + 1. First line, + second line. + +Problem? + + 1. First para. + + Block quote. (no good: requires some indent relative to first + para) + + Second Para. + + 2. Have to carefully define where the literal block ends:: + + Literal block + + Literal block? + +Hmm... Non-strict indentation isn't such a good idea. + + +Lazy Indentation of List Items +------------------------------ + +Another approach: Going back to the first draft of reStructuredText +(2000-11-27 post to Doc-SIG):: + + - This is the fourth item of the main list (no blank line above). + The second line of this item is not indented relative to the + bullet, which precludes it from having a second paragraph. + +Change that to *require* a blank line above and below, to reduce +ambiguity. This "loosening" may be added later, once the parser's +been nailed down. However, a serious drawback of this approach is to +limit the content of each list item to a single paragraph. + + +David's Idea for Lazy Indentation +````````````````````````````````` + +Consider a paragraph in a word processor. It is a single logical line +of text which ends with a newline, soft-wrapped arbitrarily at the +right edge of the page or screen. We can think of a plaintext +paragraph in the same way, as a single logical line of text, ending +with two newlines (a blank line) instead of one, and which may contain +arbitrary line breaks (newlines) where it was accidentally +hard-wrapped by an application. We can compensate for the accidental +hard-wrapping by "unwrapping" every unindented second and subsequent +line. The indentation of the first line of a paragraph or list item +would determine the indentation for the entire element. Blank lines +would be required between list items when using lazy indentation. + +The following example shows the lazy indentation of multiple body +elements:: + + - This is the first paragraph + of the first list item. + + Here is the second paragraph + of the first list item. + + - This is the first paragraph + of the second list item. + + Here is the second paragraph + of the second list item. + +A more complex example shows the limitations of lazy indentation:: + + - This is the first paragraph + of the first list item. + + Next is a definition list item: + + Term + Definition. The indentation of the term is + required, as is the indentation of the definition's + first line. + + When the definition extends to more than + one line, lazy indentation may occur. (This is the second + paragraph of the definition.) + + - This is the first paragraph + of the second list item. + + - Here is the first paragraph of + the first item of a nested list. + + So this paragraph would be outside of the nested list, + but inside the second list item of the outer list. + + But this paragraph is not part of the list at all. + +And the ambiguity remains:: + + - Look at the hyphen at the beginning of the next line + - is it a second list item marker, or a dash in the text? + + Similarly, we may want to refer to numbers inside enumerated + lists: + + 1. How many socks in a pair? There are + 2. How many pants in a pair? Exactly + 1. Go figure. + +Literal blocks and block quotes would still require consistent +indentation for all their lines. For block quotes, we might be able +to get away with only requiring that the first line of each contained +element be indented. For example:: + + Here's a paragraph. + + This is a paragraph inside a block quote. + Second and subsequent lines need not be indented at all. + + - A bullet list inside + the block quote. + + Second paragraph of the + bullet list inside the block quote. + +Although feasible, this form of lazy indentation has problems. The +document structure and hierarchy is not obvious from the indentation, +making the source plaintext difficult to read. This will also make +keeping track of the indentation while writing difficult and +error-prone. However, these problems may be acceptable for Wikis and +email mode, where we may be able to rely on less complex structure +(few nested lists, for example). + + +Field Lists +=========== + +Prior to the syntax for field lists being finalized, several +alternatives were proposed. + +1. Unadorned RFC822_ everywhere:: + + Author: Me + Version: 1 + + Advantages: clean, precedent (RFC822-compliant). Disadvantage: + ambiguous (these paragraphs are a prime example). + + Conclusion: rejected. + +2. Special case: use unadorned RFC822_ for the very first or very last + text block of a document:: + + """ + Author: Me + Version: 1 + + The rest of the document... + """ + + Advantages: clean, precedent (RFC822-compliant). Disadvantages: + special case, flat (unnested) field lists only, still ambiguous:: + + """ + Usage: cmdname [options] arg1 arg2 ... + + We obviously *don't* want the like above to be interpreted as a + field list item. Or do we? + """ + + Conclusion: rejected for the general case, accepted for specific + contexts (PEPs, email). + +3. Use a directive:: + + .. fields:: + + Author: Me + Version: 1 + + Advantages: explicit and unambiguous, RFC822-compliant. + Disadvantage: cumbersome. + + Conclusion: rejected for the general case (but such a directive + could certainly be written). + +4. Use Javadoc-style:: + + @Author: Me + @Version: 1 + @param a: integer + + Advantages: unambiguous, precedent, flexible. Disadvantages: + non-intuitive, ugly, not RFC822-compliant. + + Conclusion: rejected. + +5. Use leading colons:: + + :Author: Me + :Version: 1 + + Advantages: unambiguous, obvious (*almost* RFC822-compliant), + flexible, perhaps even elegant. Disadvantages: no precedent, not + quite RFC822-compliant. + + Conclusion: accepted! + +6. Use double colons:: + + Author:: Me + Version:: 1 + + Advantages: unambiguous, obvious? (*almost* RFC822-compliant), + flexible, similar to syntax already used for literal blocks and + directives. Disadvantages: no precedent, not quite + RFC822-compliant, similar to syntax already used for literal blocks + and directives. + + Conclusion: rejected because of the syntax similarity & conflicts. + +Why is RFC822 compliance important? It's a universal Internet +standard, and super obvious. Also, I'd like to support the PEP format +(ulterior motive: get PEPs to use reStructuredText as their standard). +But it *would* be easy to get used to an alternative (easy even to +convert PEPs; probably harder to convert python-deviants ;-). + +Unfortunately, without well-defined context (such as in email headers: +RFC822 only applies before any blank lines), the RFC822 format is +ambiguous. It is very common in ordinary text. To implement field +lists unambiguously, we need explicit syntax. + +The following question was posed in a footnote: + + Should "bibliographic field lists" be defined at the parser level, + or at the DPS transformation level? In other words, are they + reStructuredText-specific, or would they also be applicable to + another (many/every other?) syntax? + +The answer is that bibliographic fields are a +reStructuredText-specific markup convention. Other syntaxes may +implement the bibliographic elements explicitly. For example, there +would be no need for such a transformation for an XML-based markup +syntax. + +.. _RFC822: http://www.rfc-editor.org/rfc/rfc822.txt + + +Interpreted Text "Roles" +======================== + +The original purpose of interpreted text was as a mechanism for +descriptive markup, to describe the nature or role of a word or +phrase. For example, in XML we could say "len" +to mark up "len" as a function. It is envisaged that within Python +docstrings (inline documentation in Python module source files, the +primary market for reStructuredText) the role of a piece of +interpreted text can be inferred implicitly from the context of the +docstring within the program source. For other applications, however, +the role may have to be indicated explicitly. + +Interpreted text is enclosed in single backquotes (`). + +1. Initially, it was proposed that an explicit role could be indicated + as a word or phrase within the enclosing backquotes: + + - As a prefix, separated by a colon and whitespace:: + + `role: interpreted text` + + - As a suffix, separated by whitespace and a colon:: + + `interpreted text :role` + + There are problems with the initial approach: + + - There could be ambiguity with interpreted text containing colons. + For example, an index entry of "Mission: Impossible" would + require a backslash-escaped colon. + + - The explicit role is descriptive markup, not content, and will + not be visible in the processed output. Putting it inside the + backquotes doesn't feel right; the *role* isn't being quoted. + +2. Tony Ibbs suggested that the role be placed outside the + backquotes:: + + role:`prefix` or `suffix`:role + + This removes the embedded-colons ambiguity, but limits the role + identifier to be a single word (whitespace would be illegal). + Since roles are not meant to be visible after processing, the lack + of whitespace support is not important. + + The suggested syntax remains ambiguous with respect to ratios and + some writing styles. For example, suppose there is a "signal" + identifier, and we write:: + + ...calculate the `signal`:noise ratio. + + "noise" looks like a role. + +3. As an improvement on #2, we can bracket the role with colons:: + + :role:`prefix` or `suffix`:role: + + This syntax is similar to that of field lists, which is fine since + both are doing similar things: describing. + + This is the syntax chosen for reStructuredText. + +4. Another alternative is two colons instead of one:: + + role::`prefix` or `suffix`::role + + But this is used for analogies ("A:B::C:D": "A is to B as C is to + D"). + + Both alternative #2 and #4 lack delimiters on both sides of the + role, making it difficult to parse (by the reader). + +5. Some kind of bracketing could be used: + + - Parentheses:: + + (role)`prefix` or `suffix`(role) + + - Braces:: + + {role}`prefix` or `suffix`{role} + + - Square brackets:: + + [role]`prefix` or `suffix`[role] + + - Angle brackets:: + + `prefix` or `suffix` + + (The overlap of \*ML tags with angle brackets would be too + confusing and precludes their use.) + +Syntax #3 was chosen for reStructuredText. + + +Comments +======== + +A problem with comments (actually, with all indented constructs) is +that they cannot be followed by an indented block -- a block quote -- +without swallowing it up. + +I thought that perhaps comments should be one-liners only. But would +this mean that footnotes, hyperlink targets, and directives must then +also be one-liners? Not a good solution. + +Tony Ibbs suggested a "comment" directive. I added that we could +limit a comment to a single text block, and that a "multi-block +comment" could use "comment-start" and "comment-end" directives. This +would remove the indentation incompatibility. A "comment" directive +automatically suggests "footnote" and (hyperlink) "target" directives +as well. This could go on forever! Bad choice. + +Garth Kidd suggested that an "empty comment", a ".." explicit markup +start with nothing on the first line (except possibly whitespace) and +a blank line immediately following, could serve as an "unindent". An +empty comment does **not** swallow up indented blocks following it, +so block quotes are safe. "A tiny but practical wart." Accepted. + + +Anonymous Hyperlinks +==================== + +Alan Jaffray came up with this idea, along with the following syntax:: + + Search the `Python DOC-SIG mailing list archives`{}_. + + .. _: http://mail.python.org/pipermail/doc-sig/ + +The idea is sound and useful. I suggested a "double underscore" +syntax:: + + Search the `Python DOC-SIG mailing list archives`__. + + .. __: http://mail.python.org/pipermail/doc-sig/ + +But perhaps single underscores are okay? The syntax looks better, but +the hyperlink itself doesn't explicitly say "anonymous":: + + Search the `Python DOC-SIG mailing list archives`_. + + .. _: http://mail.python.org/pipermail/doc-sig/ + +Mixing anonymous and named hyperlinks becomes confusing. The order of +targets is not significant for named hyperlinks, but it is for +anonymous hyperlinks:: + + Hyperlinks: anonymous_, named_, and another anonymous_. + + .. _named: named + .. _: anonymous1 + .. _: anonymous2 + +Without the extra syntax of double underscores, determining which +hyperlink references are anonymous may be difficult. We'd have to +check which references don't have corresponding targets, and match +those up with anonymous targets. Keeping to a simple consistent +ordering (as with auto-numbered footnotes) seems simplest. + +reStructuredText will use the explicit double-underscore syntax for +anonymous hyperlinks. An alternative (see `Reworking Explicit +Markup`_ below) for the somewhat awkward ".. __:" syntax is "__":: + + An anonymous__ reference. + + __ http://anonymous + + +Reworking Explicit Markup +========================= + +Alan Jaffray came up with the idea of `anonymous hyperlinks`_, added +to reStructuredText. Subsequently it was asserted that hyperlinks +(especially anonymous hyperlinks) would play an increasingly important +role in reStructuredText documents, and therefore they require a +simpler and more concise syntax. This prompted a review of the +current and proposed explicit markup syntaxes with regards to +improving usability. + +1. Original syntax:: + + .. _blah: internal hyperlink target + .. _blah: http://somewhere external hyperlink target + .. _blah: blahblah_ indirect hyperlink target + .. __: anonymous internal target + .. __: http://somewhere anonymous external target + .. __: blahblah_ anonymous indirect target + .. [blah] http://somewhere footnote + .. blah:: http://somewhere directive + .. blah: http://somewhere comment + + .. Note:: + + The comment text was intentionally made to look like a hyperlink + target. + + Origins: + + * Except for the colon (a delimiter necessary to allow for + phrase-links), hyperlink target ``.. _blah:`` comes from Setext. + * Comment syntax from Setext. + * Footnote syntax from StructuredText ("named links"). + * Directives and anonymous hyperlinks original to reStructuredText. + + Advantages: + + + Consistent explicit markup indicator: "..". + + Consistent hyperlink syntax: ".. _" & ":". + + Disadvantages: + + - Anonymous target markup is awkward: ".. __:". + - The explicit markup indicator ("..") is excessively overloaded? + - Comment text is limited (can't look like a footnote, hyperlink, + or directive). But this is probably not important. + +2. Alan Jaffray's proposed syntax #1:: + + __ _blah internal hyperlink target + __ blah: http://somewhere external hyperlink target + __ blah: blahblah_ indirect hyperlink target + __ anonymous internal target + __ http://somewhere anonymous external target + __ blahblah_ anonymous indirect target + __ [blah] http://somewhere footnote + .. blah:: http://somewhere directive + .. blah: http://somewhere comment + + The hyperlink-connoted underscores have become first-level syntax. + + Advantages: + + + Anonymous targets are simpler. + + All hyperlink targets are one character shorter. + + Disadvantages: + + - Inconsistent internal hyperlink targets. Unlike all other named + hyperlink targets, there's no colon. There's an extra leading + underscore, but we can't drop it because without it, "blah" looks + like a relative URI. Unless we restore the colon:: + + __ blah: internal hyperlink target + + - Obtrusive markup? + +3. Alan Jaffray's proposed syntax #2:: + + .. _blah internal hyperlink target + .. blah: http://somewhere external hyperlink target + .. blah: blahblah_ indirect hyperlink target + .. anonymous internal target + .. http://somewhere anonymous external target + .. blahblah_ anonymous indirect target + .. [blah] http://somewhere footnote + !! blah: http://somewhere directive + ## blah: http://somewhere comment + + Leading underscores have been (almost) replaced by "..", while + comments and directives have gained their own syntax. + + Advantages: + + + Anonymous hyperlinks are simpler. + + Unique syntax for comments. Connotation of "comment" from + some programming languages (including our favorite). + + Unique syntax for directives. Connotation of "action!". + + Disadvantages: + + - Inconsistent internal hyperlink targets. Again, unlike all other + named hyperlink targets, there's no colon. There's a leading + underscore, matching the trailing underscores of references, + which no other hyperlink targets have. We can't drop that one + leading underscore though: without it, "blah" looks like a + relative URI. Again, unless we restore the colon:: + + .. blah: internal hyperlink target + + - All (except for internal) hyperlink targets lack their leading + underscores, losing the "hyperlink" connotation. + + - Obtrusive syntax for comments. Alternatives:: + + ;; blah: http://somewhere + (also comment syntax in Lisp & others) + ,, blah: http://somewhere + ("comma comma": sounds like "comment"!) + + - Iffy syntax for directives. Alternatives? + +4. Tony Ibbs' proposed syntax:: + + .. _blah: internal hyperlink target + .. _blah: http://somewhere external hyperlink target + .. _blah: blahblah_ indirect hyperlink target + .. anonymous internal target + .. http://somewhere anonymous external target + .. blahblah_ anonymous indirect target + .. [blah] http://somewhere footnote + .. blah:: http://somewhere directive + .. blah: http://somewhere comment + + This is the same as the current syntax, except for anonymous + targets which drop their "__: ". + + Advantage: + + + Anonymous targets are simpler. + + Disadvantages: + + - Anonymous targets lack their leading underscores, losing the + "hyperlink" connotation. + - Anonymous targets are almost indistinguishable from comments. + (Better to know "up front".) + +5. David Goodger's proposed syntax: Perhaps going back to one of + Alan's earlier suggestions might be the best solution. How about + simply adding "__ " as a synonym for ".. __: " in the original + syntax? These would become equivalent:: + + .. __: anonymous internal target + .. __: http://somewhere anonymous external target + .. __: blahblah_ anonymous indirect target + + __ anonymous internal target + __ http://somewhere anonymous external target + __ blahblah_ anonymous indirect target + +Alternative 5 has been adopted. + + +Backquotes in Phrase-Links +========================== + +[From a 2001-06-05 Doc-SIG post in reply to questions from Doug +Hellmann.] + +The first draft of the spec, posted to the Doc-SIG in November 2000, +used square brackets for phrase-links. I changed my mind because: + +1. In the first draft, I had already decided on single-backquotes for + inline literal text. + +2. However, I wanted to minimize the necessity for backslash escapes, + for example when quoting Python repr-equivalent syntax that uses + backquotes. + +3. The processing of identifiers (funtion/method/attribute/module/etc. + names) into hyperlinks is a useful feature. PyDoc recognizes + identifiers heuristically, but it doesn't take much imagination to + come up with counter-examples where PyDoc's heuristics would result + in embarassing failure. I wanted to do it deterministically, and + that called for syntax. I called this construct 'interpreted + text'. + +4. Leveraging off the ``*emphasis*/**strong**`` syntax, lead to the + idea of using double-backquotes as syntax. + +5. I worked out some rules for inline markup recognition. + +6. In combination with #5, double backquotes lent themselves to inline + literals, neatly satisfying #2, minimizing backslash escapes. In + fact, the spec says that no interpretation of any kind is done + within double-backquote inline literal text; backslashes do *no* + escaping within literal text. + +7. Single backquotes are then freed up for interpreted text. + +8. I already had square brackets required for footnote references. + +9. Since interpreted text will typically turn into hyperlinks, it was + a natural fit to use backquotes as the phrase-quoting syntax for + trailing-underscore hyperlinks. + +The original inspiration for the trailing underscore hyperlink syntax +was Setext. But for phrases Setext used a very cumbersome +``underscores_between_words_like_this_`` syntax. + +The underscores can be viewed as if they were right-pointing arrows: +``-->``. So ``hyperlink_`` points away from the reference, and +``.. _hyperlink:`` points toward the target. + + +Substitution Mechanism +====================== + +Substitutions arose out of a Doc-SIG thread begun on 2001-10-28 by +Alan Jaffray, "reStructuredText inline markup". It reminded me of a +missing piece of the reStructuredText puzzle, first referred to in my +contribution to "Documentation markup & processing / PEPs" (Doc-SIG +2001-06-21). + +Substitutions allow the power and flexibility of directives to be +shared by inline text. They are a way to allow arbitrarily complex +inline objects, while keeping the details out of the flow of text. +They are the equivalent of SGML/XML's named entities. For example, an +inline image (using reference syntax alternative 4d (vertical bars) +and definition alternative 3, the alternatives chosen for inclusion in +the spec):: + + The |biohazard| symbol must be used on containers used to dispose + of medical waste. + + .. |biohazard| image:: biohazard.png + [height=20 width=20] + +The ``|biohazard|`` substitution reference will be replaced in-line by +whatever the ``.. |biohazard|`` substitution definition generates (in +this case, an image). A substitution definition contains the +substitution text bracketed with vertical bars, followed by a an +embedded inline-compatible directive, such as "image". A transform is +required to complete the substitution. + +Syntax alternatives for the reference: + +1. Use the existing interpreted text syntax, with a predefined role + such as "sub":: + + The `biohazard`:sub: symbol... + + Advantages: existing syntax, explicit. Disadvantages: verbose, + obtrusive. + +2. Use a variant of the interpreted text syntax, with a new suffix + akin to the underscore in phrase-link references:: + + (a) `name`@ + (b) `name`# + (c) `name`& + (d) `name`/ + (e) `name`< + (f) `name`:: + (g) `name`: + + + Due to incompatibility with other constructs and ordinary text + usage, (f) and (g) are not possible. + +3. Use interpreted text syntax with a fixed internal format:: + + (a) `:name:` + (b) `name:` + (c) `name::` + (d) `::name::` + (e) `%name%` + (f) `#name#` + (g) `/name/` + (h) `&name&` + (i) `|name|` + (j) `[name]` + (k) `` + (l) `&name;` + (m) `'name'` + + To avoid ML confusion (k) and (l) are definitely out. Square + brackets (j) won't work in the target (the substitution definition + would be indistinguishable from a footnote). + + The ```/name/``` syntax (g) is reminiscent of "s/find/sub" + substitution syntax in ed-like languages. However, it may have a + misleading association with regexps, and looks like an absolute + POSIX path. (i) is visually equivalent and lacking the + connotations. + + A disadvantage of all of these is that they limit interpreted text, + albeit only slightly. + +4. Use specialized syntax, something new:: + + (a) #name# + (b) @name@ + (c) /name/ + (d) |name| + (e) <> + (f) //name// + (g) ||name|| + (h) ^name^ + (i) [[name]] + (j) ~name~ + (k) !name! + (l) =name= + (m) ?name? + (n) >name< + + "#" (a) and "@" (b) are obtrusive. "/" (c) without backquotes + looks just like a POSIX path; it is likely for such usage to appear + in text. + + "|" (d) and "^" (h) are feasible. + +5. Redefine the trailing underscore syntax. See definition syntax + alternative 4, below. + +Syntax alternatives for the definition: + +1. Use the existing directive syntax, with a predefined directive such + as "sub". It contains a further embedded directive resolving to an + inline-compatible object:: + + .. sub:: biohazard + .. image:: biohazard.png + [height=20 width=20] + + .. sub:: parrot + That bird wouldn't *voom* if you put 10,000,000 volts + through it! + + The advantages and disadvantages are the same as in inline + alternative 1. + +2. Use syntax as in #1, but with an embedded directivecompressed:: + + .. sub:: biohazard image:: biohazard.png + [height=20 width=20] + + This is a bit better than alternative 1, but still too much. + +3. Use a variant of directive syntax, incorporating the substitution + text, obviating the need for a special "sub" directive name. If we + assume reference alternative 4d (vertical bars), the matching + definition would look like this:: + + .. |biohazard| image:: biohazard.png + [height=20 width=20] + +4. (Suggested by Alan Jaffray on Doc-SIG from 2001-11-06.) + + Instead of adding new syntax, redefine the trailing underscore + syntax to mean "substitution reference" instead of "hyperlink + reference". Alan's example:: + + I had lunch with Jonathan_ today. We talked about Zope_. + + .. _Jonathan: lj [user=jhl] + .. _Zope: http://www.zope.org/ + + A problem with the proposed syntax is that URIs which look like + simple reference names (alphanum plus ".", "-", "_") would be + indistinguishable from substitution directive names. A more + consistent syntax would be:: + + I had lunch with Jonathan_ today. We talked about Zope_. + + .. _Jonathan: lj:: user=jhl + .. _Zope: http://www.zope.org/ + + (``::`` after ``.. _Jonathan: lj``.) + + The "Zope" target is a simple external hyperlink, but the + "Jonathan" target contains a directive. Alan proposed is that the + reference text be replaced by whatever the referenced directive + (the "directive target") produces. A directive reference becomes a + hyperlink reference if the contents of the directive target resolve + to a hyperlink. If the directive target resolves to an icon, the + reference is replaced by an inline icon. If the directive target + resolves to a hyperlink, the directive reference becomes a + hyperlink reference. + + This seems too indirect and complicated for easy comprehension. + + The reference in the text will sometimes become a link, sometimes + not. Sometimes the reference text will remain, sometimes not. We + don't know *at the reference*:: + + This is a `hyperlink reference`_; its text will remain. + This is an `inline icon`_; its text will disappear. + + That's a problem. + +The syntax that has been incorporated into the spec and parser is +reference alternative 4d with definition alternative 3:: + + The |biohazard| symbol... + + .. |biohazard| image:: biohazard.png + [height=20 width=20] + +We can also combine substitution references with hyperlink references, +by appending a "_" (named hyperlink reference) or "__" (anonymous +hyperlink reference) suffix to the substitution reference. This +allows us to click on an image-link:: + + The |biohazard|_ symbol... + + .. |biohazard| image:: biohazard.png + [height=20 width=20] + .. _biohazard: http://www.cdc.gov/ + +There have been several suggestions for the naming of these +constructs, originally called "substitution references" and +"substitutions". + +1. Candidate names for the reference construct: + + (a) substitution reference + (b) tagging reference + (c) inline directive reference + (d) directive reference + (e) indirect inline directive reference + (f) inline directive placeholder + (g) inline directive insertion reference + (h) directive insertion reference + (i) insertion reference + (j) directive macro reference + (k) macro reference + (l) substitution directive reference + +2. Candidate names for the definition construct: + + (a) substitution + (b) substitution directive + (c) tag + (d) tagged directive + (e) directive target + (f) inline directive + (g) inline directive definition + (h) referenced directive + (i) indirect directive + (j) indirect directive definition + (k) directive definition + (l) indirect inline directive + (m) named directive definition + (n) inline directive insertion definition + (o) directive insertion definition + (p) insertion definition + (q) insertion directive + (r) substitution definition + (s) directive macro definition + (t) macro definition + (u) substitution directive definition + (v) substitution definition + +"Inline directive reference" (1c) seems to be an appropriate term at +first, but the term "inline" is redundant in the case of the +reference. Its counterpart "inline directive definition" (2g) is +awkward, because the directive definition itself is not inline. + +"Directive reference" (1d) and "directive definition" (2k) are too +vague. "Directive definition" could be used to refer to any +directive, not just those used for inline substitutions. + +One meaning of the term "macro" (1k, 2s, 2t) is too +programming-language-specific. Also, macros are typically simple text +substitution mechanisms: the text is substituted first and evaluated +later. reStructuredText substitution definitions are evaluated in +place at parse time and substituted afterwards. + +"Insertion" (1h, 1i, 2n-2q) is almost right, but it implies that +something new is getting added rather than one construct being +replaced by another. + +Which brings us back to "substitution". The overall best names are +"substitution reference" (1a) and "substitution definition" (2v). A +long way to go to add one word! + + +Reworking Footnotes +=================== + +As a further wrinkle (see `Reworking Explicit Markup`_ above), in the +wee hours of 2002-02-28 I posted several ideas for changes to footnote +syntax: + + - Change footnote syntax from ``.. [1]`` to ``_[1]``? ... + - Differentiate (with new DTD elements) author-date "citations" + (``[GVR2002]``) from numbered footnotes? ... + - Render footnote references as superscripts without "[]"? ... + +These ideas are all related, and suggest changes in the +reStructuredText syntax as well as the docutils tree model. + +The footnote has been used for both true footnotes (asides expanding +on points or defining terms) and for citations (references to external +works). Rather than dealing with one amalgam construct, we could +separate the current footnote concept into strict footnotes and +citations. Citations could be interpreted and treated differently +from footnotes. Footnotes would be limited to numerical labels: +manual ("1") and auto-numbered (anonymous "#", named "#label"). + +The footnote is the only explicit markup construct (starts with ".. ") +that directly translates to a visible body element. I've always been +a little bit uncomfortable with the ".. " marker for footnotes because +of this; ".. " has a connotation of "special", but footnotes aren't +especially "special". Printed texts often put footnotes at the bottom +of the page where the reference occurs (thus "foot note"). Some HTML +designs would leave footnotes to be rendered the same positions where +they're defined. Other online and printed designs will gather +footnotes into a section near the end of the document, converting them +to "endnotes" (perhaps using a directive in our case); but this +"special processing" is not an intrinsic property of the footnote +itself, but a decision made by the document author or processing +system. + +Citations are almost invariably collected in a section at the end of a +document or section. Citations "disappear" from where they are +defined and are magically reinserted at some well-defined point. +There's more of a connection to the "special" connotation of the ".. " +syntax. The point at which the list of citations is inserted could be +defined manually by a directive (e.g., ".. citations::"), and/or have +default behavior (e.g., a section automatically inserted at the end of +the document) that might be influenced by options to the Writer. + +Syntax proposals: + ++ Footnotes: + + - Current syntax:: + + .. [1] Footnote 1 + .. [#] Auto-numbered footnote. + .. [#label] Auto-labeled footnote. + + - The syntax proposed in the original 2002-02-28 Doc-SIG post: + remove the ".. ", prefix a "_":: + + _[1] Footnote 1 + _[#] Auto-numbered footnote. + _[#label] Auto-labeled footnote. + + The leading underscore syntax (earlier dropped because + ``.. _[1]:`` was too verbose) is a useful reminder that footnotes + are hyperlink targets. + + - Minimal syntax: remove the ".. [" and "]", prefix a "_", and + suffix a ".":: + + _1. Footnote 1. + _#. Auto-numbered footnote. + _#label. Auto-labeled footnote. + + ``_1.``, ``_#.``, and ``_#label.`` are markers, + like list markers. + + Footnotes could be rendered something like this in HTML + + | 1. This is a footnote. The brackets could be dropped + | from the label, and a vertical bar could set them + | off from the rest of the document in the HTML. + + Two-way hyperlinks on the footnote marker ("1." above) would also + help to differentiate footnotes from enumerated lists. + + If converted to endnotes (by a directive/transform), a horizontal + half-line might be used instead. Page-oriented output formats + would typically use the horizontal line for true footnotes. + ++ Footnote references: + + - Current syntax:: + + [1]_, [#]_, [#label]_ + + - Minimal syntax to match the minimal footnote syntax above:: + + 1_, #_, #label_ + + As a consequence, pure-numeric hyperlink references would not be + possible; they'd be interpreted as footnote references. + ++ Citation references: no change is proposed from the current footnote + reference syntax:: + + [GVR2001]_ + ++ Citations: + + - Current syntax (footnote syntax):: + + .. [GVR2001] Python Documentation; van Rossum, Drake, et al.; + http://www.python.org/doc/ + + - Possible new syntax:: + + _[GVR2001] Python Documentation; van Rossum, Drake, et al.; + http://www.python.org/doc/ + + _[DJG2002] + Docutils: Python Documentation Utilities project; Goodger + et al.; http://docutils.sourceforge.net/ + + Without the ".. " marker, subsequent lines would either have to + align as in one of the above, or we'd have to allow loose + alignment (I'd rather not):: + + _[GVR2001] Python Documentation; van Rossum, Drake, et al.; + http://www.python.org/doc/ + +I proposed adopting the "minimal" syntax for footnotes and footnote +references, and adding citations and citation references to +reStructuredText's repertoire. The current footnote syntax for +citations is better than the alternatives given. + +From a reply by Tony Ibbs on 2002-03-01: + + However, I think easier with examples, so let's create one:: + + Fans of Terry Pratchett are perhaps more likely to use + footnotes [1]_ in their own writings than other people + [2]_. Of course, in *general*, one only sees footnotes + in academic or technical writing - it's use in fiction + and letter writing is not normally considered good + style [4]_, particularly in emails (not a medium that + lends itself to footnotes). + + .. [1] That is, little bits of referenced text at the + bottom of the page. + .. [2] Because Terry himself does, of course [3]_. + .. [3] Although he has the distinction of being + *funny* when he does it, and his fans don't always + achieve that aim. + .. [4] Presumably because it detracts from linear + reading of the text - this is, of course, the point. + + and look at it with the second syntax proposal:: + + Fans of Terry Pratchett are perhaps more likely to use + footnotes [1]_ in their own writings than other people + [2]_. Of course, in *general*, one only sees footnotes + in academic or technical writing - it's use in fiction + and letter writing is not normally considered good + style [4]_, particularly in emails (not a medium that + lends itself to footnotes). + + _[1] That is, little bits of referenced text at the + bottom of the page. + _[2] Because Terry himself does, of course [3]_. + _[3] Although he has the distinction of being + *funny* when he does it, and his fans don't always + achieve that aim. + _[4] Presumably because it detracts from linear + reading of the text - this is, of course, the point. + + (I note here that if I have gotten the indentation of the + footnotes themselves correct, this is clearly not as nice. And if + the indentation should be to the left margin instead, I like that + even less). + + and the third (new) proposal:: + + Fans of Terry Pratchett are perhaps more likely to use + footnotes 1_ in their own writings than other people + 2_. Of course, in *general*, one only sees footnotes + in academic or technical writing - it's use in fiction + and letter writing is not normally considered good + style 4_, particularly in emails (not a medium that + lends itself to footnotes). + + _1. That is, little bits of referenced text at the + bottom of the page. + _2. Because Terry himself does, of course 3_. + _3. Although he has the distinction of being + *funny* when he does it, and his fans don't always + achieve that aim. + _4. Presumably because it detracts from linear + reading of the text - this is, of course, the point. + + I think I don't, in practice, mind the targets too much (the use + of a dot after the number helps a lot here), but I do have a + problem with the body text, in that I don't naturally separate out + the footnotes as different than the rest of the text - instead I + keep wondering why there are numbers interspered in the text. The + use of brackets around the numbers ([ and ]) made me somehow parse + the footnote references as "odd" - i.e., not part of the body text + - and thus both easier to skip, and also (paradoxically) easier to + pick out so that I could follow them. + + Thus, for the moment (and as always susceptable to argument), I'd + say -1 on the new form of footnote reference (i.e., I much prefer + the existing ``[1]_`` over the proposed ``1_``), and ambivalent + over the proposed target change. + + That leaves David's problem of wanting to distinguish footnotes + and citations - and the only thing I can propose there is that + footnotes are numeric or # and citations are not (which, as a + human being, I can probably cope with!). + +From a reply by Paul Moore on 2002-03-01: + + I think the current footnote syntax ``[1]_`` is *exactly* the + right balance of distinctness vs unobtrusiveness. I very + definitely don't think this should change. + + On the target change, it doesn't matter much to me. + +From a further reply by Tony Ibbs on 2002-03-01, referring to the +"[1]" form and actual usage in email: + + Clearly this is a form people are used to, and thus we should + consider it strongly (in the same way that the usage of ``*..*`` + to mean emphasis was taken partly from email practise). + + Equally clearly, there is something "magical" for people in the + use of a similar form (i.e., ``[1]``) for both footnote reference + and footnote target - it seems natural to keep them similar. + + ... + + I think that this established plaintext usage leads me to strongly + believe we should retain square brackets at both ends of a + footnote. The markup of the reference end (a single trailing + underscore) seems about as minimal as we can get away with. The + markup of the target end depends on how one envisages the thing - + if ".." means "I am a target" (as I tend to see it), then that's + good, but one can also argue that the "_[1]" syntax has a neat + symmetry with the footnote reference itself, if one wishes (in + which case ".." presumably means "hidden/special" as David seems + to think, which is why one needs a ".." *and* a leading underline + for hyperlink targets. + +Given the persuading arguments voiced, we'll leave footnote & footnote +reference syntax alone. Except that these discussions gave rise to +the "auto-symbol footnote" concept, which has been added. Citations +and citation references have also been added. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt new file mode 100644 index 000000000..f366bdf3f --- /dev/null +++ b/docs/dev/rst/problems.txt @@ -0,0 +1,761 @@ +============================== + Problems With StructuredText +============================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +There are several problems, unresolved issues, and areas of +controversy within StructuredText_ (Classic and Next Generation). In +order to resolve all these issues, this analysis brings all of the +issues out into the open, enumerates all the alternatives, and +proposes solutions to be incorporated into the reStructuredText_ +specification. + + +.. contents:: + + +Formal Specification +==================== + +The description in the original StructuredText.py has been criticized +for being vague. For practical purposes, "the code *is* the spec." +Tony Ibbs has been working on deducing a `detailed description`_ from +the documentation and code of StructuredTextNG_. Edward Loper's +STMinus_ is another attempt to formalize a spec. + +For this kind of a project, the specification should always precede +the code. Otherwise, the markup is a moving target which can never be +adopted as a standard. Of course, a specification may be revised +during lifetime of the code, but without a spec there is no visible +control and thus no confidence. + + +Understanding and Extending the Code +==================================== + +The original StructuredText_ is a dense mass of sparsely commented +code and inscrutable regular expressions. It was not designed to be +extended and is very difficult to understand. StructuredTextNG_ has +been designed to allow input (syntax) and output extensions, but its +documentation (both internal [comments & docstrings], and external) is +inadequate for the complexity of the code itself. + +For reStructuredText to become truly useful, perhaps even part of +Python's standard library, it must have clear, understandable +documentation and implementation code. For the implementation of +reStructuredText to be taken seriously, it must be a sterling example +of the potential of docstrings; the implementation must practice what +the specification preaches. + + +Section Structure via Indentation +================================= + +Setext_ required that body text be indented by 2 spaces. The original +StructuredText_ and StructuredTextNG_ require that section structure +be indicated through indentation, as "inspired by Python". For +certain structures with a very limited, local extent (such as lists, +block quotes, and literal blocks), indentation naturally indicates +structure or hierarchy. For sections (which may have a very large +extent), structure via indentation is unnecessary, unnatural and +ambiguous. Rather, the syntax of the section title *itself* should +indicate that it is a section title. + +The original StructuredText states that "A single-line paragraph whose +immediately succeeding paragraphs are lower level is treated as a +header." Requiring indentation in this way is: + +- Unnecessary. The vast majority of docstrings and standalone + documents will have no more than one level of section structure. + Requiring indentation for such docstrings is unnecessary and + irritating. + +- Unnatural. Most published works use title style (type size, face, + weight, and position) and/or section/subsection numbering rather + than indentation to indicate hierarchy. This is a tradition with a + very long history. + +- Ambiguous. A StructuredText header is indistinguishable from a + one-line paragraph followed by a block quote (precluding the use of + block quotes). Enumerated section titles are ambiguous (is it a + header? is it a list item?). Some additional adornment must be + required to confirm the line's role as a title, both to a parser and + to the human reader of the source text. + +Python's use of significant whitespace is a wonderful (if not +original) innovation, however requiring indentation in ordinary +written text is hypergeneralization. + +reStructuredText_ indicates section structure through title adornment +style (as exemplified by this document). This is far more natural. +In fact, it is already in widespread use in plain text documents, +including in Python's standard distribution (such as the toplevel +README_ file). + + +Character Escaping Mechanism +============================ + +No matter what characters are chosen for markup, some day someone will +want to write documentation *about* that markup or using markup +characters in a non-markup context. Therefore, any complete markup +language must have an escaping or encoding mechanism. For a +lightweight markup system, encoding mechanisms like SGML/XML's '*' +are out. So an escaping mechanism is in. However, with carefully +chosen markup, it should be necessary to use the escaping mechanism +only infrequently. + +reStructuredText_ needs an escaping mechanism: a way to treat +markup-significant characters as the characters themselves. Currently +there is no such mechanism (although ZWiki uses '!'). What are the +candidates? + +1. ``!`` (http://dev.zope.org/Members/jim/StructuredTextWiki/NGEscaping) +2. ``\`` +3. ``~`` +4. doubling of characters + +The best choice for this is the backslash (``\``). It's "the single +most popular escaping character in the world!", therefore familiar and +unsurprising. Since characters only need to be escaped under special +circumstances, which are typically those explaining technical +programming issues, the use of the backslash is natural and +understandable. Python docstrings can be raw (prefixed with an 'r', +as in 'r""'), which would obviate the need for gratuitous doubling-up +of backslashes. + +(On 2001-03-29 on the Doc-SIG mailing list, GvR endorsed backslash +escapes, saying, "'nuff said. Backslash it is." Although neither +legally binding nor irrevocable nor any kind of guarantee of anything, +it is a good sign.) + +The rule would be: An unescaped backslash followed by any markup +character escapes the character. The escaped character represents the +character itself, and is prevented from playing a role in any markup +interpretation. The backslash is removed from the output. A literal +backslash is represented by an "escaped backslash," two backslashes in +a row. + +A carefully constructed set of recognition rules for inline markup +will obviate the need for backslash-escapes in almost all cases; see +`Delimitation of Inline Markup`_ below. + +When an expression (requiring backslashes and other characters used +for markup) becomes too complicated and therefore unreadable, a +literal block may be used instead. Inside literal blocks, no markup +is recognized, therefore backslashes (for the purpose of escaping +markup) become unnecessary. + +We could allow backslashes preceding non-markup characters to remain +in the output. This would make describing regular expressions and +other uses of backslashes easier. However, this would complicate the +markup rules and would be confusing. + + +Blank Lines in Lists +==================== + +Oft-requested in Doc-SIG (the earliest reference is dated 1996-08-13) +is the ability to write lists without requiring blank lines between +items. In docstrings, space is at a premium. Authors want to convey +their API or usage information in as compact a form as possible. +StructuredText_ requires blank lines between all body elements, +including list items, even when boundaries are obvious from the markup +itself. + +In reStructuredText, blank lines are optional between list items. +However, in order to eliminate ambiguity, a blank line is required +before the first list item and after the last. Nested lists also +require blank lines before the list start and after the list end. + + +Bullet List Markup +================== + +StructuredText_ includes 'o' as a bullet character. This is dangerous +and counter to the language-independent nature of the markup. There +are many languages in which 'o' is a word. For example, in Spanish:: + + Llamame a la casa + o al trabajo. + + (Call me at home or at work.) + +And in Japanese (when romanized):: + + Senshuu no doyoubi ni tegami + o kakimashita. + + ([I] wrote a letter on Saturday last week.) + +If a paragraph containing an 'o' word wraps such that the 'o' is the +first text on a line, or if a paragraph begins with such a word, it +could be misinterpreted as a bullet list. + +In reStructuredText_, 'o' is not used as a bullet character. '-', +'*', and '+' are the possible bullet characters. + + +Enumerated List Markup +====================== + +StructuredText enumerated lists are allowed to begin with numbers and +letters followed by a period or right-parenthesis, then whitespace. +This has surprising consequences for writing styles. For example, +this is recognized as an enumerated list item by StructuredText:: + + Mr. Creosote. + +People will write enumerated lists in all different ways. It is folly +to try to come up with the "perfect" format for an enumerated list, +and limit the docstring parser's recognition to that one format only. + +Rather, the parser should recognize a variety of enumerator styles, +marking each block as a potential enumerated list item (PELI), and +interpret the enumerators of adjacent PELIs to decide whether they +make up a consistent enumerated list. + +If a PELI is labeled with a "1.", and is immediately followed by a +PELI labeled with a "2.", we've got an enumerated list. Or "(A)" +followed by "(B)". Or "i)" followed by "ii)", etc. The chances of +accidentally recognizing two adjacent and consistently labeled PELIs, +are acceptably small. + +For an enumerated list to be recognized, the following must be true: + +- the list must consist of multiple adjacent list items (2 or more) +- the enumerators must all have the same format +- the enumerators must be sequential + +It is also recommended that the enumerator of the first list item be +ordinal-1 ('1', 'A', 'a', 'I', or 'i'), as output formats may not be +able to begin a list at an arbitrary enumeration. + + +Definition List Markup +====================== + +StructuredText uses ' -- ' (whitespace, two hyphens, whitespace) on +the first line of a paragraph to indicate a definition list item. The +' -- ' serves to separate the term (on the left) from the definition +(on the right). + +Many people use ' -- ' as an em-dash in their text, conflicting with +the StructuredText usage. Although the Chicago Manual of Style says +that spaces should not be used around an em-dash, Peter Funk pointed +out that this is standard usage in German (according to the Duden, the +official German reference), and possibly in other languages as well. +The widespread use of ' -- ' precludes its use for definition lists; +it would violate the "unsurprising" criterion. + +A simpler, and at least equally visually distinctive construct +(proposed by Guido van Rossum, who incidentally is a frequent user of +' -- ') would do just as well:: + + term 1 + Definition. + + term 2 + Definition 2, paragraph 1. + + Definition 2, paragraph 2. + +A reStructuredText definition list item consists of a term and a +definition. A term is a simple one-line paragraph. A definition is a +block indented relative to the term, and may contain multiple +paragraphs and other body elements. No blank line precedes a +definition (this distinguishes definition lists from block quotes). + + +Literal Blocks +============== +The StructuredText_ specification has literal blocks indicated by +'example', 'examples', or '::' ending the preceding paragraph. STNG +only recognizes '::'; 'example'/'examples' are not implemented. This +is good; it fixes an unnecessary language dependency. The problem is +what to do with the sometimes- unwanted '::'. + +In reStructuredText_ '::' at the end of a paragraph indicates that +subsequent *indented* blocks are treated as literal text. No further +markup interpretation is done within literal blocks (not even +backslash-escapes). If the '::' is preceded by whitespace, '::' is +omitted from the output; if '::' was the sole content of a paragraph, +the entire paragraph is removed (no 'empty' paragraph remains). If +'::' is preceded by a non-whitespace character, '::' is replaced by +':' (i.e., the extra colon is removed). + +Thus, a section could begin with a literal block as follows:: + + Section Title + ------------- + + :: + + print "this is example literal" + + +Tables +====== + +The table markup scheme in classic StructuredText was horrible. Its +omission from StructuredTextNG is welcome, and its markup will not be +repeated here. However, tables themselves are useful in +documentation. Alternatives: + +1. This format is the most natural and obvious. It was independently + invented (no great feat of creation!), and later found to be the + format supported by the `Emacs table mode`_:: + + +------------+------------+------------+--------------+ + | Header 1 | Header 2 | Header 3 | Header 4 | + +============+============+============+==============+ + | Column 1 | Column 2 | Column 3 & 4 span (Row 1) | + +------------+------------+------------+--------------+ + | Column 1 & 2 span | Column 3 | - Column 4 | + +------------+------------+------------+ - Row 2 & 3 | + | 1 | 2 | 3 | - span | + +------------+------------+------------+--------------+ + + Tables are described with a visual outline made up of the + characters '-', '=', '|', and '+': + + - The hyphen ('-') is used for horizontal lines (row separators). + - The equals sign ('=') is optionally used as a header separator + (as of version 1.5.24, this is not supported by the Emacs table + mode). + - The vertical bar ('|') is used for for vertical lines (column + separators). + - The plus sign ('+') is used for intersections of horizontal and + vertical lines. + + Row and column spans are possible simply by omitting the column or + row separators, respectively. The header row separator must be + complete; in other words, a header cell may not span into the table + body. Each cell contains body elements, and may have multiple + paragraphs, lists, etc. Initial spaces for a left margin are + allowed; the first line of text in a cell determines its left + margin. + +2. Below is a minimalist possibility. It may be better suited to + manual input than alternative #1, but there is no Emacs editing + mode available. One disadvantage is that it resembles section + titles; a one-column table would look exactly like section & + subsection titles. :: + + ============ ============ ============ ============== + Header 1 Header 2 Header 3 Header 4 + ============ ============ ============ ============== + Column 1 Column 2 Column 3 & 4 span (Row 1) + ------------ ------------ --------------------------- + Column 1 & 2 span Column 3 - Column 4 + ------------------------- ------------ - Row 2 & 3 + 1 2 3 - span + ============ ============ ============ ============== + + The table begins with a top border of equals signs with a space at + each column boundary (regardless of spans). Each row is + underlined. Internal row separators are underlines of '-', with + spaces at column boundaries. The last of the optional head rows is + underlined with '=', again with spaces at column boundaries. + Column spans have no spaces in their underline. Row spans simply + lack an underline at the row boundary. The bottom boundary of the + table consists of '=' underlines. A blank line is required + following a table. + +Alternative #1 is the choice adopted by reStructuredText. + + +Delimitation of Inline Markup +============================= + +StructuredText specifies that inline markup must begin with +whitespace, precluding such constructs as parenthesized or quoted +emphatic text:: + + "**What?**" she cried. (*exit stage left*) + +The `reStructuredText markup specification`_ allows for such +constructs and disambiguates inline markup through a set of +recognition rules. These recognition rules define the context of +markup start-strings and end-strings, allowing markup characters to be +used in most non-markup contexts without a problem (or a backslash). +So we can say, "Use asterisks (*) around words or phrases to +*emphasisze* them." The '(*)' will not be recognized as markup. This +reduces the need for markup escaping to the point where an escape +character is *almost* (but not quite!) unnecessary. + + +Underlining +=========== + +StructuredText uses '_text_' to indicate underlining. To quote David +Ascher in his 2000-01-21 Doc-SIG mailing list post, "Docstring +grammar: a very revised proposal": + + The tagging of underlined text with _'s is suboptimal. Underlines + shouldn't be used from a typographic perspective (underlines were + designed to be used in manuscripts to communicate to the + typesetter that the text should be italicized -- no well-typeset + book ever uses underlines), and conflict with double-underscored + Python variable names (__init__ and the like), which would get + truncated and underlined when that effect is not desired. Note + that while *complete* markup would prevent that truncation + ('__init__'), I think of docstring markups much like I think of + type annotations -- they should be optional and above all do no + harm. In this case the underline markup does harm. + +Underlining is not part of the reStructuredText specification. + + +Inline Literals +=============== + +StructuredText's markup for inline literals (text left as-is, +verbatim, usually in a monospaced font; as in HTML ) is single +quotes ('literals'). The problem with single quotes is that they are +too often used for other purposes: + +- Apostrophes: "Don't blame me, 'cause it ain't mine, it's Chris'."; + +- Quoting text: + + First Bruce: "Well Bruce, I heard the prime minister use it. + 'S'hot enough to boil a monkey's bum in 'ere your Majesty,' he + said, and she smiled quietly to herself." + + In the UK, single quotes are used for dialogue in published works. + +- String literals: s = '' + +Alternatives:: + + 'text' \'text\' ''text'' "text" \"text\" ""text"" + #text# @text@ `text` ^text^ ``text'' ``text`` + +The examples below contain inline literals, quoted text, and +apostrophes. Each example should evaluate to the following HTML:: + + Some code, with a 'quote', "double", ain't it grand? + Does a[b] = 'c' + "d" + `2^3` work? + + 0. Some code, with a quote, double, ain't it grand? + Does a[b] = 'c' + "d" + `2^3` work? + 1. Some 'code', with a \'quote\', "double", ain\'t it grand? + Does 'a[b] = \'c\' + "d" + `2^3`' work? + 2. Some \'code\', with a 'quote', "double", ain't it grand? + Does \'a[b] = 'c' + "d" + `2^3`\' work? + 3. Some ''code'', with a 'quote', "double", ain't it grand? + Does ''a[b] = 'c' + "d" + `2^3`'' work? + 4. Some "code", with a 'quote', \"double\", ain't it grand? + Does "a[b] = 'c' + "d" + `2^3`" work? + 5. Some \"code\", with a 'quote', "double", ain't it grand? + Does \"a[b] = 'c' + "d" + `2^3`\" work? + 6. Some ""code"", with a 'quote', "double", ain't it grand? + Does ""a[b] = 'c' + "d" + `2^3`"" work? + 7. Some #code#, with a 'quote', "double", ain't it grand? + Does #a[b] = 'c' + "d" + `2^3`# work? + 8. Some @code@, with a 'quote', "double", ain't it grand? + Does @a[b] = 'c' + "d" + `2^3`@ work? + 9. Some `code`, with a 'quote', "double", ain't it grand? + Does `a[b] = 'c' + "d" + \`2^3\`` work? + 10. Some ^code^, with a 'quote', "double", ain't it grand? + Does ^a[b] = 'c' + "d" + `2\^3`^ work? + 11. Some ``code'', with a 'quote', "double", ain't it grand? + Does ``a[b] = 'c' + "d" + `2^3`'' work? + 12. Some ``code``, with a 'quote', "double", ain't it grand? + Does ``a[b] = 'c' + "d" + `2^3\``` work? + +Backquotes (#9 & #12) are the best choice. They are unobtrusive and +relatviely rarely used (more rarely than ' or ", anyhow). Backquotes +have the connotation of 'quotes', which other options (like carets, +#10) don't. + +Analogously with ``*emph*`` & ``**strong**``, double-backquotes (#12) +could be used for inline literals. If single-backquotes are used for +'interpreted text' (context-sensitive domain-specific descriptive +markup) such as function name hyperlinks in Python docstrings, then +double-backquotes could be used for absolute-literals, wherein no +processing whatsoever takes place. An advantage of double-backquotes +would be that backslash-escaping would no longer be necessary for +embedded single-backquotes; however, embedded double-backquotes (in an +end-string context) would be illegal. See `Backquotes in +Phrase-Links`__ in `Record of reStructuredText Syntax Alternatives`__. + +__ alternatives.html#backquotes-in-phrase-links +__ alternatives.html + +Alternative choices are carets (#10) and TeX-style quotes (#11). For +examples of TeX-style quoting, see +http://www.zope.org/Members/jim/StructuredTextWiki/CustomizingTheDocumentProcessor. + +Some existing uses of backquotes: + +1. As a synonym for repr() in Python. +2. For command-interpolation in shell scripts. +3. Used as open-quotes in TeX code (and carried over into plaintext + by TeXies). + +The inline markup start-string and end-string recognition rules +defined by the `reStructuredText markup specification`_ would allow +all of these cases inside inline literals, with very few exceptions. +As a fallback, literal blocks could handle all cases. + +Outside of inline literals, the above uses of backquotes would require +backslash-escaping. However, these are all prime examples of text +that should be marked up with inline literals. + +If either backquotes or straight single-quotes are used as markup, +TeX-quotes are too troublesome to support, so no special-casing of +TeX-quotes should be done (at least at first). If TeX-quotes have to +be used outside of literals, a single backslash-escaped would suffice: +\``TeX quote''. Ugly, true, but very infrequently used. + +Using literal blocks is a fallback option which removes the need for +backslash-escaping:: + + like this:: + + Here, we can do ``absolutely'' anything `'`'\|/|\ we like! + +No mechanism for inline literals is perfect, just as no escaping +mechanism is perfect. No matter what we use, complicated inline +expressions involving the inline literal quote and/or the backslash +will end up looking ugly. We can only choose the least often ugly +option. + +reStructuredText will use double backquotes for inline literals, and +single backqoutes for interpreted text. + + +Hyperlinks +========== + +There are three forms of hyperlink currently in StructuredText_: + +1. (Absolute & relative URIs.) Text enclosed by double quotes + followed by a colon, a URI, and concluded by punctuation plus white + space, or just white space, is treated as a hyperlink:: + + "Python":http://www.python.org/ + +2. (Absolute URIs only.) Text enclosed by double quotes followed by a + comma, one or more spaces, an absolute URI and concluded by + punctuation plus white space, or just white space, is treated as a + hyperlink:: + + "mail me", mailto:me@mail.com + +3. (Endnotes.) Text enclosed by brackets link to an endnote at the + end of the document: at the beginning of the line, two dots, a + space, and the same text in brackets, followed by the end note + itself:: + + Please refer to the fine manual [GVR2001]. + + .. [GVR2001] Python Documentation, Release 2.1, van Rossum, + Drake, et al., http://www.python.org/doc/ + +The problem with forms 1 and 2 is that they are neither intuitive nor +unobtrusive (they break design goals 5 & 2). They overload +double-quotes, which are too often used in ordinary text (potentially +breaking design goal 4). The brackets in form 3 are also too common +in ordinary text (such as [nested] asides and Python lists like [12]). + +Alternatives: + +1. Have no special markup for hyperlinks. + +2. A. Interpret and mark up hyperlinks as any contiguous text + containing '://' or ':...@' (absolute URI) or '@' (email + address) after an alphanumeric word. To de-emphasize the URI, + simply enclose it in parentheses: + + Python (http://www.python.org/) + + B. Leave special hyperlink markup as a domain-specific extension. + Hyperlinks in ordinary reStructuredText documents would be + required to be standalone (i.e. the URI text inline in the + document text). Processed hyperlinks (where the URI text is + hidden behind the link) are important enough to warrant syntax. + +3. The original Setext_ introduced a mechanism of indirect hyperlinks. + A source link word ('hot word') in the text was given a trailing + underscore:: + + Here is some text with a hyperlink_ built in. + + The hyperlink itself appeared at the end of the document on a line + by itself, beginning with two dots, a space, the link word with a + leading underscore, whitespace, and the URI itself:: + + .. _hyperlink http://www.123.xyz + + Setext used ``underscores_instead_of_spaces_`` for phrase links. + +With some modification, alternative 3 best satisfies the design goals. +It has the advantage of being readable and relatively unobtrusive. +Since each source link must match up to a target, the odd variable +ending in an underscore can be spared being marked up (although it +should generate a "no such link target" warning). The only +disadvantage is that phrase-links aren't possible without some +obtrusive syntax. + +We could achieve phrase-links if we enclose the link text: + +1. in double quotes:: + + "like this"_ + +2. in brackets:: + + [like this]_ + +3. or in backquotes:: + + `like this`_ + +Each gives us somewhat obtrusive markup, but that is unavoidable. The +bracketed syntax (#2) is reminiscent of links on many web pages +(intuitive), although it is somewhat obtrusive. Alternative #3 is +much less obtrusive, and is consistent with interpreted text: the +trailing underscore indicates the interpretation of the phrase, as a +hyperlink. #3 also disambiguates hyperlinks from footnote references. +Alternative #3 wins. + +The same trailing underscore markup can also be used for footnote and +citation references, removing the problem with ordinary bracketed text +and Python lists:: + + Please refer to the fine manual [GVR2000]_. + + .. [GVR2000] Python Documentation, van Rossum, Drake, et al., + http://www.python.org/doc/ + +The two-dots-and-a-space syntax was generalized by Setext for +comments, which are removed from the (visible) processed output. +reStructuredText uses this syntax for comments, footnotes, and link +target, collectively termed "explicit markup". For link targets, in +order to eliminate ambiguity with comments and footnotes, +reStructuredText specifies that a colon always follow the link target +word/phrase. The colon denotes 'maps to'. There is no reason to +restrict target links to the end of the document; they could just as +easily be interspersed. + +Internal hyperlinks (links from one point to another within a single +document) can be expressed by a source link as before, and a target +link with a colon but no URI. In effect, these targets 'map to' the +element immediately following. + +As an added bonus, we now have a perfect candidate for +reStructuredText directives, a simple extension mechanism: explicit +markup containing a single word followed by two colons and whitespace. +The interpretation of subsequent data on the directive line or +following is directive-dependent. + +To summarize:: + + .. This is a comment. + + .. The line below is an example of a directive. + .. version:: 1 + + This is a footnote [1]_. + + This internal hyperlink will take us to the footnotes_ area below. + + Here is a one-word_ external hyperlink. + + Here is `a hyperlink phrase`_. + + .. _footnotes: + .. [1] Footnote text goes here. + + .. external hyperlink target mappings: + .. _one-word: http://www.123.xyz + .. _a hyperlink phrase: http://www.123.xyz + +The presence or absence of a colon after the target link +differentiates an indirect hyperlink from a footnote, respectively. A +footnote requires brackets. Backquotes around a target link word or +phrase are required if the phrase contains a colon, optional +otherwise. + +Below are examples using no markup, the two StructuredText hypertext +styles, and the reStructuredText hypertext style. Each example +contains an indirect link, a direct link, a footnote/endnote, and +bracketed text. In HTML, each example should evaluate to:: + +

A URI, see + [eggs2000] (in Bacon [Publisher]). Also see + http://eggs.org.

+ +

[eggs2000] "Spam, Spam, Spam, Eggs, + Bacon, and Spam"

+ +1. No markup:: + + A URI http://spam.org, see eggs2000 (in Bacon [Publisher]). + Also see http://eggs.org. + + eggs2000 "Spam, Spam, Spam, Eggs, Bacon, and Spam" + +2. StructuredText absolute/relative URI syntax + ("text":http://www.url.org):: + + A "URI":http://spam.org, see [eggs2000] (in Bacon [Publisher]). + Also see "http://eggs.org":http://eggs.org. + + .. [eggs2000] "Spam, Spam, Spam, Eggs, Bacon, and Spam" + + Note that StructuredText does not recognize standalone URIs, + forcing doubling up as shown in the second line of the example + above. + +3. StructuredText absolute-only URI syntax + ("text", mailto:you@your.com):: + + A "URI", http://spam.org, see [eggs2000] (in Bacon + [Publisher]). Also see "http://eggs.org", http://eggs.org. + + .. [eggs2000] "Spam, Spam, Spam, Eggs, Bacon, and Spam" + +4. reStructuredText syntax:: + + 4. A URI_, see [eggs2000]_ (in Bacon [Publisher]). + Also see http://eggs.org. + + .. _URI: http:/spam.org + .. [eggs2000] "Spam, Spam, Spam, Eggs, Bacon, and Spam" + +The bracketed text '[Publisher]' may be problematic with +StructuredText (syntax 2 & 3). + +reStructuredText's syntax (#4) is definitely the most readable. The +text is separated from the link URI and the footnote, resulting in +cleanly readable text. + +.. _StructuredText: + http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage +.. _Setext: http://docutils.sourceforge.net/mirror/setext.html +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _detailed description: + http://www.tibsnjoan.demon.co.uk/STNG-format.html +.. _STMinus: http://www.cis.upenn.edu/~edloper/pydoc/stminus.html +.. _StructuredTextNG: + http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNG +.. _README: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/ + python/python/dist/src/README +.. _Emacs table mode: http://table.sourceforge.net/ +.. _reStructuredText Markup Specification: reStructuredText.html + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt new file mode 100644 index 000000000..311751f37 --- /dev/null +++ b/docs/dev/todo.txt @@ -0,0 +1,385 @@ +================ + Docutils Notes +================ +:Date: $Date$ +:Revision: $Revision$ + +.. contents:: + +To Do +===== + +General +------- + +- Document! + + - Internal module documentation. + + - User docs. + + - Doctree nodes (DTD element) semantics: + + - External (public) attributes (node.attributes). + - Internal attributes (node.*). + - Linking mechanism. + +- Refactor + + - Rename methods & variables according to the `coding conventions`_ + below. + + - The name->id conversion and hyperlink resolution code needs to be + checked for correctness and refactored. I'm afraid it's a bit of + a spaghetti mess now. + +- Add validation? See http://pytrex.sourceforge.net, RELAX NG. + +- Ask Python-dev for opinions (GvR for a pronouncement) on special + variables (__author__, __version__, etc.): convenience vs. namespace + pollution. Ask opinions on whether or not Docutils should recognize + & use them. + +- Provide a mechanism to pass options to Readers, Writers, and Parsers + through docutils.core.publish/Publisher? Or create custom + Reader/Writer/Parser objects first, and pass *them* to + publish/Publisher? + +- In reader.get_reader_class (& parser & writer too), should we be + importing 'standalone' or 'docutils.readers.standalone'? (This would + avoid importing top-level modules if the module name is not in + docutils/readers. Potential nastiness.) + +- Perhaps store a name->id mapping file? This could be stored + permanently, read by subsequent processing runs, and updated with + new entries. ("Persistent ID mapping"?) + +- The "Docutils System Messages" section appears even if no actual + system messages are there. They must be below the threshold. The + transform should be fixed. + +- TOC transform: use alt-text for inline images. + + +Specification +------------- + +- Complete PEP 258 Docutils Design Specification. + + - Fill in the blanks in API details. + + - Specify the nodes.py internal data structure implementation. + + [Tibs:] Eventually we need to have direct documentation in + there on how it all hangs together - the DTD is not enough + (indeed, is it still meant to be correct? [Yes, it is.]). + +- Rework PEP 257, separating style from spec from tools, wrt Docutils? + See Doc-SIG from 2001-06-19/20. + +- Add layout component to framework? Or part of the formatter? + +- Once doctree.txt is fleshed out, how about breaking (most of) it up + and putting it into nodes.py as docstrings? + + +reStructuredText Parser +----------------------- + +- Add motivation sections for constructs in spec. + +- Allow very long titles (on two or more lines)? + +- And for the sake of completeness, should definition list terms be + allowed to be very long (two or more lines) also? + +- Allow hyperlink references to targets in other documents? Not in an + HTML-centric way, though (it's trivial to say + ``http://www.whatever.com/doc#name``, and useless in non-HTML + contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG + 2001-08-10. + +- Add character processing? For example: + + - ``--`` -> em-dash (or ``--`` -> en-dash, and ``---`` -> em-dash). + (Look for pre-existing conventions.) + - Convert quotes to curly quote entities. (Essentially impossible + for HTML? Unnecessary for TeX. An output issue?) + - Various forms of ``:-)`` to smiley icons. + - ``"\ "`` ->  . + - Escaped newlines ->
. + - Escaped period or quote as a disappearing catalyst to allow + character-level inline markup? + - Others? + + How to represent character entities in the text though? Probably as + Unicode. + + Which component is responsible for this, the parser, the reader, or + the writer? + +- Implement the header row separator modification to table.el. (Wrote + to Takaaki Ota & the table.el mailing list on 2001-08-12, suggesting + support for '=====' header rows. On 2001-08-17 he replied, saying + he'd put it on his to-do list, but "don't hold your breath".) + +- Tony says inline markup rule 7 could do with a *little* more + exposition in the spec, to make clear what is going on for people + with head colds. + +- Alan Jaffray suggested (and I agree) that it would be sensible to: + + - have a directive to specify a default role for interpreted text + - allow the reST processor to take an argument for the default role + - issue a warning when processing documents with no default role + which contain interpreted text with no explicitly specified role + +- Fix the parser's indentation handling to conform with the stricter + definition in the spec. (Explicit markup blocks should be strict or + forgiving?) + +- Tighten up the spec for indentation of "constructs using complex + markers": field lists and option lists? Bodies may begin on the + same line as the marker or on a subsequent line (with blank lines + optional). Require that for bodies beginning on the same line as + the marker, all lines be in strict alignment. Currently, this is + acceptable:: + + :Field-name-of-medium-length: Field body beginning on the same + line as the field name. + + This proposal would make the above example illegal, instead + requiring strict alignment. A field body may either begin on the + same line:: + + :Field-name-of-medium-length: Field body beginning on the same + line as the field name. + + Or it may begin on a subsequent line:: + + :Field-name-of-medium-length: + Field body beginning on a line subsequent to that of the + field name. + + This would be especially relevant in degenerate cases like this:: + + :Number-of-African-swallows-requried-to-carry-a-coconut: + It would be very difficult to align the field body with + the left edge of the first line if it began on the same + line as the field name. + +- Allow syntax constructs to be added or disabled at run-time. + +- Make footnotes two-way, GNU-style? What if there are multiple + references to a single footnote? + +- Add RFC-2822 header parsing (for PEP, email Readers). + +- Change ``.. meta::`` to use a "pending" element, only activated for + HTML writers. + +- Allow for variant styles by interpreting indented lists as if they + weren't indented? For example, currently the list below will be + parsed as a list within a block quote:: + + paragraph + + * list item 1 + * list item 2 + + But a lot of people seem to write that way, and HTML browsers make + it look as if that's the way it should be. The parser could check + the contents of block quotes, and if they contain only a single + list, remove the block quote wrapper. There would be two problems: + + 1. What if we actually *do* want a list inside a block quote? + + 2. What if such a list comes immediately after an indented + construct, such as a literal block? + + Both could be solved using empty comments (problem 2 already exists + for a block quote after a literal block). But that's a hack. + + See the Doc-SIG discussion starting 2001-04-18 with Ed Loper's + "Structuring: a summary; and an attempt at EBNF", item 4. + +- Produce a better system message when a list ends abruptly. Input:: + + -1 Option "1" + -2 + + Produces:: + + Reporter: WARNING (2) Unindent without blank line at line 2. + + But it should produce:: + + Reporter: WARNING (2) List ends without blank line at line 2. + + +Directives +`````````` + +- Allow directives to be added at run-time. + +- Use the language module for directive attribute names? + +- Add more attributes to the image directive: align, border? + +- Implement directives: + + - html.imagemap + + - components.endnotes, .citations, .topic, .sectnum (section + numbering; add support to .contents; could be cmdline option also) + + - misc.raw + + - misc.include: ``#include`` one file in another. But how to + parse wrt sections, reference names, conflicts? + + - misc.exec: Execute Python code & insert the results. Perhaps + dangerous? + + - misc.eval: Evaluate an expression & insert the text. At parse + time or at substitution time? + + - block.qa: Questions & Answers. Implement as a generic two-column + marked list? Or as a standalone construct? + + - block.columns: Multi-column table/list, with number of columns as + argument. + + - block.verse: Paragraphs with linebreaks preserved. A directive + would be easy; what about a literal-block-like prefix, perhaps + ';;'? E.g.:: + + Take it away, Eric the orchestra leader! ;; + + Half a bee, + Philosophically, + Must ipso-facto + Half not be. + You see? + + ... + + - colorize.python: Colorize Python code. Fine for HTML output, but + what about other formats? Revert to a literal block? Do we need + some kind of "alternate" mechanism? Perhaps use a "pending" + transform, which could switch its output based on the "format" in + use. Use a factory function "transformFF()" which returns either + "HTMLTransform()" instance or "GenericTransform" instance? + + - text.date: Datestamp. For substitutions. + + - Combined with misc.include, implement canned macros? + + +Unimplemented Transforms +------------------------ + +- Footnote Gathering + + Collect and move footnotes to the end of a document. + +- Hyperlink Target Gathering + + It probably comes in two phases, because in a Python context we need + to *resolve* them on a per-docstring basis [do we? --DG], but if the + user is trying to do the callout form of presentation, they would + then want to group them all at the end of the document. + +- Reference Merging + + When merging two or more subdocuments (such as docstrings), + conflicting references may need to be resolved. There may be: + + - duplicate reference and/or substitution names that need to be made + unique; and/or + - duplicate footnote numbers that need to be renumbered. + + Should this be done before or after reference-resolving transforms + are applied? What about references from within one subdocument to + inside another? + +- Document Splitting + + If the processed document is written to multiple files (possibly in + a directory tree), it will need to be split up. References will + have to be adjusted. + + (HTML only?) + +- Navigation + + If a document is split up, each segment will need navigation links: + parent, children (small TOC), previous (preorder), next (preorder). + +- Index + + +HTML Writer +----------- + +- Considerations for an HTML Writer [#]_: + + - Boolean attributes. ```` is good, ```` is bad. Use a special value in attribute + mappings, such as ``None``? + + - Escape double-dashes inside comments. + + - Put the language code into an appropriate element's LANG + attribute (?). + + - Docutils identifiers (the "class" and "id" attributes) will + conform to the regular expression ``[a-z][-a-z0-9]*``. See + ``docutils.utils.id()``. + + .. _HTML 4.01 spec: http://www.w3.org/TR/html401 + .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 + .. [#] Source: `HTML 4.0 in Netscape and Explorer`__. + __ http://www.webreference.com/dev/html4nsie/index.html + +- Allow for style sheet info to be passed in, either as a , or + as embedded style info. + +- Construct a templating system, as in ht2html/yaptu, using directives + and substitutions for dynamic stuff. + +- Improve the granularity of document parts in the HTML writer, so + that one could just grab the parts needed. + + +Coding Conventions +================== + +This project shall follow the generic coding conventions as specified +in the `Style Guide for Python Code`__ and `Docstring Conventions`__ +PEPs, with the following clarifications: + +- 4 spaces per indentation level. No tabs. +- No one-liner compound statements (i.e., no ``if x: return``: use two + lines & indentation), except for degenerate class or method + definitions (i.e., ``class X: pass`` is O.K.). +- Lines should be no more than 78 or 79 characters long. +- "CamelCase" shall be used for class names. +- Use "lowercase" or "lowercase_with_underscores" for function, + method, and variable names. For short names, maximum two joined + words, use lowercase (e.g. 'tagname'). For long names with three or + more joined words, or where it's hard to parse the split between two + words, use lowercase_with_underscores (e.g., 'note_explicit_target', + 'explicit_target'). + +__ http://www.python.org/peps/pep-0008.html +__ http://www.python.org/peps/pep-0257.html + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt new file mode 100644 index 000000000..92c8e7f61 --- /dev/null +++ b/docs/peps/pep-0256.txt @@ -0,0 +1,253 @@ +PEP: 256 +Title: Docstring Processing System Framework +Version: $Revision$ +Last-Modified: $Date$ +Author: goodger@users.sourceforge.net (David Goodger) +Discussions-To: doc-sig@python.org +Status: Draft +Type: Standards Track +Created: 01-Jun-2001 +Post-History: 13-Jun-2001 + + +Abstract + + Python lends itself to inline documentation. With its built-in + docstring syntax, a limited form of Literate Programming [1]_ is + easy to do in Python. However, there are no satisfactory standard + tools for extracting and processing Python docstrings. The lack + of a standard toolset is a significant gap in Python's + infrastructure; this PEP aims to fill the gap. + + The issues surrounding docstring processing have been contentious + and difficult to resolve. This PEP proposes a generic Docstring + Processing System (DPS) framework, which separates out the + components (program and conceptual), enabling the resolution of + individual issues either through consensus (one solution) or + through divergence (many). It promotes standard interfaces which + will allow a variety of plug-in components (input context readers, + markup parsers, and output format writers) to be used. + + The concepts of a DPS framework are presented independently of + implementation details. + + +Rationale + + There are standard inline documentation systems for some other + languages. For example, Perl has POD [2]_ and Java has Javadoc + [3]_, but neither of these mesh with the Pythonic way. POD syntax + is very explicit, but takes after Perl in terms of readability. + Javadoc is HTML-centric; except for '@field' tags, raw HTML is + used for markup. There are also general tools such as Autoduck + [4]_ and Web (Tangle & Weave) [5]_, useful for multiple languages. + + There have been many attempts to write auto-documentation systems + for Python (not an exhaustive list): + + - Marc-Andre Lemburg's doc.py [6]_ + + - Daniel Larsson's pythondoc & gendoc [7]_ + + - Doug Hellmann's HappyDoc [8]_ + + - Laurence Tratt's Crystal [9]_ + + - Ka-Ping Yee's htmldoc & pydoc [10]_ (pydoc.py is now part of the + Python standard library; see below) + + - Tony Ibbs' docutils [11]_ + + - Edward Loper's STminus formalization and related efforts [12]_ + + These systems, each with different goals, have had varying degrees + of success. A problem with many of the above systems was + over-ambition combined with inflexibility. They provided a + self-contained set of components: a docstring extraction system, + a markup parser, an internal processing system and one or more + output format writers. Inevitably, one or more aspects of each + system had serious shortcomings, and they were not easily extended + or modified, preventing them from being adopted as standard tools. + + It has become clear (to this author, at least) that the "all or + nothing" approach cannot succeed, since no monolithic + self-contained system could possibly be agreed upon by all + interested parties. A modular component approach designed for + extension, where components may be multiply implemented, may be + the only chance for success. By separating out the issues, we can + form consensus more easily (smaller fights ;-), and accept + divergence more readily. + + Each of the components of a docstring processing system should be + developed independently. A 'best of breed' system should be + chosen, either merged from existing systems, and/or developed + anew. This system should be included in Python's standard + library. + + +PyDoc & Other Existing Systems + + PyDoc became part of the Python standard library as of release + 2.1. It extracts and displays docstrings from within the Python + interactive interpreter, from the shell command line, and from a + GUI window into a web browser (HTML). Although a very useful + tool, PyDoc has several deficiencies, including: + + - In the case of the GUI/HTML, except for some heuristic + hyperlinking of identifier names, no formatting of the + docstrings is done. They are presented within

+ tags to avoid unwanted line wrapping. Unfortunately, the result + is not attractive. + + - PyDoc extracts docstrings and structural information (class + identifiers, method signatures, etc.) from imported module + objects. There are security issues involved with importing + untrusted code. Also, information from the source is lost when + importing, such as comments, "additional docstrings" (string + literals in non-docstring contexts; see PEP 258 [13]_), and the + order of definitions. + + The functionality proposed in this PEP could be added to or used + by PyDoc when serving HTML pages. The proposed docstring + processing system's functionality is much more than PyDoc needs in + its current form. Either an independent tool will be developed + (which PyDoc may or may not use), or PyDoc could be expanded to + encompass this functionality and *become* the docstring processing + system (or one such system). That decision is beyond the scope of + this PEP. + + Similarly for other existing docstring processing systems, their + authors may or may not choose compatibility with this framework. + However, if this framework is accepted and adopted as the Python + standard, compatibility will become an important consideration in + these systems' future. + + +Specification + + The docstring processing system framework consists of components, + as follows:: + + 1. Docstring conventions. Documents issues such as: + + - What should be documented where. + + - First line is a one-line synopsis. + + PEP 257, Docstring Conventions [14]_, documents some of these + issues. + + 2. Docstring processing system design specification. Documents + issues such as: + + - High-level spec: what a DPS does. + + - Command-line interface for executable script. + + - System Python API. + + - Docstring extraction rules. + + - Readers, which encapsulate the input context . + + - Parsers. + + - Document tree: the intermediate internal data structure. The + output of the Parser and Reader, and the input to the Writer + all share the same data structure. + + - Transforms, which modify the document tree. + + - Writers for output formats. + + - Distributors, which handle output management (one file, many + files, or objects in memory). + + These issues are applicable to any docstring processing system + implementation. PEP 258, Docutils Design Specification [13 ]_, + documents these issues. + + 3. Docstring processing system implementation. + + 4. Input markup specifications: docstring syntax. PEP 2xx, + reStructuredText Standard Docstring Format [15]_, proposes a + standard syntax. + + 5. Input parser implementations. + + 6. Input context readers ("modes": Python source code, PEP, + standalone text file, email, etc.) and implementations. + + 7. Output formats (HTML, XML, TeX, DocBook, info, etc.) and writer + implementations. + + Components 1, 2/3, and 4/5 are the subject of individual companion + PEPs. If there is another implementation of the framework or + syntax/parser, additional PEPs may be required. Multiple + implementations of each of components 6 and 7 will be required; + the PEP mechanism may be overkill for these components. + + +Project Web Site + + A SourceForge project has been set up for this work at + http://docutils.sourceforge.net/. + + +References and Footnotes + + [1] http://www.literateprogramming.com/ + + [2] Perl "Plain Old Documentation" + http://www.perldoc.com/perl5.6/pod/perlpod.html + + [3] http://java.sun.com/j2se/javadoc/ + + [4] http://www.helpmaster.com/hlp-developmentaids-autoduck.htm + + [5] http://www-cs-faculty.stanford.edu/~knuth/cweb.html + + [6] http://www.lemburg.com/files/python/SoftwareDescriptions.html#doc.py + + [7] http://starship.python.net/crew/danilo/pythondoc/ + + [8] http://happydoc.sourceforge.net/ + + [9] http://www.btinternet.com/~tratt/comp/python/crystal/ + + [10] http://www.python.org/doc/current/lib/module-pydoc.html + + [11] http://homepage.ntlworld.com/tibsnjoan/docutils/ + + [12] http://www.cis.upenn.edu/~edloper/pydoc/ + + [13] PEP 258, Docutils Design Specification, Goodger + http://www.python.org/peps/pep-0258.html + + [14] PEP 257, Docstring Conventions, Goodger, Van Rossum + http://www.python.org/peps/pep-0257.html + + [15] PEP 287, reStructuredText Standard Docstring Format, Goodger + http://www.python.org/peps/pep-0287.html + + [16] http://www.python.org/sigs/doc-sig/ + + +Copyright + + This document has been placed in the public domain. + + +Acknowledgements + + This document borrows ideas from the archives of the Python + Doc-SIG [16]_. Thanks to all members past & present. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +fill-column: 70 +sentence-end-double-space: t +End: diff --git a/docs/peps/pep-0257.txt b/docs/peps/pep-0257.txt new file mode 100644 index 000000000..48425d9cc --- /dev/null +++ b/docs/peps/pep-0257.txt @@ -0,0 +1,248 @@ +PEP: 257 +Title: Docstring Conventions +Version: $Revision$ +Last-Modified: $Date$ +Author: goodger@users.sourceforge.net (David Goodger), + guido@python.org (Guido van Rossum) +Discussions-To: doc-sig@python.org +Status: Active +Type: Informational +Created: 29-May-2001 +Post-History: 13-Jun-2001 + + +Abstract + + This PEP documents the semantics and conventions associated with + Python docstrings. + + +Rationale + + The aim of this PEP is to standardize the high-level structure of + docstrings: what they should contain, and how to say it (without + touching on any markup syntax within docstrings). The PEP + contains conventions, not laws or syntax. + + "A universal convention supplies all of maintainability, + clarity, consistency, and a foundation for good programming + habits too. What it doesn't do is insist that you follow it + against your will. That's Python!" + + --Tim Peters on comp.lang.python, 2001-06-16 + + If you violate the conventions, the worst you'll get is some dirty + looks. But some software (such as the Docutils docstring + processing system [1] [2]) will be aware of the conventions, so + following them will get you the best results. + + +Specification + + What is a Docstring? + -------------------- + + A docstring is a string literal that occurs as the first statement + in a module, function, class, or method definition. Such a + docstring becomes the __doc__ special attribute of that object. + + All modules should normally have docstrings, and all functions and + classes exported by a module should also have docstrings. Public + methods (including the __init__ constructor) should also have + docstrings. A package may be documented in the module docstring + of the __init__.py file in the package directory. + + String literals occurring elsewhere in Python code may also act as + documentation. They are not recognized by the Python bytecode + compiler and are not accessible as runtime object attributes + (i.e. not assigned to __doc__), but two types of extra docstrings + may be extracted by software tools: + + 1. String literals occurring immediately after a simple assignment + at the top level of a module, class, or __init__ method + are called "attribute docstrings". + + 2. String literals occurring immediately after another docstring + are called "additional docstrings". + + Please see PEP 258 "Docutils Design Specification" [2] for a + detailed description of attribute and additional docstrings. + + XXX Mention docstrings of 2.2 properties. + + For consistency, always use """triple double quotes""" around + docstrings. Use r"""raw triple double quotes""" if you use any + backslashes in your docstrings. For Unicode docstrings, use + u"""Unicode triple-quoted strings""". + + There are two forms of docstrings: one-liners and multi-line + docstrings. + + One-line Docstrings + -------------------- + + One-liners are for really obvious cases. They should really fit + on one line. For example:: + + def kos_root(): + """Return the pathname of the KOS root directory.""" + global _kos_root + if _kos_root: return _kos_root + ... + + Notes: + + - Triple quotes are used even though the string fits on one line. + This makes it easy to later expand it. + + - The closing quotes are on the same line as the opening quotes. + This looks better for one-liners. + + - There's no blank line either before or after the docstring. + + - The docstring is a phrase ending in a period. It prescribes the + function or method's effect as a command ("Do this", "Return + that"), not as a description: e.g. don't write "Returns the + pathname ..." + + - The one-line docstring should NOT be a "signature" reiterating + the function/method parameters (which can be obtained by + introspection). Don't do:: + + def function(a, b): + """function(a, b) -> list""" + + This type of docstring is only appropriate for C functions (such + as built-ins), where introspection is not possible. + + Multi-line Docstrings + ---------------------- + + Multi-line docstrings consist of a summary line just like a + one-line docstring, followed by a blank line, followed by a more + elaborate description. The summary line may be used by automatic + indexing tools; it is important that it fits on one line and is + separated from the rest of the docstring by a blank line. The + summary line may be on the same line as the opening quotes or on + the next line. + + The entire docstring is indented the same as the quotes at its + first line (see example below). Docstring processing tools will + strip an amount of indentation from the second and further lines + of the docstring equal to the indentation of the first non-blank + line after the first line of the docstring. Relative indentation + of later lines in the docstring is retained. + + Insert a blank line before and after all docstrings (one-line or + multi-line) that document a class -- generally speaking, the + class's methods are separated from each other by a single blank + line, and the docstring needs to be offset from the first method + by a blank line; for symmetry, put a blank line between the class + header and the docstring. Docstrings documenting functions or + methods generally don't have this requirement, unless the function + or method's body is written as a number of blank-line separated + sections -- in this case, treat the docstring as another section, + and precede it with a blank line. + + The docstring of a script (a stand-alone program) should be usable + as its "usage" message, printed when the script is invoked with + incorrect or missing arguments (or perhaps with a "-h" option, for + "help"). Such a docstring should document the script's function + and command line syntax, environment variables, and files. Usage + messages can be fairly elaborate (several screens full) and should + be sufficient for a new user to use the command properly, as well + as a complete quick reference to all options and arguments for the + sophisticated user. + + The docstring for a module should generally list the classes, + exceptions and functions (and any other objects) that are exported + by the module, with a one-line summary of each. (These summaries + generally give less detail than the summary line in the object's + docstring.) The docstring for a package (i.e., the docstring of + the package's __init__.py module) should also list the modules and + subpackages exported by the package. + + The docstring for a function or method should summarize its + behavior and document its arguments, return value(s), side + effects, exceptions raised, and restrictions on when it can be + called (all if applicable). Optional arguments should be + indicated. It should be documented whether keyword arguments are + part of the interface. + + The docstring for a class should summarize its behavior and list + the public methods and instance variables. If the class is + intended to be subclassed, and has an additional interface for + subclasses, this interface should be listed separately (in the + docstring). The class constructor should be documented in the + docstring for its __init__ method. Individual methods should be + documented by their own docstring. + + If a class subclasses another class and its behavior is mostly + inherited from that class, its docstring should mention this and + summarize the differences. Use the verb "override" to indicate + that a subclass method replaces a superclass method and does not + call the superclass method; use the verb "extend" to indicate that + a subclass method calls the superclass method (in addition to its + own behavior). + + *Do not* use the Emacs convention of mentioning the arguments of + functions or methods in upper case in running text. Python is + case sensitive and the argument names can be used for keyword + arguments, so the docstring should document the correct argument + names. It is best to list each argument on a separate line. For + example:: + + def complex(real=0.0, imag=0.0): + """Form a complex number. + + Keyword arguments: + real -- the real part (default 0.0) + imag -- the imaginary part (default 0.0) + + """ + if imag == 0.0 and real == 0.0: return complex_zero + ... + + The BDFL [3] recommends inserting a blank line between the last + paragraph in a multi-line docstring and its closing quotes, + placing the closing quotes on a line by themselves. This way, + Emacs' fill-paragraph command can be used on it. + + +References and Footnotes + + [1] PEP 256, Docstring Processing System Framework, Goodger + http://www.python.org/peps/pep-0256.html + + [2] PEP 258, Docutils Design Specification, Goodger + http://www.python.org/peps/pep-0258.html + + [3] Guido van Rossum, Python's creator and Benevolent Dictator For + Life. + + [4] http://www.python.org/doc/essays/styleguide.html + + [5] http://www.python.org/sigs/doc-sig/ + + +Copyright + + This document has been placed in the public domain. + + +Acknowledgements + + The "Specification" text comes mostly verbatim from the Python + Style Guide essay by Guido van Rossum [4]. + + This document borrows ideas from the archives of the Python + Doc-SIG [5]. Thanks to all members past and present. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +fill-column: 70 +sentence-end-double-space: t +End: diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt new file mode 100644 index 000000000..6a55e20de --- /dev/null +++ b/docs/peps/pep-0258.txt @@ -0,0 +1,662 @@ +PEP: 258 +Title: Docutils Design Specification +Version: $Revision$ +Last-Modified: $Date$ +Author: goodger@users.sourceforge.net (David Goodger) +Discussions-To: doc-sig@python.org +Status: Draft +Type: Standards Track +Requires: 256, 257 +Created: 31-May-2001 +Post-History: 13-Jun-2001 + + +Abstract + + This PEP documents design issues and implementation details for + Docutils, a Python Docstring Processing System (DPS). The + rationale and high-level concepts of a DPS are documented in PEP + 256, "Docstring Processing System Framework" [1]. + + No changes to the core Python language are required by this PEP. + Its deliverables consist of a package for the standard library and + its documentation. + + +Specification + + Docstring Extraction Rules + ========================== + + 1. What to examine: + + a) If the "__all__" variable is present in the module being + documented, only identifiers listed in "__all__" are + examined for docstrings. + + b) In the absense of "__all__", all identifiers are examined, + except those whose names are private (names begin with "_" + but don't begin and end with "__"). + + c) 1a and 1b can be overridden by a parameter or command-line + option. + + 2. Where: + + Docstrings are string literal expressions, and are recognized + in the following places within Python modules: + + a) At the beginning of a module, function definition, class + definition, or method definition, after any comments. This + is the standard for Python __doc__ attributes. + + b) Immediately following a simple assignment at the top level + of a module, class definition, or __init__ method + definition, after any comments. See "Attribute Docstrings" + below. + + c) Additional string literals found immediately after the + docstrings in (a) and (b) will be recognized, extracted, and + concatenated. See "Additional Docstrings" below. + + d) @@@ 2.2-style "properties" with attribute docstrings? + + 3. How: + + Whenever possible, Python modules should be parsed by Docutils, + not imported. There are security reasons for not importing + untrusted code. Information from the source is lost when using + introspection to examine an imported module, such as comments + and the order of definitions. Also, docstrings are to be + recognized in places where the bytecode compiler ignores string + literal expressions (2b and 2c above), meaning importing the + module will lose these docstrings. Of course, standard Python + parsing tools such as the "parser" library module may be used. + + When the Python source code for a module is not available + (i.e. only the .pyc file exists) or for C extension modules, to + access docstrings the module can only be imported, and any + limitations must be lived with. + + Since attribute docstrings and additional docstrings are ignored + by the Python bytecode compiler, no namespace pollution or runtime + bloat will result from their use. They are not assigned to + __doc__ or to any other attribute. The initial parsing of a + module may take a slight performance hit. + + + Attribute Docstrings + -------------------- + + (This is a simplified version of PEP 224 [2] by Marc-Andre + Lemberg.) + + A string literal immediately following an assignment statement is + interpreted by the docstring extration machinery as the docstring + of the target of the assignment statement, under the following + conditions: + + 1. The assignment must be in one of the following contexts: + + a) At the top level of a module (i.e., not nested inside a + compound statement such as a loop or conditional): a module + attribute. + + b) At the top level of a class definition: a class attribute. + + c) At the top level of the "__init__" method definition of a + class: an instance attribute. + + Since each of the above contexts are at the top level (i.e., in + the outermost suite of a definition), it may be necessary to + place dummy assignments for attributes assigned conditionally + or in a loop. + + 2. The assignment must be to a single target, not to a list or a + tuple of targets. + + 3. The form of the target: + + a) For contexts 1a and 1b above, the target must be a simple + identifier (not a dotted identifier, a subscripted + expression, or a sliced expression). + + b) For context 1c above, the target must be of the form + "self.attrib", where "self" matches the "__init__" method's + first parameter (the instance parameter) and "attrib" is a + simple indentifier as in 3a. + + Blank lines may be used after attribute docstrings to emphasize + the connection between the assignment and the docstring. + + Examples:: + + g = 'module attribute (module-global variable)' + """This is g's docstring.""" + + class AClass: + + c = 'class attribute' + """This is AClass.c's docstring.""" + + def __init__(self): + self.i = 'instance attribute' + """This is self.i's docstring.""" + + + Additional Docstrings + --------------------- + + (This idea was adapted from PEP 216, Docstring Format [3], by + Moshe Zadka.) + + Many programmers would like to make extensive use of docstrings + for API documentation. However, docstrings do take up space in + the running program, so some of these programmers are reluctant to + "bloat up" their code. Also, not all API documentation is + applicable to interactive environments, where __doc__ would be + displayed. + + The docstring processing system's extraction tools will + concatenate all string literal expressions which appear at the + beginning of a definition or after a simple assignment. Only the + first strings in definitions will be available as __doc__, and can + be used for brief usage text suitable for interactive sessions; + subsequent string literals and all attribute docstrings are + ignored by the Python bytecode compiler and may contain more + extensive API information. + + Example:: + + def function(arg): + """This is __doc__, function's docstring.""" + """ + This is an additional docstring, ignored by the bytecode + compiler, but extracted by the Docutils. + """ + pass + + Issue: This breaks "from __future__ import" statements in Python + 2.1 for multiple module docstrings. The Python Reference Manual + specifies: + + A future statement must appear near the top of the module. + The only lines that can appear before a future statement are: + + * the module docstring (if any), + * comments, + * blank lines, and + * other future statements. + + Resolution? + + 1. Should we search for docstrings after a __future__ statement? + Very ugly. + + 2. Redefine __future__ statements to allow multiple preceeding + string literals? + + 3. Or should we not even worry about this? There shouldn't be + __future__ statements in production code, after all. Will + modules with __future__ statements simply have to put up with + the single-docstring limitation? + + + Choice of Docstring Format + ========================== + + Rather than force everyone to use a single docstring format, + multiple input formats are allowed by the processing system. A + special variable, __docformat__, may appear at the top level of a + module before any function or class definitions. Over time or + through decree, a standard format or set of formats should emerge. + + The __docformat__ variable is a string containing the name of the + format being used, a case-insensitive string matching the input + parser's module or package name (i.e., the same name as required + to "import" the module or package), or a registered alias. If no + __docformat__ is specified, the default format is "plaintext" for + now; this may be changed to the standard format once determined. + + The __docformat__ string may contain an optional second field, + separated from the format name (first field) by a single space: a + case-insensitive language identifier as defined in RFC 1766 [4]. + A typical language identifier consists of a 2-letter language code + from ISO 639 [5] (3-letter codes used only if no 2-letter code + exists; RFC 1766 is currently being revised to allow 3-letter + codes). If no language identifier is specified, the default is + "en" for English. The language identifier is passed to the parser + and can be used for language-dependent markup features. + + + Docutils Project Model + ====================== + + :: + + +--------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish() | + +--------------------------+ + / \ + / \ + 1,3,5 / \ 6,8 + +--------+ +--------+ + | READER | =======================> | WRITER | + +--------+ +--------+ + // \ / \ + // \ / \ + 2 // 4 \ 7 / 9 \ + +--------+ +------------+ +------------+ +--------------+ + | PARSER |...| reader | | writer |...| DISTRIBUTOR? | + +--------+ | transforms | | transforms | | | + | | | | | - one file | + | - docinfo | | - styling | | - many files | + | - titles | | - writer- | | - objects in | + | - linking | | specific | | memory | + | - lookups | | - etc. | +--------------+ + | - reader- | +------------+ + | specific | + | - parser- | + | specific | + | - layout | + | - etc. | + +------------+ + + The numbers indicate the path a document would take through the + code. Double-width lines between reader & parser and between + reader & writer, indicating that data sent along these paths + should be standard (pure & unextended) Docutils doc trees. + Single-width lines signify that internal tree extensions or + completely unrelated representations are possible, but they must + be supported internally at both ends. + + + Publisher + --------- + + The "docutils.core" module contains a "Publisher" facade class and + "publish" convenience function. Publisher encapsulates the + high-level logic of a Docutils system. The Publisher.publish() + method passes its input to its Reader, then passes the resulting + document tree through its Writer to its destination. + + + Readers + ------- + + Readers understand the input context (where the data is coming + from), send the whole input or discrete "chunks" to the parser, + and provide the context to bind the chunks together back into a + cohesive whole. Using transforms_, Readers also resolve + references, footnote numbers, interpreted text processing, and + anything else that requires context-sensitive computation. + + Each reader is a module or package exporting a "Reader" class with + a "read" method. The base "Reader" class can be found in the + docutils/readers/__init__.py module. + + Most Readers will have to be told what parser to use. So far (see + the list of examples below), only the Python Source Reader + (PySource) will be able to determine the syntax on its own. + + Responsibilities: + + - Do raw input on the source ("Reader.scan()"). + + - Pass the raw text to the parser, along with a fresh doctree + root ("Reader.parse()"). + + - Run transforms over the doctree(s) ("Reader.transform()"). + + Examples: + + - Standalone/Raw/Plain: Just read a text file and process it. The + reader needs to be told which parser to use. Parser-specific + readers? + + - Python Source: See `Python Source Reader`_ above. + + - Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. + + - PEP: RFC-822 headers, "PEP xxxx" and "RFC xxxx" conversion to + URIs. Either interpret PEPs' indented sections or convert + existing PEPs to reStructuredText (or both?). + + - Wiki: Global reference lookups of "wiki links" incorporated into + transforms. (CamelCase only or unrestricted?) Lazy + indentation? + + - Web Page: As standalone, but recognize meta fields as meta tags. + Support for templates of some sort? (After , before + ?) + + - FAQ: Structured "question & answer(s)" constructs. + + - Compound document: Merge chapters into a book. Master TOC file? + + + Parsers + ------- + + Parsers analyze their input and produce a Docutils `document + tree`_. They don't know or care anything about the source or + destination of the data. + + Each input parser is a module or package exporting a "Parser" + class with a "parse" method. The base "Parser" class can be found + in the docutils/parsers/__init__.py module. + + Responsibilities: Given raw input text and a doctree root node, + populate the doctree by parsing the input text. + + Example: The only parser implemented so far is for the + reStructuredText markup. + + + Transforms + ---------- + + Transforms change the document tree from one form to another, add + to the tree, or prune it. Transforms are run by Reader and Writer + objects. Some transforms are Reader-specific, some are + Parser-specific, and others are Writer-specific. The choice and + order of transforms is specified in the Reader and Writer objects. + + Each transform is a class in a module in the docutils/transforms + package, a subclass of docutils.tranforms.Transform. + + Responsibilities: + + - Modify a doctree in-place, either purely transforming one + structure into another, or adding new structures based on the + doctree and/or external data. + + Examples (in "docutils.transforms"): + + - frontmatter.DocInfo: conversion of document metadata + (bibliographic information). + + - references.Hyperlinks: resolution of hyperlinks. + + - document.Merger: combining multiple populated doctrees into one. + + + Writers + ------- + + Writers produce the final output (HTML, XML, TeX, etc.). Writers + translate the internal document tree structure into the final data + format, possibly running output-specific transforms_ first. + + Each writer is a module or package exporting a "Writer" class with + a "write" method. The base "Writer" class can be found in the + docutils/writers/__init__.py module. + + Responsibilities: + + - Run transforms over the doctree(s). + + - Translate doctree(s) into specific output formats. + + - Transform references into format-native forms. + + - Write output to the destination (possibly via a "Distributor"). + + Examples: + + - XML: Various forms, such as DocBook. Also, raw doctree XML. + + - HTML + + - TeX + + - Plain text + + - reStructuredText? + + + Distributors + ------------ + + Distributors will exist for each method of storing the results of + processing: + + - In a single file on disk. + + - In a tree of directories and files on disk. + + - In a single tree-shaped data structure in memory. + + - Some other set of data structures in memory. + + @@@ Distributors are currently just an idea; they may or may not + be practical. Issues: + + Is it better for the writer to control the distributor, or + vice versa? Or should they be equals? + + Looking at the list of writers, it seems that only HTML would + require anything other than monolithic output. Perhaps merge + the HTML "distributor" into "writer" variants? + + Perhaps translator/writer instead of writer/distributor? + + Responsibilities: + + - Do raw output to the destination. + + - Transform references per incarnation (method of distribution). + + Examples: + + - Single file. + + - Multiple files & directories. + + - Objects in memory. + + + Docutils Package Structure + ========================== + + - Package "docutils". + + - Module "docutils.core" contains facade class "Publisher" and + convenience function "publish()". See `Publisher API`_ below. + + - Module "docutils.nodes" contains the Docutils document tree + element class library plus Visitor pattern base classes. See + `Document Tree`_ below. + + - Module "docutils.roman" contains Roman numeral conversion + routines. + + - Module "docutils.statemachine" contains a finite state machine + specialized for regular-expression-based text filters. The + reStructuredText parser implementation is based on this + module. + + - Module "docutils.urischemes" contains a mapping of known URI + schemes ("http", "ftp", "mail", etc.). + + - Module "docutils.utils" contains utility functions and + classes, including a logger class ("Reporter"; see `Error + Handling`_ below). + + - Package "docutils.parsers": markup parsers_. + + - Function "get_parser_class(parsername)" returns a parser + module by name. Class "Parser" is the base class of + specific parsers. (docutils/parsers/__init__.py) + + - Package "docutils.parsers.rst": the reStructuredText parser. + + - Alternate markup parsers may be added. + + - Package "docutils.readers": context-aware input readers. + + - Function "get_reader_class(readername)" returns a reader + module by name or alias. Class "Reader" is the base class + of specific readers. (docutils/readers/__init__.py) + + - Module "docutils.readers.standalone": reads independent + document files. + + - Readers to be added for: Python source code (structure & + docstrings), PEPs, email, FAQ, and perhaps Wiki and others. + + - Package "docutils.writers": output format writers. + + - Function "get_writer_class(writername)" returns a writer + module by name. Class "Writer" is the base class of + specific writers. (docutils/writers/__init__.py) + + - Module "docutils.writers.pprint" is a simple internal + document tree writer; it writes indented pseudo-XML. + + - Module "docutils.writers.html4css1" is a simple HyperText + Markup Language document tree writer for HTML 4.01 and CSS1. + + - Writers to be added: HTML 3.2 or 4.01-loose, XML (various + forms, such as DocBook and the raw internal doctree), TeX, + plaintext, reStructuredText, and perhaps others. + + - Package "docutils.transforms": tree transform classes. + + - Class "Transform" is the base class of specific transforms; + see `Transform API`_ below. + (docutils/transforms/__init__.py) + + - Each module contains related transform classes. + + - Package "docutils.languages": Language modules contain + language-dependent strings and mappings. They are named for + their language identifier (as defined in `Choice of Docstring + Format`_ above), converting dashes to underscores. + + - Function "getlanguage(languagecode)", returns matching + language module. (docutils/languages/__init__.py) + + - Module "docutils.languages.en" (English). + + - Other languages to be added. + + + Front-End Tools + =============== + + @@@ To be determined. + + @@@ Document tools & summarize their command-line interfaces. + + + Document Tree + ============= + + A single intermediate data structure is used internally by + Docutils, in the interfaces between components; it is defined in + the docutils.nodes module. It is not required that this data + structure be used *internally* by any of the components, just + *between* components. This data structure is similar to a DOM + tree whose schema is documented in an XML DTD (eXtensible Markup + Language Document Type Definition), which comes in two parts: + + - the Docutils Generic DTD, docutils.dtd [6], and + + - the OASIS Exchange Table Model, soextbl.dtd [7]. + + The DTD defines a rich set of elements, suitable for many input + and output formats. The DTD retains all information necessary to + reconstruct the original input text, or a reasonable facsimile + thereof. + + + Error Handling + ============== + + When the parser encounters an error in markup, it inserts a system + message (DTD element "system_message"). There are five levels of + system messages: + + - Level-0, "DEBUG": an internal reporting issue. There is no + effect on the processing. Level-0 system messages are + handled separately from the others. + + - Level-1, "INFO": a minor issue that can be ignored. There is + little or no effect on the processing. Typically level-1 system + messages are not reported. + + - Level-2, "WARNING": an issue that should be addressed. If + ignored, there may be unpredictable problems with the output. + Typically level-2 system messages are reported but do not halt + processing + + - Level-3, "ERROR": a major issue that should be addressed. If + ignored, the output will contain errors. Typically level-3 + system messages are reported but do not halt processing + + - Level-4, "SEVERE": a critical error that must be addressed. + Typically level-4 system messages are turned into exceptions + which halt processing. If ignored, the output will contain + severe errors. + + Although the initial message levels were devised independently, + they have a strong correspondence to VMS error condition severity + levels [8]; the names in quotes for levels 1 through 4 were + borrowed from VMS. Error handling has since been influenced by + the log4j project [9]. + + +References and Footnotes + + [1] PEP 256, Docstring Processing System Framework, Goodger + http://www.python.org/peps/pep-0256.html + + [2] PEP 224, Attribute Docstrings, Lemburg + http://www.python.org/peps/pep-0224.html + + [3] PEP 216, Docstring Format, Zadka + http://www.python.org/peps/pep-0216.html + + [4] http://www.rfc-editor.org/rfc/rfc1766.txt + + [5] http://lcweb.loc.gov/standards/iso639-2/englangn.html + + [6] http://docutils.sourceforge.net/spec/docutils.dtd + + [7] http://docstring.sourceforge.net/spec/soextblx.dtd + + [8] http://www.openvms.compaq.com:8000/73final/5841/ + 5841pro_027.html#error_cond_severity + + [9] http://jakarta.apache.org/log4j/ + + [10] http://www.python.org/sigs/doc-sig/ + + +Project Web Site + + A SourceForge project has been set up for this work at + http://docutils.sourceforge.net/. + + +Copyright + + This document has been placed in the public domain. + + +Acknowledgements + + This document borrows ideas from the archives of the Python + Doc-SIG [10]. Thanks to all members past & present. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +fill-column: 70 +sentence-end-double-space: t +End: diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt new file mode 100644 index 000000000..90aea7054 --- /dev/null +++ b/docs/ref/doctree.txt @@ -0,0 +1,344 @@ +================================== + Docutils Document Tree Structure +================================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +This document describes the internal data structure representing +document trees in Docutils. The data structure is defined by the +hierarchy of classes in the ``docutils.nodes`` module. It is also +formally described by the `Docutils Generic DTD`_ XML document type +definition, docutils.dtd_, which is the definitive source for element +hierarchy details. + +Below is a simplified diagram of the hierarchy of element types in the +Docutils document tree structure. An element may contain any other +elements immediately below it in the diagram. Text in square brackets +are notes. Element types in parentheses indicate recursive or +one-to-many relationships; sections may contain (sub)sections, tables +contain further body elements, etc. :: + + +--------------------------------------------------------------------+ + | document [may begin with a title, subtitle, docinfo] | + | +--------------------------------------+ + | | sections [each begins with a title] | + +-----------------------------+-------------------------+------------+ + | [body elements:] | (sections) | + | | - literal | - lists | | - hyperlink +------------+ + | | blocks | - tables | | targets | + | para- | - doctest | - block | foot- | - sub. defs | + | graphs | blocks | quotes | notes | - comments | + +---------+-----------+----------+-------+--------------+ + | [text]+ | [text] | (body elements) | [text] | + | (inline +-----------+------------------+--------------+ + | markup) | + +---------+ + + +------------------- + Element Hierarchy +------------------- + +A class hierarchy has been implemented in nodes.py where the position +of the element (the level at which it can occur) is significant. +E.G., Root, Structural, Body, Inline classes etc. Certain +transformations will be easier because we can use isinstance() on +them. + +The elements making up Docutils document trees can be categorized into +the following groups: + +- _`Root element`: document_ + +- _`Title elements`: title_, subtitle_ + +- _`Bibliographic elements`: docinfo_, author_, authors_, + organization_, contact_, version_, revision_, status_, date_, + copyright_ + +- _`Structural elements`: document_, section_, topic_, transition_ + +- _`Body elements`: + + - _`General body elements`: paragraph_, literal_block_, + block_quote_, doctest_block_, table_, figure_, image_, footnote_ + + - _`Lists`: bullet_list_, enumerated_list_, definition_list_, + field_list_, option_list_ + + - _`Admonitions`: note_, tip_, warning_, error_, caution_, danger_, + important_ + + - _`Special body elements`: target_, substitution_definition_, + comment_, system_warning_ + +- _`Inline elements`: emphasis_, strong_, interpreted_, literal_, + reference_, target_, footnote_reference_, substitution_reference_, + image_, problematic_ + + +``Node`` +======== + + +``Text`` +======== + + +``Element`` +=========== + + +``TextElement`` +=============== + + +------------------- + Element Reference +------------------- + +``document`` +============ +description + +contents + +External attributes +------------------- +`Common external attributes`_. + + +Internal attributes +------------------- +- `Common internal attributes`_. +- ``explicittargets`` +- ``implicittargets`` +- ``externaltargets`` +- ``indirecttargets`` +- ``refnames`` +- ``anonymoustargets`` +- ``anonymousrefs`` +- ``autofootnotes`` +- ``autofootnoterefs`` +- ``reporter`` + + +--------------------- + Attribute Reference +--------------------- + +External Attributes +=================== + +Through the `%basic.atts;`_ parameter entity, all elements share the +following _`common external attributes`: id_, name_, dupname_, +source_. + + +``anonymous`` +------------- +The ``anonymous`` attribute + + +``auto`` +-------- +The ``auto`` attribute + + +``dupname`` +----------- +The ``dupname`` attribute + + +``id`` +------ +The ``id`` attribute + + +``name`` +-------- +The ``name`` attribute + + +``refid`` +--------- +The ``refid`` attribute + + +``refname`` +----------- +The ``refname`` attribute + + +``refuri`` +---------- +The ``refuri`` attribute + + +``source`` +---------- +The ``source`` attribute + + +``xml:space`` +------------- +The ``xml:space`` attribute + + +Internal Attributes +=================== + +All element objects share the following _`common internal attributes`: +rawsource_, children_, attributes_, tagname_. + + +------------------------ + DTD Parameter Entities +------------------------ + +``%basic.atts;`` +================ +The ``%basic.atts;`` parameter entity lists attributes common to all +elements. See `Common Attributes`_. + + +``%body.elements;`` +=================== +The ``%body.elements;`` parameter entity + + +``%inline.elements;`` +==================== +The ``%inline.elements;`` parameter entity + + +``%reference.atts;`` +==================== +The ``%reference.atts;`` parameter entity + + +``%structure.model;`` +===================== +The ``%structure.model;`` parameter entity + + +``%text.model;`` +================ +The ``%text.model;`` parameter entity + + +-------------------------------- + Appendix: Miscellaneous Topics +-------------------------------- + +Representation of Horizontal Rules +================================== + +Having added the "horizontal rule" construct to the reStructuredText_ +spec, a decision had to be made as to how to reflect the construct in +the implementation of the document tree. Given this source:: + + Document + ======== + + Paragraph + + -------- + + Paragraph + +The horizontal rule indicates a "transition" (in prose terms) or the +start of a new "division". Before implementation, the parsed document +tree would be:: + + +

+ + Document + <paragraph> + Paragraph + -------- <--- error here + <paragraph> + Paragraph + +There are several possibilities for the implementation. Solution 3 +was chosen. + +1. Implement horizontal rules as "divisions" or segments. A + "division" is a title-less, non-hierarchical section. The first + try at an implementation looked like this:: + + <document> + <section name="document"> + <title> + Document + <paragraph> + Paragraph + <division> + <paragraph> + Paragraph + + But the two paragraphs are really at the same level; they shouldn't + appear to be at different levels. There's really an invisible + "first division". The horizontal rule splits the document body + into two segments, which should be treated uniformly. + +2. Treating "divisions" uniformly brings us to the second + possibility:: + + <document> + <section name="document"> + <title> + Document + <division> + <paragraph> + Paragraph + <division> + <paragraph> + Paragraph + + With this change, documents and sections will directly contain + divisions and sections, but not body elements. Only divisions will + directly contain body elements. Even without a horizontal rule + anywhere, the body elements of a document or section would be + contained within a division element. This makes the document tree + deeper. This is similar to the way HTML treats document contents: + grouped within a <BODY> element. + +3. Implement them as "transitions", empty elements:: + + <document> + <section name="document"> + <title> + Document + <paragraph> + Paragraph + <transition> + <paragraph> + Paragraph + + A transition would be a "point element", not containing anything, + only identifying a point within the document structure. This keeps + the document tree flatter, but the idea of a "point element" like + "transition" smells bad. A transition isn't a thing itself, it's + the space between two divisions. + + This solution has been chosen for incorporation into the document + tree. + + +.. _Docutils Generic DTD: +.. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd +.. _reStructuredText: + http://docutils.sourceforge.net/spec/rst/reStructuredText.html + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd new file mode 100644 index 000000000..d47238b4d --- /dev/null +++ b/docs/ref/docutils.dtd @@ -0,0 +1,514 @@ +<!-- +====================================================================== + Docutils Generic DTD +====================================================================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This DTD has been placed in the public domain. +:Filename: docutils.dtd + +More information about this DTD (document type definition) and the +Docutils project can be found at http://docutils.sourceforge.net/. +The latest version of this DTD is available from +http://docutils.sourceforge.net/spec/docutils.dtd. + +The proposed formal public identifier for this DTD is:: + + +//IDN python.org//DTD Docutils Generic//EN//XML +--> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Parameter Entities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Parameter entities are used to simplify the DTD (reduce duplication) +and to allow the DTD to be customized by wrapper DTDs. Parameter +entities beginning with 'additional' are meant to allow easy extension +by wrapper DTDs. +--> + +<!-- Attributes +================================================================== --> + +<!-- Boolean: no if zero(s), yes if any other value. --> +<!ENTITY % yesorno "NMTOKEN"> + +<!ENTITY % additional.basic.atts ""> +<!-- +Attributes shared by all elements in this DTD: + +- `id` is a unique identifier, typically assigned by the system. +- `name` is an identifier assigned in the markup. +- `dupname` is the same as `name`, used when it's a duplicate. +- `source` is the name of the source of this document or fragment. +- `class` is used to transmit individuality information forward. +--> +<!ENTITY % basic.atts + " id ID #IMPLIED + name CDATA #IMPLIED + dupname CDATA #IMPLIED + source CDATA #IMPLIED + class CDATA #IMPLIED + %additional.basic.atts; "> + +<!-- External reference to a URI/URL. --> +<!ENTITY % refuri.att + " refuri CDATA #IMPLIED "> + +<!-- Internal reference to the `id` attribute of an element. --> +<!ENTITY % refid.att + " refid IDREF #IMPLIED "> + +<!-- Space-separated list of id references, for backlinks. --> +<!ENTITY % backrefs.att + " backrefs IDREFS #IMPLIED "> + +<!-- +Internal reference to the `name` attribute of an element. On a +'target' element, 'refname' indicates an indirect target which may +resolve to either an internal or external reference. +--> +<!ENTITY % refname.att + " refname CDATA #IMPLIED "> + +<!ENTITY % additional.reference.atts ""> +<!-- Collected hyperlink reference attributes. --> +<!ENTITY % reference.atts + " %refuri.att; + %refid.att; + %refname.att; + %additional.reference.atts; "> + +<!-- Unnamed hyperlink. --> +<!ENTITY % anonymous.att + " anonymous %yesorno; #IMPLIED "> + +<!-- Auto-numbered footnote. --> +<!ENTITY % auto.att + " auto %yesorno; #IMPLIED "> + +<!-- XML standard attribute for whitespace-preserving elements. --> +<!ENTITY % fixedspace.att + " xml:space (default | preserve) #FIXED 'preserve' "> + + +<!-- Element OR-Lists +============================================================= --> + +<!ENTITY % additional.bibliographic.elements ""> +<!ENTITY % bibliographic.elements + " author | authors | organization | contact + | version | revision | status | date | copyright + %additional.bibliographic.elements; "> + +<!ENTITY % additional.structural.elements ""> +<!ENTITY % structural.elements + " section + %additional.structural.elements; "> + +<!ENTITY % additional.body.elements ""> +<!ENTITY % body.elements + " paragraph | literal_block | block_quote | doctest_block| table + | figure | image | footnote | citation + | bullet_list | enumerated_list | definition_list | field_list + | option_list + | attention | caution | danger | error | hint | important | note + | tip | warning + | target | substitution_definition | comment | pending + | system_message | raw + %additional.body.elements; "> + +<!ENTITY % additional.inline.elements ""> +<!ENTITY % inline.elements + " emphasis | strong | interpreted | literal + | reference | footnote_reference | citation_reference + | substitution_reference | target | image | problematic | raw + %additional.inline.elements; "> + +<!-- Element Content Models +================================================================== --> + +<!ENTITY % structure.model + " ( ( (%body.elements; | topic)+, + (transition, (%body.elements; | topic)+ )*, + (%structural.elements;)* ) + | (%structural.elements;)+ ) "> + +<!ENTITY % text.model + " (#PCDATA | %inline.elements;)* "> + +<!-- Table Model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This DTD uses the Exchange subset of the CALS-table model (OASIS +Technical Memorandum 9901:1999 "XML Exchange Table Model DTD", +http://www.oasis-open.org/html/tm9901.htm). +--> + +<!ENTITY % calstblx PUBLIC + "-//OASIS//DTD XML Exchange Table Model 19990315//EN" + "soextblx.dtd"> + +<!-- These parameter entities customize the table model DTD. --> +<!ENTITY % bodyatt " %basic.atts; "> <!-- table elt --> +<!ENTITY % tbl.tgroup.att " %basic.atts; "> +<!ENTITY % tbl.thead.att " %basic.atts; "> +<!ENTITY % tbl.tbody.att " %basic.atts; "> +<!ENTITY % tbl.colspec.att " %basic.atts; "> +<!ENTITY % tbl.row.att " %basic.atts; "> +<!ENTITY % tbl.entry.mdl " (%body.elements;)* "> +<!ENTITY % tbl.entry.att + " %basic.atts; + morecols NMTOKEN #IMPLIED "> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Root Element +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!-- Optional elements may be generated by internal processing. --> +<!ELEMENT document + ((title, subtitle?)?, docinfo?, %structure.model;)> +<!ATTLIST document %basic.atts;> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Title Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!ELEMENT title %text.model;> +<!ATTLIST title + %basic.atts; + %refid.att;> + +<!ELEMENT subtitle %text.model;> +<!ATTLIST subtitle %basic.atts;> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Bibliographic Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!-- Container for bibliographic elements. May not be empty. --> +<!ELEMENT docinfo (%bibliographic.elements;)+> +<!ATTLIST docinfo %basic.atts;> + +<!ELEMENT author %text.model;> +<!ATTLIST author %basic.atts;> + +<!ELEMENT authors ((author, organization?, contact?)+)> +<!ATTLIST authors %basic.atts;> + +<!ELEMENT organization %text.model;> +<!ATTLIST organization %basic.atts;> + +<!ELEMENT contact %text.model;> +<!ATTLIST contact %basic.atts;> + +<!ELEMENT version %text.model;> +<!ATTLIST version %basic.atts;> + +<!ELEMENT revision %text.model;> +<!ATTLIST revision %basic.atts;> + +<!ELEMENT status %text.model;> +<!ATTLIST status %basic.atts;> + +<!ELEMENT date %text.model;> +<!ATTLIST date %basic.atts;> + +<!ELEMENT copyright %text.model;> +<!ATTLIST copyright %basic.atts;> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Structural Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!ELEMENT section (title, %structure.model;)> +<!ATTLIST section %basic.atts;> + +<!ELEMENT topic (title?, (%body.elements;)+)> +<!ATTLIST topic %basic.atts;> + +<!ELEMENT transition EMPTY> +<!ATTLIST transition %basic.atts;> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Body Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!ELEMENT paragraph %text.model;> +<!ATTLIST paragraph %basic.atts;> + +<!ELEMENT bullet_list (list_item+)> +<!ATTLIST bullet_list + %basic.atts; + bullet CDATA #IMPLIED> + +<!ELEMENT enumerated_list (list_item+)> +<!ATTLIST enumerated_list + %basic.atts; + enumtype (arabic | loweralpha | upperalpha + | lowerroman | upperroman) + #IMPLIED + prefix CDATA #IMPLIED + suffix CDATA #IMPLIED + start NUMBER #IMPLIED> + +<!ELEMENT list_item (%body.elements;)+> +<!ATTLIST list_item %basic.atts;> + +<!ELEMENT definition_list (definition_list_item+)> +<!ATTLIST definition_list %basic.atts;> + +<!ELEMENT definition_list_item (term, classifier?, definition)> +<!ATTLIST definition_list_item %basic.atts;> + +<!ELEMENT term %text.model;> +<!ATTLIST term %basic.atts;> + +<!ELEMENT classifier %text.model;> +<!ATTLIST classifier %basic.atts;> + +<!ELEMENT definition (%body.elements;)+> +<!ATTLIST definition %basic.atts;> + +<!ELEMENT field_list (field+)> +<!ATTLIST field_list %basic.atts;> + +<!ELEMENT field (field_name, field_argument*, field_body)> +<!ATTLIST field %basic.atts;> + +<!ELEMENT field_name (#PCDATA)> +<!ATTLIST field_name %basic.atts;> + +<!-- Support for Javadoc-style tags with arguments. --> +<!ELEMENT field_argument (#PCDATA)> +<!ATTLIST field_argument %basic.atts;> + +<!ELEMENT field_body (%body.elements;)+> +<!ATTLIST field_body %basic.atts;> + +<!ELEMENT option_list (option_list_item+)> +<!ATTLIST option_list %basic.atts;> + +<!ELEMENT option_list_item (option_group, description)> +<!ATTLIST option_list_item %basic.atts;> + +<!ELEMENT option_group (option+)> +<!ATTLIST option_group %basic.atts;> + +<!ELEMENT option (option_string, option_argument*)> +<!ATTLIST option %basic.atts;> + +<!ELEMENT option_string (#PCDATA)> +<!ATTLIST option_string %basic.atts;> + +<!-- +`delimiter` contains the string preceding the `option_argument`: +either the string separating it from the `option` (typically either +"=" or " ") or the string between option arguments (typically either +"," or " "). +--> +<!ELEMENT option_argument (#PCDATA)> +<!ATTLIST option_argument + %basic.atts; + delimiter CDATA #IMPLIED> + +<!ELEMENT description (%body.elements;)+> +<!ATTLIST description %basic.atts;> + +<!ELEMENT literal_block (#PCDATA)> +<!ATTLIST literal_block + %basic.atts; + %fixedspace.att;> + +<!ELEMENT block_quote (%body.elements;)+> +<!ATTLIST block_quote %basic.atts;> + +<!ELEMENT doctest_block (#PCDATA)> +<!ATTLIST doctest_block + %basic.atts; + %fixedspace.att;> + +<!ELEMENT attention (%body.elements;)+> +<!ATTLIST attention %basic.atts;> + +<!ELEMENT caution (%body.elements;)+> +<!ATTLIST caution %basic.atts;> + +<!ELEMENT danger (%body.elements;)+> +<!ATTLIST danger %basic.atts;> + +<!ELEMENT error (%body.elements;)+> +<!ATTLIST error %basic.atts;> + +<!ELEMENT hint (%body.elements;)+> +<!ATTLIST hint %basic.atts;> + +<!ELEMENT important (%body.elements;)+> +<!ATTLIST important %basic.atts;> + +<!ELEMENT note (%body.elements;)+> +<!ATTLIST note %basic.atts;> + +<!ELEMENT tip (%body.elements;)+> +<!ATTLIST tip %basic.atts;> + +<!ELEMENT warning (%body.elements;)+> +<!ATTLIST warning %basic.atts;> + +<!ELEMENT footnote (label?, (%body.elements;)+)> +<!ATTLIST footnote + %basic.atts; + %backrefs.att; + %auto.att;> + +<!ELEMENT citation (label, (%body.elements;)+)> +<!ATTLIST citation + %basic.atts; + %backrefs.att;> + +<!ELEMENT label (#PCDATA)> +<!ATTLIST label %basic.atts;> + +<!-- Empty except when used as an inline element. --> +<!ELEMENT target (%text.model;)> +<!ATTLIST target + %basic.atts; + %reference.atts; + %anonymous.att;> + +<!ELEMENT substitution_definition (%text.model;)> +<!ATTLIST substitution_definition %basic.atts;> + +<!ELEMENT comment (#PCDATA)> +<!ATTLIST comment + %basic.atts; + %fixedspace.att;> + +<!ELEMENT pending EMPTY> +<!ATTLIST pending %basic.atts;> + +<!ELEMENT figure (image, ((caption, legend?) | legend) > +<!ATTLIST figure %basic.atts;> + +<!-- Also an inline element. --> +<!ELEMENT image EMPTY> +<!ATTLIST image + %basic.atts; + uri CDATA #REQUIRED + alt CDATA #IMPLIED + height NMTOKEN #IMPLIED + width NMTOKEN #IMPLIED + scale NMTOKEN #IMPLIED> + +<!ELEMENT caption %text.model;> +<!ATTLIST caption %basic.atts;> + +<!ELEMENT legend (%body.elements;)+> +<!ATTLIST legend %basic.atts;> + +<!-- +Table elements: table, tgroup, colspec, thead, tbody, row, entry. +--> +%calstblx; + +<!-- Used to record processing information. --> +<!ELEMENT system_message (%body.elements;)+> +<!ATTLIST system_message + %basic.atts; + %backrefs.att; + level NMTOKEN #IMPLIED + type CDATA #IMPLIED> + +<!-- Used to pass raw data through the system. Also inline. --> +<!ELEMENT raw %text.model;> +<!ATTLIST raw + %basic.atts; + %fixedspace.att; + format CDATA #IMPLIED> + + +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Inline Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Inline elements occur within the text contents of body elements. Some +nesting of inline elements is allowed by these definitions, with the +following caveats: + +- An inline element may not contain a nested element of the same type + (e.g. <strong> may not contain another <strong>). +- Nested inline elements may or may not be supported by individual + applications using this DTD. +- The inline elements <footnote_reference>, <citation_reference>, + <literal>, and <image> do not support nesting. +--> + +<!ELEMENT emphasis (%text.model;)> +<!ATTLIST emphasis %basic.atts;> + +<!ELEMENT strong (%text.model;)> +<!ATTLIST strong %basic.atts;> + +<!ELEMENT interpreted (%text.model;)> +<!ATTLIST interpreted + %basic.atts; + type CDATA #IMPLIED> + +<!ELEMENT literal (#PCDATA)> +<!ATTLIST literal %basic.atts;> + +<!ELEMENT reference (%text.model;)> +<!ATTLIST reference + %basic.atts; + %reference.atts; + %anonymous.att;> + +<!ELEMENT footnote_reference (#PCDATA)> +<!ATTLIST footnote_reference + %basic.atts; + %reference.atts; + %auto.att;> + +<!ELEMENT citation_reference (#PCDATA)> +<!ATTLIST citation_reference + %basic.atts; + %reference.atts;> + +<!ELEMENT substitution_reference (%text.model;)> +<!ATTLIST substitution_reference + %basic.atts; + %refname.att;> + +<!ELEMENT problematic (%text.model;)> +<!ATTLIST problematic + %basic.atts; + %refid.att;> + + +<!-- +Local Variables: +mode: sgml +indent-tabs-mode: nil +fill-column: 70 +End: +--> diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt new file mode 100644 index 000000000..cbb8b4609 --- /dev/null +++ b/docs/ref/rst/directives.txt @@ -0,0 +1,360 @@ +============================= + reStructuredText Directives +============================= +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +This document describes the directives implemented in the reference +reStructuredText parser. + + +.. contents:: + + +------------- + Admonitions +------------- + +DTD elements: attention, caution, danger, error, hint, important, +note, tip, warning. + +Directive block: directive data and all following indented text +are interpreted as body elements. + +Admonitions are specially marked "topics" that can appear anywhere an +ordinary body element can. They contain arbitrary body elements. +Typically, an admonition is rendered as an offset block in a document, +sometimes outlined or shaded, with a title matching the admonition +type. For example:: + + .. DANGER:: + Beware killer rabbits! + +This directive might be rendered something like this:: + + +------------------------+ + | !DANGER! | + | | + | Beware killer rabbits! | + +------------------------+ + +The following admonition directives have been implemented: + +- attention +- caution +- danger +- error +- hint +- important +- note +- tip +- warning + +Any text immediately following the directive indicator (on the same +line and/or indented on following lines) is interpreted as a directive +block and is parsed for normal body elements. For example, the +following "note" admonition directive contains one paragraph and a +bullet list consisting of two list items:: + + .. note:: This is a note admonition. + This is the second line of the first paragraph. + + - The note contains all indented body elements + following. + - It includes this bullet list. + + +-------- + Images +-------- + +There are two image directives: "image" and "figure". + + +Image +===== + +DTD element: image. + +Directive block: directive data and following indented lines (up to +the first blank line) are interpreted as image URI and optional +attributes. + +An "image" is a simple picture:: + + .. image:: picture.png + +The URI for the image source file is specified in the directive data. +As with hyperlink targets, the image URI may begin on the same line as +the explicit markup start and target name, or it may begin in an +indented text block immediately following, with no intervening blank +lines. If there are multiple lines in the link block, they are +stripped of leading and trailing whitespace and joined together. + +Optionally, the image link block may end with a flat field list, the +_`image attributes`. For example:: + + .. image:: picture.png + :height: 100 + :width: 200 + :scale: 50 + :alt: alternate text + +The following attributes are recognized: + +``alt`` : text + Alternate text: a short description of the image, displayed by + applications that cannot display images, or spoken by applications + for visually impaired users. +``height`` : integer + The height of the image in pixels, used to reserve space or scale + the image vertically. +``width`` : integer + The width of the image in pixels, used to reserve space or scale + the image horizontally. +``scale`` : integer + The uniform scaling factor of the image, a percentage (but no "%" + symbol is required or allowed). "100" means full-size. + + +Figure +====== + +DTD elements: figure, image, caption, legend. + +Directive block: directive data and all following indented text are +interpreted as an image URI, optional attributes, a caption, and an +optional legend. + +A "figure" consists of image_ data (optionally including `image +attributes`_), an optional caption (a single paragraph), and an +optional legend (arbitrary body elements):: + + .. figure:: picture.png + :scale: 50 + :alt: map to buried treasure + + This is the caption of the figure (a simple paragraph). + + The legend consists of all elements after the caption. In this + case, the legend consists of this paragraph and the following + table: + + +-----------------------+-----------------------+ + | Symbol | Meaning | + +=======================+=======================+ + | .. image:: tent.png | Campground | + +-----------------------+-----------------------+ + | .. image:: waves.png | Lake | + +-----------------------+-----------------------+ + | .. image:: peak.png | Mountain | + +-----------------------+-----------------------+ + +There must be a blank line before the caption paragraph and before the +legend. To specify a legend without a caption, use an empty comment +("..") in place of the caption. + + +--------------------- + Document Components +--------------------- + +Table of Contents +================= + +DTD elements: pending, topic. + +Directive block: directive data and following indented lines (up to +the first blank line) are interpreted as the topic title and optional +attributes. + +The "contents" directive inserts a table of contents (TOC) in two +passes: initial parse and transform. During the initial parse, a +"pending" element is generated which acts as a placeholder, storing +the TOC title and any attributes internally. At a later stage in the +processing, the "pending" element is replaced by a "topic" element, a +title and the table of contents proper. + +The directive in its simplest form:: + + .. contents:: + +Language-dependent boilerplate text will be used for the title. The +English default title text is "Contents". + +An explicit title, may be specified:: + + .. contents:: Table of Contents + +The title may span lines, although it is not recommended:: + + .. contents:: Here's a very long Table of + Contents title + +Attributes may be specified for the directive, using a field list:: + + .. contents:: Table of Contents + :depth: 2 + +If the default title is to be used, the attribute field list may begin +on the same line as the directive marker:: + + .. contents:: :depth: 2 + +The following attributes are recognized: + +``depth`` : integer + The number of section levels that are collected in the table of + contents. +``local`` : empty + Generate a local table of contents. Entries will only include + subsections of the section in which the directive is given. If no + explicit title is given, the table of contents will not be titled. + + +Footnotes +========= + +DTD elements: pending, topic. + +@@@ + + +Citations +========= + +DTD elements: pending, topic. + +@@@ + + +Topic +===== + +DTD element: topic. + +@@@ + + +--------------- + HTML-Specific +--------------- + +Meta +==== + +Non-standard element: meta. + +Directive block: directive data and following indented lines (up to +the first blank line) are parsed for a flat field list. + +The "meta" directive is used to specify HTML metadata stored in HTML +META tags. "Metadata" is data about data, in this case data about web +pages. Metadata is used to describe and classify web pages in the +World Wide Web, in a form that is easy for search engines to extract +and collate. + +Within the directive block, a flat field list provides the syntax for +metadata. The field name becomes the contents of the "name" attribute +of the META tag, and the field body (interpreted as a single string +without inline markup) becomes the contents of the "content" +attribute. For example:: + + .. meta:: + :description: The reStructuredText plaintext markup language + :keywords: plaintext, markup language + +This would be converted to the following HTML:: + + <meta name="description" + content="The reStructuredText plaintext markup language"> + <meta name="keywords" content="plaintext, markup language"> + +Support for other META attributes ("http-equiv", "scheme", "lang", +"dir") are provided through field arguments, which must be of the form +"attr=value":: + + .. meta:: + :description lang=en: An amusing story + :description lang=fr: Un histoire amusant + +And their HTML equivalents:: + + <meta name="description" lang="en" content="An amusing story"> + <meta name="description" lang="fr" content="Un histoire amusant"> + +Some META tags use an "http-equiv" attribute instead of the "name" +attribute. To specify "http-equiv" META tags, simply omit the name:: + + .. meta:: + :http-equiv=Content-Type: text/html; charset=ISO-8859-1 + +HTML equivalent:: + + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1"> + + +Imagemap +======== + +Non-standard element: imagemap. + + +--------------- + Miscellaneous +--------------- + +Raw Data Pass-Through +===================== + +DTD element: pending. + +Directive block: the directive data is interpreted as an output format +type, and all following indented text is stored verbatim, +uninterpreted. + +The "raw" directive indicates non-reStructuredText data that is to be +passed untouched to the Writer. The name of the output format is +given in the directive data. During the initial parse, a "pending" +element is generated which acts as a placeholder, storing the format +and raw data internally. The interpretation of the code is up to the +Writer. A Writer may ignore any raw output not matching its format. + +For example, the following input would be passed untouched by an HTML +Writer:: + + .. raw:: html + <hr width=50 size=10> + +A LaTeX Writer could insert the following raw content into its +output stream:: + + .. raw:: latex + \documentclass[twocolumn]{article} + + +Restructuredtext-Test-Directive +=============================== + +DTD element: system_warning. + +Directive block: directive data is stored, and all following indented +text is interpreted as a literal block. + +This directive is provided for test purposes only. (Nobody is +expected to type in a name *that* long!) It is converted into a +level-1 (info) system message showing the directive data, possibly +followed by a literal block containing the rest of the directive +block. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/ref/rst/introduction.txt b/docs/ref/rst/introduction.txt new file mode 100644 index 000000000..3d7cfc5f8 --- /dev/null +++ b/docs/ref/rst/introduction.txt @@ -0,0 +1,307 @@ +===================================== + An Introduction to reStructuredText +===================================== +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +reStructuredText_ is an easy-to-read, what-you-see-is-what-you-get +plaintext markup syntax and parser system. It is useful for in-line +program documentation (such as Python docstrings), for quickly +creating simple web pages, and for standalone documents. +reStructuredText_ is a proposed revision and reinterpretation of the +StructuredText_ and Setext_ lightweight markup systems. + +reStructuredText is designed for extensibility for specific +application domains. Its parser is a component of Docutils_. + +This document defines the goals_ of reStructuredText and provides a +history_ of the project. It is written using the reStructuredText +markup, and therefore serves as an example of its use. Please also +see an analysis of the `problems with StructuredText`_ and the +`reStructuredText markup specification`_ itself at project's web page, +http://docutils.sourceforge.net/rst.html. + +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _StructuredText: + http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage +.. _Setext: http://docutils.sourceforge.net/mirror/setext.html +.. _Docutils: http://docutils.sourceforge.net/ +.. _Problems with StructuredText: problems.html +.. _reStructuredText Markup Specification: reStructuredText.html + + +Goals +===== + +The primary goal of reStructuredText_ is to define a markup syntax for +use in Python docstrings and other documentation domains, that is +readable and simple, yet powerful enough for non-trivial use. The +intended purpose of the reStructuredText markup is twofold: + +- the establishment of a set of standard conventions allowing the + expression of structure within plaintext, and + +- the conversion of such documents into useful structured data + formats. + +The secondary goal of reStructuredText is to be accepted by the Python +community (by way of being blessed by PythonLabs and the BDFL [#]_) as +a standard for Python inline documentation (possibly one of several +standards, to account for taste). + +.. [#] Python's creator and "Benevolent Dictator For Life", + Guido van Rossum. + +To clarify the primary goal, here are specific design goals, in order, +beginning with the most important: + +1. Readable. The marked-up text must be easy to read without any + prior knowledge of the markup language. It should be as easily + read in raw form as in processed form. + +2. Unobtrusive. The markup that is used should be as simple and + unobtrusive as possible. The simplicity of markup constructs + should be roughly proporional to their frequency of use. The most + common constructs, with natural and obvious markup, should be the + simplest and most unobtrusive. Less common contstructs, for which + there is no natural or obvious markup, should be distinctive. + +3. Unambiguous. The rules for markup must not be open for + interpretation. For any given input, there should be one and only + one possible output (including error output). + +4. Unsurprising. Markup constructs should not cause unexpected output + upon processing. As a fallback, there must be a way to prevent + unwanted markup processing when a markup construct is used in a + non-markup context (for example, when documenting the markup syntax + itself). + +5. Intuitive. Markup should be as obvious and easily remembered as + possible, for the author as well as for the reader. Constructs + should take their cues from such naturally occurring sources as + plaintext email messages, newsgroup postings, and text + documentation such as README.txt files. + +6. Easy. It should be easy to mark up text using any ordinary text + editor. + +7. Scalable. The markup should be applicable regardless of the length + of the text. + +8. Powerful. The markup should provide enough constructs to produce a + reasonably rich structured document. + +9. Language-neutral. The markup should apply to multiple natural (as + well as artificial) languages, not only English. + +10. Extensible. The markup should provide a simple syntax and + interface for adding more complex general markup, and custom + markup. + +11. Output-format-neutral. The markup will be appropriate for + processing to multiple output formats, and will not be biased + toward any particular format. + +The design goals above were used as criteria for accepting or +rejecting syntax, or selecting between alternatives. + +It is emphatically *not* the goal of reStructuredText to define +docstring semantics, such as docstring contents or docstring length. +These issues are orthogonal to the markup syntax and beyond the scope +of this specification. + +Also, it is not the goal of reStructuredText to maintain compatibility +with StructuredText_ or Setext_. reStructuredText shamelessly steals +their great ideas and ignores the not-so-great. + +Author's note: + + Due to the nature of the problem we're trying to solve (or, + perhaps, due to the nature of the proposed solution), the above + goals unavoidably conflict. I have tried to extract and distill + the wisdom accumulated over the years in the Python Doc-SIG_ + mailing list and elsewhere, to come up with a coherent and + consistent set of syntax rules, and the above goals by which to + measure them. + + There will inevitably be people who disagree with my particular + choices. Some desire finer control over their markup, others + prefer less. Some are concerned with very short docstrings, + others with full-length documents. This specification is an + effort to provide a reasonably rich set of markup constructs in a + reasonably simple form, that should satisfy a reasonably large + group of reasonable people. + + David Goodger (goodger@users.sourceforge.net), 2001-04-20 + +.. _Doc-SIG: http://www.python.org/sigs/doc-sig/ + + +History +======= + +reStructuredText_, the specification, is based on StructuredText_ and +Setext_. StructuredText was developed by Jim Fulton of `Zope +Corporation`_ (formerly Digital Creations) and first released in 1996. +It is now released as a part of the open-source 'Z Object Publishing +Environment' (ZOPE_). Ian Feldman's and Tony Sanders' earlier Setext_ +specification was either an influence on StructuredText or, by their +similarities, at least evidence of the correctness of this approach. + +I discovered StructuredText_ in late 1999 while searching for a way to +document the Python modules in one of my projects. Version 1.1 of +StructuredText was included in Daniel Larsson's pythondoc_. Although +I was not able to get pythondoc to work for me, I found StructuredText +to be almost ideal for my needs. I joined the Python Doc-SIG_ +(Documentation Special Interest Group) mailing list and found an +ongoing discussion of the shortcomings of the StructuredText +'standard'. This discussion has been going on since the inception of +the mailing list in 1996, and possibly predates it. + +I decided to modify the original module with my own extensions and +some suggested by the Doc-SIG members. I soon realized that the +module was not written with extension in mind, so I embarked upon a +general reworking, including adapting it to the 're' regular +expression module (the original inspiration for the name of this +project). Soon after I completed the modifications, I discovered that +StructuredText.py was up to version 1.23 in the ZOPE distribution. +Implementing the new syntax extensions from version 1.23 proved to be +an exercise in frustration, as the complexity of the module had become +overwhelming. + +In 2000, development on StructuredTextNG_ ("Next Generation") began at +`Zope Corporation`_ (then Digital Creations). It seems to have many +improvements, but still suffers from many of the problems of classic +StructuredText. + +I decided that a complete rewrite was in order, and even started a +`reStructuredText SourceForge project`_ (now inactive). My +motivations (the 'itches' I aim to 'scratch') are as follows: + +- I need a standard format for inline documentation of the programs I + write. This inline documentation has to be convertible to other + useful formats, such as HTML. I believe many others have the same + need. + +- I believe in the Setext/StructuredText idea and want to help + formalize the standard. However, I feel the current specifications + and implementations have flaws that desperately need fixing. + +- reStructuredText could form part of the foundation for a + documentation extraction and processing system, greatly benefitting + Python. But it is only a part, not the whole. reStructuredText is + a markup language specification and a reference parser + implementation, but it does not aspire to be the entire system. I + don't want reStructuredText or a hypothetical Python documentation + processor to die stillborn because of overambition. + +- Most of all, I want to help ease the documentation chore, the bane + of many a programmer. + +Unfortunately I was sidetracked and stopped working on this project. +In November 2000 I made the time to enumerate the problems of +StructuredText and possible solutions, and complete the first draft of +a specification. This first draft was posted to the Doc-SIG in three +parts: + +- `A Plan for Structured Text`__ +- `Problems With StructuredText`__ +- `reStructuredText: Revised Structured Text Specification`__ + +__ http://mail.python.org/pipermail/doc-sig/2000-November/001239.html +__ http://mail.python.org/pipermail/doc-sig/2000-November/001240.html +__ http://mail.python.org/pipermail/doc-sig/2000-November/001241.html + +In March 2001 a flurry of activity on the Doc-SIG spurred me to +further revise and refine my specification, the result of which you +are now reading. An offshoot of the reStructuredText project has been +the realization that a single markup scheme, no matter how well +thought out, may not be enough. In order to tame the endless debates +on Doc-SIG, a flexible `Docstring Processing System framework`_ needed +to be constructed. This framework has become the more important of +the two projects; reStructuredText_ has found its place as one +possible choice for a single component of the larger framework. + +The project web site and the first project release were rolled out in +June 2001, including posting the second draft of the spec [#spec-2]_ +and the first draft of PEPs 256, 257, and 258 [#peps-1]_ to the +Doc-SIG. These documents and the project implementation proceeded to +evolve at a rapid pace. Implementation history details can be found +in the project file, HISTORY.txt_. + +In November 2001, the reStructuredText parser was nearing completion. +Development of the parser continued with the addition of small +convenience features, improvements to the syntax, the filling in of +gaps, and bug fixes. After a long holiday break, in early 2002 most +development moved over to the other Docutils components, the +"Readers", "Writers", and "Transforms". A "standalone" reader +(processes standalone text file documents) was completed in February, +and a basic HTML writer (producing HTML 4.01, using CSS-1) was +completed in early March. + +`PEP 287`_, "reStructuredText Standard Docstring Format", was created +to formally propose reStructuredText as a standard format for Python +docstrings, PEPs, and other files. It was first posted to +comp.lang.python_ and the Python-dev_ mailing list on 2002-04-02. + +Version 0.4 of the reStructuredText__ and `Docstring Processing +System`_ projects were released in April 2002. The two projects were +immediately merged, renamed to "Docutils_", and a 0.1 release soon +followed. + +.. __: `reStructuredText SourceForge project`_ + +.. [#spec-2] + - `An Introduction to reStructuredText`__ + - `Problems With StructuredText`__ + - `reStructuredText Markup Specification`__ + - `Python Extensions to the reStructuredText Markup + Specification`__ + + __ http://mail.python.org/pipermail/doc-sig/2001-June/001858.html + __ http://mail.python.org/pipermail/doc-sig/2001-June/001859.html + __ http://mail.python.org/pipermail/doc-sig/2001-June/001860.html + __ http://mail.python.org/pipermail/doc-sig/2001-June/001861.html + +.. [#peps-1] + - `PEP 256: Docstring Processing System Framework`__ + - `PEP 258: DPS Generic Implementation Details`__ + - `PEP 257: Docstring Conventions`__ + + Current working versions of the PEPs can be found in + http://docutils.sourceforge.net/spec/, and official versions can be + found in the `master PEP repository`_. + + __ http://mail.python.org/pipermail/doc-sig/2001-June/001855.html + __ http://mail.python.org/pipermail/doc-sig/2001-June/001856.html + __ http://mail.python.org/pipermail/doc-sig/2001-June/001857.html + + +.. _Zope Corporation: http://www.zope.com +.. _ZOPE: http://www.zope.org +.. _reStructuredText SourceForge project: + http://structuredtext.sourceforge.net/ +.. _pythondoc: http://starship.python.net/crew/danilo/pythondoc/ +.. _StructuredTextNG: + http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNG +.. _HISTORY.txt: + http://docutils.sourceforge.net/HISTORY.txt +.. _PEP 287: http://docutils.sourceforge.net/spec/pep-0287.txt +.. _Docstring Processing System framework: + http://docutils.sourceforge.net/spec/pep-0256.txt +.. _comp.lang.python: news:comp.lang.python +.. _Python-dev: http://mail.python.org/pipermail/python-dev/ +.. _Docstring Processing System: http://docstring.sourceforge.net/ +.. _Docutils: http://docutils.sourceforge.net/ +.. _master PEP repository: http://www.python.org/peps/ + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt new file mode 100644 index 000000000..149ef3fd4 --- /dev/null +++ b/docs/ref/rst/restructuredtext.txt @@ -0,0 +1,2344 @@ +======================================= + reStructuredText Markup Specification +======================================= +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ + +reStructuredText_ is plain text that uses simple and intuitive +constructs to indicate the structure of a document. These constructs +are equally easy to read in raw and processed forms. This document is +itself an example of reStructuredText (raw, if you are reading the +text file, or processed, if you are reading an HTML document, for +example). The reStructuredText parser is a component of Docutils_. + +Simple, implicit markup is used to indicate special constructs, such +as section headings, bullet lists, and emphasis. The markup used is +as minimal and unobtrusive as possible. Less often-used constructs +and extensions to the basic reStructuredText syntax may have more +elaborate or explicit markup. + +reStructuredText is applicable to documents of any length, from the +very small (such as inline program documentation fragments, e.g. +Python docstrings) to the quite large (this document). + +The first section gives a quick overview of the syntax of the +reStructuredText markup by example. A complete specification is given +in the `Syntax Details`_ section. + +`Literal blocks`_ (in which no markup processing is done) are used for +examples throughout this document, to illustrate the plain text +markup. + + +.. contents:: + + +----------------------- + Quick Syntax Overview +----------------------- + +A reStructuredText document is made up of body or block-level +elements, and may be structured into sections. Sections_ are +indicated through title style (underlines & optional overlines). +Sections contain body elements and/or subsections. Some body elements +contain further elements, such as lists containing list items, which +in turn may contain paragraphs and other body elemens. Others, such +as paragraphs, contain text and `inline markup`_ elements. + +Here are examples of `body elements`_: + +- Paragraphs_ (and `inline markup`_):: + + Paragraphs contain text and may contain inline markup: + *emphasis*, **strong emphasis**, `interpreted text`, ``inline + literals``, standalone hyperlinks (http://www.python.org), + external hyperlinks (Python_), internal cross-references + (example_), footnote references ([1]_), citation references + ([CIT2002]_), substitution references (|example|), and _`inline + hyperlink targets`. + + Paragraphs are separated by blank lines and are left-aligned. + +- Five types of lists: + + 1. `Bullet lists`_:: + + - This is a bullet list. + + - Bullets can be "-", "*", or "+". + + 2. `Enumerated lists`_:: + + 1. This is an enumerated list. + + 2. Enumerators may be arabic numbers, letters, or roman + numerals. + + 3. `Definition lists`_:: + + what + Definition lists associate a term with a definition. + + how + The term is a one-line phrase, and the definition is one + or more paragraphs or body elements, indented relative to + the term. + + 4. `Field lists`_:: + + :what: Field lists map field names to field bodies, like + database records. They are often part of an extension + syntax. + + :how: The field marker is a colon, the field name, optional + field arguments, and a colon. + + The field body may contain one or more body elements, + indented relative to the field marker. + + 5. `Option lists`_, for listing command-line options:: + + -a command-line option "a" + -b file options can have arguments + and long descriptions + --long options can be long also + --input=file long options can also have + arguments + /V DOS/VMS-style options too + + There must be at least two spaces between the option and the + description. + +- `Literal blocks`_:: + + Literal blocks are indented, and indicated with a double-colon + ("::") at the end of the preceding paragraph (right here -->):: + + if literal_block: + text = 'is left as-is' + spaces_and_linebreaks = 'are preserved' + markup_processing = None + +- `Block quotes`_:: + + Block quotes consist of indented body elements: + + This theory, that is mine, is mine. + + Anne Elk (Miss) + +- `Doctest blocks`_:: + + >>> print 'Python-specific usage examples; begun with ">>>"' + Python-specific usage examples; begun with ">>>" + >>> print '(cut and pasted from interactive Python sessions)' + (cut and pasted from interactive Python sessions) + +- Tables_:: + + +------------------------+------------+----------+ + | Header row, column 1 | Header 2 | Header 3 | + +========================+============+==========+ + | body row 1, column 1 | column 2 | column 3 | + +------------------------+------------+----------+ + | body row 2 | Cells may span | + +------------------------+-----------------------+ + +- `Explicit markup blocks`_ all begin with an explicit block marker, + two periods and a space: + + - Footnotes_:: + + .. [1] A footnote contains body elements, consistently + indented by at least 3 spaces. + + - Citations_:: + + .. [CIT2002] Just like a footnote, except the label is + textual. + + - `Hyperlink targets`_:: + + .. _Python: http://www.python.org + + .. _example: + + The "_example" target above points to this paragraph. + + - Directives_:: + + .. image:: mylogo.png + + - `Substitution definitions`_:: + + .. |symbol here| image:: symbol.png + + - Comments_:: + + .. Comments begin with two dots and a space. Anything may + follow, except for the syntax of footnotes/citations, + hyperlink targets, directives, or substitution definitions. + + +---------------- + Syntax Details +---------------- + +Descriptions below list "DTD elements" (XML "generic identifiers") +corresponding to syntax constructs. For details on the hierarchy of +elements, please see `Docutils Document Tree Structure`_ and the +`Generic Plaintext Document Interface DTD`_ XML document type +definition. + + +Whitespace +========== + +Spaces are recommended for indentation_, but tabs may also be used. +Tabs will be converted to spaces. Tab stops are at every 8th column. + +Other whitespace characters (form feeds [chr(12)] and vertical tabs +[chr(11)]) are converted to single spaces before processing. + + +Blank Lines +----------- + +Blank lines are used to separate paragraphs and other elements. +Multiple successive blank lines are equivalent to a single blank line, +except within literal blocks (where all whitespace is preserved). +Blank lines may be omitted when the markup makes element separation +unambiguous, in conjunction with indentation. The first line of a +document is treated as if it is preceded by a blank line, and the last +line of a document is treated as if it is followed by a blank line. + + +Indentation +----------- + +Indentation is used to indicate, and is only significant in +indicating: + +- multi-line contents of list items, +- multiple body elements within a list item (including nested lists), +- the definition part of a definition list item, +- block quotes, +- the extent of literal blocks, and +- the extent of explicit markup blocks. + +Any text whose indentation is less than that of the current level +(i.e., unindented text or "dedents") ends the current level of +indentation. + +Since all indentation is significant, the level of indentation must be +consistent. For example, indentation is the sole markup indicator for +`block quotes`_:: + + This is a top-level paragraph. + + This paragraph belongs to a first-level block quote. + + Paragraph 2 of the first-level block quote. + +Multiple levels of indentation within a block quote will result in +more complex structures:: + + This is a top-level paragraph. + + This paragraph belongs to a first-level block quote. + + This paragraph belongs to a second-level block quote. + + Another top-level paragraph. + + This paragraph belongs to a second-level block quote. + + This paragraph belongs to a first-level block quote. The + second-level block quote above is inside this first-level + block quote. + +When a paragraph or other construct consists of more than one line of +text, the lines must be left-aligned:: + + This is a paragraph. The lines of + this paragraph are aligned at the left. + + This paragraph has problems. The + lines are not left-aligned. In addition + to potential misinterpretation, warning + and/or error messages will be generated + by the parser. + +Several constructs begin with a marker, and the body of the construct +must be indented relative to the marker. For constructs using simple +markers (`bullet lists`_, `enumerated lists`_, footnotes_, citations_, +`hyperlink targets`_, directives_, and comments_), the level of +indentation of the body is determined by the position of the first +line of text, which begins on the same line as the marker. For +example, bullet list bodies must be indented by at least two columns +relative to the left edge of the bullet:: + + - This is the first line of a bullet list + item's paragraph. All lines must align + relative to the first line. [1]_ + + This indented paragraph is interpreted + as a block quote. + + Because it is not sufficiently indented, + this paragraph does not belong to the list + item. + + .. [1] Here's a footnote. The second line is aligned + with the beginning of the footnote label. The ".." + marker is what determines the indentation. + +For constructs using complex markers (`field lists`_ and `option +lists`_), where the marker may contain arbitrary text, the indentation +of the first line *after* the marker determines the left edge of the +body. For example, field lists may have very long markers (containing +the field names):: + + :Hello: This field has a short field name, so aligning the field + body with the first line is feasible. + + :Number-of-African-swallows-requried-to-carry-a-coconut: It would + be very difficult to align the field body with the left edge + of the first line. It may even be preferable not to begin the + body on the same line as the marker. + + +Escaping Mechanism +================== + +The character set universally available to plain text documents, 7-bit +ASCII, is limited. No matter what characters are used for markup, +they will already have multiple meanings in written text. Therefore +markup characters *will* sometimes appear in text **without being +intended as markup**. Any serious markup system requires an escaping +mechanism to override the default meaning of the characters used for +the markup. In reStructuredText we use the backslash, commonly used +as an escaping character in other domains. + +A backslash followed by any character escapes that character. The +escaped character represents the character itself, and is prevented +from playing a role in any markup interpretation. The backslash is +removed from the output. A literal backslash is represented by two +backslashes in a row (the first backslash "escapes" the second, +preventing it being interpreted in an "escaping" role). + +There are two contexts in which backslashes have no special meaning: +literal blocks and inline literals. In these contexts, a single +backslash represents a literal backslash, without having to double up. + +Please note that the reStructuredText specification and parser do not +address the issue of the representation or extraction of text input +(how and in what form the text actually *reaches* the parser). +Backslashes and other characters may serve a character-escaping +purpose in certain contexts and must be dealt with appropriately. For +example, Python uses backslashes in strings to escape certain +characters, but not others. The simplest solution when backslashes +appear in Python docstrings is to use raw docstrings:: + + r"""This is a raw docstring. Backslashes (\) are not touched.""" + + +Reference Names +=============== + +Simple reference names are single words consisting of alphanumerics +plus internal hypens, underscores, and periods; no whitespace or other +characters are allowed. Footnote labels (Footnotes_ & `Footnote +References`_), citation labels (Citations_ & `Citation References`_), +`interpreted text`_ roles, and some `hyperlink references`_ use the +simple reference name syntax. + +Reference names using punctuation or whose names are phrases (two or +more space-separated words) are called "phrase-references". +Phrase-references are expressed by enclosing the phrase in backquotes +and treating the backquoted text as a reference name:: + + Want to learn about `my favorite programming language`_? + + .. _my favorite programming language: http://www.python.org + +Simple reference names may also optionally use backquotes. + +Reference names are whitespace-neutral and case-insensitive. When +resolving reference names internally: + +- whitespace is normalized (one or more spaces, horizontal or vertical + tabs, newlines, carriage returns, or form feeds, are interpreted as + a single space), and + +- case is normalized (all alphabetic characters are converted to + lowercase). + +For example, the following `hyperlink references`_ are equivalent:: + + - `A HYPERLINK`_ + - `a hyperlink`_ + - `A + Hyperlink`_ + +Hyperlinks_, footnotes_, and citations_ all share the same namespace +for reference names. The labels of citations (simple reference names) +and manually-numbered footnotes (numbers) are entered into the same +database as other hyperlink names. This means that a footnote +(defined as "``.. [1]``") which can be referred to by a footnote +reference (``[1]_``), can also be referred to by a plain hyperlink +reference (1_). Of course, each type of reference (hyperlink, +footnote, citation) may be processed and rendered differently. Some +care should be taken to avoid reference name conflicts. + + +Document Structure +================== + +Document +-------- + +DTD element: document. + +The top-level element of a parsed reStructuredText document is the +"document" element. After initial parsing, the document element is a +simple container for a document fragment, consisting of `body +elements`_, transitions_, and sections_, but lacking a document title +or other bibliographic elements. The code that calls the parser may +choose to run one or more optional post-parse transforms_, +rearranging the document fragment into a complete document with a +title and possibly other metadata elements (author, date, etc.; see +`Bibliographic Fields`_). + +Specifically, there is no way to specify a document title and subtitle +explicitly in reStructuredText. Instead, a lone top-level section +title (see Sections_ below) can be treated as the document +title. Similarly, a lone second-level section title immediately after +the "document title" can become the document subtitle. See the +`DocTitle transform`_ for details. + + +Sections +-------- + +DTD elements: section, title. + +Sections are identified through their titles, which are marked up with +adornment: "underlines" below the title text, and, in some cases, +matching "overlines" above the title. An underline/overline is a +single repeated punctuation character that begins in column 1 and +forms a line extending at least as far as the right edge of the title +text. Specifically, an underline/overline character may be any +non-alphanumeric printable 7-bit ASCII character [#]_. An +underline/overline must be at least 4 characters long (to avoid +mistaking ellipses ["..."] for overlines). When an overline is used, +the length and character used must match the underline. There may be +any number of levels of section titles, although some output formats +may have limits (HTML has 6 levels). + +.. [#] The following are all valid section title adornment + characters:: + + ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + + Some characters are more suitable than others. The following are + recommended:: + + = - ` : ' " ~ ^ _ * + # < > + +Rather than imposing a fixed number and order of section title +adornment styles, the order enforced will be the order as encountered. +The first style encountered will be an outermost title (like HTML H1), +the second style will be a subtitle, the third will be a subsubtitle, +and so on. + +Below are examples of section title styles:: + + =============== + Section Title + =============== + + --------------- + Section Title + --------------- + + Section Title + ============= + + Section Title + ------------- + + Section Title + ````````````` + + Section Title + ''''''''''''' + + Section Title + ............. + + Section Title + ~~~~~~~~~~~~~ + + Section Title + ************* + + Section Title + +++++++++++++ + + Section Title + ^^^^^^^^^^^^^ + +When a title has both an underline and an overline, the title text may +be inset, as in the first two examples above. This is merely +aesthetic and not significant. Underline-only title text may *not* be +inset. + +A blank line after a title is optional. All text blocks up to the +next title of the same or higher level are included in a section (or +subsection, etc.). + +All section title styles need not be used, nor need any specific +section title style be used. However, a document must be consistent +in its use of section titles: once a hierarchy of title styles is +established, sections must use that hierarchy. + +Each section title automatically generates a hyperlink target pointing +to the section. The text of the hyperlink target (the "reference +name") is the same as that of the section title. See `Implicit +Hyperlink Targets`_ for a complete description. + +Sections may contain `body elements`_, transitions_, and nested +sections. + + +Transitions +----------- + +DTD element: transition. + + Instead of subheads, extra space or a type ornament between + paragraphs may be used to mark text divisions or to signal + changes in subject or emphasis. + + (The Chicago Manual of Style, 14th edition, section 1.80) + +Transitions are commonly seen in novels and short fiction, as a gap +spanning one or more lines, with or without a type ornament such as a +row of asterisks. Transitions separate other body elements. A +transition should not begin or end a section or document, nor should +two transitions be immediately adjacent. + +The syntax for a transition marker is a horizontal line of 4 or more +repeated punctuation characters. The syntax is the same as section +title underlines without title text. Transition markers require blank +lines before and after:: + + Para. + + ---------- + + Para. + +Unlike section title underlines, no hierarchy of transition markers is +enforced, nor do differences in transition markers accomplish +anything. It is recommended that a single consistent style be used. + +The processing system is free to render transitions in output in any +way it likes. For example, horizontal rules (``<HR>``) in HTML output +would be an obvious choice. + + +Body Elements +============= + +Paragraphs +---------- + +DTD element: paragraph. + +Paragraphs consist of blocks of left-aligned text with no markup +indicating any other body element. Blank lines separate paragraphs +from each other and from other body elements. Paragraphs may contain +`inline markup`_. + +Syntax diagram:: + + +------------------------------+ + | paragraph | + | | + +------------------------------+ + + +------------------------------+ + | paragraph | + | | + +------------------------------+ + + +Bullet Lists +------------ + +DTD elements: bullet_list, list_item. + +A text block which begins with a "-", "*", or "+", followed by +whitespace, is a bullet list item (a.k.a. "unordered" list item). +List item bodies must be left-aligned and indented relative to the +bullet; the text immediately after the bullet determines the +indentation. For example:: + + - This is the first bullet list item. The blank line above the + first list item is required; blank lines between list items + (such as below this paragraph) are optional. + + - This is the first paragraph in the second item in the list. + + This is the second paragraph in the second item in the list. + The blank line above this paragraph is required. The left edge + of this paragraph lines up with the paragraph above, both + indented relative to the bullet. + + - This is a sublist. The bullet lines up with the left edge of + the text blocks above. A sublist is a new list so requires a + blank line above and below. + + - This is the third item of the main list. + + This paragraph is not part of the list. + +Here are examples of **incorrectly** formatted bullet lists:: + + - This first line is fine. + A blank line is required between list items and paragraphs. + (Warning) + + - The following line appears to be a new sublist, but it is not: + - This is a paragraph contination, not a sublist (since there's + no blank line). This line is also incorrectly indented. + - Warnings may be issued by the implementation. + +Syntax diagram:: + + +------+-----------------------+ + | "- " | list item | + +------| (body elements)+ | + +-----------------------+ + + +Enumerated Lists +---------------- + +DTD elements: enumerated_list, list_item. + +Enumerated lists (a.k.a. "ordered" lists) are similar to bullet lists, +but use enumerators instead of bullets. An enumerator consists of an +enumeration sequence member and formatting, followed by whitespace. +The following enumeration sequences are recognized: + +- arabic numerals: 1, 2, 3, ... (no upper limit). +- uppercase alphabet characters: A, B, C, ..., Z. +- lower-case alphabet characters: a, b, c, ..., z. +- uppercase Roman numerals: I, II, III, IV, ..., MMMMCMXCIX (4999). +- lowercase Roman numerals: i, ii, iii, iv, ..., mmmmcmxcix (4999). + +The following formatting types are recognized: + +- suffixed with a period: "1.", "A.", "a.", "I.", "i.". +- surrounded by parentheses: "(1)", "(A)", "(a)", "(I)", "(i)". +- suffixed with a right-parenthesis: "1)", "A)", "a)", "I)", "i)". + +A system message will be generated for each of the following cases: + +- The enumerators do not all have the same format and sequence type. + +- The enumerators are not in sequence (i.e., "1.", "3." generates a + level-1 [info] system message and produces two separate lists). + +It is recommended that the enumerator of the first list item be +ordinal-1 ("1", "A", "a", "I", or "i"). Although other start-values +will be recognized, they may not be supported by the output format. + +Lists using Roman numerals must begin with "I"/"i" or a +multi-character value, such as "II" or "XV". Any other +single-character Roman numeral ("V", "X", etc.) will be interpreted as +a letter of the alphabet, not as a Roman numeral. Likewise, lists +using letters of the alphabet may not begin with "I"/"i", since these +are recognized as Roman numeral 1. + +Nested enumerated lists must be created with indentation. For +example:: + + 1. Item 1. + + a) Item 1a. + b) Item 1b. + +Example syntax diagram:: + + +-------+----------------------+ + | "1. " | list item | + +-------| (body elements)+ | + +----------------------+ + + +Definition Lists +---------------- + +DTD elements: definition_list, definition_list_item, term, classifier, +definition. + +Each definition list item contains a term, an optional classifier, and +a definition. A term is a simple one-line word or phrase. An +optional classifier may follow the term on the same line, after " : " +(space, colon, space). A definition is a block indented relative to +the term, and may contain multiple paragraphs and other body elements. +There may be no blank line between a term and a definition (this +distinguishes definition lists from `block quotes`_). Blank lines are +required before the first and after the last definition list item, but +are optional in-between. For example:: + + term 1 + Definition 1. + + term 2 + Definition 2, paragraph 1. + + Definition 2, paragraph 2. + + term 3 : classifier + Definition 3. + +A definition list may be used in various ways, including: + +- As a dictionary or glossary. The term is the word itself, a + classifier may be used to indicate the usage of the term (noun, + verb, etc.), and the definition follows. + +- To describe program variables. The term is the variable name, a + classifier may be used to indicate the type of the variable (string, + integer, etc.), and the definition describes the variable's use in + the program. This usage of definition lists supports the classifier + syntax of Grouch_, a system for describing and enforcing a Python + object schema. + +Syntax diagram:: + + +---------------------------+ + | term [ " : " classifier ] | + +--+------------------------+--+ + | definition | + | (body elements)+ | + +---------------------------+ + + +Field Lists +----------- + +DTD elements: field_list, field, field_name, field_argument, +field_body. + +Field lists are mappings from field names to field bodies, modeled on +RFC822_ headers. A field name is made up of one or more letters, +numbers, and punctuation, except colons (":") and whitespace. Field +names are case-insensitive. There may be additional data separated +from the field name, called field arguments. The field name and +optional field argument(s), along with a single colon prefix and +suffix, together form the field marker. The field marker is followed +by whitespace and the field body. The field body may contain multiple +body elements, indented relative to the field marker. The first line +after the field name marker determines the indentation of the field +body. For example:: + + :Date: 2001-08-16 + :Version: 1 + :Authors: - Me + - Myself + - I + :Indentation: Since the field marker may be quite long, the second + and subsequent lines of the field body do not have to line up + with the first line, but they must be indented relative to the + field name marker, and they must line up with each other. + :Parameter i: integer + +Field arguments are separated from the field name and each other by +whitespace, and may not contain colons (":"). The interpretation of +field arguments is up to the application. For example:: + + :name1 word number=1: + Both "word" and "number=1" are single words. + +The syntax for field arguments may be extended in the future. For +example, quoted phrases may be treated as a single argument, and +direct support for the "name=value" syntax may be added. + +Applications of reStructuredText may recognize field names and +transform fields or field bodies in certain contexts; they are often +used as part of an extension syntax. See `Bibliographic Fields`_ +below for one example, or the "image" directive in `reStructuredText +Directives`_ for another. + +Standard RFC822 headers cannot be used for this construct because they +are ambiguous. A word followed by a colon at the beginning of a line +is common in written text. However, in well-defined contexts such as +when a field list invariably occurs at the beginning of a document +(PEPs and email messages), standard RFC822 headers could be used. + +Syntax diagram (simplified):: + + +------------------------------+------------+ + | ":" name (" " argument)* ":" | field body | + +-------+----------------------+ | + | (body elements)+ | + +-----------------------------------+ + + +Bibliographic Fields +```````````````````` + +DTD elements: docinfo, author, authors, organization, contact, +version, status, date, copyright, topic. + +When a field list is the first non-comment element in a document +(after the document title, if there is one), it may have certain +specific fields transformed to document bibliographic data. This +bibliographic data corresponds to the front matter of a book, such as +the title page and copyright page. + +Certain field names (listed below) are recognized and transformed to +the corresponding DTD elements, most becoming child elements of the +"docinfo" element. No ordering is required of these fields, although +they may be rearranged to fit the document structure, as noted. +Unless otherwise indicated in the list below, each of the +bibliographic elements' field bodies may contain a single paragraph +only. Field bodies may be checked for `RCS keywords`_ and cleaned up. +Any unrecognized fields will remain in a generic field list in the +document body. + +The registered bibliographic field names and their corresponding DTD +elements are as follows: + +- Field name "Author": author element. +- "Authors": authors. May contain either: a single paragraph + consisting of a list of authors, separated by ";" or ","; or a + bullet list whose elements each contain a single paragraph per + author. +- "Organization": organization. +- "Contact": contact. +- "Version": version. +- "Status": status. +- "Date": date. +- "Copyright": copyright. +- "Abstract": topic. May contain arbitrary body elements. Only one + abstract is allowed. The abstract becomes a topic element with + title "Abstract" (or language equivalent) immediately following the + docinfo element. + +This field-name-to-element mapping can be extended, or replaced for +other languages. See the `DocInfo transform`_ implementation +documentation for details. + + +RCS Keywords +```````````` + +`Bibliographic fields`_ recognized by the parser are normally checked +for RCS [#]_ keywords and cleaned up [#]_. RCS keywords may be +entered into source files as "$keyword$", and once stored under RCS or +CVS [#]_, they are expanded to "$keyword: expansion text $". For +example, a "Status" field will be transformed to a "status" element:: + + :Status: $keyword: expansion text $ + +.. [#] Revision Control System. +.. [#] RCS keyword processing can be turned off (unimplemented). +.. [#] Concurrent Versions System. CVS uses the same keywords as RCS. + +Processed, the "status" element's text will become simply "expansion +text". The dollar sign delimiters and leading RCS keyword name are +removed. + +The RCS keyword processing only kicks in when all of these conditions +hold: + +1. The field list is in bibliographic context (first non-comment + contstruct in the document, after a document title if there is + one). + +2. The field name is a recognized bibliographic field name. + +3. The sole contents of the field is an expanded RCS keyword, of the + form "$Keyword: data $". + + +Option Lists +------------ + +DTD elements: option_list, option_list_item, option_group, option, +option_string, option_argument, description. + +Option lists are two-column lists of command-line options and +descriptions, documenting a program's options. For example:: + + -a Output all. + -b Output both (this description is + quite long). + -c arg Output just arg. + --long Output all day long. + + -p This option has two paragraphs in the description. + This is the first. + + This is the second. Blank lines may be omitted between + options (as above) or left in (as here and below). + + --very-long-option A VMS-syle option. Note the adjustment for + the required two spaces. + + --an-even-longer-option + The description can also start on the next line. + + -2, --two This option has two variants. + + -f FILE, --file=FILE These two options are synonyms; both have + arguments. + + /V A VMS/DOS-style option. + +There are several types of options recognized by reStructuredText: + +- Short POSIX options consist of one dash and an option letter. +- Long POSIX options consist of two dashes and an option word; some + systems use a single dash. +- Old GNU-style "plus" options consist of one plus and an option + letter ("plus" options are deprecated now, their use discouraged). +- DOS/VMS options consist of a slash and an option letter or word. + +Please note that both POSIX-style and DOS/VMS-style options may be +used by DOS or Windows software. These and other variations are +sometimes used mixed together. The names above have been chosen for +convenience only. + +The syntax for short and long POSIX options is based on the syntax +supported by Python's getopt.py_ module, which implements an option +parser similar to the `GNU libc getopt_long()`_ function but with some +restrictions. There are many variant option systems, and +reStructuredText option lists do not support all of them. + +Although long POSIX and DOS/VMS option words may be allowed to be +truncated by the operating system or the application when used on the +command line, reStructuredText option lists do not show or support +this with any special syntax. The complete option word should be +given, supported by notes about truncation if and when applicable. + +Options may be followed by an argument placeholder, whose role and +syntax should be explained in the description text. Either a space or +an equals sign may be used as a delimiter between options and option +argument placeholders. + +Multiple option "synonyms" may be listed, sharing a single +description. They must be separated by comma-space. + +There must be at least two spaces between the option(s) and the +description. The description may contain multiple body elements. The +first line after the option marker determines the indentation of the +description. As with other types of lists, blank lines are required +before the first option list item and after the last, but are optional +between option entries. + +Syntax diagram (simplified):: + + +----------------------------+-------------+ + | option [" " argument] " " | description | + +-------+--------------------+ | + | (body elements)+ | + +----------------------------------+ + + +Literal Blocks +-------------- + +DTD element: literal_block. + +A paragraph consisting of two colons ("::") signifies that all +following **indented** text blocks comprise a literal block. No +markup processing is done within a literal block. It is left as-is, +and is typically rendered in a monospaced typeface:: + + This is a typical paragraph. A literal block follows. + + :: + + for a in [5,4,3,2,1]: # this is program code, shown as-is + print a + print "it's..." + # a literal block continues until the indentation ends + + This text has returned to the indentation of the first paragraph, + is outside of the literal block, and is therefore treated as an + ordinary paragraph. + +The paragraph containing only "::" will be completely removed from the +output; no empty paragraph will remain. + +As a convenience, the "::" is recognized at the end of any paragraph. +If immediately preceded by whitespace, both colons will be removed +from the output (this is the "partially minimized" form). When text +immediately precedes the "::", *one* colon will be removed from the +output, leaving only one colon visible (i.e., "::" will be replaced by +":"; this is the "fully minimized" form). + +In other words, these are all equivalent (please pay attention to the +colons after "Paragraph"): + +1. Expanded form:: + + Paragraph: + + :: + + Literal block + +2. Partially minimized form:: + + Paragraph: :: + + Literal block + +3. Fully minimized form:: + + Paragraph:: + + Literal block + +The minimum leading whitespace will be removed from each line of the +literal block. Other than that, all whitespace (including line +breaks) is preserved. Blank lines are required before and after a +literal block, but these blank lines are not included as part of the +literal block. + +Syntax diagram:: + + +------------------------------+ + | paragraph | + | (ends with "::") | + +------------------------------+ + +---------------------------+ + | literal block | + +---------------------------+ + + +Block Quotes +------------ + +DTD element: block_quote. + +A text block that is indented relative to the preceding text, without +markup indicating it to be a literal block, is a block quote. All +markup processing (for body elements and inline markup) continues +within the block quote:: + + This is an ordinary paragraph, introducing a block quote. + + "It is my business to know things. That is my trade." + + -- Sherlock Holmes + +Blank lines are required before and after a block quote, but these +blank lines are not included as part of the block quote. + +Syntax diagram:: + + +------------------------------+ + | (current level of | + | indentation) | + +------------------------------+ + +---------------------------+ + | block quote | + | (body elements)+ | + +---------------------------+ + + +Doctest Blocks +-------------- + +DTD element: doctest_block. + +Doctest blocks are interactive Python sessions cut-and-pasted into +docstrings. They are meant to illustrate usage by example, and +provide an elegant and powerful testing environment via the `doctest +module`_ in the Python standard library. + +Doctest blocks are text blocks which begin with ``">>> "``, the Python +interactive interpreter main prompt, and end with a blank line. +Doctest blocks are treated as a special case of literal blocks, +without requiring the literal block syntax. If both are present, the +literal block syntax takes priority over Doctest block syntax:: + + This is an ordinary paragraph. + + >>> print 'this is a Doctest block' + this is a Doctest block + + The following is a literal block:: + + >>> This is not recognized as a doctest block by + reStructuredText. It *will* be recognized by the doctest + module, though! + +Indentation is not required for doctest blocks. + + +Tables +------ + +DTD elements: table, tgroup, colspec, thead, tbody, row, entry. + +Tables are described with a visual outline made up of the characters +"-", "=", "|", and "+". The hyphen ("-") is used for horizontal lines +(row separators). The equals sign ("=") may be used to separate +optional header rows from the table body. The vertical bar ("|") is +used for vertical lines (column separators). The plus sign ("+") is +used for intersections of horizontal and vertical lines. + +Each table cell is treated as a miniature document; the top and bottom +cell boundaries act as delimiting blank lines. Each cell contains +zero or more body elements. Cell contents may include left and/or +right margins, which are removed before processing. Example:: + + +------------------------+------------+----------+----------+ + | Header row, column 1 | Header 2 | Header 3 | Header 4 | + | (header rows optional) | | | | + +========================+============+==========+==========+ + | body row 1, column 1 | column 2 | column 3 | column 4 | + +------------------------+------------+----------+----------+ + | body row 2 | Cells may span columns. | + +------------------------+------------+---------------------+ + | body row 3 | Cells may | - Table cells | + +------------------------+ span rows. | - contain | + | body row 4 | | - body elements. | + +------------------------+------------+---------------------+ + +As with other body elements, blank lines are required before and after +tables. Tables' left edges should align with the left edge of +preceding text blocks; otherwise, the table is considered to be part +of a block quote. + +Some care must be taken with tables to avoid undesired interactions +with cell text in rare cases. For example, the following table +contains a cell in row 2 spanning from column 2 to column 4:: + + +--------------+----------+-----------+-----------+ + | row 1, col 1 | column 2 | column 3 | column 4 | + +--------------+----------+-----------+-----------+ + | row 2 | | + +--------------+----------+-----------+-----------+ + | row 3 | | | | + +--------------+----------+-----------+-----------+ + +If a vertical bar is used in the text of that cell, it could have +unintended effects if accidentally aligned with column boundaries:: + + +--------------+----------+-----------+-----------+ + | row 1, col 1 | column 2 | column 3 | column 4 | + +--------------+----------+-----------+-----------+ + | row 2 | Use the command ``ls | more``. | + +--------------+----------+-----------+-----------+ + | row 3 | | | | + +--------------+----------+-----------+-----------+ + +Several solutions are possible. All that is needed is to break the +continuity of the cell outline rectangle. One possibility is to shift +the text by adding an extra space before:: + + +--------------+----------+-----------+-----------+ + | row 1, col 1 | column 2 | column 3 | column 4 | + +--------------+----------+-----------+-----------+ + | row 2 | Use the command ``ls | more``. | + +--------------+----------+-----------+-----------+ + | row 3 | | | | + +--------------+----------+-----------+-----------+ + +Another possibility is to add an extra line to row 2:: + + +--------------+----------+-----------+-----------+ + | row 1, col 1 | column 2 | column 3 | column 4 | + +--------------+----------+-----------+-----------+ + | row 2 | Use the command ``ls | more``. | + | | | + +--------------+----------+-----------+-----------+ + | row 3 | | | | + +--------------+----------+-----------+-----------+ + + +Explicit Markup Blocks +---------------------- + +An explicit markup block is a text block: + +- whose first line begins with ".." followed by whitespace (the + "explicit markup start"), +- whose second and subsequent lines (if any) are indented relative to + the first, and +- which ends before an unindented line. + +Explicit markup blocks are analogous to bullet list items, with ".." +as the bullet. The text immediately after the explicit markup start +determines the indentation of the block body. Blank lines are +required between explicit markup blocks and other elements, but are +optional between explicit markup blocks where unambiguous. + +The explicit markup syntax is used for footnotes, citations, hyperlink +targets, directives, and comments. + + +Footnotes +````````` + +DTD elements: footnote, label. + +Each footnote consists of an explicit markup start (".. "), a left +square bracket, the footnote label, a right square bracket, and +whitespace, followed by indented body elements. A footnote label can +be: + +- a whole decimal number consisting of one or more digits, + +- a single "#" (denoting `auto-numbered footnotes`_), + +- a "#" followed by a simple reference name (an `autonumber label`_), + or + +- a single "*" (denoting `auto-symbol footnotes`_). + +If the first body element within a footnote is a simple paragraph, it +may begin on the same line as the footnote label. Other elements must +begin on a new line, consistently indented (by at least 3 spaces) and +left-aligned. + +Footnotes may occur anywhere in the document, not only at the end. +Where or how they appear in the processed output depends on the +processing system. + +Here is a manually numbered footnote:: + + .. [1] Body elements go here. + +Each footnote automatically generates a hyperlink target pointing to +itself. The text of the hyperlink target name is the same as that of +the footnote label. `Auto-numbered footnotes`_ generate a number as +their footnote label and reference name. See `Implicit Hyperlink +Targets`_ for a complete description of the mechanism. + +Syntax diagram:: + + +-------+-------------------------+ + | ".. " | "[" label "]" footnote | + +-------+ | + | (body elements)+ | + +-------------------------+ + + +Auto-Numbered Footnotes +....................... + +A number sign ("#") may be used as the first character of a footnote +label to request automatic numbering of the footnote or footnote +reference. + +The first footnote to request automatic numbering is assigned the +label "1", the second is assigned the label "2", and so on (assuming +there are no manually numbered footnotes present; see `Mixed Manual +and Auto-Numbered Footnotes`_ below). A footnote which has +automatically received a label "1" generates an implicit hyperlink +target with name "1", just as if the label was explicitly specified. + +.. _autonumber label: `autonumber labels`_ + +A footnote may specify a label explicitly while at the same time +requesting automatic numbering: ``[#label]``. These labels are called +_`autonumber labels`. Autonumber labels do two things: + +- On the footnote itself, they generate a hyperlink target whose name + is the autonumber label (doesn't include the "#"). + +- They allow an automatically numbered footnote to be referred to more + than once, as a footnote reference or hyperlink reference. For + example:: + + If [#note]_ is the first footnote reference, it will show up as + "[1]". We can refer to it again as [#note]_ and again see + "[1]". We can also refer to it as note_ (an ordinary internal + hyperlink reference). + + .. [#note] This is the footnote labeled "note". + +The numbering is determined by the order of the footnotes, not by the +order of the references. For footnote references without autonumber +labels (``[#]_``), the footnotes and footnote references must be in +the same relative order but need not alternate in lock-step. For +example:: + + [#]_ is a reference to footnote 1, and [#]_ is a reference to + footnote 2. + + .. [#] This is footnote 1. + .. [#] This is footnote 2. + .. [#] This is footnote 3. + + [#]_ is a reference to footnote 3. + +Special care must be taken if footnotes themselves contain +auto-numbered footnote references, or if multiple references are made +in close proximity. Footnotes and references are noted in the order +they are encountered in the document, which is not necessarily the +same as the order in which a person would read them. + + +Auto-Symbol Footnotes +..................... + +An asterisk ("*") may be used for footnote labels to request automatic +symbol generation for footnotes and footnote references. The asterisk +may be the only character in the label. For example:: + + Here is a symbolic footnote reference: [*]_. + + .. [*] This is the footnote. + +A transform will insert symbols as labels into corresponding footnotes +and footnote references. + +The standard Docutils system uses the following symbols for footnote +marks [#]_: + +- asterisk/star ("*") +- dagger (HTML character entity "†") +- double dagger ("‡") +- section mark ("§") +- pilcrow or paragraph mark ("¶") +- number sign ("#") +- spade suit ("♠") +- heart suit ("♥") +- diamond suit ("♦") +- club suit ("♣") + +.. [#] This list was inspired by the list of symbols for "Note + Reference Marks" in The Chicago Manual of Style, 14th edition, + section 12.51. "Parallels" ("\|\|") were given in CMoS instead of + the pilcrow. The last four symbols (the card suits) were added + arbitrarily. + +If more than ten symbols are required, the same sequence will be +reused, doubled and then tripled, and so on ("**" etc.). + + +Mixed Manual and Auto-Numbered Footnotes +........................................ + +Manual and automatic footnote numbering may both be used within a +single document, although the results may not be expected. Manual +numbering takes priority. Only unused footnote numbers are assigned +to auto-numbered footnotes. The following example should be +illustrative:: + + [2]_ will be "2" (manually numbered), + [#]_ will be "3" (anonymous auto-numbered), and + [#label]_ will be "1" (labeled auto-numbered). + + .. [2] This footnote is labeled manually, so its number is fixed. + + .. [#label] This autonumber-labeled footnote will be labeled "1". + It is the first auto-numbered footnote and no other footnote + with label "1" exists. The order of the footnotes is used to + determine numbering, not the order of the footnote references. + + .. [#] This footnote will be labeled "3". It is the second + auto-numbered footnote, but footnote label "2" is already used. + + +Citations +````````` + +Citations are identical to footnotes except that they use only +non-numeric labels such as ``[note]`` or ``[GVR2001]``. Citation +labels are simple `reference names`_ (case-insensitive single words +consisting of alphanumerics plus internal hyphens, underscores, and +periods; no whitespace). Citations may be rendered separately and +differently from footnotes. For example:: + + Here is a citation reference: [CIT2002]_. + + .. [CIT2002] This is the citation. It's just like a footnote, + except the label is textual. + + +.. _hyperlinks: + +Hyperlink Targets +````````````````` + +DTD element: target. + +These are also called _`explicit hyperlink targets`, to differentiate +them from `implicit hyperlink targets`_ defined below. + +Hyperlink targets identify a location within or outside of a document, +which may be linked to by `hyperlink references`_. + +Hyperlink targets may be named or anonymous. Named hyperlink targets +consist of an explicit markup start (".. "), an underscore, the +reference name (no trailing underscore), a colon, whitespace, and a +link block:: + + .. _hyperlink-name: link-block + +Reference names are whitespace-neutral and case-insensitive. See +`Reference Names`_ for details and examples. + +Anonymous hyperlink targets consist of an explicit markup start +(".. "), two underscores, a colon, whitespace, and a link block; there +is no reference name:: + + .. __: anonymous-hyperlink-target-link-block + +An alternate syntax for anonymous hyperlinks consists of two +underscores, a space, and a link block:: + + __ anonymous-hyperlink-target-link-block + +See `Anonymous Hyperlinks`_ below. + +There are three types of hyperlink targets: internal, external, and +indirect. + +1. _`Internal hyperlink targets` have empty link blocks. They provide + an end point allowing a hyperlink to connect one place to another + within a document. An internal hyperlink target points to the + element following the target. For example:: + + Clicking on this internal hyperlink will take us to the target_ + below. + + .. _target: + + The hyperlink target above points to this paragraph. + + Internal hyperlink targets may be "chained". Multiple adjacent + internal hyperlink targets all point to the same element:: + + .. _target1: + .. _target2: + + The targets "target1" and "target2" are synonyms; they both + point to this paragraph. + + If the element "pointed to" is an external hyperlink target (with a + URI in its link block; see #2 below) the URI from the external + hyperlink target is propagated to the internal hyperlink targets; + they will all "point to" the same URI. There is no need to + duplicate a URI. For example, all three of the following hyperlink + targets refer to the same URI:: + + .. _Python DOC-SIG mailing list archive: + .. _archive: + .. _Doc-SIG: http://mail.python.org/pipermail/doc-sig/ + + An inline form of internal hyperlink target is available; see + `Inline Hyperlink Targets`_. + +2. _`External hyperlink targets` have an absolute or relative URI in + their link blocks. For example, take the following input:: + + See the Python_ home page for info. + + .. _Python: http://www.python.org + + After processing into HTML, the hyperlink might be expressed as:: + + See the <A HREF="http://www.python.org">Python</A> home page + for info. + + An external hyperlink's URI may begin on the same line as the + explicit markup start and target name, or it may begin in an + indented text block immediately following, with no intervening + blank lines. If there are multiple lines in the link block, they + are stripped of leading and trailing whitespace and concatenated. + The following external hyperlink targets are equivalent:: + + .. _one-liner: http://docutils.sourceforge.net/rst.html + + .. _starts-on-this-line: http:// + docutils.sourceforge.net/rst.html + + .. _entirely-below: + http://docutils. + sourceforge.net/rst.html + + If an external hyperlink target's URI contains an underscore as its + last character, it must be escaped to avoid being mistaken for an + indirect hyperlink target:: + + This link_ refers to a file called ``underscore_``. + + .. _link: underscore\_ + +3. _`Indirect hyperlink targets` have a hyperlink reference in their + link blocks. In the following example, target "one" indirectly + references whatever target "two" references, and target "two" + references target "three", an internal hyperlink target. In + effect, all three reference the same thing:: + + .. _one: two_ + .. _two: three_ + .. _three: + + Just as with `hyperlink references`_ anywhere else in a document, + if a phrase-reference is used in the link block it must be enclosed + in backquotes. As with `external hyperlink targets`_, the link + block of an indirect hyperlink target may begin on the same line as + the explicit markup start or the next line. It may also be split + over multiple lines, in which case the lines are joined with + whitespace before being normalized. + + For example, the following indirect hyperlink targets are + equivalent:: + + .. _one-liner: `A HYPERLINK`_ + .. _entirely-below: + `a hyperlink`_ + .. _split: `A + Hyperlink`_ + +If a reference name contains a colon followed by whitespace, either: + +- the phrase must be enclosed in backquotes:: + + .. _`FAQTS: Computers: Programming: Languages: Python`: + http://python.faqts.com/ + +- or the colon(s) must be backslash-escaped in the link target:: + + .. _Chapter One\: "Tadpole Days": + + It's not easy being green... + +See `Implicit Hyperlink Targets`_ below for the resolution of +duplicate reference names. + +Syntax diagram:: + + +-------+----------------------+ + | ".. " | "_" name ":" link | + +-------+ block | + | | + +----------------------+ + + +Anonymous Hyperlinks +.................... + +The `World Wide Web Consortium`_ recommends in its `HTML Techniques +for Web Content Accessibility Guidelines`_ that authors should +"clearly identify the target of each link." Hyperlink references +should be as verbose as possible, but duplicating a verbose hyperlink +name in the target is onerous and error-prone. Anonymous hyperlinks +are designed to allow convenient verbose hyperlink references, and are +analogous to `Auto-Numbered Footnotes`_. They are particularly useful +in short or one-off documents. + +Anonymous `hyperlink references`_ are specified with two underscores +instead of one:: + + See `the web site of my favorite programming language`__. + +Anonymous targets begin with ".. __:"; no reference name is required +or allowed:: + + .. __: http://www.python.org + +As a convenient alternative, anonymous targets may begin with "__" +only:: + + __ http://www.python.org + +The reference name of the reference is not used to match the reference +to its target. Instead, the order of anonymous hyperlink references +and targets within the document is significant: the first anonymous +reference will link to the first anonymous target. The number of +anonymous hyperlink references in a document must match the number of +anonymous targets. + + +Directives +`````````` + +DTD elements: depend on the directive. + +Directives are indicated by an explicit markup start (".. ") followed +by the directive type, two colons, and whitespace. Directive types +are case-insensitive single words (alphanumerics plus internal +hyphens, underscores, and periods; no whitespace). Two colons are +used after the directive type for these reasons: + +- To avoid clashes with common comment text like:: + + .. Danger: modify at your own risk! + +- If an implementation of reStructuredText does not recognize a + directive (i.e., the directive-handler is not installed), the entire + directive block (including the directive itself) will be treated as + a literal block, and a level-3 (error) system message generated. + Thus "::" is a natural choice. + +Any text on the first line after the directive indicator is directive +data. The interpretation of directive data is up to the directive +code. Directive data may be interpreted as arguments to the +directive, or simply as the first line of the directive's text block. + +Actions taken in response to directives and the interpretation of text +in the directive block or subsequent text block(s) are +directive-dependent. Indented text following a directive may be +interpreted as a directive block. Simple directives may not require +any text beyond the directive data (if that), and will not process any +following indented text. + +Directives which have been implemented and registered in the reference +reStructuredText parser are described in the `reStructuredText +Directives`_ document. Below are examples of implemented directives. + +Directives are meant for the arbitrary processing of their contents +(the directive data & text block), which can be transformed into +something possibly unrelated to the original text. Directives are +used as an extension mechanism for reStructuredText, a way of adding +support for new constructs without adding new syntax. For example, +here's how an image may be placed:: + + .. image:: mylogo.png + +A figure (a graphic with a caption) may placed like this:: + + .. figure:: larch.png + The larch. + +An admonition (note, caution, etc.) contains other body elements:: + + .. note:: This is a paragraph + + - Here is a bullet list. + +It may also be possible for directives to be used as pragmas, to +modify the behavior of the parser, such as to experiment with +alternate syntax. There is no parser support for this functionality +at present; if a reasonable need for pragma directives is found, they +may be supported. + +Directives normally do not survive as "directive" elements past the +parsing stage; they are a *parser construct* only, and have no +intrinsic meaning outside of reStructuredText. Instead, the parser +will transform recognized directives into (possibly specialized) +document elements. Unknown directives will trigger level-3 (error) +system messages. + +Syntax diagram:: + + +-------+--------------------------+ + | ".. " | directive type "::" data | + +-------+ directive block | + | | + +--------------------------+ + + +Substitution Definitions +```````````````````````` + +DTD element: substitution_definition. + +Substitution definitions are indicated by an explicit markup start +(".. ") followed by a vertical bar, the substitution text, another +vertical bar, whitespace, and the definition block. Substitution text +may not begin or end with whitespace. A substitution definition block +contains an embedded inline-compatible directive (without the leading +".. "), such as an image. For example:: + + The |biohazard| symbol must be used on containers used to + dispose of medical waste. + + .. |biohazard| image:: biohazard.png + +It is an error for a substitution definition block to directly or +indirectly contain a circular substitution reference. + +`Substitution references`_ are replaced in-line by the processed +contents of the corresponding definition (linked by matching +substitution text). Substitution definitions allow the power and +flexibility of block-level directives_ to be shared by inline text. +They are a way to include arbitrarily complex inline structures within +text, while keeping the details out of the flow of text. They are the +equivalent of SGML/XML's named entities or programming language +macros. + +Without the substitution mechanism, every time someone wants an +application-specific new inline structure, they would have to petition +for a syntax change. In combination with existing directive syntax, +any inline structure can be coded without new syntax (except possibly +a new directive). + +Syntax diagram:: + + +-------+-----------------------------------------------------+ + | ".. " | "|" substitution text "| " directive type "::" data | + +-------+ directive block | + | | + +-----------------------------------------------------+ + +Following are some use cases for the substitution mechanism. Please +note that most of the embedded directives shown are examples only and +have not been implemented. + +Objects + Substitution references may be used to associate ambiguous text + with a unique object identifier. + + For example, many sites may wish to implement an inline "user" + directive:: + + |Michael| and |Jon| are our widget-wranglers. + + .. |Michael| user:: mjones + .. |Jon| user:: jhl + + Depending on the needs of the site, this may be used to index the + document for later searching, to hyperlink the inline text in + various ways (mailto, homepage, mouseover Javascript with profile + and contact information, etc.), or to customize presentation of + the text (include username in the inline text, include an icon + image with a link next to the text, make the text bold or a + different color, etc.). + + The same approach can be used in documents which frequently refer + to a particular type of objects with unique identifiers but + ambiguous common names. Movies, albums, books, photos, court + cases, and laws are possible. For example:: + + |The Transparent Society| offers a fascinating alternate view + on privacy issues. + + .. |The Transparent Society| book:: isbn=0738201448 + + Classes or functions, in contexts where the module or class names + are unclear and/or interpreted text cannot be used, are another + possibility:: + + 4XSLT has the convenience method |runString|, so you don't + have to mess with DOM objects if all you want is the + transformed output. + + .. |runString| function:: module=xml.xslt class=Processor + +Images + Images are a common use for substitution references:: + + West led the |H| 3, covered by dummy's |H| Q, East's |H| K, + and trumped in hand with the |S| 2. + + .. |H| image:: /images/heart.png + :height: 11 + :width: 11 + .. |S| image:: /images/spade.png + :height: 11 + :width: 11 + + * |Red light| means stop. + * |Green light| means go. + * |Yellow light| means go really fast. + + .. |Red light| image:: red_light.png + .. |Green light| image:: green_light.png + .. |Yellow light| image:: yellow_light.png + + |-><-| is the official symbol of POEE_. + + .. |-><-| image:: discord.png + .. _POEE: http://www.poee.org/ + + The "image" directive has been implemented. + +Styles [#]_ + Substitution references may be used to associate inline text with + an externally defined presentation style:: + + Even |the text in Texas| is big. + + .. |the text in Texas| style:: big + + The style name may be meaningful in the context of some particular + output format (CSS class name for HTML output, LaTeX style name + for LaTeX, etc), or may be ignored for other output formats (often + for plain text). + + .. @@@ This needs to be rethought & rewritten or removed: + + Interpreted text is unsuitable for this purpose because the set + of style names cannot be predefined - it is the domain of the + content author, not the author of the parser and output + formatter - and there is no way to associate a stylename + argument with an interpreted text style role. Also, it may be + desirable to use the same mechanism for styling blocks:: + + .. style:: motto + At Bob's Underwear Shop, we'll do anything to get in + your pants. + + .. style:: disclaimer + All rights reversed. Reprint what you like. + + .. [#] There may be sufficient need for a "style" mechanism to + warrant simpler syntax such as an extension to the interpreted + text role syntax. The substitution mechanism is cumbersome for + simple text styling. + +Templates + Inline markup may be used for later processing by a template + engine. For example, a Zope_ author might write:: + + Welcome back, |name|! + + .. |name| tal:: replace user/getUserName + + After processing, this ZPT output would result:: + + Welcome back, + <span tal:replace="user/getUserName">name</span>! + + Zope would then transform this to something like "Welcome back, + David!" during a session with an actual user. + +Replacement text + The substitution mechanism may be used for simple macro + substitution. This may be appropriate when the replacement text + is repeated many times throughout one or more documents, + especially if it may need to change later. A short example is + unavoidably contrived:: + + |RST| is a little annoying to type over and over, especially + when writing about |RST| itself, and spelling out the + bicapitalized word |RST| every time isn't really necessary for + |RST| source readability. + + .. |RST| replace:: reStructuredText_ + .. _reStructuredText: http://docutils.sourceforge.net/rst.html + + Substitution is also appropriate when the replacement text cannot + be represented using other inline constructs, or is obtrusively + long:: + + But still, that's nothing compared to a name like + |j2ee-cas|__. + + .. |j2ee-cas| replace:: + the Java `TM`:super: 2 Platform, Enterprise Edition Client + Access Services + __ http://developer.java.sun.com/developer/earlyAccess/ + j2eecas/ + + +Comments +```````` + +DTD element: comment. + +Arbitrary indented text may follow the explicit markup start and will +be processed as a comment element. No further processing is done on +the comment block text; a comment contains a single "text blob". +Depending on the output formatter, comments may be removed from the +processed output. The only restriction on comments is that they not +use the same syntax as directives, footnotes, citations, or hyperlink +targets. + +A explicit markup start followed by a blank line and nothing else +(apart from whitespace) is an "empty comment". It serves to terminate +a preceding construct, and does **not** consume any indented text +following. To have a block quote follow a list or any indented +construct, insert an unindented empty comment in-between. + +Syntax diagram:: + + +-------+----------------------+ + | ".. " | comment | + +-------+ block | + | | + +----------------------+ + + +Implicit Hyperlink Targets +========================== + +Implicit hyperlink targets are generated by section titles, footnotes, +and citations, and may also be generated by extension constructs. +Implicit hyperlink targets otherwise behave identically to explicit +`hyperlink targets`_. + +Problems of ambiguity due to conflicting duplicate implicit and +explicit reference names are avoided by following this procedure: + +1. `Explicit hyperlink targets`_ override any implicit targets having + the same reference name. The implicit hyperlink targets are + removed, and level-1 (info) system messages are inserted. + +2. Duplicate implicit hyperlink targets are removed, and level-1 + (info) system messages inserted. For example, if two or more + sections have the same title (such as "Introduction" subsections of + a rigidly-structured document), there will be duplicate implicit + hyperlink targets. + +3. Duplicate explicit hyperlink targets are removed, and level-2 + (warning) system messages are inserted. Exception: duplicate + `external hyperlink targets`_ (identical hyperlink names and + referenced URIs) do not conflict, and are not removed. + +System messages are inserted where target links have been removed. +See "Error Handling" in `PEP 258`_. + +The parser must return a set of *unique* hyperlink targets. The +calling software (such as the Docutils_) can warn of unresolvable +links, giving reasons for the messages. + + +Inline Markup +============= + +In reStructuredText, inline markup applies to words or phrases within +a text block. The same whitespace and punctuation that serves to +delimit words in written text is used to delimit the inline markup +syntax constructs. The text within inline markup may not begin or end +with whitespace. Arbitrary character-level markup is not supported; +it is not possible to mark up individual characters within a word. +Inline markup cannot be nested. + +There are nine inline markup constructs. Five of the constructs use +identical start-strings and end-strings to indicate the markup: + +- emphasis_: "*" +- `strong emphasis`_: "**" +- `interpreted text`_: "`" +- `inline literals`_: "``" +- `substitution references`_: "|" + +Three constructs use different start-strings and end-strings: + +- `inline hyperlink targets`_: "_`" and "`" +- `footnote references`_: "[" and "]_" +- `hyperlink references`_: "`" and "\`_" (phrases), or just a + trailing "_" (single words) + +`Standalone hyperlinks`_ are recognized implicitly, and use no extra +markup. + +The inline markup start-string and end-string recognition rules are as +follows. If any of the conditions are not met, the start-string or +end-string will not be recognized or processed. + +1. Inline markup start-strings must start a text block or be + immediately preceded by whitespace, single or double quotes, "(", + "[", "{", or "<". + +2. Inline markup start-strings must be immediately followed by + non-whitespace. + +3. Inline markup end-strings must be immediately preceded by + non-whitespace. + +4. Inline markup end-strings must end a text block or be immediately + followed by whitespace or one of:: + + ' " . , : ; ! ? - ) ] } > + +5. If an inline markup start-string is immediately preceded by a + single or double quote, "(", "[", "{", or "<", it must not be + immediately followed by the corresponding single or double quote, + ")", "]", "}", or ">". + +6. An inline markup end-string must be separated by at least one + character from the start-string. + +7. An unescaped backslash preceding a start-string or end-string will + disable markup recognition, except for the end-string of `inline + literals`_. See `Escaping Mechanism`_ above for details. + +For example, none of the following are recognized as containing inline +markup start-strings: " * ", '"*"', "'*'", "(*)", "(* ", "[*]", "{*}", +"\*", " ` ", etc. + +The inline markup recognition rules were devised intentionally to +allow 90% of non-markup uses of "*", "`", "_", and "|" *without* +resorting to backslashes. For 9 of the remaining 10%, use inline +literals or literal blocks:: + + "``\*``" -> "\*" (possibly in another font or quoted) + +Only those who understand the escaping and inline markup rules should +attempt the remaining 1%. ;-) + +Inline markup delimiter characters are used for multiple constructs, +so to avoid ambiguity there must be a specific recognition order for +each character. The inline markup recognition order is as follows: + +- Asterisks: `Strong emphasis`_ ("**") is recognized before emphasis_ + ("*"). + +- Backquotes: `Inline literals`_ ("``"), `inline hyperlink targets`_ + (leading "_`", trailing "`"), are mutually independent, and are + recognized before phrase `hyperlink references`_ (leading "`", + trailing "\`_") and `interpreted text`_ ("`"). + +- Trailing underscores: Footnote references ("[" + label + "]_") and + simple `hyperlink references`_ (name + trailing "_") are mutually + independent. + +- Vertical bars: `Substitution references`_ ("|") are independently + recognized. + +- `Standalone hyperlinks`_ are the last to be recognized. + + +Emphasis +-------- + +DTD element: emphasis. + +Start-string = end-string = "*". + +Text enclosed by single asterisk characters is emphasized:: + + This is *emphasized text*. + +Emphasized text is typically displayed in italics. + + +Strong Emphasis +--------------- + +DTD element: strong. + +Start-string = end-string = "**". + +Text enclosed by double-asterisks is emphasized strongly:: + + This is **strong text**. + +Strongly emphasized text is typically displayed in boldface. + + +Interpreted Text +---------------- + +DTD element: interpreted. + +Start-string = end-string = "`". + +Text enclosed by single backquote characters is interpreted:: + + This is `interpreted text`. + +Interpreted text is text that is meant to be related, indexed, linked, +summarized, or otherwise processed, but the text itself is left +alone. The text is "tagged" directly, in-place. The semantics of +interpreted text are domain-dependent. It can be used as implicit or +explicit descriptive markup (such as for program identifiers, as in +the `Python Source Reader`_), for cross-reference interpretation (such +as index entries), or for other applications where context can be +inferred. + +The role of the interpreted text determines how the text is +interpreted. It is normally inferred implicitly. The role of the +interpreted text may also be indicated explicitly, using a role +marker, either as a prefix or as a suffix to the interpreted text, +depending on which reads better:: + + :role:`interpreted text` + + `interpreted text`:role: + +Roles are simply extensions of the available inline constructs; to +emphasis_, `strong emphasis`_, `inline literals`_, and `hyperlink +references`_, we can add "index entry", "acronym", "class", "red", +"blinking" or anything else we want. + +A role marker consists of a colon, the role name, and another colon. +A role name is a single word consisting of alphanumerics plus internal +hypens, underscores, and periods; no whitespace or other characters +are allowed. + + +Inline Literals +--------------- + +DTD element: literal. + +Start-string = end-string = "``". + +Text enclosed by double-backquotes is treated as inline literals:: + + This text is an example of ``inline literals``. + +Inline literals may contain any characters except two adjacent +backquotes in an end-string context (according to the recognition +rules above). No markup interpretation (including backslash-escape +interpretation) is done within inline literals. + +Line breaks are *not* preserved in inline literals. Although a +reStructuredText parser will preserve runs of spaces in its output, +the final representation of the processed document is dependent on the +output formatter, thus the preservation of whitespace cannot be +guaranteed. If the preservation of line breaks and/or other +whitespace is important, `literal blocks`_ should be used. + +Inline literals are useful for short code snippets. For example:: + + The regular expression ``[+-]?(\d+(\.\d*)?|\.\d+)`` matches + floating-point numbers (without exponents). + + +Hyperlink References +-------------------- + +DTD element: reference. + +- Named hyperlink references: + + - Start-string = "" (empty string), end-string = "_". + - Start-string = "`", end-string = "\`_". (Phrase references.) + +- Anonymous hyperlink references: + + - Start-string = "" (empty string), end-string = "__". + - Start-string = "`", end-string = "\`__". (Phrase references.) + +Hyperlink references are indicated by a trailing underscore, "_", +except for `standalone hyperlinks`_ which are recognized +independently. The underscore can be thought of as a right-pointing +arrow. The trailing underscores point away from hyperlink references, +and the leading underscores point toward `hyperlink targets`_. + +Hyperlinks consist of two parts. In the text body, there is a source +link, a reference name with a trailing underscore (or two underscores +for `anonymous hyperlinks`_):: + + See the Python_ home page for info. + +A target link with a matching reference name must exist somewhere else +in the document. See `Hyperlink Targets`_ for a full description). + +`Anonymous hyperlinks`_ (which see) do not use reference names to +match references to targets, but otherwise behave similarly to named +hyperlinks. + + +Inline Hyperlink Targets +------------------------ + +DTD element: target. + +Start-string = "_`", end-string = "`". + +Inline hyperlink targets are the equivalent of explicit `internal +hyperlink targets`_, but may appear within running text. The syntax +begins with an underscore and a backquote, is followed by a hyperlink +name or phrase, and ends with a backquote. Inline hyperlink targets +may not be anonymous. + +For example, the following paragraph contains a hyperlink target named +"Norwegian Blue":: + + Oh yes, the _`Norwegian Blue`. What's, um, what's wrong with it? + +See `Implicit Hyperlink Targets`_ for the resolution of duplicate +reference names. + + +Footnote References +------------------- + +DTD element: footnote_reference. + +Start-string = "[", end-string = "]_". + +Each footnote reference consists of a square-bracketed label followed +by a trailing underscore. Footnote labels are one of: + +- one or more digits (i.e., a number), + +- a single "#" (denoting `auto-numbered footnotes`_), + +- a "#" followed by a simple reference name (an `autonumber label`_), + or + +- a single "*" (denoting `auto-symbol footnotes`_). + +For example:: + + Please RTFM [1]_. + + .. [1] Read The Fine Manual + + +Citation References +------------------- + +DTD element: citation_reference. + +Start-string = "[", end-string = "]_". + +Each citation reference consists of a square-bracketed label followed +by a trailing underscore. Citation labels are simple `reference +names`_ (case-insensitive single words, consisting of alphanumerics +plus internal hyphens, underscores, and periods; no whitespace). + +For example:: + + Here is a citation reference: [CIT2002]_. + +See Citations_ for the citation itself. + + +Substitution References +----------------------- + +DTD element: substitution_reference, reference. + +Start-string = "|", end-string = "|" (optionally followed by "_" or +"__"). + +Vertical bars are used to bracket the substitution reference text. A +substitution reference may also be a hyperlink reference by appending +a "_" (named) or "__" (anonymous) suffix; the substitution text is +used for the reference text in the named case. + +The processing system replaces substitution references with the +processed contents of the corresponding `substitution definitions`_. +Substitution definitions produce inline-compatible elements. + +Examples:: + + This is a simple |substitution reference|. It will be replaced by + the processing system. + + This is a combination |substitution and hyperlink reference|_. In + addition to being replaced, the replacement text or element will + refer to the "substitution and hyperlink reference" target. + + +Standalone Hyperlinks +--------------------- + +DTD element: link. + +Start-string = end-string = "" (empty string). + +A URI (absolute URI [#URI]_ or standalone email address) within a text +block is treated as a general external hyperlink with the URI itself +as the link's text. For example:: + + See http://www.python.org for info. + +would be marked up in HTML as:: + + See <A HREF="http://www.python.org">http://www.python.org</A> for + info. + +Two forms of URI are recognized: + +1. Absolute URIs. These consist of a scheme, a colon (":"), and a + scheme-specific part whose interpretation depends on the scheme. + + The scheme is the name of the protocol, such as "http", "ftp", + "mailto", or "telnet". The scheme consists of an initial letter, + followed by letters, numbers, and/or "+", "-", ".". Recognition is + limited to known schemes, per the W3C's `Index of WWW Addressing + Schemes`_. + + The scheme-specific part of the resource identifier may be either + hierarchical or opaque: + + - Hierarchical identifiers begin with one or two slashes and may + use slashes to separate hierarchical components of the path. + Examples are web pages and FTP sites:: + + http://www.python.org + + ftp://ftp.python.org/pub/python + + - Opaque identifiers do not begin with slashes. Examples are + email addresses and newsgroups:: + + mailto:someone@somewhere.com + + news:comp.lang.python + + With queries, fragments, and %-escape sequences, URIs can become + quite complicated. A reStructuredText parser must be able to + recognize any absolute URI, as defined in RFC2396_ and RFC2732_. + +2. Standalone email addresses, which are treated as if they were + ablsolute URIs with a "mailto:" scheme. Example:: + + someone@somewhere.com + +Punctuation at the end of a URI is not considered part of the URI. + +.. [#URI] Uniform Resource Identifier. URIs are a general form of + URLs (Uniform Resource Locators). For the syntax of URIs see + RFC2396_ and RFC2732_. + + +---------------- + Error Handling +---------------- + +DTD element: system_message, problematic. + +Markup errors are handled according to the specification in `PEP +258`_. + + +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _Docutils: http://docutils.sourceforge.net/ +.. _Docutils Document Tree Structure: + http://docutils.sourceforge.net/spec/doctree.txt +.. _Generic Plaintext Document Interface DTD: + http://docutils.sourceforge.net/spec/gpdi.dtd +.. _transforms: + http://docutils.sourceforge.net/docutils/transforms/ +.. _Grouch: http://www.mems-exchange.org/software/grouch/ +.. _RFC822: http://www.rfc-editor.org/rfc/rfc822.txt +.. _DocTitle transform: +.. _DocInfo transform: + http://docutils.sourceforge.net/docutils/transforms/frontmatter.py +.. _doctest module: + http://www.python.org/doc/current/lib/module-doctest.html +.. _getopt.py: + http://www.python.org/doc/current/lib/module-getopt.html +.. _GNU libc getopt_long(): + http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_516.html +.. _Index of WWW Addressing Schemes: + http://www.w3.org/Addressing/schemes.html +.. _World Wide Web Consortium: http://www.w3.org/ +.. _HTML Techniques for Web Content Accessibility Guidelines: + http://www.w3.org/TR/WCAG10-HTML-TECHS/#link-text +.. _reStructuredText Directives: directives.html +.. _Python Source Reader: + http://docutils.sourceforge.net/spec/pysource.txt +.. _RFC2396: http://www.rfc-editor.org/rfc/rfc2396.txt +.. _RFC2732: http://www.rfc-editor.org/rfc/rfc2732.txt +.. _Zope: http://www.zope.com/ +.. _PEP 258: http://docutils.sourceforge.net/spec/pep-0258.txt + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/ref/soextblx.dtd b/docs/ref/soextblx.dtd new file mode 100644 index 000000000..56ba311ba --- /dev/null +++ b/docs/ref/soextblx.dtd @@ -0,0 +1,312 @@ +<!-- +=========================================================================== + OASIS XML Exchange Table Model Declaration Module +=========================================================================== +:Date: 1999-03-15 +--> + +<!-- This set of declarations defines the XML version of the Exchange + Table Model as of the date shown in the Formal Public Identifier + (FPI) for this entity. + + This set of declarations may be referred to using a public external + entity declaration and reference as shown in the following three + lines: + + <!ENTITY % calstblx + PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN"> + %calstblx; + + If various parameter entities used within this set of declarations + are to be given non-default values, the appropriate declarations + should be given before calling in this package (i.e., before the + "%calstblx;" reference). +--> + +<!-- The motivation for this XML version of the Exchange Table Model + is simply to create an XML version of the SGML Exchange Table + Model. By design, no effort has been made to "improve" the model. + + This XML version incorporates the logical bare minimum changes + necessary to make the Exchange Table Model a valid XML DTD. +--> + +<!-- The XML version of the Exchange Table Model differs from + the SGML version in the following ways: + + The following parameter entities have been removed: + + - tbl.table.excep, tbl.hdft.excep, tbl.row.excep, tbl.entry.excep + There are no exceptions in XML. The following normative statement + is made in lieu of exceptions: the exchange table model explicitly + forbids a table from occurring within another table. If the + content model of an entry includes a table element, then this + cannot be enforced by the DTD, but it is a deviation from the + exchange table model to include a table within a table. + + - tbl.hdft.name, tbl.hdft.mdl, tbl.hdft.excep, tbl.hdft.att + The motivation for these elements was to change the table + header/footer elements. Since XML does not allow element declarations + to contain name groups, and the exchange table model does not + allow a table to contain footers, the continued presence of these + attributes seems unnecessary. + + The following parameter entity has been added: + + - tbl.thead.att + This entity parameterizes the attributes on thead. It replaces + the tbl.hdft.att parameter entity. + + Other miscellaneous changes: + + - Tag ommission indicators have been removed + - Comments have been removed from declarations + - NUMBER attributes have been changed to NMTOKEN + - NUTOKEN attributes have been to changed to NMTOKEN + - Removed the grouping characters around the content model + parameter entry for the 'entry' element. This is necessary + so that an entry can contain #PCDATA and be defined as an + optional, repeatable OR group beginning with #PCDATA. +--> + +<!-- This entity includes a set of element and attribute declarations + that partially defines the Exchange table model. However, the model + is not well-defined without the accompanying natural language + description of the semantics (meanings) of these various elements, + attributes, and attribute values. The semantic writeup, also available + from SGML Open, should be used in conjunction with this entity. +--> + +<!-- In order to use the Exchange table model, various parameter entity + declarations are required. A brief description is as follows: + + ENTITY NAME WHERE USED WHAT IT IS + + %yesorno In ATTLIST of: An attribute declared value + almost all elements for a "boolean" attribute + + %paracon In content model of: The "text" (logical content) + <entry> of the model group for <entry> + + %titles In content model of: The "title" part of the model + table element group for the table element + + %tbl.table.name In declaration of: The name of the "table" + table element element + + %tbl.table-titles.mdl In content model of: The model group for the title + table elements part of the content model for + table element + + %tbl.table.mdl In content model of: The model group for the content + table elements model for table element, + often (and by default) defined + in terms of %tbl.table-titles.mdl + and tgroup + + %tbl.table.att In ATTLIST of: Additional attributes on the + table element table element + + %bodyatt In ATTLIST of: Additional attributes on the + table element table element (for backward + compatibility with the SGML + model) + + %tbl.tgroup.mdl In content model of: The model group for the content + <tgroup> model for <tgroup> + + %tbl.tgroup.att In ATTLIST of: Additional attributes on the +4 <tgroup> <tgroup> element + + %tbl.thead.att In ATTLIST of: Additional attributes on the + <thead> <thead> element + + %tbl.tbody.att In ATTLIST of: Additional attributes on the + <tbody> <tbody> element + + %tbl.colspec.att In ATTLIST of: Additional attributes on the + <colspec> <colspec> element + + %tbl.row.mdl In content model of: The model group for the content + <row> model for <row> + + %tbl.row.att In ATTLIST of: Additional attributes on the + <row> <row> element + + %tbl.entry.mdl In content model of: The model group for the content + <entry> model for <entry> + + %tbl.entry.att In ATTLIST of: Additional attributes on the + <entry> <entry> element + + This set of declarations will use the default definitions shown below + for any of these parameter entities that are not declared before this + set of declarations is referenced. +--> + +<!-- These definitions are not directly related to the table model, but are + used in the default CALS table model and may be defined elsewhere (and + prior to the inclusion of this table module) in the referencing DTD. --> + +<!ENTITY % yesorno 'NMTOKEN'> <!-- no if zero(s), yes if any other value --> +<!ENTITY % titles 'title?'> +<!ENTITY % paracon '#PCDATA'> <!-- default for use in entry content --> + +<!-- +The parameter entities as defined below change and simplify the CALS table +model as published (as part of the Example DTD) in MIL-HDBK-28001. The +resulting simplified DTD has support from the SGML Open vendors and is +therefore more interoperable among different systems. + +These following declarations provide the Exchange default definitions +for these entities. However, these entities can be redefined (by giving +the appropriate parameter entity declaration(s) prior to the reference +to this Table Model declaration set entity) to fit the needs of the +current application. + +Note, however, that changes may have significant effect on the ability to +interchange table information. These changes may manifest themselves +in useability, presentation, and possible structure information degradation. +--> + +<!ENTITY % tbl.table.name "table"> +<!ENTITY % tbl.table-titles.mdl "%titles;,"> +<!ENTITY % tbl.table-main.mdl "tgroup+"> +<!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;"> +<!ENTITY % tbl.table.att " + pgwide %yesorno; #IMPLIED "> +<!ENTITY % bodyatt ""> +<!ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody"> +<!ENTITY % tbl.tgroup.att ""> +<!ENTITY % tbl.thead.att ""> +<!ENTITY % tbl.tbody.att ""> +<!ENTITY % tbl.colspec.att ""> +<!ENTITY % tbl.row.mdl "entry+"> +<!ENTITY % tbl.row.att ""> +<!ENTITY % tbl.entry.mdl "(%paracon;)*"> +<!ENTITY % tbl.entry.att ""> + +<!-- ===== Element and attribute declarations follow. ===== --> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.table.name "table" + ENTITY % tbl.table-titles.mdl "%titles;," + ENTITY % tbl.table.mdl "%tbl.table-titles; tgroup+" + ENTITY % tbl.table.att " + pgwide %yesorno; #IMPLIED " +--> + +<!ELEMENT %tbl.table.name; (%tbl.table.mdl;)> + +<!ATTLIST %tbl.table.name; + frame (top|bottom|topbot|all|sides|none) #IMPLIED + colsep %yesorno; #IMPLIED + rowsep %yesorno; #IMPLIED + %tbl.table.att; + %bodyatt; +> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody" + ENTITY % tbl.tgroup.att "" +--> + +<!ELEMENT tgroup (%tbl.tgroup.mdl;) > + +<!ATTLIST tgroup + cols NMTOKEN #REQUIRED + colsep %yesorno; #IMPLIED + rowsep %yesorno; #IMPLIED + align (left|right|center|justify|char) #IMPLIED + %tbl.tgroup.att; +> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.colspec.att "" +--> + +<!ELEMENT colspec EMPTY > + +<!ATTLIST colspec + colnum NMTOKEN #IMPLIED + colname NMTOKEN #IMPLIED + colwidth CDATA #IMPLIED + colsep %yesorno; #IMPLIED + rowsep %yesorno; #IMPLIED + align (left|right|center|justify|char) #IMPLIED + char CDATA #IMPLIED + charoff NMTOKEN #IMPLIED + %tbl.colspec.att; +> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.thead.att "" +--> + +<!ELEMENT thead (row+)> + +<!ATTLIST thead + valign (top|middle|bottom) #IMPLIED + %tbl.thead.att; +> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.tbody.att "" +--> + +<!ELEMENT tbody (row+)> + +<!ATTLIST tbody + valign (top|middle|bottom) #IMPLIED + %tbl.tbody.att; +> + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % tbl.row.mdl "entry+" + ENTITY % tbl.row.att "" +--> + +<!ELEMENT row (%tbl.row.mdl;)> + +<!ATTLIST row + rowsep %yesorno; #IMPLIED + valign (top|middle|bottom) #IMPLIED + %tbl.row.att; +> + + +<!-- + Default declarations previously defined in this entity and + referenced below include: + ENTITY % paracon "#PCDATA" + ENTITY % tbl.entry.mdl "(%paracon;)*" + ENTITY % tbl.entry.att "" +--> + +<!ELEMENT entry %tbl.entry.mdl;> + +<!ATTLIST entry + colname NMTOKEN #IMPLIED + namest NMTOKEN #IMPLIED + nameend NMTOKEN #IMPLIED + morerows NMTOKEN #IMPLIED + colsep %yesorno; #IMPLIED + rowsep %yesorno; #IMPLIED + align (left|right|center|justify|char) #IMPLIED + char CDATA #IMPLIED + charoff NMTOKEN #IMPLIED + valign (top|middle|bottom) #IMPLIED + %tbl.entry.att; +> diff --git a/docs/user/rst/images/ball1.gif b/docs/user/rst/images/ball1.gif new file mode 100644 index 000000000..3e14441d9 Binary files /dev/null and b/docs/user/rst/images/ball1.gif differ diff --git a/docs/user/rst/images/biohazard.bmp b/docs/user/rst/images/biohazard.bmp new file mode 100644 index 000000000..aceb52948 Binary files /dev/null and b/docs/user/rst/images/biohazard.bmp differ diff --git a/docs/user/rst/images/biohazard.gif b/docs/user/rst/images/biohazard.gif new file mode 100644 index 000000000..7e1ea34ed Binary files /dev/null and b/docs/user/rst/images/biohazard.gif differ diff --git a/docs/user/rst/images/biohazard.png b/docs/user/rst/images/biohazard.png new file mode 100644 index 000000000..ae4629d8b Binary files /dev/null and b/docs/user/rst/images/biohazard.png differ diff --git a/docs/user/rst/images/title.png b/docs/user/rst/images/title.png new file mode 100644 index 000000000..cc6218efe Binary files /dev/null and b/docs/user/rst/images/title.png differ diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html new file mode 100644 index 000000000..886a02107 --- /dev/null +++ b/docs/user/rst/quickref.html @@ -0,0 +1,1096 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> + <head> + <title>Quick reStructuredText + + + + +

Quick reStructuredText

+ + + + + + + + + + +

http://docutils.sourceforge.net/docs/rst/quickref.html +
Being a cheat-sheet for reStructuredText +
Version 0.8 of 2002-04-19 + + +

The full details may be found on the + reStructuredText + page. This document is just intended as a reminder. + +

Links that look like "(details?)" point + into the HTML version of the full reStructuredText + specification document. These are relative links; if they + don't work, please use the master "Quick reStructuredText" document. + +

Contents

+ + + +

Inline Markup

+ +

(details?) + +

+ + + + + + + + + + + + + + + + +
Plain text + Typical result + Notes +
*emphasis* + emphasis +   + +
**strong emphasis** + strong emphasis +   + +
`interpreted text` + interpreted text + What interpreted text means is domain dependent. + +
``inline literal`` + inline literal + Spaces should be preserved, but line breaks will not be. + +
reference_ + reference + A simple, one-word hyperlink reference. See Hyperlinks. + +
`phrase reference`_ + phrase reference + A hyperlink reference with spaces or punctuation needs to be quoted with backquotes. + See Hyperlinks. + +
anonymous__ + anonymous + Both simple and phrase references may be anonymous (two underscores). + See Hyperlinks. + +
_`inline hyperlink target` + inline hyperlink target + A crossreference target within text. + See Hyperlinks. + +
|substitution reference| + (see note) + The result is substituted in from the substitution definition. + It could be text, an image, a hyperlink, or a combination of these and others. + +
footnote reference [1]_ + footnote reference [1] + See Footnotes. + +
citation reference [CIT2002]_ + citation reference [CIT2002] + See Citations. + +
http://docutils.sf.net/ + http://docutils.sf.net/ + A standalone hyperlink. + +
+ +

Asterisk, backquote, vertical bar, and underscore are inline + delimiter characters. Asterisk, backquote, and vertical bar act + like quote marks; matching characters surround the marked-up word + or phrase, whitespace or other quoting is required outside them, + and there can't be whitespace just inside them. If you want to use + inline delimiter characters literally, escape + (with backslash) or quote them (with double backquotes; i.e. + use inline literals). + +

In detail, the reStructuredText specifications says that in + inline markup: +

    +
  1. The start-string must start a text block or be + immediately preceded by whitespace,  + ' " ( [ { or  <. +
  2. The start-string must be immediately followed by non-whitespace. +
  3. The end-string must be immediately preceded by non-whitespace. +
  4. The end-string must end a text block or be immediately + followed by whitespace,  + ' " . , : ; ! ? - ) ] } or  >. +
  5. If a start-string is immediately preceded by one of  + ' " ( [ { or  <, it must not be + immediately followed by the corresponding character from  + ' " ) ] } or  >. +
  6. An end-string must be separated by at least one + character from the start-string. +
  7. An unescaped backslash preceding a start-string or end-string will + disable markup recognition, except for the end-string of inline + literals. +
+ +

Also remember that inline markup may not be nested (well, + except that inline literals can contain any of the other inline + markup delimiter characters, but that doesn't count because + nothing is processed). + +

Escaping with Bashslashes

+ +

(details?) + +

reStructuredText uses backslashes ("\") to override the special + meaning given to markup characters and get the literal characters + themselves. To get a literal backslash, use an escaped backslash + ("\\"). For example: + +

+ + + + +
Raw reStructuredText + Typical result +
+ *escape* ``with`` "\" + escape with "" +
+ \*escape* \``with`` "\\" + *escape* ``with`` "\" +
+ +

In Python strings it will, of course, be necessary + to escape any backslash characters so that they actually + reach reStructuredText. + The simplest way to do this is to use raw strings: + +

+ + + + +
Python string + Typical result +
+ r"""\*escape* \`with` "\\"""" + *escape* `with` "\" +
+  """\\*escape* \\`with` "\\\\"""" + *escape* `with` "\" +
+  """\*escape* \`with` "\\"""" + escape with "" +
+ +

Section Structure

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+ ===== +
Title +
===== +
Subtitle +
-------- +
Titles are underlined (or over- +
and underlined) with a printing +
nonalphanumeric 7-bit ASCII +
character. Recommended choices +
are "``= - ` : ' " ~ ^ _ * + # < >``". +
+ Title +

Subtitle +

Titles are underlined (or over- + and underlined) with a printing + nonalphanumeric 7-bit ASCII + character. Recommended choices + are "= - ` : ' " ~ ^ _ * + # < >". +

+ +

Paragraphs

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+

This is a paragraph. + +

Paragraphs line up at their left +
edges, and are normally separated +
by blank lines. + +

+

This is a paragraph. + +

Paragraphs line up at their left edges, and are normally + separated by blank lines. + +

+ +

Bullet Lists

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+Bullet lists: + +

- This is item 1 +
- This is item 2 + +

- Bullets are "-", "*" or "+". +
  Continuing text must be aligned +
  after the bullet and whitespace. + +

Note that a blank line is required +
before the first item and after the +
last, but is optional between items. +

Bullet lists: +
    +
  • This is item 1 +
  • This is item 2 +
  • Bullets are "-", "*" or "+". + Continuing text must be aligned + after the bullet and whitespace. +
+

Note that a blank line is required before the first + item and after the last, but is optional between items. +

+ +

Enumerated Lists

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+Enumerated lists: + +

3. This is the first item +
4. This is the second item +
5. Enumerators are arabic numbers, +
   single letters, or roman numerals +
6. List items should be sequentially +
   numbered, but need not start at 1 +
   (although not all formatters will +
   honour the first index). +

Enumerated lists: +
    +
  1. This is the first item +
  2. This is the second item +
  3. Enumerators are arabic numbers, single letters, + or roman numerals +
  4. List items should be sequentially numbered, + but need not start at 1 (although not all + formatters will honour the first index). +
+
+ +

Definition Lists

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+Definition lists: +
+
what +
  Definition lists associate a term with +
  a definition. +
+
how +
  The term is a one-line phrase, and the +
  definition is one or more paragraphs or +
  body elements, indented relative to the +
  term. Blank lines are not allowed +
  between term and definition. +
Definition lists: +
+
what +
Definition lists associate a term with + a definition. + +
how +
The term is a one-line phrase, and the + definition is one or more paragraphs or + body elements, indented relative to the + term. Blank lines are not allowed + between term and definition. +
+
+ +

Field Lists

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+:Authors: +
    Tony J. (Tibs) Ibbs, +
    David Goodger + +

    (and sundry other good-natured folks) + +

:Version: 1.0 of 2001/08/08 +
:Dedication: To my father. +

+ + +
Authors: + Tony J. (Tibs) Ibbs, + David Goodger +
(and sundry other good-natured folks) +
Version:1.0 of 2001/08/08 +
Dedication:To my father. +
+
+ +

Option Lists

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+

+-a            command-line option "a" +
-b file       options can have arguments +
              and long descriptions +
--long        options can be long also +
--input=file  long options can also have +
              arguments +
/V            DOS/VMS-style options too +
+ +

+ + + + + + + +

-a +

command-line option "a" +

-b file +

options can have arguments and long descriptions +

--long +

options can be long also +

--input=file +

long options can also have arguments +

/V +

DOS/VMS-style options too +

+
+ +

There must be at least two spaces between the option and the + description. + +

Literal Blocks

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+A paragraph containing only two colons +
indicates that the following indented +
text is a literal block. +
+
:: +
+
  Whitespace, newlines, blank lines, and +
  all kinds of markup (like *this* or +
  \this) is preserved by literal blocks. +
+
  The paragraph containing only '::' +
  will be omitted from the result. +
+
The ``::`` may be tacked onto the very +
end of any paragraph. The ``::`` will be +
omitted if it is preceded by whitespace. +
The ``::`` will be converted to a single +
colon if preceded by text, like this:: +
+
  It's very convenient to use this form. +
+
Literal blocks end when text returns to +
the preceding paragraph's indentation. +
This means that something like:: +
+
      We start here +
    and continue here +
  and end here. +
+
is possible. + +
+

A paragraph containing only two colons +indicates that the following indented +text is a literal block. + +

+  Whitespace, newlines, blank lines, and
+  all kinds of markup (like *this* or
+  \this) is preserved by literal blocks.
+
+  The paragraph containing only '::'
+  will be omitted from the result.
+ +

The :: may be tacked onto the very +end of any paragraph. The :: will be +omitted if it is preceded by whitespace. +The :: will be converted to a single +colon if preceded by text, like this: + +

+  It's very convenient to use this form.
+ +

Literal blocks end when text returns to +the preceding paragraph's indentation. +This means that something like: + +

+      We start here
+    and continue here
+  and end here.
+ +

is possible. +

+ +

Block Quotes

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+Block quotes are just: + +

    Indented paragraphs, + +

        and they may nest. +

+ Block quotes are just: +
+

Indented paragraphs, +

+

and they may nest. +

+
+
+ +

Doctest Blocks

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+

Doctest blocks are interactive +
Python sessions. They begin with +
"``>>>``" and end with a blank line.
+ +

>>> print "This is a doctest block." +
This is a doctest block.
+ +

+

Doctest blocks are interactive + Python sessions. They begin with + ">>>" and end with a blank line. + +

>>> print "This is a doctest block." +
This is a doctest block.
+

+ +

"The doctest + module searches a module's docstrings for text that looks like an + interactive Python session, then executes all such sessions to + verify they still work exactly as shown." (From the doctest docs.) + +

Tables

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+    +------------+------------+-----------+ +
    | Header 1   | Header 2   | Header 3  | +
    +============+============+===========+ +
    | body row 1 | column 2   | column 3  | +
    +------------+------------+-----------+ +
    | body row 2 | Cells may span columns.| +
    +------------+------------+-----------+ +
    | body row 3 | Cells may  | - Cells   | +
    +------------+ span rows. | - contain | +
    | body row 4 |            | - blocks. | +
    +------------+------------+-----------+ +
+ + + + + + +
Header 1 + Header 2 + Header 3 +
body row 1 + column 2 + column 3 +
body row 2 + Cells may span columns. +
body row 3 + Cells may
span rows. +
+
    +
  • Cells +
  • contain +
  • blocks. +
+
body row 4 +
+
+ +

Transitions

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
+

+A transition marker is a horizontal line +
of 4 or more repeated punctuation +
characters.
+ +

------------ + +

A transition should not begin or end a +
section or document, nor should two +
transitions be immediately adjacent.
+ +

+

A transition marker is a horizontal line + of 4 or more repeated punctuation + characters.

+ +
+ +

A transition should not begin or end a + section or document, nor should two + transitions be immediately adjacent. +

+ +

Transitions are commonly seen in novels and short fiction, as a + gap spanning one or more lines, marking text divisions or + signaling changes in subject, time, point of view, or emphasis. + +

Footnotes

+ +

(details?) + +

+ + + + + + + + +
Plain text + Typical result +
+ Footnote references, like [5]_. +
Note that footnotes may get +
rearranged, e.g., to the bottom of +
the "page". + +

.. [5] A numerical footnote. Note +
   there's no colon after the ``]``. + +

+ Footnote references, like [5]. + Note that footnotes may get rearranged, e.g., to the bottom of + the "page". + +

+

+ +
[5] A numerical footnote. + Note there's no colon after the ]. +
+ +

+ Autonumbered footnotes are +
possible, like using [#]_ and [#]_. +

.. [#] This is the first one. +
.. [#] This is the second one. + +

They may be assigned 'autonumber +
labels' - for instance, +
[#fourth]_ and [#third]_.
+ +

.. [#third] a.k.a. third_ +

.. [#fourth] a.k.a. fourth_ +

+ Autonumbered footnotes are possible, like using 1 and 2. + +

They may be assigned 'autonumber labels' - for instance, + 4 and 3. + +

+

+ +
[1] This is the first one. +
[2] This is the second one. +
[3] a.k.a. third +
[4] a.k.a. fourth +
+ +

+ Auto-symbol footnotes are also +
possible, like this: [*]_ and [*]_. +

.. [*] This is the first one. +
.. [*] This is the second one. + +

+ Auto-symbol footnotes are also + possible, like this: * + and . + +

+

+ +
[*] This is the first symbol footnote +
[†] This is the second one. +
+ +

+ +

The numbering of auto-numbered footnotes is determined by the + order of the footnotes, not of the references. For auto-numbered + footnote references without autonumber labels + ("[#]_"), the references and footnotes must be in the + same relative order. Similarly for auto-symbol footnotes + ("[*]_"). + +

Citations

+ +

(details?) + +

+ + + + + + +
Plain text + Typical result +
+ Citation references, like [CIT2002]_. +
Note that citations may get +
rearranged, e.g., to the bottom of +
the "page". + +

.. [CIT2002] A citation +
   (as often used in journals). + +

Citation labels contain alphanumerics, +
underlines, hyphens and fullstops. +
Case is not significant. + +

Given a citation like [this]_, one +
can also refer to it like this_. + +

.. [this] here. + +

+ Citation references, like [CIT2002]. + Note that citations may get rearranged, e.g., to the bottom of + the "page". + +

Citation labels contain alphanumerics, underlines, hyphens + and fullstops. Case is not significant. + +

Given a citation like [this], one + can also refer to it like this. + +

+

+ +
[CIT2002] A citation + (as often used in journals). +
[this] here. +
+ +

+ +

Hyperlink Targets

+ +

(details?) + +

External Hyperlink Targets

+ +

+ + + + + + +
Plain text + Typical result +
+ External hyperlinks, like Python_. + +

.. _Python: http://www.python.org/ +

+ +
Fold-in form +
Indirect hyperlinks, like + Python. +
Call-out form +
External hyperlinks, like + Python. + +

+

+
Python: + http://www.python.org/ +
+

+
+ +

"Fold-in" is the representation typically used in HTML + documents (think of the indirect hyperlink being "folded in" like + ingredients into a cake), and "call-out" is more suitable for + printed documents, where the link needs to be presented explicitly, for + example as a footnote. + +

Internal Hyperlink Targets

+ +

+ + + + + + +
Plain text + Typical result +
Internal crossreferences, like example_. + +

.. _example: + +

This is an example crossreference target. +

+ +
Fold-in form + + + + +
Internal crossreferences, like example +

This is an example + crossreference target. +

Call-out form +
Internal crossreferences, like example + +

example: +
This is an example crossreference target. +

+ +
+ +

Indirect Hyperlink Targets

+ +

(details?) + +

+ + + + + + +
Plain text + Typical result +
+ Python_ is `my favourite +
programming language`__.
+ +

.. _Python: http://www.python.org/ + +

__ Python_ + +

+

Python is + my favourite + programming language. + +

+ +

The second hyperlink target (the line beginning with + "__") is both an indirect hyperlink target + (indirectly pointing at the Python website via the + "Python_" reference) and an anonymous hyperlink + target. In the text, a double-underscore suffix is used to + indicate an anonymous hyperlink reference. + +

Implicit Hyperlink Targets

+ +

(details?) + +

Section titles, footnotes, and citations automatically generate + hyperlink targets (the title text or footnote/citation label is + used as the hyperlink name). + +

+ + + +
Plain text + Typical result + +
+ Titles are targets, too +
======================= +
Implict references, like `Titles are +
targets, too`_. +
+ Titles are targets, too +

Implict references, like Titles are + targets, too. +

+ +

Directives

+ +

(details?) + +

+ + + + + +
Plain text + Typical result +
For instance: + +

.. image:: images/ball1.gif + +

+ For instance: +

ball1 +

+ +

Substitution References and Definitions

+ +

(details?) + +

Substitutions are like inline directives, allowing graphics and + arbitrary constructs within text. + +

+ + + + + +
Plain text + Typical result +
+The |biohazard| symbol must be +used on containers used to +dispose of medical waste. + +

+.. |biohazard| image:: biohazard.png + +

+ +

The biohazard symbol + must be used on containers used to dispose of medical waste. + +

+ +

Comments

+ +

(details?) + +

+ + + + + + +
Plain text + Typical result +
.. This text will not be shown +
   (but, for instance, in HTML might be +
   rendered as an HTML comment) + +
  + + + + +
+ An empty "comment" directive does not +
"consume" following blocks. +

.. +

        So this block is not "lost", +
        despite its indentation. +

+ An empty "comment" directive does not + "consume" following blocks. +
+ So this block is not "lost", + despite its indentation. +
+
+ +


+
+

Authors: + Tibs + (tony@lsl.co.uk or + tibs@tibsnjoan.co.uk) + and David Goodger + (goodger@users.sourceforge.net) +

+ + + diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt new file mode 100644 index 000000000..be9139d60 --- /dev/null +++ b/docs/user/rst/quickstart.txt @@ -0,0 +1,301 @@ +A ReStructuredText Primer +========================= + +:Author: Richard Jones +:Version: $Revision$ + +The text below contains links that look like "(quickref__)". These +are relative links that point to the `Quick reStructuredText`_ user +reference. If these links don't work, please refer to the `master +quick reference`_ document. + +__ +.. _Quick reStructuredText: quickref.html +.. _master quick reference: + http://docutils.sourceforge.net/docs/rst/quickref.html + + +Structure +--------- + +From the outset, let me say that "Structured Text" is probably a bit +of a misnomer. It's more like "Relaxed Text" that uses certain +consistent patterns. These patterns are interpreted by a HTML +converter to produce "Very Structured Text" that can be used by a web +browser. + +The most basic pattern recognised is a **paragraph** (quickref__). +That's a chunk of text that is separated by blank lines (one is +enough). Paragraphs must have the same indentation -- that is, line +up at their left edge. Paragraphs that start indented will result in +indented quote paragraphs. For example:: + + This is a paragraph. It's quite + short. + + This paragraph will result in an indented block of + text, typically used for quoting other text. + + This is another one. + +Results in: + + This is a paragraph. It's quite + short. + + This paragraph will result in an indented block of + text, typically used for quoting other text. + + This is another one. + +__ quickref.html#paragraphs + +Text styles +----------- + +(quickref__) + +__ quickref.html#inline-markup + +Inside paragraphs and other bodies of text, you may additionally mark +text for *italics* with "``*italics*``" or **bold** with +"``**bold**``". + +If you want something to appear as a fixed-space literal, use +"````double back-quotes````". Note that no further fiddling is done +inside the double back-quotes -- so asterisks "``*``" etc. are left +alone. + +If you find that you want to use one of the "special" characters in +text, it will generally be OK -- ReST is pretty smart. For example, +this * asterisk is handled just fine. If you actually want text +\*surrounded by asterisks* to **not** be italicised, then you need to +indicate that the asterisk is not special. You do this by placing a +backslash just before it, like so "``\*``" (quickref__). + +__ quickref.html#escaping + +Lists +----- + +Lists of items come in three main flavours: **enumerated**, +**bulleted** and **definitions**. In all list cases, you may have as +many paragraphs, sublists, etc. as you want, as long as the left-hand +side of the paragraph or whatever aligns with the first line of text +in the list item. + +Lists must always start a new paragraph -- that is, they must appear +after a blank line. + +**enumerated** lists (numbers, letters or roman numerals; quickref__) + __ quickref.html#enumerated-lists + + Start a line off with a number or letter followed by a period ".", + right bracket ")" or surrounded by brackets "( )" -- whatever you're + comfortable with. All of the following forms are recognised:: + + 1. numbers + + A. upper-case letters + and it goes over many lines + + with two paragraphs and all! + + a. lower-case letters + + 3. with a sub-list starting at a different number + 4. make sure the numbers are in the correct sequence though! + + I. upper-case roman numerals + + i. lower-case roman numerals + + (1) numbers again + + 1) and again + + Results in (note: the different enumerated list styles are not + always supported by every web browser, so you may not get the full + effect here): + + 1. numbers + + A. upper-case letters + and it goes over many lines + + with two paragraphs and all! + + a. lower-case letters + + 3. with a sub-list starting at a different number + 4. make sure the numbers are in the correct sequence though! + + I. upper-case roman numerals + + i. lower-case roman numerals + + (1) numbers again + + 1) and again + +**bulleted** lists (quickref__) + __ quickref.html#bullet-lists + + Just like enumerated lists, start the line off with a bullet point + character - either "-", "+" or "*":: + + * a bullet point using "*" + + - a sub-list using "-" + + + yet another sub-list + + - another item + + Results in: + + * a bullet point using "*" + + - a sub-list using "-" + + + yet another sub-list + + - another item + +**definition** lists (quickref__) + __ quickref.html#definition-lists + + Unlike the other two, the definition lists consist of a term, and + the definition of that term. The format of a definition list is:: + + what + Definition lists associate a term with a definition. + + *how* + The term is a one-line phrase, and the definition is one or more + paragraphs or body elements, indented relative to the term. + Blank lines are not allowed between term and definition. + + Results in: + + what + Definition lists associate a term with a definition. + + *how* + The term is a one-line phrase, and the definition is one or more + paragraphs or body elements, indented relative to the term. + Blank lines are not allowed between term and definition. + +Preformatting (code samples) +---------------------------- +(quickref__) + +__ quickref.html#literal-blocks + +To just include a chunk of preformatted, never-to-be-fiddled-with +text, finish the prior paragraph with "``::``". The preformatted +block is finished when the text falls back to the same indentation +level as a paragraph prior to the preformatted block. For example:: + + An example:: + + Whitespace, newlines, blank lines, and all kinds of markup + (like *this* or \this) is preserved by literal blocks. + Lookie here, I've dropped an indentation level + (but not far enough) + + no more example + +Results in: + + An example:: + + Whitespace, newlines, blank lines, and all kinds of markup + (like *this* or \this) is preserved by literal blocks. + Lookie here, I've dropped an indentation level + (but not far enough) + + no more example + +Note that if a paragraph consists only of "``::``", then it's removed +from the output:: + + :: + + This is preformatted text, and the + last "::" paragraph is removed + +Results in: + +:: + + This is preformatted text, and the + last "::" paragraph is removed + +Sections +-------- + +(quickref__) + +__ quickref.html#section-structure + +To break longer text up into sections, you use **section headers**. +These are a single line of text (one or more words) with an underline +(and optionally an overline) in dashes "``-----``", equals +"``======``", tildes "``~~~~~~``" or any of the non-alphanumeric +characters ``= - ` : ' " ~ ^ _ * + # < >`` that you feel comfortable +with. Be consistent though, since all sections marked with the same +underline style are deemed to be at the same level:: + + Chapter 1 Title + =============== + + Section 1.1 Title + ----------------- + + Subsection 1.1.1 Title + ~~~~~~~~~~~~~~~~~~~~~~ + + Section 1.2 Title + ----------------- + + Chapter 2 Title + =============== + +results in: + +.. sorry, I change the heading style here, but it's only an example :) + +Chapter 1 Title +~~~~~~~~~~~~~~~ + +Section 1.1 Title +''''''''''''''''' + +Subsection 1.1.1 Title +"""""""""""""""""""""" + +Section 1.2 Title +''''''''''''''''' + +Chapter 2 Title +~~~~~~~~~~~~~~~ + +Note that section headers are available as link targets, just using +their name. To link to the Lists_ heading, I write "``Lists_``". If +the heading has a space in it like `text styles`_, we need to quote +the heading "```text styles`_``". + +What Next? +---------- + +This primer introduces the most common features of reStructuredText, +but there are a lot more to explore. The `Quick reStructuredText`_ +user reference is a good place to go next. For complete details, the +`reStructuredText Markup Specification`_ is the place to go [#]_. + +.. _reStructuredText Markup Specification: + ../../spec/rst/reStructuredText.html + +.. [#] If that relative link doesn't work, try the master document: + http://docutils.sourceforge.net/spec/rst/reStructuredText.html. diff --git a/docutils/__init__.py b/docutils/__init__.py new file mode 100644 index 000000000..0ee88d94a --- /dev/null +++ b/docutils/__init__.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This is the Docutils (Python Documentation Utilities) package. + +Package Structure +================= + +Modules: + +- __init__.py: Contains the package docstring only (this text). + +- core.py: Contains the ``Publisher`` class and ``publish()`` convenience + function. + +- nodes.py: DPS document tree (doctree) node class library. + +- roman.py: Conversion to and from Roman numerals. Courtesy of Mark + Pilgrim (http://diveintopython.org/). + +- statemachine.py: A finite state machine specialized for + regular-expression-based text filters. + +- urischemes.py: Contains a complete mapping of known URI addressing + scheme names to descriptions. + +- utils.py: Contains the ``Reporter`` system warning class and miscellaneous + utilities. + +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. + +- writers: Format-specific output translators. +""" + +__docformat__ = 'reStructuredText' diff --git a/docutils/core.py b/docutils/core.py new file mode 100644 index 000000000..b553b07b7 --- /dev/null +++ b/docutils/core.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + + +""" + +__docformat__ = 'reStructuredText' + + +import readers, parsers, writers, utils + + +class Publisher: + + """ + Publisher encapsulates the high-level logic of a Docutils system. + """ + + reporter = None + """A `utils.Reporter` instance used for all document processing.""" + + def __init__(self, reader=None, parser=None, writer=None, reporter=None, + languagecode='en', warninglevel=2, errorlevel=4, + warningstream=None, debug=0): + """ + Initial setup. If any of `reader`, `parser`, or `writer` are + not specified, the corresponding 'set*' method should be + called. + """ + self.reader = reader + self.parser = parser + self.writer = writer + if not reporter: + reporter = utils.Reporter(warninglevel, errorlevel, warningstream, + debug) + self.reporter = reporter + self.languagecode = languagecode + + def setreader(self, readername, languagecode=None): + """Set `self.reader` by name.""" + readerclass = readers.get_reader_class(readername) + self.reader = readerclass(self.reporter, + languagecode or self.languagecode) + + def setparser(self, parsername): + """Set `self.parser` by name.""" + parserclass = parsers.get_parser_class(parsername) + self.parser = parserclass() + + def setwriter(self, writername): + """Set `self.writer` by name.""" + writerclass = writers.get_writer_class(writername) + self.writer = writerclass() + + def publish(self, source, destination): + """ + Run `source` through `self.reader`, then through `self.writer` to + `destination`. + """ + document = self.reader.read(source, self.parser) + self.writer.write(document, destination) + + +def publish(source=None, destination=None, + reader=None, readername='standalone', + parser=None, parsername='restructuredtext', + writer=None, writername='pprint', + reporter=None, languagecode='en', + warninglevel=2, errorlevel=4, warningstream=None, debug=0): + """Set up & run a `Publisher`.""" + pub = Publisher(reader, parser, writer, reporter, languagecode, + warninglevel, errorlevel, warningstream, debug) + if reader is None: + pub.setreader(readername) + if parser is None: + pub.setparser(parsername) + if writer is None: + pub.setwriter(writername) + pub.publish(source, destination) diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py new file mode 100644 index 000000000..4c10d9124 --- /dev/null +++ b/docutils/languages/__init__.py @@ -0,0 +1,22 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This package contains modules for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +_languages = {} + +def getlanguage(languagecode): + if _languages.has_key(languagecode): + return _languages[languagecode] + module = __import__(languagecode, globals(), locals()) + _languages[languagecode] = module + return module diff --git a/docutils/languages/en.py b/docutils/languages/en.py new file mode 100644 index 000000000..5b97dadb7 --- /dev/null +++ b/docutils/languages/en.py @@ -0,0 +1,58 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +English-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +labels = { + 'author': 'Author', + 'authors': 'Authors', + 'organization': 'Organization', + 'contact': 'Contact', + 'version': 'Version', + 'revision': 'Revision', + 'status': 'Status', + 'date': 'Date', + 'copyright': 'Copyright', + 'abstract': 'Abstract', + 'attention': 'Attention!', + 'caution': 'Caution!', + 'danger': '!DANGER!', + 'error': 'Error', + 'hint': 'Hint', + 'important': 'Important', + 'note': 'Note', + 'tip': 'Tip', + 'warning': 'Warning', + 'contents': 'Contents'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'author': nodes.author, + 'authors': nodes.authors, + 'organization': nodes.organization, + 'contact': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'date': nodes.date, + 'copyright': nodes.copyright, + 'abstract': nodes.topic} +"""Field name (lowcased) to node class name mapping for bibliographic fields +(field_list).""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/nodes.py b/docutils/nodes.py new file mode 100644 index 000000000..ece182c85 --- /dev/null +++ b/docutils/nodes.py @@ -0,0 +1,1112 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Docutils document tree element class library. + +Classes in CamelCase are abstract base classes or auxiliary classes. The one +exception is `Text`, for a text node; uppercase is used to differentiate from +element classes. + +Classes in lower_case_with_underscores are element classes, matching the XML +element generic identifiers in the DTD_. + +.. _DTD: http://docstring.sourceforge.net/spec/gpdi.dtd +""" + +import sys, os +import xml.dom.minidom +from types import IntType, SliceType, StringType, TupleType, ListType +from UserString import MutableString +import utils +import docutils + + +# ============================== +# Functional Node Base Classes +# ============================== + +class Node: + + """Abstract base class of nodes in a document tree.""" + + parent = None + """Back-reference to the `Node` containing this `Node`.""" + + def __nonzero__(self): + """Node instances are always true.""" + return 1 + + def asdom(self, dom=xml.dom.minidom): + """Return a DOM representation of this Node.""" + return self._dom_node(dom) + + def pformat(self, indent=' ', level=0): + """Return an indented pseudo-XML representation, for test purposes.""" + raise NotImplementedError + + def walk(self, visitor): + """ + Traverse a tree of `Node` objects, calling ``visit_...`` methods of + `visitor` when entering each node. If there is no + ``visit_particular_node`` method for a node of type + ``particular_node``, the ``unknown_visit`` method is called. + + Doesn't handle arbitrary modification in-place during the traversal. + Replacing one element with one element is OK. + + Parameter `visitor`: A `NodeVisitor` object, containing a + ``visit_...`` method for each `Node` subclass encountered. + """ + name = 'visit_' + self.__class__.__name__ + method = getattr(visitor, name, visitor.unknown_visit) + visitor.doctree.reporter.debug(name, category='nodes.Node.walk') + try: + method(self) + children = self.getchildren() + try: + for i in range(len(children)): + children[i].walk(visitor) + except SkipSiblings: + pass + except (SkipChildren, SkipNode): + pass + + def walkabout(self, visitor): + """ + Perform a tree traversal similarly to `Node.walk()`, except also call + ``depart_...`` methods before exiting each node. If there is no + ``depart_particular_node`` method for a node of type + ``particular_node``, the ``unknown_departure`` method is called. + + Parameter `visitor`: A `NodeVisitor` object, containing ``visit_...`` + and ``depart_...`` methods for each `Node` subclass encountered. + """ + name = 'visit_' + self.__class__.__name__ + method = getattr(visitor, name, visitor.unknown_visit) + visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') + try: + method(self) + children = self.getchildren() + try: + for i in range(len(children)): + children[i].walkabout(visitor) + except SkipSiblings: + pass + except SkipChildren: + pass + except SkipNode: + return + name = 'depart_' + self.__class__.__name__ + method = getattr(visitor, name, visitor.unknown_departure) + visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') + method(self) + + +class Text(Node, MutableString): + + tagname = '#text' + + def __repr__(self): + data = repr(self.data) + if len(data) > 70: + data = repr(self.data[:64] + ' ...') + return '<%s: %s>' % (self.tagname, data) + + def shortrepr(self): + data = repr(self.data) + if len(data) > 20: + data = repr(self.data[:16] + ' ...') + return '<%s: %s>' % (self.tagname, data) + + def _dom_node(self, dom): + return dom.Text(self.data) + + def _rooted_dom_node(self, domroot): + return domroot.createTextNode(self.data) + + def astext(self): + return self.data + + def pformat(self, indent=' ', level=0): + result = [] + indent = indent * level + for line in self.data.splitlines(): + result.append(indent + line + '\n') + return ''.join(result) + + def getchildren(self): + """Text nodes have no children. Return [].""" + return [] + + +class Element(Node): + + """ + `Element` is the superclass to all specific elements. + + Elements contain attributes and child nodes. Elements emulate dictionaries + for attributes, indexing by attribute name (a string). To set the + attribute 'att' to 'value', do:: + + element['att'] = 'value' + + Elements also emulate lists for child nodes (element nodes and/or text + nodes), indexing by integer. To get the first child node, use:: + + element[0] + + Elements may be constructed using the ``+=`` operator. To add one new + child node to element, do:: + + element += node + + To add a list of multiple child nodes at once, use the same ``+=`` + operator:: + + element += [node1, node2] + """ + + tagname = None + """The element generic identifier. If None, it is set as an instance + attribute to the name of the class.""" + + child_text_separator = '\n\n' + """Separator for child nodes, used by `astext()` method.""" + + def __init__(self, rawsource='', *children, **attributes): + self.rawsource = rawsource + """The raw text from which this element was constructed.""" + + self.children = [] + """List of child nodes (elements and/or `Text`).""" + + self.extend(children) # extend self.children w/ attributes + + self.attributes = {} + """Dictionary of attribute {name: value}.""" + + for att, value in attributes.items(): + self.attributes[att.lower()] = value + + if self.tagname is None: + self.tagname = self.__class__.__name__ + + def _dom_node(self, dom): + element = dom.Element(self.tagname) + for attribute, value in self.attributes.items(): + element.setAttribute(attribute, str(value)) + for child in self.children: + element.appendChild(child._dom_node(dom)) + return element + + def _rooted_dom_node(self, domroot): + element = domroot.createElement(self.tagname) + for attribute, value in self.attributes.items(): + element.setAttribute(attribute, str(value)) + for child in self.children: + element.appendChild(child._rooted_dom_node(domroot)) + return element + + def __repr__(self): + data = '' + for c in self.children: + data += c.shortrepr() + if len(data) > 60: + data = data[:56] + ' ...' + break + if self.hasattr('name'): + return '<%s "%s": %s>' % (self.__class__.__name__, + self.attributes['name'], data) + else: + return '<%s: %s>' % (self.__class__.__name__, data) + + def shortrepr(self): + if self.hasattr('name'): + return '<%s "%s"...>' % (self.__class__.__name__, + self.attributes['name']) + else: + return '<%s...>' % self.tagname + + def __str__(self): + if self.children: + return '%s%s%s' % (self.starttag(), + ''.join([str(c) for c in self.children]), + self.endtag()) + else: + return self.emptytag() + + def starttag(self): + parts = [self.tagname] + for name, value in self.attlist(): + if value is None: # boolean attribute + parts.append(name) + elif isinstance(value, ListType): + values = [str(v) for v in value] + parts.append('%s="%s"' % (name, ' '.join(values))) + else: + parts.append('%s="%s"' % (name, str(value))) + return '<%s>' % ' '.join(parts) + + def endtag(self): + return '' % self.tagname + + def emptytag(self): + return '<%s/>' % ' '.join([self.tagname] + + ['%s="%s"' % (n, v) + for n, v in self.attlist()]) + + def __len__(self): + return len(self.children) + + def __getitem__(self, key): + if isinstance(key, StringType): + return self.attributes[key] + elif isinstance(key, IntType): + return self.children[key] + elif isinstance(key, SliceType): + assert key.step is None, 'cannot handle slice with stride' + return self.children[key.start:key.stop] + else: + raise TypeError, ('element index must be an integer, a slice, or ' + 'an attribute name string') + + def __setitem__(self, key, item): + if isinstance(key, StringType): + self.attributes[key] = item + elif isinstance(key, IntType): + item.parent = self + self.children[key] = item + elif isinstance(key, SliceType): + assert key.step is None, 'cannot handle slice with stride' + for node in item: + node.parent = self + self.children[key.start:key.stop] = item + else: + raise TypeError, ('element index must be an integer, a slice, or ' + 'an attribute name string') + + def __delitem__(self, key): + if isinstance(key, StringType): + del self.attributes[key] + elif isinstance(key, IntType): + del self.children[key] + elif isinstance(key, SliceType): + assert key.step is None, 'cannot handle slice with stride' + del self.children[key.start:key.stop] + else: + raise TypeError, ('element index must be an integer, a simple ' + 'slice, or an attribute name string') + + def __add__(self, other): + return self.children + other + + def __radd__(self, other): + return other + self.children + + def __iadd__(self, other): + """Append a node or a list of nodes to `self.children`.""" + if isinstance(other, Node): + other.parent = self + self.children.append(other) + elif other is not None: + for node in other: + node.parent = self + self.children.extend(other) + return self + + def astext(self): + return self.child_text_separator.join( + [child.astext() for child in self.children]) + + def attlist(self): + attlist = self.attributes.items() + attlist.sort() + return attlist + + def get(self, key, failobj=None): + return self.attributes.get(key, failobj) + + def hasattr(self, attr): + return self.attributes.has_key(attr) + + def delattr(self, attr): + if self.attributes.has_key(attr): + del self.attributes[attr] + + def setdefault(self, key, failobj=None): + return self.attributes.setdefault(key, failobj) + + has_key = hasattr + + def append(self, item): + item.parent = self + self.children.append(item) + + def extend(self, item): + for node in item: + node.parent = self + self.children.extend(item) + + def insert(self, i, item): + assert isinstance(item, Node) + item.parent = self + self.children.insert(i, item) + + def pop(self, i=-1): + return self.children.pop(i) + + def remove(self, item): + self.children.remove(item) + + def index(self, item): + return self.children.index(item) + + def replace(self, old, new): + """Replace one child `Node` with another child or children.""" + index = self.index(old) + if isinstance(new, Node): + self[index] = new + elif new is not None: + self[index:index+1] = new + + def findclass(self, childclass, start=0, end=sys.maxint): + """ + Return the index of the first child whose class exactly matches. + + Parameters: + + - `childclass`: A `Node` subclass to search for, or a tuple of `Node` + classes. If a tuple, any of the classes may match. + - `start`: Initial index to check. + - `end`: Initial index to *not* check. + """ + if not isinstance(childclass, TupleType): + childclass = (childclass,) + for index in range(start, min(len(self), end)): + for c in childclass: + if isinstance(self[index], c): + return index + return None + + def findnonclass(self, childclass, start=0, end=sys.maxint): + """ + Return the index of the first child whose class does *not* match. + + Parameters: + + - `childclass`: A `Node` subclass to skip, or a tuple of `Node` + classes. If a tuple, none of the classes may match. + - `start`: Initial index to check. + - `end`: Initial index to *not* check. + """ + if not isinstance(childclass, TupleType): + childclass = (childclass,) + for index in range(start, min(len(self), end)): + match = 0 + for c in childclass: + if isinstance(self.children[index], c): + match = 1 + if not match: + return index + return None + + def pformat(self, indent=' ', level=0): + return ''.join(['%s%s\n' % (indent * level, self.starttag())] + + [child.pformat(indent, level+1) + for child in self.children]) + + def getchildren(self): + """Return this element's children.""" + return self.children + + +class TextElement(Element): + + """ + An element which directly contains text. + + Its children are all Text or TextElement nodes. + """ + + child_text_separator = '' + """Separator for child nodes, used by `astext()` method.""" + + def __init__(self, rawsource='', text='', *children, **attributes): + if text != '': + textnode = Text(text) + Element.__init__(self, rawsource, textnode, *children, + **attributes) + else: + Element.__init__(self, rawsource, *children, **attributes) + + +# ======== +# Mixins +# ======== + +class Resolvable: + + resolved = 0 + + +class BackLinkable: + + def add_backref(self, refid): + self.setdefault('backrefs', []).append(refid) + + +# ==================== +# Element Categories +# ==================== + +class Root: pass + +class Titular: pass + +class Bibliographic: pass + + +class PreBibliographic: + """Category of Node which may occur before Bibliographic Nodes.""" + pass + + +class Structural: pass + +class Body: pass + +class General(Body): pass + +class Sequential(Body): pass + +class Admonition(Body): pass + + +class Special(Body): + """Special internal body elements, not true document components.""" + pass + + +class Component: pass + +class Inline: pass + +class Referential(Resolvable): pass + #refnode = None + #"""Resolved reference to a node.""" + + +class Targetable(Resolvable): + + referenced = 0 + + +# ============== +# Root Element +# ============== + +class document(Root, Structural, Element): + + def __init__(self, reporter, languagecode, *args, **kwargs): + Element.__init__(self, *args, **kwargs) + + self.reporter = reporter + """System message generator.""" + + self.languagecode = languagecode + """ISO 639 2-letter language identifier.""" + + self.explicit_targets = {} + """Mapping of target names to explicit target nodes.""" + + self.implicit_targets = {} + """Mapping of target names to implicit (internal) target + nodes.""" + + self.external_targets = [] + """List of external target nodes.""" + + self.internal_targets = [] + """List of internal target nodes.""" + + self.indirect_targets = [] + """List of indirect target nodes.""" + + self.substitution_defs = {} + """Mapping of substitution names to substitution_definition nodes.""" + + self.refnames = {} + """Mapping of names to lists of referencing nodes.""" + + self.refids = {} + """Mapping of ids to lists of referencing nodes.""" + + self.nameids = {} + """Mapping of names to unique id's.""" + + self.ids = {} + """Mapping of ids to nodes.""" + + self.substitution_refs = {} + """Mapping of substitution names to lists of substitution_reference + nodes.""" + + self.footnote_refs = {} + """Mapping of footnote labels to lists of footnote_reference nodes.""" + + self.citation_refs = {} + """Mapping of citation labels to lists of citation_reference nodes.""" + + self.anonymous_targets = [] + """List of anonymous target nodes.""" + + self.anonymous_refs = [] + """List of anonymous reference nodes.""" + + self.autofootnotes = [] + """List of auto-numbered footnote nodes.""" + + self.autofootnote_refs = [] + """List of auto-numbered footnote_reference nodes.""" + + self.symbol_footnotes = [] + """List of symbol footnote nodes.""" + + self.symbol_footnote_refs = [] + """List of symbol footnote_reference nodes.""" + + self.footnotes = [] + """List of manually-numbered footnote nodes.""" + + self.citations = [] + """List of citation nodes.""" + + self.pending = [] + """List of pending elements @@@.""" + + self.autofootnote_start = 1 + """Initial auto-numbered footnote number.""" + + self.symbol_footnote_start = 0 + """Initial symbol footnote symbol index.""" + + self.id_start = 1 + """Initial ID number.""" + + self.messages = Element() + """System messages generated after parsing.""" + + def asdom(self, dom=xml.dom.minidom): + domroot = dom.Document() + domroot.appendChild(Element._rooted_dom_node(self, domroot)) + return domroot + + def set_id(self, node, msgnode=None): + if msgnode == None: + msgnode = self.messages + if node.has_key('id'): + id = node['id'] + if self.ids.has_key(id) and self.ids[id] is not node: + msg = self.reporter.severe('Duplicate ID: "%s".' % id) + msgnode += msg + else: + if node.has_key('name'): + id = utils.id(node['name']) + else: + id = '' + while not id or self.ids.has_key(id): + id = 'id%s' % self.id_start + self.id_start += 1 + node['id'] = id + self.ids[id] = node + if node.has_key('name'): + self.nameids[node['name']] = id + return id + + def note_implicit_target(self, target, msgnode=None): + if msgnode == None: + msgnode = self.messages + id = self.set_id(target, msgnode) + name = target['name'] + if self.explicit_targets.has_key(name) \ + or self.implicit_targets.has_key(name): + msg = self.reporter.info( + 'Duplicate implicit target name: "%s".' % name, backrefs=[id]) + msgnode += msg + self.clear_target_names(name, self.implicit_targets) + del target['name'] + target['dupname'] = name + self.implicit_targets[name] = None + else: + self.implicit_targets[name] = target + + def note_explicit_target(self, target, msgnode=None): + if msgnode == None: + msgnode = self.messages + id = self.set_id(target, msgnode) + name = target['name'] + if self.explicit_targets.has_key(name): + level = 2 + if target.has_key('refuri'): # external target, dups OK + refuri = target['refuri'] + t = self.explicit_targets[name] + if t.has_key('name') and t.has_key('refuri') \ + and t['refuri'] == refuri: + level = 1 # just inform if refuri's identical + msg = self.reporter.system_message( + level, 'Duplicate explicit target name: "%s".' % name, + backrefs=[id]) + msgnode += msg + self.clear_target_names(name, self.explicit_targets, + self.implicit_targets) + if level > 1: + del target['name'] + target['dupname'] = name + elif self.implicit_targets.has_key(name): + msg = self.reporter.info( + 'Duplicate implicit target name: "%s".' % name, backrefs=[id]) + msgnode += msg + self.clear_target_names(name, self.implicit_targets) + self.explicit_targets[name] = target + + def clear_target_names(self, name, *targetdicts): + for targetdict in targetdicts: + if not targetdict.has_key(name): + continue + node = targetdict[name] + if node.has_key('name'): + node['dupname'] = node['name'] + del node['name'] + + def note_refname(self, node): + self.refnames.setdefault(node['refname'], []).append(node) + + def note_refid(self, node): + self.refids.setdefault(node['refid'], []).append(node) + + def note_external_target(self, target): + self.external_targets.append(target) + + def note_internal_target(self, target): + self.internal_targets.append(target) + + def note_indirect_target(self, target): + self.indirect_targets.append(target) + if target.has_key('name'): + self.note_refname(target) + + def note_anonymous_target(self, target): + self.set_id(target) + self.anonymous_targets.append(target) + + def note_anonymous_ref(self, ref): + self.anonymous_refs.append(ref) + + def note_autofootnote(self, footnote): + self.set_id(footnote) + self.autofootnotes.append(footnote) + + def note_autofootnote_ref(self, ref): + self.set_id(ref) + self.autofootnote_refs.append(ref) + + def note_symbol_footnote(self, footnote): + self.set_id(footnote) + self.symbol_footnotes.append(footnote) + + def note_symbol_footnote_ref(self, ref): + self.set_id(ref) + self.symbol_footnote_refs.append(ref) + + def note_footnote(self, footnote): + self.set_id(footnote) + self.footnotes.append(footnote) + + def note_footnote_ref(self, ref): + self.set_id(ref) + self.footnote_refs.setdefault(ref['refname'], []).append(ref) + self.note_refname(ref) + + def note_citation(self, citation): + self.set_id(citation) + self.citations.append(citation) + + def note_citation_ref(self, ref): + self.set_id(ref) + self.citation_refs.setdefault(ref['refname'], []).append(ref) + self.note_refname(ref) + + def note_substitution_def(self, subdef, msgnode=None): + name = subdef['name'] + if self.substitution_defs.has_key(name): + msg = self.reporter.error( + 'Duplicate substitution definition name: "%s".' % name) + if msgnode == None: + msgnode = self.messages + msgnode += msg + oldnode = self.substitution_defs[name] + oldnode['dupname'] = oldnode['name'] + del oldnode['name'] + # keep only the last definition + self.substitution_defs[name] = subdef + + def note_substitution_ref(self, subref): + self.substitution_refs.setdefault( + subref['refname'], []).append(subref) + + def note_pending(self, pending): + self.pending.append(pending) + + +# ================ +# Title Elements +# ================ + +class title(Titular, PreBibliographic, TextElement): pass +class subtitle(Titular, PreBibliographic, TextElement): pass + + +# ======================== +# Bibliographic Elements +# ======================== + +class docinfo(Bibliographic, Element): pass +class author(Bibliographic, TextElement): pass +class authors(Bibliographic, Element): pass +class organization(Bibliographic, TextElement): pass +class contact(Bibliographic, TextElement): pass +class version(Bibliographic, TextElement): pass +class revision(Bibliographic, TextElement): pass +class status(Bibliographic, TextElement): pass +class date(Bibliographic, TextElement): pass +class copyright(Bibliographic, TextElement): pass + + +# ===================== +# Structural Elements +# ===================== + +class section(Structural, Element): pass + +class topic(Structural, Element): + + """ + Topics are terminal, "leaf" mini-sections, like block quotes with titles, + or textual figures. A topic is just like a section, except that it has no + subsections, and it doesn't have to conform to section placement rules. + + Topics are allowed wherever body elements (list, table, etc.) are allowed, + but only at the top level of a section or document. Topics cannot nest + inside topics or body elements; you can't have a topic inside a table, + list, block quote, etc. + """ + + pass + + +class transition(Structural, Element): pass + + +# =============== +# Body Elements +# =============== + +class paragraph(General, TextElement): pass +class bullet_list(Sequential, Element): pass +class enumerated_list(Sequential, Element): pass +class list_item(Component, Element): pass +class definition_list(Sequential, Element): pass +class definition_list_item(Component, Element): pass +class term(Component, TextElement): pass +class classifier(Component, TextElement): pass +class definition(Component, Element): pass +class field_list(Sequential, Element): pass +class field(Component, Element): pass +class field_name(Component, TextElement): pass +class field_argument(Component, TextElement): pass +class field_body(Component, Element): pass + + +class option(Component, Element): + + child_text_separator = '' + + +class option_argument(Component, TextElement): + + def astext(self): + return self.get('delimiter', ' ') + TextElement.astext(self) + + +class option_group(Component, Element): + + child_text_separator = ', ' + + +class option_list(Sequential, Element): pass + + +class option_list_item(Component, Element): + + child_text_separator = ' ' + + +class option_string(Component, TextElement): pass +class description(Component, Element): pass +class literal_block(General, TextElement): pass +class block_quote(General, Element): pass +class doctest_block(General, TextElement): pass +class attention(Admonition, Element): pass +class caution(Admonition, Element): pass +class danger(Admonition, Element): pass +class error(Admonition, Element): pass +class important(Admonition, Element): pass +class note(Admonition, Element): pass +class tip(Admonition, Element): pass +class hint(Admonition, Element): pass +class warning(Admonition, Element): pass +class comment(Special, PreBibliographic, TextElement): pass +class substitution_definition(Special, TextElement): pass +class target(Special, Inline, TextElement, Targetable): pass +class footnote(General, Element, BackLinkable): pass +class citation(General, Element, BackLinkable): pass +class label(Component, TextElement): pass +class figure(General, Element): pass +class caption(Component, TextElement): pass +class legend(Component, Element): pass +class table(General, Element): pass +class tgroup(Component, Element): pass +class colspec(Component, Element): pass +class thead(Component, Element): pass +class tbody(Component, Element): pass +class row(Component, Element): pass +class entry(Component, Element): pass + + +class system_message(Special, PreBibliographic, Element, BackLinkable): + + def __init__(self, comment=None, *children, **attributes): + if comment: + p = paragraph('', comment) + children = (p,) + children + Element.__init__(self, '', *children, **attributes) + + def astext(self): + return '%s (%s) %s' % (self['type'], self['level'], + Element.astext(self)) + + +class pending(Special, PreBibliographic, Element): + + """ + The "pending" element is used to encapsulate a pending operation: the + operation, the point at which to apply it, and any data it requires. Only + the pending operation's location within the document is stored in the + public document tree; the operation itself and its data are stored in + internal instance attributes. + + For example, say you want a table of contents in your reStructuredText + document. The easiest way to specify where to put it is from within the + document, with a directive:: + + .. contents:: + + But the "contents" directive can't do its work until the entire document + has been parsed (and possibly transformed to some extent). So the + directive code leaves a placeholder behind that will trigger the second + phase of the its processing, something like this:: + + + internal attributes + + The "pending" node is also appended to `document.pending`, so that a later + stage of processing can easily run all pending transforms. + """ + + def __init__(self, transform, stage, details, + rawsource='', *children, **attributes): + Element.__init__(self, rawsource, *children, **attributes) + + self.transform = transform + """The `docutils.transforms.Transform` class implementing the pending + operation.""" + + self.stage = stage + """The stage of processing when the function will be called.""" + + self.details = details + """Detail data (dictionary) required by the pending operation.""" + + def pformat(self, indent=' ', level=0): + internals = [ + '.. internal attributes:', + ' .transform: %s.%s' % (self.transform.__module__, + self.transform.__name__), + ' .stage: %r' % self.stage, + ' .details:'] + details = self.details.items() + details.sort() + for key, value in details: + if isinstance(value, Node): + internals.append('%7s%s:' % ('', key)) + internals.extend(['%9s%s' % ('', line) + for line in value.pformat().splitlines()]) + else: + internals.append('%7s%s: %r' % ('', key, value)) + return (Element.pformat(self, indent, level) + + ''.join([(' %s%s\n' % (indent * level, line)) + for line in internals])) + + +class raw(Special, Inline, PreBibliographic, TextElement): + + """ + Raw data that is to be passed untouched to the Writer. + """ + + pass + + +# ================= +# Inline Elements +# ================= + +class emphasis(Inline, TextElement): pass +class strong(Inline, TextElement): pass +class interpreted(Inline, Referential, TextElement): pass +class literal(Inline, TextElement): pass +class reference(Inline, Referential, TextElement): pass +class footnote_reference(Inline, Referential, TextElement): pass +class citation_reference(Inline, Referential, TextElement): pass +class substitution_reference(Inline, TextElement): pass + + +class image(General, Inline, TextElement): + + def astext(self): + return self.get('alt', '') + + +class problematic(Inline, TextElement): pass + + +# ======================================== +# Auxiliary Classes, Functions, and Data +# ======================================== + +node_class_names = """ + Text + attention author authors + block_quote bullet_list + caption caution citation citation_reference classifier colspec + comment contact copyright + danger date definition definition_list definition_list_item + description docinfo doctest_block document + emphasis entry enumerated_list error + field field_argument field_body field_list field_name figure + footnote footnote_reference + hint + image important interpreted + label legend list_item literal literal_block + note + option option_argument option_group option_list option_list_item + option_string organization + paragraph pending problematic + raw reference revision row + section status strong substitution_definition + substitution_reference subtitle system_message + table target tbody term tgroup thead tip title topic transition + version + warning""".split() +"""A list of names of all concrete Node subclasses.""" + + +class NodeVisitor: + + """ + "Visitor" pattern [GoF95]_ abstract superclass implementation for document + tree traversals. + + Each node class has corresponding methods, doing nothing by default; + override individual methods for specific and useful behaviour. The + "``visit_`` + node class name" method is called by `Node.walk()` upon + entering a node. `Node.walkabout()` also calls the "``depart_`` + node + class name" method before exiting a node. + + .. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of + Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA, + 1995. + """ + + def __init__(self, doctree): + self.doctree = doctree + + def unknown_visit(self, node): + """ + Called when entering unknown `Node` types. + + Raise an exception unless overridden. + """ + raise NotImplementedError('visiting unknown node type: %s' + % node.__class__.__name__) + + def unknown_departure(self, node): + """ + Called before exiting unknown `Node` types. + + Raise exception unless overridden. + """ + raise NotImplementedError('departing unknown node type: %s' + % node.__class__.__name__) + + # Save typing with dynamic definitions. + for name in node_class_names: + exec """def visit_%s(self, node): pass\n""" % name + exec """def depart_%s(self, node): pass\n""" % name + del name + + +class GenericNodeVisitor(NodeVisitor): + + """ + Generic "Visitor" abstract superclass, for simple traversals. + + Unless overridden, each ``visit_...`` method calls `default_visit()`, and + each ``depart_...`` method (when using `Node.walkabout()`) calls + `default_departure()`. `default_visit()` (`default_departure()`) must be + overridden in subclasses. + + Define fully generic visitors by overriding `default_visit()` + (`default_departure()`) only. Define semi-generic visitors by overriding + individual ``visit_...()`` (``depart_...()``) methods also. + + `NodeVisitor.unknown_visit()` (`NodeVisitor.unknown_departure()`) should + be overridden for default behavior. + """ + + def default_visit(self, node): + """Override for generic, uniform traversals.""" + raise NotImplementedError + + def default_departure(self, node): + """Override for generic, uniform traversals.""" + raise NotImplementedError + + # Save typing with dynamic definitions. + for name in node_class_names: + exec """def visit_%s(self, node): + self.default_visit(node)\n""" % name + exec """def depart_%s(self, node): + self.default_departure(node)\n""" % name + del name + + +class VisitorException(Exception): pass +class SkipChildren(VisitorException): pass +class SkipSiblings(VisitorException): pass +class SkipNode(VisitorException): pass diff --git a/docutils/parsers/__init__.py b/docutils/parsers/__init__.py new file mode 100644 index 000000000..72e2e4e49 --- /dev/null +++ b/docutils/parsers/__init__.py @@ -0,0 +1,37 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. +""" + +__docformat__ = 'reStructuredText' + + +class Parser: + + def parse(self, inputstring, docroot): + """Override to parse `inputstring` into document tree `docroot`.""" + raise NotImplementedError('subclass must override this method') + + def setup_parse(self, inputstring, docroot): + """Initial setup, used by `parse()`.""" + self.inputstring = inputstring + self.docroot = docroot + + +_parser_aliases = { + 'restructuredtext': 'rst', + 'rest': 'rst', + 'rtxt': 'rst',} + +def get_parser_class(parsername): + """Return the Parser class from the `parsername` module.""" + parsername = parsername.lower() + if _parser_aliases.has_key(parsername): + parsername = _parser_aliases[parsername] + module = __import__(parsername, globals(), locals()) + return module.Parser diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py new file mode 100644 index 000000000..06589513b --- /dev/null +++ b/docutils/parsers/rst/__init__.py @@ -0,0 +1,68 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This is ``the docutils.parsers.restructuredtext`` package. It exports a single +class, `Parser`. + +Usage +===== + +1. Create a parser:: + + parser = docutils.parsers.restructuredtext.Parser() + + Several optional arguments may be passed to modify the parser's behavior. + Please see `docutils.parsers.Parser` for details. + +2. Gather input (a multi-line string), by reading a file or the standard + input:: + + input = sys.stdin.read() + +3. Create a new empty `docutils.nodes.document` tree:: + + docroot = docutils.utils.newdocument() + + See `docutils.utils.newdocument()` for parameter details. + +4. Run the parser, populating the document tree:: + + document = parser.parse(input, docroot) + +Parser Overview +=============== + +The reStructuredText parser is implemented as a state machine, examining its +input one line at a time. To understand how the parser works, please first +become familiar with the `docutils.statemachine` module, then see the +`states` module. +""" + +__docformat__ = 'reStructuredText' + + +import docutils.parsers +import docutils.statemachine +import states + + +class Parser(docutils.parsers.Parser): + + """The reStructuredText parser.""" + + def parse(self, inputstring, docroot): + """Parse `inputstring` and populate `docroot`, a document tree.""" + self.setup_parse(inputstring, docroot) + debug = docroot.reporter[''].debug + self.statemachine = states.RSTStateMachine( + stateclasses=states.stateclasses, initialstate='Body', + debug=debug) + inputlines = docutils.statemachine.string2lines( + inputstring, convertwhitespace=1) + self.statemachine.run(inputlines, docroot) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py new file mode 100644 index 000000000..43b0c1dd3 --- /dev/null +++ b/docutils/parsers/rst/directives/__init__.py @@ -0,0 +1,88 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This package contains directive implementation modules. + +The interface for directive functions is as follows:: + + def directivefn(match, type, data, state, statemachine, attributes) + +Where: + +- ``match`` is a regular expression match object which matched the first line + of the directive. ``match.group(1)`` gives the directive name. +- ``type`` is the directive type or name. +- ``data`` contains the remainder of the first line of the directive after the + "::". +- ``state`` is the state which called the directive function. +- ``statemachine`` is the state machine which controls the state which called + the directive function. +- ``attributes`` is a dictionary of extra attributes which may be added to the + element the directive produces. Currently, only an "alt" attribute is passed + by substitution definitions (value: the substitution name), which may by + used by an embedded image directive. +""" + +__docformat__ = 'reStructuredText' + + +_directive_registry = { + 'attention': ('admonitions', 'attention'), + 'caution': ('admonitions', 'caution'), + 'danger': ('admonitions', 'danger'), + 'error': ('admonitions', 'error'), + 'important': ('admonitions', 'important'), + 'note': ('admonitions', 'note'), + 'tip': ('admonitions', 'tip'), + 'hint': ('admonitions', 'hint'), + 'warning': ('admonitions', 'warning'), + 'image': ('images', 'image'), + 'figure': ('images', 'figure'), + 'contents': ('components', 'contents'), + 'footnotes': ('components', 'footnotes'), + 'citations': ('components', 'citations'), + 'topic': ('components', 'topic'), + 'meta': ('html', 'meta'), + 'imagemap': ('html', 'imagemap'), + 'raw': ('misc', 'raw'), + 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} +"""Mapping of directive name to (module name, function name). The directive +'name' is canonical & must be lowercase; language-dependent names are defined +in the language package.""" + +_modules = {} +"""Cache of imported directive modules.""" + +_directives = {} +"""Cache of imported directive functions.""" + +def directive(directivename, languagemodule): + """ + Locate and return a directive function from its language-dependent name. + """ + normname = directivename.lower() + if _directives.has_key(normname): + return _directives[normname] + try: + canonicalname = languagemodule.directives[normname] + modulename, functionname = _directive_registry[canonicalname] + except KeyError: + return None + if _modules.has_key(modulename): + module = _modules[modulename] + else: + try: + module = __import__(modulename, globals(), locals()) + except ImportError: + return None + try: + function = getattr(module, functionname) + except AttributeError: + return None + return function diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py new file mode 100644 index 000000000..f594cd431 --- /dev/null +++ b/docutils/parsers/rst/directives/admonitions.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Admonition directives. +""" + +__docformat__ = 'reStructuredText' + + +from docutils.parsers.rst import states +from docutils import nodes + + +def admonition(nodeclass, match, typename, data, state, statemachine, + attributes): + indented, indent, lineoffset, blankfinish \ + = statemachine.getfirstknownindented(match.end()) + text = '\n'.join(indented) + admonitionnode = nodeclass(text) + if text: + state.nestedparse(indented, lineoffset, admonitionnode) + return [admonitionnode], blankfinish + +def attention(*args, **kwargs): + return admonition(nodes.attention, *args, **kwargs) + +def caution(*args, **kwargs): + return admonition(nodes.caution, *args, **kwargs) + +def danger(*args, **kwargs): + return admonition(nodes.danger, *args, **kwargs) + +def error(*args, **kwargs): + return admonition(nodes.error, *args, **kwargs) + +def important(*args, **kwargs): + return admonition(nodes.important, *args, **kwargs) + +def note(*args, **kwargs): + return admonition(nodes.note, *args, **kwargs) + +def tip(*args, **kwargs): + return admonition(nodes.tip, *args, **kwargs) + +def hint(*args, **kwargs): + return admonition(nodes.hint, *args, **kwargs) + +def warning(*args, **kwargs): + return admonition(nodes.warning, *args, **kwargs) diff --git a/docutils/parsers/rst/directives/components.py b/docutils/parsers/rst/directives/components.py new file mode 100644 index 000000000..8463f41b0 --- /dev/null +++ b/docutils/parsers/rst/directives/components.py @@ -0,0 +1,59 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Document component directives. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes +import docutils.transforms.components + + +contents_attribute_spec = {'depth': int, + 'local': (lambda x: x)} + +def contents(match, typename, data, state, statemachine, attributes): + lineno = statemachine.abslineno() + lineoffset = statemachine.lineoffset + datablock, indent, offset, blankfinish = \ + statemachine.getfirstknownindented(match.end(), uptoblank=1) + blocktext = '\n'.join(statemachine.inputlines[ + lineoffset : lineoffset + len(datablock) + 1]) + for i in range(len(datablock)): + if datablock[i][:1] == ':': + attlines = datablock[i:] + datablock = datablock[:i] + break + else: + attlines = [] + i = 0 + titletext = ' '.join([line.strip() for line in datablock]) + if titletext: + textnodes, messages = state.inline_text(titletext, lineno) + title = nodes.title(titletext, '', *textnodes) + else: + messages = [] + title = None + pending = nodes.pending(docutils.transforms.components.Contents, + 'last_reader', {'title': title}, blocktext) + if attlines: + success, data, blankfinish = state.parse_extension_attributes( + contents_attribute_spec, attlines, blankfinish) + if success: # data is a dict of attributes + pending.details.update(data) + else: # data is an error string + error = statemachine.memo.reporter.error( + 'Error in "%s" directive attributes at line %s:\n%s.' + % (match.group(1), lineno, data), '', + nodes.literal_block(blocktext, blocktext)) + return [error] + messages, blankfinish + statemachine.memo.document.note_pending(pending) + return [pending] + messages, blankfinish diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py new file mode 100644 index 000000000..d971300e0 --- /dev/null +++ b/docutils/parsers/rst/directives/html.py @@ -0,0 +1,89 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Directives for typically HTML-specific constructs. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes, utils +from docutils.parsers.rst import states + + +def meta(match, typename, data, state, statemachine, attributes): + lineoffset = statemachine.lineoffset + block, indent, offset, blankfinish = \ + statemachine.getfirstknownindented(match.end(), uptoblank=1) + node = nodes.Element() + if block: + newlineoffset, blankfinish = state.nestedlistparse( + block, offset, node, initialstate='MetaBody', + blankfinish=blankfinish, statemachinekwargs=metaSMkwargs) + if (newlineoffset - offset) != len(block): # incomplete parse of block? + blocktext = '\n'.join(statemachine.inputlines[ + lineoffset : statemachine.lineoffset+1]) + msg = statemachine.memo.reporter.error( + 'Invalid meta directive at line %s.' + % statemachine.abslineno(), '', + nodes.literal_block(blocktext, blocktext)) + node += msg + else: + msg = statemachine.memo.reporter.error( + 'Empty meta directive at line %s.' % statemachine.abslineno()) + node += msg + return node.getchildren(), blankfinish + +def imagemap(match, typename, data, state, statemachine, attributes): + return [], 0 + + +class MetaBody(states.SpecializedBody): + + class meta(nodes.Special, nodes.PreBibliographic, nodes.Element): + """HTML-specific "meta" element.""" + pass + + def field_marker(self, match, context, nextstate): + """Meta element.""" + node, blankfinish = self.parsemeta(match) + self.statemachine.node += node + return [], nextstate, [] + + def parsemeta(self, match): + name, args = self.parse_field_marker(match) + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + node = self.meta() + node['content'] = ' '.join(indented) + if not indented: + line = self.statemachine.line + msg = self.statemachine.memo.reporter.info( + 'No content for meta tag "%s".' % name, '', + nodes.literal_block(line, line)) + self.statemachine.node += msg + try: + attname, val = utils.extract_name_value(name)[0] + node[attname.lower()] = val + except utils.NameValueError: + node['name'] = name + for arg in args: + try: + attname, val = utils.extract_name_value(arg)[0] + node[attname.lower()] = val + except utils.NameValueError, detail: + line = self.statemachine.line + msg = self.statemachine.memo.reporter.error( + 'Error parsing meta tag attribute "%s": %s' + % (arg, detail), '', nodes.literal_block(line, line)) + self.statemachine.node += msg + return node, blankfinish + + +metaSMkwargs = {'stateclasses': (MetaBody,)} diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py new file mode 100644 index 000000000..7a719333b --- /dev/null +++ b/docutils/parsers/rst/directives/images.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Directives for figures and simple images. +""" + +__docformat__ = 'reStructuredText' + + +import sys +from docutils.parsers.rst import states +from docutils import nodes, utils + +def unchanged(arg): + return arg # unchanged! + +image_attribute_spec = {'alt': unchanged, + 'height': int, + 'width': int, + 'scale': int} + +def image(match, typename, data, state, statemachine, attributes): + lineno = statemachine.abslineno() + lineoffset = statemachine.lineoffset + datablock, indent, offset, blankfinish = \ + statemachine.getfirstknownindented(match.end(), uptoblank=1) + blocktext = '\n'.join(statemachine.inputlines[ + lineoffset : lineoffset + len(datablock) + 1]) + for i in range(len(datablock)): + if datablock[i][:1] == ':': + attlines = datablock[i:] + datablock = datablock[:i] + break + else: + attlines = [] + if not datablock: + error = statemachine.memo.reporter.error( + 'Missing image URI argument at line %s.' % lineno, '', + nodes.literal_block(blocktext, blocktext)) + return [error], blankfinish + attoffset = lineoffset + i + reference = ''.join([line.strip() for line in datablock]) + if reference.find(' ') != -1: + error = statemachine.memo.reporter.error( + 'Image URI at line %s contains whitespace.' % lineno, '', + nodes.literal_block(blocktext, blocktext)) + return [error], blankfinish + if attlines: + success, data, blankfinish = state.parse_extension_attributes( + image_attribute_spec, attlines, blankfinish) + if success: # data is a dict of attributes + attributes.update(data) + else: # data is an error string + error = statemachine.memo.reporter.error( + 'Error in "%s" directive attributes at line %s:\n%s.' + % (match.group(1), lineno, data), '', + nodes.literal_block(blocktext, blocktext)) + return [error], blankfinish + attributes['uri'] = reference + imagenode = nodes.image(blocktext, **attributes) + return [imagenode], blankfinish + +def figure(match, typename, data, state, statemachine, attributes): + lineoffset = statemachine.lineoffset + (imagenode,), blankfinish = image(match, typename, data, state, + statemachine, attributes) + indented, indent, offset, blankfinish \ + = statemachine.getfirstknownindented(sys.maxint) + blocktext = '\n'.join(statemachine.inputlines[lineoffset: + statemachine.lineoffset+1]) + if isinstance(imagenode, nodes.system_message): + if indented: + imagenode[-1] = nodes.literal_block(blocktext, blocktext) + return [imagenode], blankfinish + figurenode = nodes.figure('', imagenode) + if indented: + node = nodes.Element() # anonymous container for parsing + state.nestedparse(indented, lineoffset, node) + firstnode = node[0] + if isinstance(firstnode, nodes.paragraph): + caption = nodes.caption(firstnode.rawsource, '', + *firstnode.children) + figurenode += caption + elif not (isinstance(firstnode, nodes.comment) and len(firstnode) == 0): + error = statemachine.memo.reporter.error( + 'Figure caption must be a paragraph or empty comment.', '', + nodes.literal_block(blocktext, blocktext)) + return [figurenode, error], blankfinish + if len(node) > 1: + figurenode += nodes.legend('', *node[1:]) + return [figurenode], blankfinish diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py new file mode 100644 index 000000000..f8a9d5217 --- /dev/null +++ b/docutils/parsers/rst/directives/misc.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Miscellaneous directives. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +def raw(match, typename, data, state, statemachine, attributes): + return [], 1 + +def directive_test_function(match, typename, data, state, statemachine, + attributes): + try: + statemachine.nextline() + indented, indent, offset, blankfinish = statemachine.getindented() + text = '\n'.join(indented) + except IndexError: + text = '' + blankfinish = 1 + if text: + info = statemachine.memo.reporter.info( + 'Directive processed. Type="%s", data="%s", directive block:' + % (typename, data), '', nodes.literal_block(text, text)) + else: + info = statemachine.memo.reporter.info( + 'Directive processed. Type="%s", data="%s", directive block: None' + % (typename, data)) + return [info], blankfinish diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py new file mode 100644 index 000000000..ee36d1148 --- /dev/null +++ b/docutils/parsers/rst/languages/__init__.py @@ -0,0 +1,23 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This package contains modules for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + +_languages = {} + +def getlanguage(languagecode): + if _languages.has_key(languagecode): + return _languages[languagecode] + module = __import__(languagecode, globals(), locals()) + _languages[languagecode] = module + return module diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py new file mode 100644 index 000000000..2b1c52649 --- /dev/null +++ b/docutils/parsers/rst/languages/en.py @@ -0,0 +1,38 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +English-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + 'attention': 'attention', + 'caution': 'caution', + 'danger': 'danger', + 'error': 'error', + 'hint': 'hint', + 'important': 'important', + 'note': 'note', + 'tip': 'tip', + 'warning': 'warning', + 'image': 'image', + 'figure': 'figure', + 'contents': 'contents', + 'footnotes': 'footnotes', + 'citations': 'citations', + 'topic': 'topic', + 'meta': 'meta', + 'imagemap': 'imagemap', + 'raw': 'raw', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English name to registered (in directives/__init__.py) directive name +mapping.""" diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py new file mode 100644 index 000000000..b2dbf9b3e --- /dev/null +++ b/docutils/parsers/rst/states.py @@ -0,0 +1,2115 @@ +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This is the ``docutils.parsers.restructuredtext.states`` module, the core of +the reStructuredText parser. It defines the following: + +:Classes: + - `RSTStateMachine`: reStructuredText parser's entry point. + - `NestedStateMachine`: recursive StateMachine. + - `RSTState`: reStructuredText State superclass. + - `Body`: Generic classifier of the first line of a block. + - `BulletList`: Second and subsequent bullet_list list_items + - `DefinitionList`: Second and subsequent definition_list_items. + - `EnumeratedList`: Second and subsequent enumerated_list list_items. + - `FieldList`: Second and subsequent fields. + - `OptionList`: Second and subsequent option_list_items. + - `Explicit`: Second and subsequent explicit markup constructs. + - `SubstitutionDef`: For embedded directives in substitution definitions. + - `Text`: Classifier of second line of a text block. + - `Definition`: Second line of potential definition_list_item. + - `Line`: Second line of overlined section title or transition marker. + - `Stuff`: An auxilliary collection class. + +:Exception classes: + - `MarkupError` + - `ParserError` + - `TransformationError` + +:Functions: + - `escape2null()`: Return a string, escape-backslashes converted to nulls. + - `unescape()`: Return a string, nulls removed or restored to backslashes. + - `normname()`: Return a case- and whitespace-normalized name. + +:Attributes: + - `stateclasses`: set of State classes used with `RSTStateMachine`. + +Parser Overview +=============== + +The reStructuredText parser is implemented as a state machine, examining its +input one line at a time. To understand how the parser works, please first +become familiar with the `docutils.statemachine` module. In the description +below, references are made to classes defined in this module; please see the +individual classes for details. + +Parsing proceeds as follows: + +1. The state machine examines each line of input, checking each of the + transition patterns of the state `Body`, in order, looking for a match. The + implicit transitions (blank lines and indentation) are checked before any + others. The 'text' transition is a catch-all (matches anything). + +2. The method associated with the matched transition pattern is called. + + A. Some transition methods are self-contained, appending elements to the + document tree ('doctest' parses a doctest block). The parser's current + line index is advanced to the end of the element, and parsing continues + with step 1. + + B. Others trigger the creation of a nested state machine, whose job is to + parse a compound construct ('indent' does a block quote, 'bullet' does a + bullet list, 'overline' does a section [first checking for a valid + section header]). + + - In the case of lists and explicit markup, a new state machine is + created and run to parse the first item. + + - A new state machine is created and its initial state is set to the + appropriate specialized state (`BulletList` in the case of the + 'bullet' transition). This state machine is run to parse the compound + element (or series of explicit markup elements), and returns as soon + as a non-member element is encountered. For example, the `BulletList` + state machine aborts as soon as it encounters an element which is not + a list item of that bullet list. The optional omission of + inter-element blank lines is handled by the nested state machine. + + - The current line index is advanced to the end of the elements parsed, + and parsing continues with step 1. + + C. The result of the 'text' transition depends on the next line of text. + The current state is changed to `Text`, under which the second line is + examined. If the second line is: + + - Indented: The element is a definition list item, and parsing proceeds + similarly to step 2.B, using the `DefinitionList` state. + + - A line of uniform punctuation characters: The element is a section + header; again, parsing proceeds as in step 2.B, and `Body` is still + used. + + - Anything else: The element is a paragraph, which is examined for + inline markup and appended to the parent element. Processing continues + with step 1. +""" + +__docformat__ = 'reStructuredText' + + +import sys, re, string +from docutils import nodes, statemachine, utils, roman, urischemes +from docutils.statemachine import StateMachineWS, StateWS +from docutils.utils import normname +import directives, languages +from tableparser import TableParser, TableMarkupError + + +class MarkupError(Exception): pass +class ParserError(Exception): pass + + +class Stuff: + + """Stores a bunch of stuff for dotted-attribute access.""" + + def __init__(self, **keywordargs): + self.__dict__.update(keywordargs) + + +class RSTStateMachine(StateMachineWS): + + """ + reStructuredText's master StateMachine. + + The entry point to reStructuredText parsing is the `run()` method. + """ + + def run(self, inputlines, docroot, inputoffset=0, matchtitles=1): + """ + Parse `inputlines` and return a `docutils.nodes.document` instance. + + Extend `StateMachineWS.run()`: set up parse-global data, run the + StateMachine, and return the resulting + document. + """ + self.language = languages.getlanguage(docroot.languagecode) + self.matchtitles = matchtitles + self.memo = Stuff(document=docroot, + reporter=docroot.reporter, + language=self.language, + titlestyles=[], + sectionlevel=0) + self.node = docroot + results = StateMachineWS.run(self, inputlines, inputoffset) + assert results == [], 'RSTStateMachine.run() results should be empty.' + self.node = self.memo = None # remove unneeded references + + +class NestedStateMachine(StateMachineWS): + + """ + StateMachine run from within other StateMachine runs, to parse nested + document structures. + """ + + def run(self, inputlines, inputoffset, memo, node, matchtitles=1): + """ + Parse `inputlines` and populate a `docutils.nodes.document` instance. + + Extend `StateMachineWS.run()`: set up document-wide data. + """ + self.matchtitles = matchtitles + self.memo = memo + self.node = node + results = StateMachineWS.run(self, inputlines, inputoffset) + assert results == [], 'NestedStateMachine.run() results should be empty' + return results + + +class RSTState(StateWS): + + """ + reStructuredText State superclass. + + Contains methods used by all State subclasses. + """ + + nestedSM = NestedStateMachine + + def __init__(self, statemachine, debug=0): + self.nestedSMkwargs = {'stateclasses': stateclasses, + 'initialstate': 'Body'} + StateWS.__init__(self, statemachine, debug) + + def gotoline(self, abslineoffset): + """Jump to input line `abslineoffset`, ignoring jumps past the end.""" + try: + self.statemachine.gotoline(abslineoffset) + except IndexError: + pass + + def bof(self, context): + """Called at beginning of file.""" + return [], [] + + def nestedparse(self, block, inputoffset, node, matchtitles=0, + statemachineclass=None, statemachinekwargs=None): + """ + Create a new StateMachine rooted at `node` and run it over the input + `block`. + """ + if statemachineclass is None: + statemachineclass = self.nestedSM + if statemachinekwargs is None: + statemachinekwargs = self.nestedSMkwargs + statemachine = statemachineclass(debug=self.debug, **statemachinekwargs) + statemachine.run(block, inputoffset, memo=self.statemachine.memo, + node=node, matchtitles=matchtitles) + statemachine.unlink() + return statemachine.abslineoffset() + + def nestedlistparse(self, block, inputoffset, node, initialstate, + blankfinish, blankfinishstate=None, extrasettings={}, + matchtitles=0, statemachineclass=None, + statemachinekwargs=None): + """ + Create a new StateMachine rooted at `node` and run it over the input + `block`. Also keep track of optional intermdediate blank lines and the + required final one. + """ + if statemachineclass is None: + statemachineclass = self.nestedSM + if statemachinekwargs is None: + statemachinekwargs = self.nestedSMkwargs.copy() + statemachinekwargs['initialstate'] = initialstate + statemachine = statemachineclass(debug=self.debug, **statemachinekwargs) + if blankfinishstate is None: + blankfinishstate = initialstate + statemachine.states[blankfinishstate].blankfinish = blankfinish + for key, value in extrasettings.items(): + setattr(statemachine.states[initialstate], key, value) + statemachine.run(block, inputoffset, memo=self.statemachine.memo, + node=node, matchtitles=matchtitles) + blankfinish = statemachine.states[blankfinishstate].blankfinish + statemachine.unlink() + return statemachine.abslineoffset(), blankfinish + + def section(self, title, source, style, lineno): + """ + When a new section is reached that isn't a subsection of the current + section, back up the line count (use previousline(-x)), then raise + EOFError. The current StateMachine will finish, then the calling + StateMachine can re-examine the title. This will work its way back up + the calling chain until the correct section level isreached. + + Alternative: Evaluate the title, store the title info & level, and + back up the chain until that level is reached. Store in memo? Or + return in results? + """ + if self.checksubsection(source, style, lineno): + self.newsubsection(title, lineno) + + def checksubsection(self, source, style, lineno): + """ + Check for a valid subsection header. Return 1 (true) or None (false). + + :Exception: `EOFError` when a sibling or supersection encountered. + """ + memo = self.statemachine.memo + titlestyles = memo.titlestyles + mylevel = memo.sectionlevel + try: # check for existing title style + level = titlestyles.index(style) + 1 + except ValueError: # new title style + if len(titlestyles) == memo.sectionlevel: # new subsection + titlestyles.append(style) + return 1 + else: # not at lowest level + self.statemachine.node += self.titleinconsistent(source, lineno) + return None + if level <= mylevel: # sibling or supersection + memo.sectionlevel = level # bubble up to parent section + # back up 2 lines for underline title, 3 for overline title + self.statemachine.previousline(len(style) + 1) + raise EOFError # let parent section re-evaluate + if level == mylevel + 1: # immediate subsection + return 1 + else: # invalid subsection + self.statemachine.node += self.titleinconsistent(source, lineno) + return None + + def titleinconsistent(self, sourcetext, lineno): + literalblock = nodes.literal_block('', sourcetext) + error = self.statemachine.memo.reporter.severe( + 'Title level inconsistent at line %s:' % lineno, '', literalblock) + return error + + def newsubsection(self, title, lineno): + """Append new subsection to document tree. On return, check level.""" + memo = self.statemachine.memo + mylevel = memo.sectionlevel + memo.sectionlevel += 1 + sectionnode = nodes.section() + self.statemachine.node += sectionnode + textnodes, messages = self.inline_text(title, lineno) + titlenode = nodes.title(title, '', *textnodes) + name = normname(titlenode.astext()) + sectionnode['name'] = name + sectionnode += titlenode + sectionnode += messages + memo.document.note_implicit_target(sectionnode, sectionnode) + offset = self.statemachine.lineoffset + 1 + absoffset = self.statemachine.abslineoffset() + 1 + newabsoffset = self.nestedparse( + self.statemachine.inputlines[offset:], inputoffset=absoffset, + node=sectionnode, matchtitles=1) + self.gotoline(newabsoffset) + if memo.sectionlevel <= mylevel: # can't handle next section? + raise EOFError # bubble up to supersection + # reset sectionlevel; next pass will detect it properly + memo.sectionlevel = mylevel + + def paragraph(self, lines, lineno): + """ + Return a list (paragraph & messages) and a boolean: literal_block next? + """ + data = '\n'.join(lines).rstrip() + if data[-2:] == '::': + if len(data) == 2: + return [], 1 + elif data[-3] == ' ': + text = data[:-3].rstrip() + else: + text = data[:-1] + literalnext = 1 + else: + text = data + literalnext = 0 + textnodes, messages = self.inline_text(text, lineno) + p = nodes.paragraph(data, '', *textnodes) + return [p] + messages, literalnext + + inline = Stuff() + """Patterns and constants used for inline markup recognition.""" + + inline.openers = '\'"([{<' + inline.closers = '\'")]}>' + inline.start_string_prefix = (r'(?:(?<=^)|(?<=[ \n%s]))' + % re.escape(inline.openers)) + inline.end_string_suffix = (r'(?:(?=$)|(?=[- \n.,:;!?%s]))' + % re.escape(inline.closers)) + inline.non_whitespace_before = r'(? 0: + textnodes.append(nodes.Text(unescape( + remainder[:match.start(whole)]))) + if match.group(email): + addscheme = 'mailto:' + else: + addscheme = '' + text = match.group(whole) + unescaped = unescape(text, 0) + textnodes.append( + nodes.reference(unescape(text, 1), unescaped, + refuri=addscheme + unescaped)) + remainder = remainder[match.end(whole):] + start = 0 + else: # not a valid scheme + start = match.end(whole) + else: + if remainder: + textnodes.append(nodes.Text(unescape(remainder))) + break + return textnodes + + inline.dispatch = {'*': emphasis, + '**': strong, + '`': interpreted_or_phrase_ref, + '``': literal, + '_`': inline_target, + ']_': footnote_reference, + '|': substitution_reference, + '_': reference, + '__': anonymous_reference} + + def inline_text(self, text, lineno): + """ + Return 2 lists: nodes (text and inline elements), and system_messages. + + Using a `pattern` matching start-strings (for emphasis, strong, + interpreted, phrase reference, literal, substitution reference, and + inline target) or complete constructs (simple reference, footnote + reference) we search for a candidate. When one is found, we check for + validity (e.g., not a quoted '*' character). If valid, search for the + corresponding end string if applicable, and check for validity. If not + found or invalid, generate a warning and ignore the start-string. + Standalone hyperlinks are found last. + """ + pattern = self.inline.patterns.initial + dispatch = self.inline.dispatch + start = self.inline.groups.initial.start - 1 + backquote = self.inline.groups.initial.backquote - 1 + refend = self.inline.groups.initial.refend - 1 + fnend = self.inline.groups.initial.fnend - 1 + remaining = escape2null(text) + processed = [] + unprocessed = [] + messages = [] + while remaining: + match = pattern.search(remaining) + if match: + groups = match.groups() + before, inlines, remaining, sysmessages = \ + dispatch[groups[start] or groups[backquote] + or groups[refend] + or groups[fnend]](self, match, lineno) + unprocessed.append(before) + messages += sysmessages + if inlines: + processed += self.standalone_uri(''.join(unprocessed), + lineno) + processed += inlines + unprocessed = [] + else: + break + remaining = ''.join(unprocessed) + remaining + if remaining: + processed += self.standalone_uri(remaining, lineno) + return processed, messages + + def unindentwarning(self): + return self.statemachine.memo.reporter.warning( + ('Unindent without blank line at line %s.' + % (self.statemachine.abslineno() + 1))) + + +class Body(RSTState): + + """ + Generic classifier of the first line of a block. + """ + + enum = Stuff() + """Enumerated list parsing information.""" + + enum.formatinfo = { + 'parens': Stuff(prefix='(', suffix=')', start=1, end=-1), + 'rparen': Stuff(prefix='', suffix=')', start=0, end=-1), + 'period': Stuff(prefix='', suffix='.', start=0, end=-1)} + enum.formats = enum.formatinfo.keys() + enum.sequences = ['arabic', 'loweralpha', 'upperalpha', + 'lowerroman', 'upperroman'] # ORDERED! + enum.sequencepats = {'arabic': '[0-9]+', + 'loweralpha': '[a-z]', + 'upperalpha': '[A-Z]', + 'lowerroman': '[ivxlcdm]+', + 'upperroman': '[IVXLCDM]+',} + enum.converters = {'arabic': int, + 'loweralpha': + lambda s, zero=(ord('a')-1): ord(s) - zero, + 'upperalpha': + lambda s, zero=(ord('A')-1): ord(s) - zero, + 'lowerroman': + lambda s: roman.fromRoman(s.upper()), + 'upperroman': roman.fromRoman} + + enum.sequenceregexps = {} + for sequence in enum.sequences: + enum.sequenceregexps[sequence] = re.compile(enum.sequencepats[sequence] + + '$') + + tabletoppat = re.compile(r'\+-[-+]+-\+ *$') + """Matches the top (& bottom) of a table).""" + + tableparser = TableParser() + + pats = {} + """Fragments of patterns used by transitions.""" + + pats['nonalphanum7bit'] = '[!-/:-@[-`{-~]' + pats['alpha'] = '[a-zA-Z]' + pats['alphanum'] = '[a-zA-Z0-9]' + pats['alphanumplus'] = '[a-zA-Z0-9_-]' + pats['enum'] = ('(%(arabic)s|%(loweralpha)s|%(upperalpha)s|%(lowerroman)s' + '|%(upperroman)s)' % enum.sequencepats) + pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats + pats['optarg'] = '%(alpha)s%(alphanumplus)s*' % pats + pats['option'] = r'(--?|\+|/)%(optname)s([ =]%(optarg)s)?' % pats + + for format in enum.formats: + pats[format] = '(?P<%s>%s%s%s)' % ( + format, re.escape(enum.formatinfo[format].prefix), + pats['enum'], re.escape(enum.formatinfo[format].suffix)) + + patterns = {'bullet': r'[-+*]( +|$)', + 'enumerator': r'(%(parens)s|%(rparen)s|%(period)s)( +|$)' + % pats, + 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', + 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, + 'doctest': r'>>>( +|$)', + 'tabletop': tabletoppat, + 'explicit_markup': r'\.\.( +|$)', + 'anonymous': r'__( +|$)', + 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, + #'rfc822': r'[!-9;-~]+:( +|$)', + 'text': r''} + initialtransitions = ['bullet', + 'enumerator', + 'field_marker', + 'option_marker', + 'doctest', + 'tabletop', + 'explicit_markup', + 'anonymous', + 'line', + 'text'] + + def indent(self, match, context, nextstate): + """Block quote.""" + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getindented() + blockquote = self.block_quote(indented, lineoffset) + self.statemachine.node += blockquote + if not blankfinish: + self.statemachine.node += self.unindentwarning() + return context, nextstate, [] + + def block_quote(self, indented, lineoffset): + blockquote = nodes.block_quote() + self.nestedparse(indented, lineoffset, blockquote) + return blockquote + + def bullet(self, match, context, nextstate): + """Bullet list item.""" + bulletlist = nodes.bullet_list() + self.statemachine.node += bulletlist + bulletlist['bullet'] = match.string[0] + i, blankfinish = self.list_item(match.end()) + bulletlist += i + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=bulletlist, initialstate='BulletList', + blankfinish=blankfinish) + if not blankfinish: + self.statemachine.node += self.unindentwarning() + self.gotoline(newlineoffset) + return [], nextstate, [] + + def list_item(self, indent): + indented, lineoffset, blankfinish = \ + self.statemachine.getknownindented(indent) + listitem = nodes.list_item('\n'.join(indented)) + if indented: + self.nestedparse(indented, inputoffset=lineoffset, node=listitem) + return listitem, blankfinish + + def enumerator(self, match, context, nextstate): + """Enumerated List Item""" + format, sequence, text, ordinal = self.parse_enumerator(match) + if ordinal is None: + msg = self.statemachine.memo.reporter.error( + ('Enumerated list start value invalid at line %s: ' + '%r (sequence %r)' % (self.statemachine.abslineno(), + text, sequence))) + self.statemachine.node += msg + indented, lineoffset, blankfinish = \ + self.statemachine.getknownindented(match.end()) + bq = self.block_quote(indented, lineoffset) + self.statemachine.node += bq + if not blankfinish: + self.statemachine.node += self.unindentwarning() + return [], nextstate, [] + if ordinal != 1: + msg = self.statemachine.memo.reporter.info( + ('Enumerated list start value not ordinal-1 at line %s: ' + '%r (ordinal %s)' % (self.statemachine.abslineno(), + text, ordinal))) + self.statemachine.node += msg + enumlist = nodes.enumerated_list() + self.statemachine.node += enumlist + enumlist['enumtype'] = sequence + if ordinal != 1: + enumlist['start'] = ordinal + enumlist['prefix'] = self.enum.formatinfo[format].prefix + enumlist['suffix'] = self.enum.formatinfo[format].suffix + listitem, blankfinish = self.list_item(match.end()) + enumlist += listitem + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=enumlist, initialstate='EnumeratedList', + blankfinish=blankfinish, + extrasettings={'lastordinal': ordinal, 'format': format}) + if not blankfinish: + self.statemachine.node += self.unindentwarning() + self.gotoline(newlineoffset) + return [], nextstate, [] + + def parse_enumerator(self, match, expectedsequence=None): + """ + Analyze an enumerator and return the results. + + :Return: + - the enumerator format ('period', 'parens', or 'rparen'), + - the sequence used ('arabic', 'loweralpha', 'upperroman', etc.), + - the text of the enumerator, stripped of formatting, and + - the ordinal value of the enumerator ('a' -> 1, 'ii' -> 2, etc.; + ``None`` is returned for invalid enumerator text). + + The enumerator format has already been determined by the regular + expression match. If `expectedsequence` is given, that sequence is + tried first. If not, we check for Roman numeral 1. This way, + single-character Roman numerals (which are also alphabetical) can be + matched. If no sequence has been matched, all sequences are checked in + order. + """ + groupdict = match.groupdict() + sequence = '' + for format in self.enum.formats: + if groupdict[format]: # was this the format matched? + break # yes; keep `format` + else: # shouldn't happen + raise ParserError, 'enumerator format not matched' + text = groupdict[format][self.enum.formatinfo[format].start + :self.enum.formatinfo[format].end] + if expectedsequence: + try: + if self.enum.sequenceregexps[expectedsequence].match(text): + sequence = expectedsequence + except KeyError: # shouldn't happen + raise ParserError, 'unknown sequence: %s' % sequence + else: + if text == 'i': + sequence = 'lowerroman' + elif text == 'I': + sequence = 'upperroman' + if not sequence: + for sequence in self.enum.sequences: + if self.enum.sequenceregexps[sequence].match(text): + break + else: # shouldn't happen + raise ParserError, 'enumerator sequence not matched' + try: + ordinal = self.enum.converters[sequence](text) + except roman.InvalidRomanNumeralError: + ordinal = None + return format, sequence, text, ordinal + + def field_marker(self, match, context, nextstate): + """Field list item.""" + fieldlist = nodes.field_list() + self.statemachine.node += fieldlist + field, blankfinish = self.field(match) + fieldlist += field + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=fieldlist, initialstate='FieldList', + blankfinish=blankfinish) + if not blankfinish: + self.statemachine.node += self.unindentwarning() + self.gotoline(newlineoffset) + return [], nextstate, [] + + def field(self, match): + name, args = self.parse_field_marker(match) + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + fieldnode = nodes.field() + fieldnode += nodes.field_name(name, name) + for arg in args: + fieldnode += nodes.field_argument(arg, arg) + fieldbody = nodes.field_body('\n'.join(indented)) + fieldnode += fieldbody + if indented: + self.nestedparse(indented, inputoffset=lineoffset, node=fieldbody) + return fieldnode, blankfinish + + def parse_field_marker(self, match): + """Extract & return name & argument list from a field marker match.""" + field = match.string[1:] # strip off leading ':' + field = field[:field.find(':')] # strip off trailing ':' etc. + tokens = field.split() + return tokens[0], tokens[1:] # first == name, others == args + + def option_marker(self, match, context, nextstate): + """Option list item.""" + optionlist = nodes.option_list() + try: + listitem, blankfinish = self.option_list_item(match) + except MarkupError, detail: # shouldn't happen; won't match pattern + msg = self.statemachine.memo.reporter.error( + ('Invalid option list marker at line %s: %s' + % (self.statemachine.abslineno(), detail))) + self.statemachine.node += msg + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + blockquote = self.block_quote(indented, lineoffset) + self.statemachine.node += blockquote + if not blankfinish: + self.statemachine.node += self.unindentwarning() + return [], nextstate, [] + self.statemachine.node += optionlist + optionlist += listitem + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=optionlist, initialstate='OptionList', + blankfinish=blankfinish) + if not blankfinish: + self.statemachine.node += self.unindentwarning() + self.gotoline(newlineoffset) + return [], nextstate, [] + + def option_list_item(self, match): + options = self.parse_option_marker(match) + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + if not indented: # not an option list item + raise statemachine.TransitionCorrection('text') + option_group = nodes.option_group('', *options) + description = nodes.description('\n'.join(indented)) + option_list_item = nodes.option_list_item('', option_group, description) + if indented: + self.nestedparse(indented, inputoffset=lineoffset, node=description) + return option_list_item, blankfinish + + def parse_option_marker(self, match): + """ + Return a list of `node.option` and `node.option_argument` objects, + parsed from an option marker match. + + :Exception: `MarkupError` for invalid option markers. + """ + optlist = [] + optionstrings = match.group().rstrip().split(', ') + for optionstring in optionstrings: + tokens = optionstring.split() + delimiter = ' ' + firstopt = tokens[0].split('=') + if len(firstopt) > 1: + tokens[:1] = firstopt + delimiter = '=' + if 0 < len(tokens) <= 2: + option = nodes.option(optionstring) + option += nodes.option_string(tokens[0], tokens[0]) + if len(tokens) > 1: + option += nodes.option_argument(tokens[1], tokens[1], + delimiter=delimiter) + optlist.append(option) + else: + raise MarkupError('wrong numer of option tokens (=%s), ' + 'should be 1 or 2: %r' % (len(tokens), + optionstring)) + return optlist + + def doctest(self, match, context, nextstate): + data = '\n'.join(self.statemachine.gettextblock()) + self.statemachine.node += nodes.doctest_block(data, data) + return [], nextstate, [] + + def tabletop(self, match, context, nextstate): + """Top border of a table.""" + nodelist, blankfinish = self.table() + self.statemachine.node += nodelist + if not blankfinish: + msg = self.statemachine.memo.reporter.warning( + 'Blank line required after table at line %s.' + % (self.statemachine.abslineno() + 1)) + self.statemachine.node += msg + return [], nextstate, [] + + def table(self): + """Parse a table.""" + block, messages, blankfinish = self.isolatetable() + if block: + try: + tabledata = self.tableparser.parse(block) + tableline = self.statemachine.abslineno() - len(block) + 1 + table = self.buildtable(tabledata, tableline) + nodelist = [table] + messages + except TableMarkupError, detail: + nodelist = self.malformedtable(block, str(detail)) + messages + else: + nodelist = messages + return nodelist, blankfinish + + def isolatetable(self): + messages = [] + blankfinish = 1 + try: + block = self.statemachine.getunindented() + except statemachine.UnexpectedIndentationError, instance: + block, lineno = instance.args + messages.append(self.statemachine.memo.reporter.error( + 'Unexpected indentation at line %s.' % lineno)) + blankfinish = 0 + width = len(block[0].strip()) + for i in range(len(block)): + block[i] = block[i].strip() + if block[i][0] not in '+|': # check left edge + blankfinish = 0 + self.statemachine.previousline(len(block) - i) + del block[i:] + break + if not self.tabletoppat.match(block[-1]): # find bottom + blankfinish = 0 + # from second-last to third line of table: + for i in range(len(block) - 2, 1, -1): + if self.tabletoppat.match(block[i]): + self.statemachine.previousline(len(block) - i + 1) + del block[i+1:] + break + else: + messages.extend(self.malformedtable(block)) + return [], messages, blankfinish + for i in range(len(block)): # check right edge + if len(block[i]) != width or block[i][-1] not in '+|': + messages.extend(self.malformedtable(block)) + return [], messages, blankfinish + return block, messages, blankfinish + + def malformedtable(self, block, detail=''): + data = '\n'.join(block) + message = 'Malformed table at line %s; formatting as a ' \ + 'literal block.' % (self.statemachine.abslineno() + - len(block) + 1) + if detail: + message += '\n' + detail + nodelist = [self.statemachine.memo.reporter.error(message), + nodes.literal_block(data, data)] + return nodelist + + def buildtable(self, tabledata, tableline): + colspecs, headrows, bodyrows = tabledata + table = nodes.table() + tgroup = nodes.tgroup(cols=len(colspecs)) + table += tgroup + for colspec in colspecs: + tgroup += nodes.colspec(colwidth=colspec) + if headrows: + thead = nodes.thead() + tgroup += thead + for row in headrows: + thead += self.buildtablerow(row, tableline) + tbody = nodes.tbody() + tgroup += tbody + for row in bodyrows: + tbody += self.buildtablerow(row, tableline) + return table + + def buildtablerow(self, rowdata, tableline): + row = nodes.row() + for cell in rowdata: + if cell is None: + continue + morerows, morecols, offset, cellblock = cell + attributes = {} + if morerows: + attributes['morerows'] = morerows + if morecols: + attributes['morecols'] = morecols + entry = nodes.entry(**attributes) + row += entry + if ''.join(cellblock): + self.nestedparse(cellblock, inputoffset=tableline+offset, + node=entry) + return row + + + explicit = Stuff() + """Patterns and constants used for explicit markup recognition.""" + + explicit.patterns = Stuff( + target=re.compile(r""" + (?: + _ # anonymous target + | # *OR* + (`?) # optional open quote + (?![ `]) # first char. not space or backquote + ( # reference name + .+? + ) + %s # not whitespace or escape + \1 # close quote if open quote used + ) + %s # not whitespace or escape + : # end of reference name + (?:[ ]+|$) # followed by whitespace + """ + % (RSTState.inline.non_whitespace_escape_before, + RSTState.inline.non_whitespace_escape_before), + re.VERBOSE), + reference=re.compile(r""" + (?: + (%s)_ # simple reference name + | # *OR* + ` # open backquote + (?![ ]) # not space + (.+?) # hyperlink phrase + %s # not whitespace or escape + `_ # close backquote & reference mark + ) + $ # end of string + """ % + (RSTState.inline.simplename, + RSTState.inline.non_whitespace_escape_before,), + re.VERBOSE), + substitution=re.compile(r""" + (?: + (?![ ]) # first char. not space + (.+?) # substitution text + %s # not whitespace or escape + \| # close delimiter + ) + (?:[ ]+|$) # followed by whitespace + """ % + RSTState.inline.non_whitespace_escape_before, + re.VERBOSE),) + explicit.groups = Stuff( + target=Stuff(quote=1, name=2), + reference=Stuff(simple=1, phrase=2), + substitution=Stuff(name=1)) + + def footnote(self, match): + indented, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + label = match.group(1) + name = normname(label) + footnote = nodes.footnote('\n'.join(indented)) + if name[0] == '#': # auto-numbered + name = name[1:] # autonumber label + footnote['auto'] = 1 + if name: + footnote['name'] = name + self.statemachine.memo.document.note_autofootnote(footnote) + elif name == '*': # auto-symbol + name = '' + footnote['auto'] = '*' + self.statemachine.memo.document.note_symbol_footnote(footnote) + else: # manually numbered + footnote += nodes.label('', label) + footnote['name'] = name + self.statemachine.memo.document.note_footnote(footnote) + if name: + self.statemachine.memo.document.note_explicit_target(footnote, + footnote) + if indented: + self.nestedparse(indented, inputoffset=offset, node=footnote) + return [footnote], blankfinish + + def citation(self, match): + indented, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + label = match.group(1) + name = normname(label) + citation = nodes.citation('\n'.join(indented)) + citation += nodes.label('', label) + citation['name'] = name + self.statemachine.memo.document.note_citation(citation) + self.statemachine.memo.document.note_explicit_target(citation, citation) + if indented: + self.nestedparse(indented, inputoffset=offset, node=citation) + return [citation], blankfinish + + def hyperlink_target(self, match): + pattern = self.explicit.patterns.target + namegroup = self.explicit.groups.target.name + lineno = self.statemachine.abslineno() + block, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end(), uptoblank=1, + stripindent=0) + blocktext = match.string[:match.end()] + '\n'.join(block) + block = [escape2null(line) for line in block] + escaped = block[0] + blockindex = 0 + while 1: + targetmatch = pattern.match(escaped) + if targetmatch: + break + blockindex += 1 + try: + escaped += block[blockindex] + except (IndexError, MarkupError): + raise MarkupError('malformed hyperlink target at line %s.' + % lineno) + del block[:blockindex] + block[0] = (block[0] + ' ')[targetmatch.end()-len(escaped)-1:].strip() + if block and block[-1].strip()[-1:] == '_': # possible indirect target + reference = ' '.join([line.strip() for line in block]) + refname = self.isreference(reference) + if refname: + target = nodes.target(blocktext, '', refname=refname) + self.addtarget(targetmatch.group(namegroup), '', target) + self.statemachine.memo.document.note_indirect_target(target) + return [target], blankfinish + nodelist = [] + reference = ''.join([line.strip() for line in block]) + if reference.find(' ') != -1: + warning = self.statemachine.memo.reporter.warning( + 'Hyperlink target at line %s contains whitespace. ' + 'Perhaps a footnote was intended?' + % (self.statemachine.abslineno() - len(block) + 1), '', + nodes.literal_block(blocktext, blocktext)) + nodelist.append(warning) + else: + unescaped = unescape(reference) + target = nodes.target(blocktext, '') + self.addtarget(targetmatch.group(namegroup), unescaped, target) + nodelist.append(target) + return nodelist, blankfinish + + def isreference(self, reference): + match = self.explicit.patterns.reference.match(normname(reference)) + if not match: + return None + return unescape(match.group(self.explicit.groups.reference.simple) + or match.group(self.explicit.groups.reference.phrase)) + + def addtarget(self, targetname, refuri, target): + if targetname: + name = normname(unescape(targetname)) + target['name'] = name + if refuri: + target['refuri'] = refuri + self.statemachine.memo.document.note_external_target(target) + else: + self.statemachine.memo.document.note_internal_target(target) + self.statemachine.memo.document.note_explicit_target( + target, self.statemachine.node) + else: # anonymous target + if refuri: + target['refuri'] = refuri + target['anonymous'] = 1 + self.statemachine.memo.document.note_anonymous_target(target) + + def substitutiondef(self, match): + pattern = self.explicit.patterns.substitution + lineno = self.statemachine.abslineno() + block, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end(), + stripindent=0) + blocktext = (match.string[:match.end()] + '\n'.join(block)) + block = [escape2null(line) for line in block] + escaped = block[0].rstrip() + blockindex = 0 + while 1: + subdefmatch = pattern.match(escaped) + if subdefmatch: + break + blockindex += 1 + try: + escaped = escaped + ' ' + block[blockindex].strip() + except (IndexError, MarkupError): + raise MarkupError('malformed substitution definition ' + 'at line %s.' % lineno) + del block[:blockindex] # strip out the substitution marker + block[0] = (block[0] + ' ')[subdefmatch.end()-len(escaped)-1:].strip() + if not block[0]: + del block[0] + offset += 1 + subname = subdefmatch.group(self.explicit.groups.substitution.name) + name = normname(subname) + substitutionnode = nodes.substitution_definition( + blocktext, name=name, alt=subname) + if block: + block[0] = block[0].strip() + newabsoffset, blankfinish = self.nestedlistparse( + block, inputoffset=offset, node=substitutionnode, + initialstate='SubstitutionDef', blankfinish=blankfinish) + self.statemachine.previousline( + len(block) + offset - newabsoffset - 1) + i = 0 + for node in substitutionnode[:]: + if not (isinstance(node, nodes.Inline) or + isinstance(node, nodes.Text)): + self.statemachine.node += substitutionnode[i] + del substitutionnode[i] + else: + i += 1 + if len(substitutionnode) == 0: + msg = self.statemachine.memo.reporter.warning( + 'Substitution definition "%s" empty or invalid at line ' + '%s.' % (subname, self.statemachine.abslineno()), '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + else: + del substitutionnode['alt'] + self.statemachine.memo.document.note_substitution_def( + substitutionnode, self.statemachine.node) + return [substitutionnode], blankfinish + else: + msg = self.statemachine.memo.reporter.warning( + 'Substitution definition "%s" missing contents at line %s.' + % (subname, self.statemachine.abslineno()), '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + return [], blankfinish + + def directive(self, match, **attributes): + typename = match.group(1) + directivefunction = directives.directive( + typename, self.statemachine.memo.language) + data = match.string[match.end():].strip() + if directivefunction: + return directivefunction(match, typename, data, self, + self.statemachine, attributes) + else: + return self.unknowndirective(typename, data) + + def unknowndirective(self, typename, data): + lineno = self.statemachine.abslineno() + indented, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(0, stripindent=0) + text = '\n'.join(indented) + error = self.statemachine.memo.reporter.error( + 'Unknown directive type "%s" at line %s.' % (typename, lineno), + '', nodes.literal_block(text, text)) + return [error], blankfinish + + def parse_extension_attributes(self, attribute_spec, datalines, blankfinish): + """ + Parse `datalines` for a field list containing extension attributes + matching `attribute_spec`. + + :Parameters: + - `attribute_spec`: a mapping of attribute name to conversion + function, which should raise an exception on bad input. + - `datalines`: a list of input strings. + - `blankfinish`: + + :Return: + - Success value, 1 or 0. + - An attribute dictionary on success, an error string on failure. + - Updated `blankfinish` flag. + """ + node = nodes.field_list() + newlineoffset, blankfinish = self.nestedlistparse( + datalines, 0, node, initialstate='FieldList', + blankfinish=blankfinish) + if newlineoffset != len(datalines): # incomplete parse of block + return 0, 'invalid attribute block', blankfinish + try: + attributes = utils.extract_extension_attributes(node, attribute_spec) + except KeyError, detail: + return 0, ('unknown attribute: "%s"' % detail), blankfinish + except (ValueError, TypeError), detail: + return 0, ('invalid attribute value:\n%s' % detail), blankfinish + except utils.ExtensionAttributeError, detail: + return 0, ('invalid attribute data: %s' % detail), blankfinish + return 1, attributes, blankfinish + + def comment(self, match): + if not match.string[match.end():].strip() \ + and self.statemachine.nextlineblank(): # an empty comment? + return [nodes.comment()], 1 # "A tiny but practical wart." + indented, indent, offset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + text = '\n'.join(indented) + return [nodes.comment(text, text)], blankfinish + + explicit.constructs = [ + (footnote, + re.compile(r""" + \.\.[ ]+ # explicit markup start + \[ + ( # footnote label: + [0-9]+ # manually numbered footnote + | # *OR* + \# # anonymous auto-numbered footnote + | # *OR* + \#%s # auto-number ed?) footnote label + | # *OR* + \* # auto-symbol footnote + ) + \] + (?:[ ]+|$) # whitespace or end of line + """ % RSTState.inline.simplename, re.VERBOSE)), + (citation, + re.compile(r""" + \.\.[ ]+ # explicit markup start + \[(%s)\] # citation label + (?:[ ]+|$) # whitespace or end of line + """ % RSTState.inline.simplename, re.VERBOSE)), + (hyperlink_target, + re.compile(r""" + \.\.[ ]+ # explicit markup start + _ # target indicator + (?![ ]) # first char. not space + """, re.VERBOSE)), + (substitutiondef, + re.compile(r""" + \.\.[ ]+ # explicit markup start + \| # substitution indicator + (?![ ]) # first char. not space + """, re.VERBOSE)), + (directive, + re.compile(r""" + \.\.[ ]+ # explicit markup start + (%s) # directive name + :: # directive delimiter + (?:[ ]+|$) # whitespace or end of line + """ % RSTState.inline.simplename, re.VERBOSE))] + + def explicit_markup(self, match, context, nextstate): + """Footnotes, hyperlink targets, directives, comments.""" + nodelist, blankfinish = self.explicit_construct(match) + self.statemachine.node += nodelist + self.explicitlist(blankfinish) + return [], nextstate, [] + + def explicit_construct(self, match): + """Determine which explicit construct this is, parse & return it.""" + errors = [] + for method, pattern in self.explicit.constructs: + expmatch = pattern.match(match.string) + if expmatch: + try: + return method(self, expmatch) + except MarkupError, detail: # never reached? + errors.append( + self.statemachine.memo.reporter.warning('%s: %s' + % (detail.__class__.__name__, detail))) + break + nodelist, blankfinish = self.comment(match) + return nodelist + errors, blankfinish + + def explicitlist(self, blankfinish): + """ + Create a nested state machine for a series of explicit markup constructs + (including anonymous hyperlink targets). + """ + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=self.statemachine.node, initialstate='Explicit', + blankfinish=blankfinish) + self.gotoline(newlineoffset) + if not blankfinish: + self.statemachine.node += self.unindentwarning() + + def anonymous(self, match, context, nextstate): + """Anonymous hyperlink targets.""" + nodelist, blankfinish = self.anonymous_target(match) + self.statemachine.node += nodelist + self.explicitlist(blankfinish) + return [], nextstate, [] + + def anonymous_target(self, match): + block, indent, offset, blankfinish \ + = self.statemachine.getfirstknownindented(match.end(), + uptoblank=1) + blocktext = match.string[:match.end()] + '\n'.join(block) + if block and block[-1].strip()[-1:] == '_': # possible indirect target + reference = escape2null(' '.join([line.strip() for line in block])) + refname = self.isreference(reference) + if refname: + target = nodes.target(blocktext, '', refname=refname, + anonymous=1) + self.statemachine.memo.document.note_anonymous_target(target) + self.statemachine.memo.document.note_indirect_target(target) + return [target], blankfinish + nodelist = [] + reference = escape2null(''.join([line.strip() for line in block])) + if reference.find(' ') != -1: + warning = self.statemachine.memo.reporter.warning( + 'Anonymous hyperlink target at line %s contains whitespace. ' + 'Perhaps a footnote was intended?' + % (self.statemachine.abslineno() - len(block) + 1), '', + nodes.literal_block(blocktext, blocktext)) + nodelist.append(warning) + else: + target = nodes.target(blocktext, '', anonymous=1) + if reference: + unescaped = unescape(reference) + target['refuri'] = unescaped + self.statemachine.memo.document.note_anonymous_target(target) + nodelist.append(target) + return nodelist, blankfinish + + def line(self, match, context, nextstate): + """Section title overline or transition marker.""" + if self.statemachine.matchtitles: + return [match.string], 'Line', [] + else: + blocktext = self.statemachine.line + msg = self.statemachine.memo.reporter.severe( + 'Unexpected section title or transition at line %s.' + % self.statemachine.abslineno(), '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + return [], nextstate, [] + + def text(self, match, context, nextstate): + """Titles, definition lists, paragraphs.""" + return [match.string], 'Text', [] + + +class SpecializedBody(Body): + + """ + Superclass for second and subsequent compound element members. + + All transition methods are disabled. Override individual methods in + subclasses to re-enable. + """ + + def invalid_input(self, match=None, context=None, nextstate=None): + """Not a compound element member. Abort this state machine.""" + self.statemachine.previousline() # back up so parent SM can reassess + raise EOFError + + indent = invalid_input + bullet = invalid_input + enumerator = invalid_input + field_marker = invalid_input + option_marker = invalid_input + doctest = invalid_input + tabletop = invalid_input + explicit_markup = invalid_input + anonymous = invalid_input + line = invalid_input + text = invalid_input + + +class BulletList(SpecializedBody): + + """Second and subsequent bullet_list list_items.""" + + def bullet(self, match, context, nextstate): + """Bullet list item.""" + if match.string[0] != self.statemachine.node['bullet']: + # different bullet: new list + self.invalid_input() + listitem, blankfinish = self.list_item(match.end()) + self.statemachine.node += listitem + self.blankfinish = blankfinish + return [], 'BulletList', [] + + +class DefinitionList(SpecializedBody): + + """Second and subsequent definition_list_items.""" + + def text(self, match, context, nextstate): + """Definition lists.""" + return [match.string], 'Definition', [] + + +class EnumeratedList(SpecializedBody): + + """Second and subsequent enumerated_list list_items.""" + + def enumerator(self, match, context, nextstate): + """Enumerated list item.""" + format, sequence, text, ordinal = self.parse_enumerator( + match, self.statemachine.node['enumtype']) + if (sequence != self.statemachine.node['enumtype'] or + format != self.format or + ordinal != self.lastordinal + 1): + # different enumeration: new list + self.invalid_input() + listitem, blankfinish = self.list_item(match.end()) + self.statemachine.node += listitem + self.blankfinish = blankfinish + self.lastordinal = ordinal + return [], 'EnumeratedList', [] + + +class FieldList(SpecializedBody): + + """Second and subsequent field_list fields.""" + + def field_marker(self, match, context, nextstate): + """Field list field.""" + field, blankfinish = self.field(match) + self.statemachine.node += field + self.blankfinish = blankfinish + return [], 'FieldList', [] + + +class OptionList(SpecializedBody): + + """Second and subsequent option_list option_list_items.""" + + def option_marker(self, match, context, nextstate): + """Option list item.""" + try: + option_list_item, blankfinish = self.option_list_item(match) + except MarkupError, detail: + self.invalid_input() + self.statemachine.node += option_list_item + self.blankfinish = blankfinish + return [], 'OptionList', [] + + +class RFC822List(SpecializedBody): + + """Second and subsequent RFC822 field_list fields.""" + + pass + + +class Explicit(SpecializedBody): + + """Second and subsequent explicit markup construct.""" + + def explicit_markup(self, match, context, nextstate): + """Footnotes, hyperlink targets, directives, comments.""" + nodelist, blankfinish = self.explicit_construct(match) + self.statemachine.node += nodelist + self.blankfinish = blankfinish + return [], nextstate, [] + + def anonymous(self, match, context, nextstate): + """Anonymous hyperlink targets.""" + nodelist, blankfinish = self.anonymous_target(match) + self.statemachine.node += nodelist + self.blankfinish = blankfinish + return [], nextstate, [] + + +class SubstitutionDef(Body): + + """ + Parser for the contents of a substitution_definition element. + """ + + patterns = { + 'embedded_directive': r'(%s)::( +|$)' % RSTState.inline.simplename, + 'text': r''} + initialtransitions = ['embedded_directive', 'text'] + + def embedded_directive(self, match, context, nextstate): + if self.statemachine.node.has_key('alt'): + attributes = {'alt': self.statemachine.node['alt']} + else: + attributes = {} + nodelist, blankfinish = self.directive(match, **attributes) + self.statemachine.node += nodelist + if not self.statemachine.ateof(): + self.blankfinish = blankfinish + raise EOFError + + def text(self, match, context, nextstate): + if not self.statemachine.ateof(): + self.blankfinish = self.statemachine.nextlineblank() + raise EOFError + + +class Text(RSTState): + + """ + Classifier of second line of a text block. + + Could be a paragraph, a definition list item, or a title. + """ + + patterns = {'underline': Body.patterns['line'], + 'text': r''} + initialtransitions = [('underline', 'Body'), ('text', 'Body')] + + def blank(self, match, context, nextstate): + """End of paragraph.""" + paragraph, literalnext = self.paragraph( + context, self.statemachine.abslineno() - 1) + self.statemachine.node += paragraph + if literalnext: + self.statemachine.node += self.literal_block() + return [], 'Body', [] + + def eof(self, context): + if context: + paragraph, literalnext = self.paragraph( + context, self.statemachine.abslineno() - 1) + self.statemachine.node += paragraph + if literalnext: + self.statemachine.node += self.literal_block() + return [] + + def indent(self, match, context, nextstate): + """Definition list item.""" + definitionlist = nodes.definition_list() + definitionlistitem, blankfinish = self.definition_list_item(context) + definitionlist += definitionlistitem + self.statemachine.node += definitionlist + offset = self.statemachine.lineoffset + 1 # next line + newlineoffset, blankfinish = self.nestedlistparse( + self.statemachine.inputlines[offset:], + inputoffset=self.statemachine.abslineoffset() + 1, + node=definitionlist, initialstate='DefinitionList', + blankfinish=blankfinish, blankfinishstate='Definition') + if not blankfinish: + self.statemachine.node += self.unindentwarning() + self.gotoline(newlineoffset) + return [], 'Body', [] + + def underline(self, match, context, nextstate): + """Section title.""" + lineno = self.statemachine.abslineno() + if not self.statemachine.matchtitles: + blocktext = context[0] + '\n' + self.statemachine.line + msg = self.statemachine.memo.reporter.severe( + 'Unexpected section title at line %s.' % lineno, '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + return [], nextstate, [] + title = context[0].rstrip() + underline = match.string.rstrip() + source = title + '\n' + underline + if len(title) > len(underline): + blocktext = context[0] + '\n' + self.statemachine.line + msg = self.statemachine.memo.reporter.info( + 'Title underline too short at line %s.' % lineno, '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + style = underline[0] + context[:] = [] + self.section(title, source, style, lineno - 1) + return [], nextstate, [] + + def text(self, match, context, nextstate): + """Paragraph.""" + startline = self.statemachine.abslineno() - 1 + msg = None + try: + block = self.statemachine.getunindented() + except statemachine.UnexpectedIndentationError, instance: + block, lineno = instance.args + msg = self.statemachine.memo.reporter.error( + 'Unexpected indentation at line %s.' % lineno) + lines = context + block + paragraph, literalnext = self.paragraph(lines, startline) + self.statemachine.node += paragraph + self.statemachine.node += msg + if literalnext: + try: + self.statemachine.nextline() + except IndexError: + pass + self.statemachine.node += self.literal_block() + return [], nextstate, [] + + def literal_block(self): + """Return a list of nodes.""" + indented, indent, offset, blankfinish = \ + self.statemachine.getindented() + nodelist = [] + while indented and not indented[-1].strip(): + indented.pop() + if indented: + data = '\n'.join(indented) + nodelist.append(nodes.literal_block(data, data)) + if not blankfinish: + nodelist.append(self.unindentwarning()) + else: + nodelist.append(self.statemachine.memo.reporter.warning( + 'Literal block expected at line %s; none found.' + % self.statemachine.abslineno())) + return nodelist + + def definition_list_item(self, termline): + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getindented() + definitionlistitem = nodes.definition_list_item('\n'.join(termline + + indented)) + termlist, messages = self.term(termline, + self.statemachine.abslineno() - 1) + definitionlistitem += termlist + definition = nodes.definition('', *messages) + definitionlistitem += definition + if termline[0][-2:] == '::': + definition += self.statemachine.memo.reporter.info( + 'Blank line missing before literal block? Interpreted as a ' + 'definition list item. At line %s.' % (lineoffset + 1)) + self.nestedparse(indented, inputoffset=lineoffset, node=definition) + return definitionlistitem, blankfinish + + def term(self, lines, lineno): + """Return a definition_list's term and optional classifier.""" + assert len(lines) == 1 + nodelist = [] + parts = lines[0].split(' : ', 1) # split into 1 or 2 parts + termpart = parts[0].rstrip() + textnodes, messages = self.inline_text(termpart, lineno) + nodelist = [nodes.term(termpart, '', *textnodes)] + if len(parts) == 2: + classifierpart = parts[1].lstrip() + textnodes, cpmessages = self.inline_text(classifierpart, lineno) + nodelist.append(nodes.classifier(classifierpart, '', *textnodes)) + messages += cpmessages + return nodelist, messages + + +class SpecializedText(Text): + + """ + Superclass for second and subsequent lines of Text-variants. + + All transition methods are disabled. Override individual methods in + subclasses to re-enable. + """ + + def eof(self, context): + """Incomplete construct.""" + return [] + + def invalid_input(self, match=None, context=None, nextstate=None): + """Not a compound element member. Abort this state machine.""" + raise EOFError + + blank = invalid_input + indent = invalid_input + underline = invalid_input + text = invalid_input + + +class Definition(SpecializedText): + + """Second line of potential definition_list_item.""" + + def eof(self, context): + """Not a definition.""" + self.statemachine.previousline(2) # back up so parent SM can reassess + return [] + + def indent(self, match, context, nextstate): + """Definition list item.""" + definitionlistitem, blankfinish = self.definition_list_item(context) + self.statemachine.node += definitionlistitem + self.blankfinish = blankfinish + return [], 'DefinitionList', [] + + +class Line(SpecializedText): + + """Second line of over- & underlined section title or transition marker.""" + + eofcheck = 1 # @@@ ??? + """Set to 0 while parsing sections, so that we don't catch the EOF.""" + + def eof(self, context): + """Transition marker at end of section or document.""" + if self.eofcheck: # ignore EOFError with sections + transition = nodes.transition(context[0]) + self.statemachine.node += transition + msg = self.statemachine.memo.reporter.error( + 'Document or section may not end with a transition ' + '(line %s).' % (self.statemachine.abslineno() - 1)) + self.statemachine.node += msg + self.eofcheck = 1 + return [] + + def blank(self, match, context, nextstate): + """Transition marker.""" + transition = nodes.transition(context[0]) + if len(self.statemachine.node) == 0: + msg = self.statemachine.memo.reporter.error( + 'Document or section may not begin with a transition ' + '(line %s).' % (self.statemachine.abslineno() - 1)) + self.statemachine.node += msg + elif isinstance(self.statemachine.node[-1], nodes.transition): + msg = self.statemachine.memo.reporter.error( + 'At least one body element must separate transitions; ' + 'adjacent transitions at line %s.' + % (self.statemachine.abslineno() - 1)) + self.statemachine.node += msg + self.statemachine.node += transition + return [], 'Body', [] + + def text(self, match, context, nextstate): + """Potential over- & underlined title.""" + lineno = self.statemachine.abslineno() - 1 + overline = context[0] + title = match.string + underline = '' + try: + underline = self.statemachine.nextline() + except IndexError: + blocktext = overline + '\n' + title + msg = self.statemachine.memo.reporter.severe( + 'Incomplete section title at line %s.' % lineno, '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + return [], 'Body', [] + source = '%s\n%s\n%s' % (overline, title, underline) + overline = overline.rstrip() + underline = underline.rstrip() + if not self.transitions['underline'][0].match(underline): + msg = self.statemachine.memo.reporter.severe( + 'Missing underline for overline at line %s.' % lineno, '', + nodes.literal_block(source, source)) + self.statemachine.node += msg + return [], 'Body', [] + elif overline != underline: + msg = self.statemachine.memo.reporter.severe( + 'Title overline & underline mismatch at ' 'line %s.' % lineno, + '', nodes.literal_block(source, source)) + self.statemachine.node += msg + return [], 'Body', [] + title = title.rstrip() + if len(title) > len(overline): + msg = self.statemachine.memo.reporter.info( + 'Title overline too short at line %s.'% lineno, '', + nodes.literal_block(source, source)) + self.statemachine.node += msg + style = (overline[0], underline[0]) + self.eofcheck = 0 # @@@ not sure this is correct + self.section(title.lstrip(), source, style, lineno + 1) + self.eofcheck = 1 + return [], 'Body', [] + + indent = text # indented title + + def underline(self, match=None, context=None, nextstate=None): + blocktext = context[0] + '\n' + self.statemachine.line + msg = self.statemachine.memo.reporter.error( + 'Invalid section title or transition marker at line %s.' + % (self.statemachine.abslineno() - 1), '', + nodes.literal_block(blocktext, blocktext)) + self.statemachine.node += msg + return [], 'Body', [] + + +stateclasses = [Body, BulletList, DefinitionList, EnumeratedList, FieldList, + OptionList, RFC822List, Explicit, Text, Definition, Line, + SubstitutionDef] +"""Standard set of State classes used to start `RSTStateMachine`.""" + + +def escape2null(text): + """Return a string with escape-backslashes converted to nulls.""" + parts = [] + start = 0 + while 1: + found = text.find('\\', start) + if found == -1: + parts.append(text[start:]) + return ''.join(parts) + parts.append(text[start:found]) + parts.append('\x00' + text[found+1:found+2]) + start = found + 2 # skip character after escape + +def unescape(text, restorebackslashes=0): + """Return a string with nulls removed or restored to backslashes.""" + if restorebackslashes: + return text.translate(RSTState.inline.null2backslash) + else: + return text.translate(RSTState.inline.identity, '\x00') diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py new file mode 100644 index 000000000..7bacf99cd --- /dev/null +++ b/docutils/parsers/rst/tableparser.py @@ -0,0 +1,313 @@ +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This module defines the `TableParser` class, which parses a plaintext-graphic +table and produces a well-formed data structure suitable for building a CALS +table. + +:Exception class: `TableMarkupError` + +:Function: + `update_dictoflists()`: Merge two dictionaries containing list values. +""" + +__docformat__ = 'reStructuredText' + + +import re + + +class TableMarkupError(Exception): pass + + +class TableParser: + + """ + Parse a plaintext graphic table using `parse()`. + + Here's an example of a plaintext graphic table:: + + +------------------------+------------+----------+----------+ + | Header row, column 1 | Header 2 | Header 3 | Header 4 | + +========================+============+==========+==========+ + | body row 1, column 1 | column 2 | column 3 | column 4 | + +------------------------+------------+----------+----------+ + | body row 2 | Cells may span columns. | + +------------------------+------------+---------------------+ + | body row 3 | Cells may | - Table cells | + +------------------------+ span rows. | - contain | + | body row 4 | | - body elements. | + +------------------------+------------+---------------------+ + + Intersections use '+', row separators use '-' (except for one optional + head/body row separator, which uses '='), and column separators use '|'. + + Passing the above table to the `parse()` method will result in the + following data structure:: + + ([24, 12, 10, 10], + [[(0, 0, 1, ['Header row, column 1']), + (0, 0, 1, ['Header 2']), + (0, 0, 1, ['Header 3']), + (0, 0, 1, ['Header 4'])]], + [[(0, 0, 3, ['body row 1, column 1']), + (0, 0, 3, ['column 2']), + (0, 0, 3, ['column 3']), + (0, 0, 3, ['column 4'])], + [(0, 0, 5, ['body row 2']), + (0, 2, 5, ['Cells may span columns.']), + None, + None], + [(0, 0, 7, ['body row 3']), + (1, 0, 7, ['Cells may', 'span rows.', '']), + (1, 1, 7, ['- Table cells', '- contain', '- body elements.']), + None], + [(0, 0, 9, ['body row 4']), None, None, None]]) + + The first item is a list containing column widths (colspecs). The second + item is a list of head rows, and the third is a list of body rows. Each + row contains a list of cells. Each cell is either None (for a cell unused + because of another cell's span), or a tuple. A cell tuple contains four + items: the number of extra rows used by the cell in a vertical span + (morerows); the number of extra columns used by the cell in a horizontal + span (morecols); the line offset of the first line of the cell contents; + and the cell contents, a list of lines of text. + """ + + headbodyseparatorpat = re.compile(r'\+=[=+]+=\+$') + """Matches the row separator between head rows and body rows.""" + + def parse(self, block): + """ + Analyze the text `block` and return a table data structure. + + Given a plaintext-graphic table in `block` (list of lines of text; no + whitespace padding), parse the table, construct and return the data + necessary to construct a CALS table or equivalent. + + Raise `TableMarkupError` if there is any problem with the markup. + """ + self.setup(block) + self.findheadbodysep() + self.parsegrid() + structure = self.structurefromcells() + return structure + + def setup(self, block): + self.block = block[:] # make a copy; it may be modified + self.bottom = len(block) - 1 + self.right = len(block[0]) - 1 + self.headbodysep = None + self.done = [-1] * len(block[0]) + self.cells = [] + self.rowseps = {0: [0]} + self.colseps = {0: [0]} + + def findheadbodysep(self): + """Look for a head/body row separator line; store the line index.""" + for i in range(len(self.block)): + line = self.block[i] + if self.headbodyseparatorpat.match(line): + if self.headbodysep: + raise TableMarkupError, ( + 'Multiple head/body row separators in table (at line ' + 'offset %s and %s); only one allowed.' + % (self.headbodysep, i)) + else: + self.headbodysep = i + self.block[i] = line.replace('=', '-') + if self.headbodysep == 0 or self.headbodysep == len(self.block) - 1: + raise TableMarkupError, ( + 'The head/body row separator may not be the first or last ' + 'line of the table.' % (self.headbodysep, i)) + + def parsegrid(self): + """ + Start with a queue of upper-left corners, containing the upper-left + corner of the table itself. Trace out one rectangular cell, remember + it, and add its upper-right and lower-left corners to the queue of + potential upper-left corners of further cells. Process the queue in + top-to-bottom order, keeping track of how much of each text column has + been seen. + + We'll end up knowing all the row and column boundaries, cell positions + and their dimensions. + """ + corners = [(0, 0)] + while corners: + top, left = corners.pop(0) + if top == self.bottom or left == self.right \ + or top <= self.done[left]: + continue + result = self.scancell(top, left) + if not result: + continue + bottom, right, rowseps, colseps = result + update_dictoflists(self.rowseps, rowseps) + update_dictoflists(self.colseps, colseps) + self.markdone(top, left, bottom, right) + cellblock = self.getcellblock(top, left, bottom, right) + self.cells.append((top, left, bottom, right, cellblock)) + corners.extend([(top, right), (bottom, left)]) + corners.sort() + if not self.checkparsecomplete(): + raise TableMarkupError, 'Malformed table; parse incomplete.' + + def markdone(self, top, left, bottom, right): + """For keeping track of how much of each text column has been seen.""" + before = top - 1 + after = bottom - 1 + for col in range(left, right): + assert self.done[col] == before + self.done[col] = after + + def checkparsecomplete(self): + """Each text column should have been completely seen.""" + last = self.bottom - 1 + for col in range(self.right): + if self.done[col] != last: + return None + return 1 + + def getcellblock(self, top, left, bottom, right): + """Given the corners, extract the text of a cell.""" + cellblock = [] + margin = right + for lineno in range(top + 1, bottom): + line = self.block[lineno][left + 1 : right].rstrip() + cellblock.append(line) + if line: + margin = margin and min(margin, len(line) - len(line.lstrip())) + if 0 < margin < right: + cellblock = [line[margin:] for line in cellblock] + return cellblock + + def scancell(self, top, left): + """Starting at the top-left corner, start tracing out a cell.""" + assert self.block[top][left] == '+' + result = self.scanright(top, left) + return result + + def scanright(self, top, left): + """ + Look for the top-right corner of the cell, and make note of all column + boundaries ('+'). + """ + colseps = {} + line = self.block[top] + for i in range(left + 1, self.right + 1): + if line[i] == '+': + colseps[i] = [top] + result = self.scandown(top, left, i) + if result: + bottom, rowseps, newcolseps = result + update_dictoflists(colseps, newcolseps) + return bottom, i, rowseps, colseps + elif line[i] != '-': + return None + return None + + def scandown(self, top, left, right): + """ + Look for the bottom-right corner of the cell, making note of all row + boundaries. + """ + rowseps = {} + for i in range(top + 1, self.bottom + 1): + if self.block[i][right] == '+': + rowseps[i] = [right] + result = self.scanleft(top, left, i, right) + if result: + newrowseps, colseps = result + update_dictoflists(rowseps, newrowseps) + return i, rowseps, colseps + elif self.block[i][right] != '|': + return None + return None + + def scanleft(self, top, left, bottom, right): + """ + Noting column boundaries, look for the bottom-left corner of the cell. + It must line up with the starting point. + """ + colseps = {} + line = self.block[bottom] + for i in range(right - 1, left, -1): + if line[i] == '+': + colseps[i] = [bottom] + elif line[i] != '-': + return None + if line[left] != '+': + return None + result = self.scanup(top, left, bottom, right) + if result is not None: + rowseps = result + return rowseps, colseps + return None + + def scanup(self, top, left, bottom, right): + """Noting row boundaries, see if we can return to the starting point.""" + rowseps = {} + for i in range(bottom - 1, top, -1): + if self.block[i][left] == '+': + rowseps[i] = [left] + elif self.block[i][left] != '|': + return None + return rowseps + + def structurefromcells(self): + """ + From the data colledted by `scancell()`, convert to the final data + structure. + """ + rowseps = self.rowseps.keys() # list of row boundaries + rowseps.sort() + rowindex = {} + for i in range(len(rowseps)): + rowindex[rowseps[i]] = i # row boundary -> row number mapping + colseps = self.colseps.keys() # list of column boundaries + colseps.sort() + colindex = {} + for i in range(len(colseps)): + colindex[colseps[i]] = i # column boundary -> col number mapping + colspecs = [(colseps[i] - colseps[i - 1] - 1) + for i in range(1, len(colseps))] # list of column widths + # prepare an empty table with the correct number of rows & columns + onerow = [None for i in range(len(colseps) - 1)] + rows = [onerow[:] for i in range(len(rowseps) - 1)] + # keep track of # of cells remaining; should reduce to zero + remaining = (len(rowseps) - 1) * (len(colseps) - 1) + for top, left, bottom, right, block in self.cells: + rownum = rowindex[top] + colnum = colindex[left] + assert rows[rownum][colnum] is None, ( + 'Cell (row %s, column %s) already used.' + % (rownum + 1, colnum + 1)) + morerows = rowindex[bottom] - rownum - 1 + morecols = colindex[right] - colnum - 1 + remaining -= (morerows + 1) * (morecols + 1) + # write the cell into the table + rows[rownum][colnum] = (morerows, morecols, top + 1, block) + assert remaining == 0, 'Unused cells remaining.' + if self.headbodysep: # separate head rows from body rows + numheadrows = rowindex[self.headbodysep] + headrows = rows[:numheadrows] + bodyrows = rows[numheadrows:] + else: + headrows = [] + bodyrows = rows + return (colspecs, headrows, bodyrows) + + +def update_dictoflists(master, newdata): + """ + Extend the list values of `master` with those from `newdata`. + + Both parameters must be dictionaries containing list values. + """ + for key, values in newdata.items(): + master.setdefault(key, []).extend(values) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py new file mode 100644 index 000000000..9b8d38654 --- /dev/null +++ b/docutils/readers/__init__.py @@ -0,0 +1,118 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger; Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This package contains Docutils Reader modules. +""" + +__docformat__ = 'reStructuredText' + + +import sys +from docutils import nodes, utils +from docutils.transforms import universal + + +class Reader: + + """ + Abstract base class for docutils Readers. + + Each reader module or package must export a subclass also called 'Reader'. + + The three steps of a Reader's responsibility are defined: `scan()`, + `parse()`, and `transform()`. Call `read()` to process a document. + """ + + transforms = () + """Ordered tuple of transform classes (each with a ``transform()`` method). + Populated by subclasses. `Reader.transform()` instantiates & runs them.""" + + def __init__(self, reporter, languagecode): + """ + Initialize the Reader instance. + + Several instance attributes are defined with dummy initial values. + Subclasses may use these attributes as they wish. + """ + + self.languagecode = languagecode + """Default language for new documents.""" + + self.reporter = reporter + """A `utils.Reporter` instance shared by all doctrees.""" + + self.source = None + """Path to the source of raw input.""" + + self.input = None + """Raw text input; either a single string or, for more complex cases, + a collection of strings.""" + + self.transforms = tuple(self.transforms) + """Instance copy of `Reader.transforms`; may be modified by client.""" + + def read(self, source, parser): + self.source = source + self.parser = parser + self.scan() # may modify self.parser, depending on input + self.parse() + self.transform() + return self.document + + def scan(self): + """Override to read `self.input` from `self.source`.""" + raise NotImplementedError('subclass must override this method') + + def scanfile(self, source): + """ + Scan a single file and return the raw data. + + Parameter `source` may be: + + (a) a file-like object, which is read directly; + (b) a path to a file, which is opened and then read; or + (c) `None`, which implies `sys.stdin`. + """ + if hasattr(source, 'read'): + return source.read() + if self.source: + return open(source).read() + return sys.stdin.read() + + def parse(self): + """Parse `self.input` into a document tree.""" + self.document = self.newdocument() + self.parser.parse(self.input, self.document) + + def transform(self): + """Run all of the transforms defined for this Reader.""" + for xclass in (universal.first_reader_transforms + + tuple(self.transforms) + + universal.last_reader_transforms): + xclass(self.document).transform() + + def newdocument(self, languagecode=None): + """Create and return a new empty document tree (root node).""" + document = nodes.document( + languagecode=(languagecode or self.languagecode), + reporter=self.reporter) + document['source'] = self.source + return document + + +_reader_aliases = {'rtxt': 'standalone', + 'restructuredtext': 'standalone'} + +def get_reader_class(readername): + """Return the Reader class from the `readername` module.""" + readername = readername.lower() + if _reader_aliases.has_key(readername): + readername = _reader_aliases[readername] + module = __import__(readername, globals(), locals()) + return module.Reader diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py new file mode 100644 index 000000000..27c0ded6b --- /dev/null +++ b/docutils/readers/standalone.py @@ -0,0 +1,34 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Standalone file Reader for the reStructuredText markup syntax. +""" + +__docformat__ = 'reStructuredText' + + +import sys +from docutils import readers +from docutils.transforms import frontmatter, references +from docutils.parsers.rst import Parser + + +class Reader(readers.Reader): + + document = None + """A single document tree.""" + + transforms = (references.Substitutions, + frontmatter.DocTitle, + frontmatter.DocInfo, + references.Footnotes, + references.Hyperlinks,) + + def scan(self): + self.input = self.scanfile(self.source) diff --git a/docutils/roman.py b/docutils/roman.py new file mode 100644 index 000000000..5972c3cef --- /dev/null +++ b/docutils/roman.py @@ -0,0 +1,81 @@ +"""Convert to and from Roman numerals""" + +__author__ = "Mark Pilgrim (f8dy@diveintopython.org)" +__version__ = "1.4" +__date__ = "8 August 2001" +__copyright__ = """Copyright (c) 2001 Mark Pilgrim + +This program is part of "Dive Into Python", a free Python tutorial for +experienced programmers. Visit http://diveintopython.org/ for the +latest version. + +This program is free software; you can redistribute it and/or modify +it under the terms of the Python 2.1.1 license, available at +http://www.python.org/2.1.1/license.html +""" + +import re + +#Define exceptions +class RomanError(Exception): pass +class OutOfRangeError(RomanError): pass +class NotIntegerError(RomanError): pass +class InvalidRomanNumeralError(RomanError): pass + +#Define digit mapping +romanNumeralMap = (('M', 1000), + ('CM', 900), + ('D', 500), + ('CD', 400), + ('C', 100), + ('XC', 90), + ('L', 50), + ('XL', 40), + ('X', 10), + ('IX', 9), + ('V', 5), + ('IV', 4), + ('I', 1)) + +def toRoman(n): + """convert integer to Roman numeral""" + if not (0 < n < 5000): + raise OutOfRangeError, "number out of range (must be 1..4999)" + if int(n) <> n: + raise NotIntegerError, "decimals can not be converted" + + result = "" + for numeral, integer in romanNumeralMap: + while n >= integer: + result += numeral + n -= integer + return result + +#Define pattern to detect valid Roman numerals +romanNumeralPattern = re.compile(''' + ^ # beginning of string + M{0,4} # thousands - 0 to 4 M's + (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), + # or 500-800 (D, followed by 0 to 3 C's) + (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), + # or 50-80 (L, followed by 0 to 3 X's) + (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), + # or 5-8 (V, followed by 0 to 3 I's) + $ # end of string + ''' ,re.VERBOSE) + +def fromRoman(s): + """convert Roman numeral to integer""" + if not s: + raise InvalidRomanNumeralError, 'Input can not be blank' + if not romanNumeralPattern.search(s): + raise InvalidRomanNumeralError, 'Invalid Roman numeral: %s' % s + + result = 0 + index = 0 + for numeral, integer in romanNumeralMap: + while s[index:index+len(numeral)] == numeral: + result += integer + index += len(numeral) + return result + diff --git a/docutils/statemachine.py b/docutils/statemachine.py new file mode 100644 index 000000000..9410cb956 --- /dev/null +++ b/docutils/statemachine.py @@ -0,0 +1,1076 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Version: 1.3 +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +A finite state machine specialized for regular-expression-based text filters, +this module defines the following classes: + +- `StateMachine`, a state machine +- `State`, a state superclass +- `StateMachineWS`, a whitespace-sensitive version of `StateMachine` +- `StateWS`, a state superclass for use with `StateMachineWS` +- `SearchStateMachine`, uses `re.search()` instead of `re.match()` +- `SearchStateMachineWS`, uses `re.search()` instead of `re.match()` + +Exception classes: + +- `UnknownStateError` +- `DuplicateStateError` +- `UnknownTransitionError` +- `DuplicateTransitionError` +- `TransitionPatternNotFound` +- `TransitionMethodNotFound` +- `UnexpectedIndentationError` +- `TransitionCorrection`: Raised to switch to another transition. + +Functions: + +- `string2lines()`: split a multi-line string into a list of one-line strings +- `extractindented()`: return indented lines with minimum indentation removed + +How To Use This Module +====================== +(See the individual classes, methods, and attributes for details.) + +1. Import it: ``import statemachine`` or ``from statemachine import ...``. + You will also need to ``import re``. + +2. Derive a subclass of `State` (or `StateWS`) for each state in your state + machine:: + + class MyState(statemachine.State): + + Within the state's class definition: + + a) Include a pattern for each transition, in `State.patterns`:: + + patterns = {'atransition': r'pattern', ...} + + b) Include a list of initial transitions to be set up automatically, in + `State.initialtransitions`:: + + initialtransitions = ['atransition', ...] + + c) Define a method for each transition, with the same name as the + transition pattern:: + + def atransition(self, match, context, nextstate): + # do something + result = [...] # a list + return context, nextstate, result + # context, nextstate may be altered + + Transition methods may raise an `EOFError` to cut processing short. + + d) You may wish to override the `State.bof()` and/or `State.eof()` implicit + transition methods, which handle the beginning- and end-of-file. + + e) In order to handle nested processing, you may wish to override the + attributes `State.nestedSM` and/or `State.nestedSMkwargs`. + + If you are using `StateWS` as a base class, in order to handle nested + indented blocks, you may wish to: + + - override the attributes `StateWS.indentSM`, `StateWS.indentSMkwargs`, + `StateWS.knownindentSM`, and/or `StateWS.knownindentSMkwargs`; + - override the `StateWS.blank()` method; and/or + - override or extend the `StateWS.indent()`, `StateWS.knownindent()`, + and/or `StateWS.firstknownindent()` methods. + +3. Create a state machine object:: + + sm = StateMachine(stateclasses=[MyState, ...], initialstate='MyState') + +4. Obtain the input text, which needs to be converted into a tab-free list of + one-line strings. For example, to read text from a file called + 'inputfile':: + + inputstring = open('inputfile').read() + inputlines = statemachine.string2lines(inputstring) + +6. Run the state machine on the input text and collect the results, a list:: + + results = sm.run(inputlines) + +7. Remove any lingering circular references:: + + sm.unlink() +""" + +__docformat__ = 'restructuredtext' + +import sys, re, string + + +class StateMachine: + + """ + A finite state machine for text filters using regular expressions. + + The input is provided in the form of a list of one-line strings (no + newlines). States are subclasses of the `State` class. Transitions consist + of regular expression patterns and transition methods, and are defined in + each state. + + The state machine is started with the `run()` method, which returns the + results of processing in a list. + """ + + def __init__(self, stateclasses, initialstate, debug=0): + """ + Initialize a `StateMachine` object; add state objects. + + Parameters: + + - `stateclasses`: a list of `State` (sub)classes. + - `initialstate`: a string, the class name of the initial state. + - `debug`: a boolean; produce verbose output if true (nonzero). + """ + + self.inputlines = None + """List of strings (without newlines). Filled by `self.run()`.""" + + self.inputoffset = 0 + """Offset of `self.inputlines` from the beginning of the file.""" + + self.line = None + """Current input line.""" + + self.lineoffset = None + """Current input line offset from beginning of `self.inputlines`.""" + + self.debug = debug + """Debugging mode on/off.""" + + self.initialstate = initialstate + """The name of the initial state (key to `self.states`).""" + + self.currentstate = initialstate + """The name of the current state (key to `self.states`).""" + + self.states = {} + """Mapping of {state_name: State_object}.""" + + self.addstates(stateclasses) + + def unlink(self): + """Remove circular references to objects no longer required.""" + for state in self.states.values(): + state.unlink() + self.states = None + + def run(self, inputlines, inputoffset=0): + """ + Run the state machine on `inputlines`. Return results (a list). + + Reset `self.lineoffset` and `self.currentstate`. Run the + beginning-of-file transition. Input one line at a time and check for a + matching transition. If a match is found, call the transition method + and possibly change the state. Store the context returned by the + transition method to be passed on to the next transition matched. + Accumulate the results returned by the transition methods in a list. + Run the end-of-file transition. Finally, return the accumulated + results. + + Parameters: + + - `inputlines`: a list of strings without newlines. + - `inputoffset`: the line offset of `inputlines` from the beginning of + the file. + """ + self.inputlines = inputlines + self.inputoffset = inputoffset + self.lineoffset = -1 + self.currentstate = self.initialstate + if self.debug: + print >>sys.stderr, ('\nStateMachine.run: inputlines:\n| %s' % + '\n| '.join(self.inputlines)) + context = None + results = [] + state = self.getstate() + try: + if self.debug: + print >>sys.stderr, ('\nStateMachine.run: bof transition') + context, result = state.bof(context) + results.extend(result) + while 1: + try: + self.nextline() + if self.debug: + print >>sys.stderr, ('\nStateMachine.run: line:\n| %s' + % self.line) + except IndexError: + break + try: + context, nextstate, result = self.checkline(context, state) + except EOFError: + break + state = self.getstate(nextstate) + results.extend(result) + if self.debug: + print >>sys.stderr, ('\nStateMachine.run: eof transition') + result = state.eof(context) + results.extend(result) + except: + self.error() + raise + return results + + def getstate(self, nextstate=None): + """ + Return current state object; set it first if `nextstate` given. + + Parameter `nextstate`: a string, the name of the next state. + + Exception: `UnknownStateError` raised if `nextstate` unknown. + """ + if nextstate: + if self.debug and nextstate != self.currentstate: + print >>sys.stderr, \ + ('\nStateMachine.getstate: Changing state from ' + '"%s" to "%s" (input line %s).' + % (self.currentstate, nextstate, self.abslineno())) + self.currentstate = nextstate + try: + return self.states[self.currentstate] + except KeyError: + raise UnknownStateError(self.currentstate) + + def nextline(self, n=1): + """Load `self.line` with the `n`'th next line and return it.""" + self.lineoffset += n + self.line = self.inputlines[self.lineoffset] + return self.line + + def nextlineblank(self): + """Return 1 if the next line is blank or non-existant.""" + try: + return not self.inputlines[self.lineoffset + 1].strip() + except IndexError: + return 1 + + def ateof(self): + """Return 1 if the input is at or past end-of-file.""" + return self.lineoffset >= len(self.inputlines) - 1 + + def atbof(self): + """Return 1 if the input is at or before beginning-of-file.""" + return self.lineoffset <= 0 + + def previousline(self, n=1): + """Load `self.line` with the `n`'th previous line and return it.""" + self.lineoffset -= n + self.line = self.inputlines[self.lineoffset] + return self.line + + def gotoline(self, lineoffset): + """Jump to absolute line offset `lineoffset`, load and return it.""" + self.lineoffset = lineoffset - self.inputoffset + self.line = self.inputlines[self.lineoffset] + return self.line + + def abslineoffset(self): + """Return line offset of current line, from beginning of file.""" + return self.lineoffset + self.inputoffset + + def abslineno(self): + """Return line number of current line (counting from 1).""" + return self.lineoffset + self.inputoffset + 1 + + def gettextblock(self): + """Return a contiguous block of text.""" + block = [] + for line in self.inputlines[self.lineoffset:]: + if not line.strip(): + break + block.append(line) + self.nextline(len(block) - 1) # advance to last line of block + return block + + def getunindented(self): + """ + Return a contiguous, flush-left block of text. + + Raise `UnexpectedIndentationError` if an indented line is encountered + before the text block ends (with a blank line). + """ + block = [self.line] + for line in self.inputlines[self.lineoffset + 1:]: + if not line.strip(): + break + if line[0] == ' ': + self.nextline(len(block) - 1) # advance to last line of block + raise UnexpectedIndentationError(block, self.abslineno() + 1) + block.append(line) + self.nextline(len(block) - 1) # advance to last line of block + return block + + def checkline(self, context, state): + """ + Examine one line of input for a transition match. + + Parameters: + + - `context`: application-dependent storage. + - `state`: a `State` object, the current state. + + Return the values returned by the transition method: + + - context: possibly modified from the parameter `context`; + - next state name (`State` subclass name), or ``None`` if no match; + - the result output of the transition, a list. + """ + if self.debug: + print >>sys.stdout, ('\nStateMachine.checkline: ' + 'context "%s", state "%s"' % + (context, state.__class__.__name__)) + context, nextstate, result = self.matchtransition(context, state) + return context, nextstate, result + + def matchtransition(self, context, state): + """ + Try to match the current line to a transition & execute its method. + + Parameters: + + - `context`: application-dependent storage. + - `state`: a `State` object, the current state. + + Return the values returned by the transition method: + + - context: possibly modified from the parameter `context`, unchanged + if no match; + - next state name (`State` subclass name), or ``None`` if no match; + - the result output of the transition, a list (empty if no match). + """ + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.matchtransition: state="%s", transitions=%r.' + % (state.__class__.__name__, state.transitionorder)) + for name in state.transitionorder: + while 1: + pattern, method, nextstate = state.transitions[name] + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.matchtransition: Trying transition ' + '"%s" in state "%s".' + % (name, state.__class__.__name__)) + match = self.match(pattern) + if match: + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.matchtransition: Matched ' + 'transition "%s" in state "%s".' + % (name, state.__class__.__name__)) + try: + return method(match, context, nextstate) + except TransitionCorrection, detail: + name = str(detail) + continue # try again with new transition name + break + else: + return context, None, [] # no match + + def match(self, pattern): + """ + Return the result of a regular expression match. + + Parameter `pattern`: an `re` compiled regular expression. + """ + return pattern.match(self.line) + + def addstate(self, stateclass): + """ + Initialize & add a `stateclass` (`State` subclass) object. + + Exception: `DuplicateStateError` raised if `stateclass` already added. + """ + statename = stateclass.__name__ + if self.states.has_key(statename): + raise DuplicateStateError(statename) + self.states[statename] = stateclass(self, self.debug) + + def addstates(self, stateclasses): + """ + Add `stateclasses` (a list of `State` subclasses). + """ + for stateclass in stateclasses: + self.addstate(stateclass) + + def error(self): + """Report error details.""" + type, value, module, line, function = _exceptiondata() + print >>sys.stderr, '%s: %s' % (type, value) + print >>sys.stderr, 'input line %s' % (self.abslineno()) + print >>sys.stderr, ('module %s, line %s, function %s' + % (module, line, function)) + + +class State: + + """ + State superclass. Contains a list of transitions, and transition methods. + + Transition methods all have the same signature. They take 3 parameters: + + - An `re` match object. ``match.string`` contains the matched input line, + ``match.start()`` gives the start index of the match, and + ``match.end()`` gives the end index. + - A context object, whose meaning is application-defined (initial value + ``None``). It can be used to store any information required by the state + machine, and the retured context is passed on to the next transition + method unchanged. + - The name of the next state, a string, taken from the transitions list; + normally it is returned unchanged, but it may be altered by the + transition method if necessary. + + Transition methods all return a 3-tuple: + + - A context object, as (potentially) modified by the transition method. + - The next state name (a return value of ``None`` means no state change). + - The processing result, a list, which is accumulated by the state + machine. + + Transition methods may raise an `EOFError` to cut processing short. + + There are two implicit transitions, and corresponding transition methods + are defined: `bof()` handles the beginning-of-file, and `eof()` handles + the end-of-file. These methods have non-standard signatures and return + values. `bof()` returns the initial context and results, and may be used + to return a header string, or do any other processing needed. `eof()` + should handle any remaining context and wrap things up; it returns the + final processing result. + + Typical applications need only subclass `State` (or a subclass), set the + `patterns` and `initialtransitions` class attributes, and provide + corresponding transition methods. The default object initialization will + take care of constructing the list of transitions. + """ + + patterns = None + """ + {Name: pattern} mapping, used by `maketransition()`. Each pattern may + be a string or a compiled `re` pattern. Override in subclasses. + """ + + initialtransitions = None + """ + A list of transitions to initialize when a `State` is instantiated. + Each entry is either a transition name string, or a (transition name, next + state name) pair. See `maketransitions()`. Override in subclasses. + """ + + nestedSM = None + """ + The `StateMachine` class for handling nested processing. + + If left as ``None``, `nestedSM` defaults to the class of the state's + controlling state machine. Override it in subclasses to avoid the default. + """ + + nestedSMkwargs = None + """ + Keyword arguments dictionary, passed to the `nestedSM` constructor. + + Two keys must have entries in the dictionary: + + - Key 'stateclasses' must be set to a list of `State` classes. + - Key 'initialstate' must be set to the name of the initial state class. + + If `nestedSMkwargs` is left as ``None``, 'stateclasses' defaults to the + class of the current state, and 'initialstate' defaults to the name of the + class of the current state. Override in subclasses to avoid the defaults. + """ + + def __init__(self, statemachine, debug=0): + """ + Initialize a `State` object; make & add initial transitions. + + Parameters: + + - `statemachine`: the controlling `StateMachine` object. + - `debug`: a boolean; produce verbose output if true (nonzero). + """ + + self.transitionorder = [] + """A list of transition names in search order.""" + + self.transitions = {} + """ + A mapping of transition names to 3-tuples containing + (compiled_pattern, transition_method, next_state_name). Initialized as + an instance attribute dynamically (instead of as a class attribute) + because it may make forward references to patterns and methods in this + or other classes. + """ + + if self.initialtransitions: + names, transitions = self.maketransitions(self.initialtransitions) + self.addtransitions(names, transitions) + + self.statemachine = statemachine + """A reference to the controlling `StateMachine` object.""" + + self.debug = debug + """Debugging mode on/off.""" + + if self.nestedSM is None: + self.nestedSM = self.statemachine.__class__ + if self.nestedSMkwargs is None: + self.nestedSMkwargs = {'stateclasses': [self.__class__], + 'initialstate': self.__class__.__name__} + + def unlink(self): + """Remove circular references to objects no longer required.""" + self.statemachine = None + + def addtransitions(self, names, transitions): + """ + Add a list of transitions to the start of the transition list. + + Parameters: + + - `names`: a list of transition names. + - `transitions`: a mapping of names to transition tuples. + + Exceptions: `DuplicateTransitionError`, `UnknownTransitionError`. + """ + for name in names: + if self.transitions.has_key(name): + raise DuplicateTransitionError(name) + if not transitions.has_key(name): + raise UnknownTransitionError(name) + self.transitionorder[:0] = names + self.transitions.update(transitions) + + def addtransition(self, name, transition): + """ + Add a transition to the start of the transition list. + + Parameter `transition`: a ready-made transition 3-tuple. + + Exception: `DuplicateTransitionError`. + """ + if self.transitions.has_key(name): + raise DuplicateTransitionError(name) + self.transitionorder[:0] = [name] + self.transitions[name] = transition + + def removetransition(self, name): + """ + Remove a transition by `name`. + + Exception: `UnknownTransitionError`. + """ + try: + del self.transitions[name] + self.transitionorder.remove(name) + except: + raise UnknownTransitionError(name) + + def maketransition(self, name, nextstate=None): + """ + Make & return a transition tuple based on `name`. + + This is a convenience function to simplify transition creation. + + Parameters: + + - `name`: a string, the name of the transition pattern & method. This + `State` object must have a method called '`name`', and a dictionary + `self.patterns` containing a key '`name`'. + - `nextstate`: a string, the name of the next `State` object for this + transition. A value of ``None`` (or absent) implies no state change + (i.e., continue with the same state). + + Exceptions: `TransitionPatternNotFound`, `TransitionMethodNotFound`. + """ + if nextstate is None: + nextstate = self.__class__.__name__ + try: + pattern = self.patterns[name] + if not hasattr(pattern, 'match'): + pattern = re.compile(pattern) + except KeyError: + raise TransitionPatternNotFound( + '%s.patterns[%r]' % (self.__class__.__name__, name)) + try: + method = getattr(self, name) + except AttributeError: + raise TransitionMethodNotFound( + '%s.%s' % (self.__class__.__name__, name)) + return (pattern, method, nextstate) + + def maketransitions(self, namelist): + """ + Return a list of transition names and a transition mapping. + + Parameter `namelist`: a list, where each entry is either a + transition name string, or a 1- or 2-tuple (transition name, optional + next state name). + """ + stringtype = type('') + names = [] + transitions = {} + for namestate in namelist: + if type(namestate) is stringtype: + transitions[namestate] = self.maketransition(namestate) + names.append(namestate) + else: + transitions[namestate[0]] = self.maketransition(*namestate) + names.append(namestate[0]) + return names, transitions + + def bof(self, context): + """ + Handle beginning-of-file. Return unchanged `context`, empty result. + + Override in subclasses. + + Parameter `context`: application-defined storage. + """ + return context, [] + + def eof(self, context): + """ + Handle end-of-file. Return empty result. + + Override in subclasses. + + Parameter `context`: application-defined storage. + """ + return [] + + def nop(self, match, context, nextstate): + """ + A "do nothing" transition method. + + Return unchanged `context` & `nextstate`, empty result. Useful for + simple state changes (actionless transitions). + """ + return context, nextstate, [] + + +class StateMachineWS(StateMachine): + + """ + `StateMachine` subclass specialized for whitespace recognition. + + The transitions 'blank' (for blank lines) and 'indent' (for indented text + blocks) are defined implicitly, and are checked before any other + transitions. The companion `StateWS` class defines default transition + methods. There are three methods provided for extracting indented text + blocks: + + - `getindented()`: use when the indent is unknown. + - `getknownindented()`: use when the indent is known for all lines. + - `getfirstknownindented()`: use when only the first line's indent is + known. + """ + + spaces = re.compile(' *') + """Indentation recognition pattern.""" + + def checkline(self, context, state): + """ + Examine one line of input for whitespace first, then transitions. + + Extends `StateMachine.checkline()`. + """ + if self.debug: + print >>sys.stdout, ('\nStateMachineWS.checkline: ' + 'context "%s", state "%s"' % + (context, state.__class__.__name__)) + context, nextstate, result = self.checkwhitespace(context, state) + if nextstate == '': # no whitespace match + return StateMachine.checkline(self, context, state) + else: + return context, nextstate, result + + def checkwhitespace(self, context, state): + """ + Check for a blank line or increased indent. Call the state's + transition method if a match is found. + + Parameters: + + - `context`: application-dependent storage. + - `state`: a `State` object, the current state. + + Return the values returned by the transition method: + + - context, possibly modified from the parameter `context`; + - next state name (`State` subclass name), or '' (empty string) if no + match; + - the result output of the transition, a list (empty if no match). + """ + if self.debug: + print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + 'context "%s", state "%s"' % + (context, state.__class__.__name__)) + match = self.spaces.match(self.line) + indent = match.end() + if indent == len(self.line): + if self.debug: + print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + 'implicit transition "blank" matched') + return state.blank(match, context, self.currentstate) + elif indent: + if self.debug: + print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + 'implicit transition "indent" matched') + return state.indent(match, context, self.currentstate) + else: + return context, '', [] # neither blank line nor indented + + def getindented(self, uptoblank=0, stripindent=1): + """ + Return a indented lines of text and info. + + Extract an indented block where the indent is unknown for all lines. + + :Parameters: + - `uptoblank`: Stop collecting at the first blank line if true (1). + - `stripindent`: Strip common leading indent if true (1, default). + + :Return: + - the indented block (a list of lines of text), + - its indent, + - its first line offset from BOF, and + - whether or not it finished with a blank line. + """ + offset = self.abslineoffset() + indented, indent, blankfinish = extractindented( + self.inputlines[self.lineoffset:], uptoblank, stripindent) + if indented: + self.nextline(len(indented) - 1) # advance to last indented line + while indented and not indented[0].strip(): + indented.pop(0) + offset += 1 + return indented, indent, offset, blankfinish + + def getknownindented(self, indent, uptoblank=0, stripindent=1): + """ + Return an indented block and info. + + Extract an indented block where the indent is known for all lines. + Starting with the current line, extract the entire text block with at + least `indent` indentation (which must be whitespace, except for the + first line). + + :Parameters: + - `indent`: The number of indent columns/characters. + - `uptoblank`: Stop collecting at the first blank line if true (1). + - `stripindent`: Strip `indent` characters of indentation if true + (1, default). + + :Return: + - the indented block, + - its first line offset from BOF, and + - whether or not it finished with a blank line. + """ + offset = self.abslineoffset() + indented = [self.line[indent:]] + for line in self.inputlines[self.lineoffset + 1:]: + if line[:indent].strip(): + blankfinish = not indented[-1].strip() and len(indented) > 1 + break + if uptoblank and line.strip(): + blankfinish = 1 + break + if stripindent: + indented.append(line[indent:]) + else: + indented.append(line) + else: + blankfinish = 1 + if indented: + self.nextline(len(indented) - 1) # advance to last indented line + while indented and not indented[0].strip(): + indented.pop(0) + offset += 1 + return indented, offset, blankfinish + + def getfirstknownindented(self, indent, uptoblank=0, stripindent=1): + """ + Return an indented block and info. + + Extract an indented block where the indent is known for the first line + and unknown for all other lines. + + :Parameters: + - `indent`: The first line's indent (# of columns/characters). + - `uptoblank`: Stop collecting at the first blank line if true (1). + - `stripindent`: Strip `indent` characters of indentation if true + (1, default). + + :Return: + - the indented block, + - its indent, + - its first line offset from BOF, and + - whether or not it finished with a blank line. + """ + offset = self.abslineoffset() + indented = [self.line[indent:]] + indented[1:], indent, blankfinish = extractindented( + self.inputlines[self.lineoffset + 1:], uptoblank, stripindent) + self.nextline(len(indented) - 1) # advance to last indented line + while indented and not indented[0].strip(): + indented.pop(0) + offset += 1 + return indented, indent, offset, blankfinish + + +class StateWS(State): + + """ + State superclass specialized for whitespace (blank lines & indents). + + Use this class with `StateMachineWS`. The transition method `blank()` + handles blank lines and `indent()` handles nested indented blocks. + Indented blocks trigger a new state machine to be created by `indent()` + and run. The class of the state machine to be created is in `indentSM`, + and the constructor keyword arguments are in the dictionary + `indentSMkwargs`. + + The methods `knownindent()` and `firstknownindent()` are provided for + indented blocks where the indent (all lines' and first line's only, + respectively) is known to the transition method, along with the attributes + `knownindentSM` and `knownindentSMkwargs`. Neither transition method is + triggered automatically. + """ + + indentSM = None + """ + The `StateMachine` class handling indented text blocks. + + If left as ``None``, `indentSM` defaults to the value of `State.nestedSM`. + Override it in subclasses to avoid the default. + """ + + indentSMkwargs = None + """ + Keyword arguments dictionary, passed to the `indentSM` constructor. + + If left as ``None``, `indentSMkwargs` defaults to the value of + `State.nestedSMkwargs`. Override it in subclasses to avoid the default. + """ + + knownindentSM = None + """ + The `StateMachine` class handling known-indented text blocks. + + If left as ``None``, `knownindentSM` defaults to the value of `indentSM`. + Override it in subclasses to avoid the default. + """ + + knownindentSMkwargs = None + """ + Keyword arguments dictionary, passed to the `knownindentSM` constructor. + + If left as ``None``, `knownindentSMkwargs` defaults to the value of + `indentSMkwargs`. Override it in subclasses to avoid the default. + """ + + def __init__(self, statemachine, debug=0): + """ + Initialize a `StateSM` object; extends `State.__init__()`. + + Check for indent state machine attributes, set defaults if not set. + """ + State.__init__(self, statemachine, debug) + if self.indentSM is None: + self.indentSM = self.nestedSM + if self.indentSMkwargs is None: + self.indentSMkwargs = self.nestedSMkwargs + if self.knownindentSM is None: + self.knownindentSM = self.indentSM + if self.knownindentSMkwargs is None: + self.knownindentSMkwargs = self.indentSMkwargs + + def blank(self, match, context, nextstate): + """Handle blank lines. Does nothing. Override in subclasses.""" + return self.nop(match, context, nextstate) + + def indent(self, match, context, nextstate): + """ + Handle an indented text block. Extend or override in subclasses. + + Recursively run the registered state machine for indented blocks + (`self.indentSM`). + """ + indented, indent, lineoffset, blankfinish = \ + self.statemachine.getindented() + sm = self.indentSM(debug=self.debug, **self.indentSMkwargs) + results = sm.run(indented, inputoffset=lineoffset) + return context, nextstate, results + + def knownindent(self, match, context, nextstate): + """ + Handle a known-indent text block. Extend or override in subclasses. + + Recursively run the registered state machine for known-indent indented + blocks (`self.knownindentSM`). The indent is the length of the match, + ``match.end()``. + """ + indented, lineoffset, blankfinish = \ + self.statemachine.getknownindented(match.end()) + sm = self.knownindentSM(debug=self.debug, **self.knownindentSMkwargs) + results = sm.run(indented, inputoffset=lineoffset) + return context, nextstate, results + + def firstknownindent(self, match, context, nextstate): + """ + Handle an indented text block (first line's indent known). + + Extend or override in subclasses. + + Recursively run the registered state machine for known-indent indented + blocks (`self.knownindentSM`). The indent is the length of the match, + ``match.end()``. + """ + indented, lineoffset, blankfinish = \ + self.statemachine.getfirstknownindented(match.end()) + sm = self.knownindentSM(debug=self.debug, **self.knownindentSMkwargs) + results = sm.run(indented, inputoffset=lineoffset) + return context, nextstate, results + + +class _SearchOverride: + + """ + Mix-in class to override `StateMachine` regular expression behavior. + + Changes regular expression matching, from the default `re.match()` + (succeeds only if the pattern matches at the start of `self.line`) to + `re.search()` (succeeds if the pattern matches anywhere in `self.line`). + When subclassing a `StateMachine`, list this class **first** in the + inheritance list of the class definition. + """ + + def match(self, pattern): + """ + Return the result of a regular expression search. + + Overrides `StateMachine.match()`. + + Parameter `pattern`: `re` compiled regular expression. + """ + return pattern.search(self.line) + + +class SearchStateMachine(_SearchOverride, StateMachine): + """`StateMachine` which uses `re.search()` instead of `re.match()`.""" + pass + + +class SearchStateMachineWS(_SearchOverride, StateMachineWS): + """`StateMachineWS` which uses `re.search()` instead of `re.match()`.""" + pass + + +class UnknownStateError(Exception): pass +class DuplicateStateError(Exception): pass +class UnknownTransitionError(Exception): pass +class DuplicateTransitionError(Exception): pass +class TransitionPatternNotFound(Exception): pass +class TransitionMethodNotFound(Exception): pass +class UnexpectedIndentationError(Exception): pass + + +class TransitionCorrection(Exception): + + """ + Raise from within a transition method to switch to another transition. + """ + + +_whitespace_conversion_table = string.maketrans('\v\f', ' ') + +def string2lines(astring, tabwidth=8, convertwhitespace=0): + """ + Return a list of one-line strings with tabs expanded and no newlines. + + Each tab is expanded with between 1 and `tabwidth` spaces, so that the + next character's index becomes a multiple of `tabwidth` (8 by default). + + Parameters: + + - `astring`: a multi-line string. + - `tabwidth`: the number of columns between tab stops. + - `convertwhitespace`: convert form feeds and vertical tabs to spaces? + """ + if convertwhitespace: + astring = astring.translate(_whitespace_conversion_table) + return [s.expandtabs(tabwidth) for s in astring.splitlines()] + +def extractindented(lines, uptoblank=0, stripindent=1): + """ + Extract and return a list of indented lines of text. + + Collect all lines with indentation, determine the minimum indentation, + remove the minimum indentation from all indented lines (unless + `stripindent` is false), and return them. All lines up to but not + including the first unindented line will be returned. + + :Parameters: + - `lines`: a list of one-line strings without newlines. + - `uptoblank`: Stop collecting at the first blank line if true (1). + - `stripindent`: Strip common leading indent if true (1, default). + + :Return: + - a list of indented lines with mininum indent removed; + - the amount of the indent; + - whether or not the block finished with a blank line or at the end of + `lines`. + """ + source = [] + indent = None + for line in lines: + if line and line[0] != ' ': # line not indented + # block finished properly iff the last indented line was blank + blankfinish = len(source) and not source[-1].strip() + break + stripped = line.lstrip() + if uptoblank and not stripped: # blank line + blankfinish = 1 + break + source.append(line) + if not stripped: # blank line + continue + lineindent = len(line) - len(stripped) + if indent is None: + indent = lineindent + else: + indent = min(indent, lineindent) + else: + blankfinish = 1 # block ends at end of lines + if indent: + if stripindent: + source = [s[indent:] for s in source] + return source, indent, blankfinish + else: + return [], 0, blankfinish + +def _exceptiondata(): + """ + Return exception information: + + - the exception's class name; + - the exception object; + - the name of the file containing the offending code; + - the line number of the offending code; + - the function name of the offending code. + """ + type, value, traceback = sys.exc_info() + while traceback.tb_next: + traceback = traceback.tb_next + code = traceback.tb_frame.f_code + return (type.__name__, value, code.co_filename, traceback.tb_lineno, + code.co_name) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py new file mode 100644 index 000000000..6c2ae279f --- /dev/null +++ b/docutils/transforms/__init__.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger, Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +: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 Reader may choose to +perform on the parsed document, depending on the input context. A Docutils +Reader may also perform Reader-specific transforms before or after performing +these standard transforms. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import languages + + +class TransformError(Exception): pass + + +class Transform: + + """ + Docutils transform component abstract base class. + """ + + def __init__(self, doctree, startnode=None): + """ + Initial setup for in-place document transforms. + """ + + self.doctree = doctree + """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.getlanguage(doctree.languagecode) + """Language module local to this document.""" + + def transform(self): + """Override to transform the document tree.""" + raise NotImplementedError('subclass must override this method') diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py new file mode 100644 index 000000000..2cfe4d2a8 --- /dev/null +++ b/docutils/transforms/components.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger, Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Transforms related to document components. + +- `Contents`: Used to build a table of contents. +""" + +__docformat__ = 'reStructuredText' + + +import re +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +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". A title is + either explicitly specified, taken from the appropriate language module, + or omitted (local table of contents). The depth may be specified. + Two-way references between the table of contents and section titles are + generated (requires Writer support). + + This transform requires a startnode, which which contains generation + options and provides the location for the generated table of contents (the + startnode is replaced by the table of contents "topic"). + """ + + def transform(self): + topic = nodes.topic(CLASS='contents') + title = self.startnode.details['title'] + if self.startnode.details.has_key('local'): + startnode = self.startnode.parent + # @@@ generate an error if the startnode (directive) not at + # section/document top-level? Drag it up until it is? + while not isinstance(startnode, nodes.Structural): + startnode = startnode.parent + if not title: + title = [] + else: + startnode = self.doctree + if not title: + title = nodes.title('', self.language.labels['contents']) + contents = self.build_contents(startnode) + if len(contents): + topic += title + topic += contents + self.startnode.parent.replace(self.startnode, topic) + else: + self.startnode.parent.remove(self.startnode) + + def build_contents(self, node, level=0): + level += 1 + sections = [] + i = len(node) - 1 + while i >= 0 and isinstance(node[i], nodes.section): + sections.append(node[i]) + i -= 1 + sections.reverse() + entries = [] + for section in sections: + title = section[0] + reference = nodes.reference('', '', refid=section['id'], + *title.getchildren()) + entry = nodes.paragraph('', '', reference) + item = nodes.list_item('', entry) + itemid = self.doctree.set_id(item) + title['refid'] = itemid + if (not self.startnode.details.has_key('depth')) \ + or level < self.startnode.details['depth']: + subsects = self.build_contents(section, level) + item += subsects + entries.append(item) + if entries: + entries = nodes.bullet_list('', *entries) + return entries diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py new file mode 100644 index 000000000..0a8068fad --- /dev/null +++ b/docutils/transforms/frontmatter.py @@ -0,0 +1,375 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger, Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Transforms related to the front matter of a document (information +found before the main text): + +- `DocTitle`: Used to transform a lone top level section's title to + the document title, and promote a remaining lone top-level section's + title to the document 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 DocTitle(Transform): + + """ + 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:: + + +
+ + Top-Level Title + <paragraph> + A paragraph. + + After running the DocTitle transform, we have:: + + <document name="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 name="top-level title"> + <title> + Top-Level Title + <subtitle name="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). + """ + + def transform(self): + if self.promote_document_title(): + self.promote_document_subtitle() + + def promote_document_title(self): + section, index = self.candidate_index() + if index is None: + return None + doctree = self.doctree + # Transfer the section's attributes to the document element (at root): + doctree.attributes.update(section.attributes) + doctree[:] = (section[:1] # section title + + doctree[:index] # everything that was in the document + # before the section + + section[1:]) # everything that was in the section + return 1 + + def promote_document_subtitle(self): + subsection, index = self.candidate_index() + if index is None: + return None + subtitle = nodes.subtitle() + # Transfer the subsection's attributes to the new subtitle: + subtitle.attributes.update(subsection.attributes) + # Transfer the contents of the subsection's title to the subtitle: + subtitle[:] = subsection[0][:] + doctree = self.doctree + doctree[:] = (doctree[:1] # document title + + [subtitle] + + doctree[1:index] # everything that was in the document + # before the section + + subsection[1:]) # everything that was in the subsection + return 1 + + def candidate_index(self): + """ + Find and return the promotion candidate and its index. + + Return (None, None) if no valid candidate was found. + """ + doctree = self.doctree + index = doctree.findnonclass(nodes.PreBibliographic) + if index is None or len(doctree) > (index + 1) or \ + not isinstance(doctree[index], nodes.section): + return None, None + else: + return doctree[index], index + + +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 the + abstract, which becomes a "topic" element 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.) + """ + + def transform(self): + doctree = self.doctree + index = doctree.findnonclass(nodes.PreBibliographic) + if index is None: + return + candidate = doctree[index] + if isinstance(candidate, nodes.field_list): + biblioindex = doctree.findnonclass(nodes.Titular) + nodelist, remainder = self.extract_bibliographic(candidate) + if remainder: + doctree[index] = remainder + else: + del doctree[index] + doctree[biblioindex:biblioindex] = nodelist + return + + def extract_bibliographic(self, field_list): + docinfo = nodes.docinfo() + remainder = [] + bibliofields = self.language.bibliographic_fields + abstract = None + for field in field_list: + try: + name = field[0][0].astext() + normedname = utils.normname(name) + if not (len(field) == 2 and bibliofields.has_key(normedname) + and self.check_empty_biblio_field(field, name)): + raise TransformError + biblioclass = bibliofields[normedname] + if issubclass(biblioclass, nodes.TextElement): + if not self.check_compound_biblio_field(field, name): + raise TransformError + self.filter_rcs_keywords(field[1][0]) + docinfo.append(biblioclass('', '', *field[1][0])) + else: # multiple body elements possible + if issubclass(biblioclass, nodes.authors): + self.extract_authors(field, name, docinfo) + elif issubclass(biblioclass, nodes.topic): + if abstract: + field[-1] += self.doctree.reporter.warning( + 'There can only be one abstract.') + raise TransformError + title = nodes.title( + name, self.language.labels['abstract']) + abstract = nodes.topic('', title, CLASS='abstract', + *field[1].children) + else: + docinfo.append(biblioclass('', *field[1].children)) + except TransformError: + remainder.append(field) + continue + nodelist = [] + if len(docinfo) != 0: + nodelist.append(docinfo) + if abstract: + nodelist.append(abstract) + if remainder: + field_list[:] = remainder + else: + field_list = None + return nodelist, field_list + + def check_empty_biblio_field(self, field, name): + if len(field[1]) < 1: + field[-1] += self.doctree.reporter.warning( + 'Cannot extract empty bibliographic field "%s".' % name) + return None + return 1 + + def check_compound_biblio_field(self, field, name): + if len(field[1]) > 1: + field[-1] += self.doctree.reporter.warning( + 'Cannot extract compound bibliographic field "%s".' % name) + return None + if not isinstance(field[1][0], nodes.paragraph): + field[-1] += self.doctree.reporter.warning( + 'Cannot extract bibliographic field "%s" containing anything ' + 'other than a single paragraph.' + % name) + return None + return 1 + + rcs_keyword_substitutions = [ + (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$', + re.IGNORECASE), r'\1-\2-\3'), + (re.compile(r'\$' r'RCSfile: (.+),v \$$', + re.IGNORECASE), r'\1'), + (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] + + def filter_rcs_keywords(self, paragraph): + if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): + textnode = paragraph[0] + for pattern, substitution in self.rcs_keyword_substitutions: + match = pattern.match(textnode.data) + if match: + textnode.data = pattern.sub(substitution, textnode.data) + return + + 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] + docinfo.append(nodes.authors('', *authornodes)) + except TransformError: + field[-1] += self.doctree.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))) + 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] + 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/references.py b/docutils/transforms/references.py new file mode 100644 index 000000000..c2ff9189b --- /dev/null +++ b/docutils/transforms/references.py @@ -0,0 +1,670 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Transforms for resolving references: + +- `Hyperlinks`: Used to resolve hyperlink targets and references. +- `Footnotes`: Resolve footnote numbering and references. +- `Substitutions`: Resolve substitutions. +""" + +__docformat__ = 'reStructuredText' + +import re +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +class Hyperlinks(Transform): + + """Resolve the various types of hyperlink targets and references.""" + + def transform(self): + stages = [] + #stages.append('Beginning of references.Hyperlinks.transform()\n' + self.doctree.pformat()) + self.resolve_chained_targets() + #stages.append('After references.Hyperlinks.resolve_chained_targets()\n' + self.doctree.pformat()) + self.resolve_anonymous() + #stages.append('After references.Hyperlinks.resolve_anonymous()\n' + self.doctree.pformat()) + self.resolve_indirect() + #stages.append('After references.Hyperlinks.resolve_indirect()\n' + self.doctree.pformat()) + self.resolve_external_targets() + #stages.append('After references.Hyperlinks.resolve_external_references()\n' + self.doctree.pformat()) + self.resolve_internal_targets() + #stages.append('After references.Hyperlinks.resolve_internal_references()\n' + self.doctree.pformat()) + #import difflib + #compare = difflib.Differ().compare + #for i in range(len(stages) - 1): + # print ''.join(compare(stages[i].splitlines(1), stages[i+1].splitlines(1))) + + def resolve_chained_targets(self): + """ + Attributes "refuri" and "refname" are migrated from the final direct + target up the chain of contiguous adjacent internal targets, using + `ChainedTargetResolver`. + """ + visitor = ChainedTargetResolver(self.doctree) + self.doctree.walk(visitor) + + def resolve_anonymous(self): + """ + Link anonymous references to targets. Given:: + + <paragraph> + <reference anonymous="1"> + internal + <reference anonymous="1"> + external + <target anonymous="1" id="id1"> + <target anonymous="1" id="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" id="id1"> + <target anonymous="1" id="id2" refuri="http://external"> + """ + if len(self.doctree.anonymous_refs) \ + != len(self.doctree.anonymous_targets): + msg = self.doctree.reporter.error( + 'Anonymous hyperlink mismatch: %s references but %s targets.' + % (len(self.doctree.anonymous_refs), + len(self.doctree.anonymous_targets))) + self.doctree.messages += msg + msgid = self.doctree.set_id(msg) + for ref in self.doctree.anonymous_refs: + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + return + for i in range(len(self.doctree.anonymous_refs)): + ref = self.doctree.anonymous_refs[i] + target = self.doctree.anonymous_targets[i] + if target.hasattr('refuri'): + ref['refuri'] = target['refuri'] + ref.resolved = 1 + else: + ref['refid'] = target['id'] + self.doctree.note_refid(ref) + target.referenced = 1 + + def resolve_indirect(self): + """ + 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"> + """ + #import mypdb as pdb + #pdb.set_trace() + for target in self.doctree.indirect_targets: + if not target.resolved: + self.resolve_indirect_target(target) + self.resolve_indirect_references(target) + + def resolve_indirect_target(self, target): + refname = target['refname'] + reftarget = None + if self.doctree.explicit_targets.has_key(refname): + reftarget = self.doctree.explicit_targets[refname] + elif self.doctree.implicit_targets.has_key(refname): + reftarget = self.doctree.implicit_targets[refname] + if not reftarget: + self.nonexistent_indirect_target(target) + return + if isinstance(reftarget, nodes.target) \ + and not reftarget.resolved and reftarget.hasattr('refname'): + self.one_indirect_target(reftarget) # multiply indirect + if reftarget.hasattr('refuri'): + target['refuri'] = reftarget['refuri'] + if target.hasattr('name'): + self.doctree.note_external_target(target) + elif reftarget.hasattr('refid'): + target['refid'] = reftarget['refid'] + self.doctree.note_refid(target) + else: + try: + target['refid'] = reftarget['id'] + self.doctree.note_refid(target) + except KeyError: + self.nonexistent_indirect_target(target) + return + del target['refname'] + target.resolved = 1 + reftarget.referenced = 1 + + def nonexistent_indirect_target(self, target): + naming = '' + if target.hasattr('name'): + naming = '"%s" ' % target['name'] + reflist = self.doctree.refnames[target['name']] + else: + reflist = self.doctree.refnames[target['id']] + naming += '(id="%s")' % target['id'] + msg = self.doctree.reporter.warning( + 'Indirect hyperlink target %s refers to target "%s", ' + 'which does not exist.' % (naming, target['refname'])) + self.doctree.messages += msg + msgid = self.doctree.set_id(msg) + for ref in reflist: + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + target.resolved = 1 + + def resolve_indirect_references(self, target): + if target.hasattr('refid'): + attname = 'refid' + call_if_named = 0 + call_method = self.doctree.note_refid + elif target.hasattr('refuri'): + attname = 'refuri' + call_if_named = 1 + call_method = self.doctree.note_external_target + else: + return + attval = target[attname] + if target.hasattr('name'): + name = target['name'] + try: + reflist = self.doctree.refnames[name] + except KeyError, instance: + if target.referenced: + return + msg = self.doctree.reporter.info( + 'Indirect hyperlink target "%s" is not referenced.' + % name) + self.doctree.messages += msg + target.referenced = 1 + return + delatt = 'refname' + else: + id = target['id'] + try: + reflist = self.doctree.refids[id] + except KeyError, instance: + if target.referenced: + return + msg = self.doctree.reporter.info( + 'Indirect hyperlink target id="%s" is not referenced.' + % id) + self.doctree.messages += msg + target.referenced = 1 + return + delatt = 'refid' + for ref in reflist: + if ref.resolved: + continue + del ref[delatt] + ref[attname] = attval + if not call_if_named or ref.hasattr('name'): + call_method(ref) + ref.resolved = 1 + if isinstance(ref, nodes.target): + self.resolve_indirect_references(ref) + target.referenced = 1 + + def resolve_external_targets(self): + """ + 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"> + """ + for target in self.doctree.external_targets: + if target.hasattr('refuri') and target.hasattr('name'): + name = target['name'] + refuri = target['refuri'] + try: + reflist = self.doctree.refnames[name] + except KeyError, instance: + if target.referenced: + continue + msg = self.doctree.reporter.info( + 'External hyperlink target "%s" is not referenced.' + % name) + self.doctree.messages += msg + target.referenced = 1 + continue + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref['refuri'] = refuri + ref.resolved = 1 + target.referenced = 1 + + def resolve_internal_targets(self): + """ + 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 target in self.doctree.internal_targets: + if target.hasattr('refuri') or target.hasattr('refid') \ + or not target.hasattr('name'): + continue + name = target['name'] + refid = target['id'] + try: + reflist = self.doctree.refnames[name] + except KeyError, instance: + if target.referenced: + continue + msg = self.doctree.reporter.info( + 'Internal hyperlink target "%s" is not referenced.' + % name) + self.doctree.messages += msg + target.referenced = 1 + continue + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref['refid'] = refid + ref.resolved = 1 + target.referenced = 1 + + +class ChainedTargetResolver(nodes.NodeVisitor): + + """ + Copy reference attributes up the length of a hyperlink target chain. + + "Chained targets" are multiple adjacent internal hyperlink targets which + "point to" an external or indirect target. After the transform, all + chained targets will effectively point to the same place. + + Given the following ``doctree`` as input:: + + <document> + <target id="a" name="a"> + <target id="b" name="b"> + <target id="c" name="c" refuri="http://chained.external.targets"> + <target id="d" name="d"> + <paragraph> + I'm known as "d". + <target id="e" name="e"> + <target id="id1"> + <target id="f" name="f" refname="d"> + + ``ChainedTargetResolver(doctree).walk()`` will transform the above into:: + + <document> + <target id="a" name="a" refuri="http://chained.external.targets"> + <target id="b" name="b" refuri="http://chained.external.targets"> + <target id="c" name="c" refuri="http://chained.external.targets"> + <target id="d" name="d"> + <paragraph> + I'm known as "d". + <target id="e" name="e" refname="d"> + <target id="id1" refname="d"> + <target id="f" name="f" refname="d"> + """ + + def unknown_visit(self, node): + pass + + def visit_target(self, node): + if node.hasattr('refuri'): + attname = 'refuri' + call_if_named = self.doctree.note_external_target + elif node.hasattr('refname'): + attname = 'refname' + call_if_named = self.doctree.note_indirect_target + elif node.hasattr('refid'): + attname = 'refid' + call_if_named = None + else: + return + attval = node[attname] + index = node.parent.index(node) + for i in range(index - 1, -1, -1): + sibling = node.parent[i] + if not isinstance(sibling, nodes.target) \ + or sibling.hasattr('refuri') \ + or sibling.hasattr('refname') \ + or sibling.hasattr('refid'): + break + sibling[attname] = attval + if sibling.hasattr('name') and call_if_named: + call_if_named(sibling) + + +class Footnotes(Transform): + + """ + Assign numbers to autonumbered footnotes, and resolve links to footnotes, + citations, and their references. + + Given the following ``doctree`` 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. + """ + + 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 transform(self): + self.autofootnote_labels = [] + startnum = self.doctree.autofootnote_start + self.doctree.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.doctree.autofootnotes: + while 1: + label = str(startnum) + startnum += 1 + if not self.doctree.explicit_targets.has_key(label): + break + footnote.insert(0, nodes.label('', label)) + if footnote.hasattr('dupname'): + continue + if footnote.hasattr('name'): + name = footnote['name'] + for ref in self.doctree.footnote_refs.get(name, []): + ref += nodes.Text(label) + ref.delattr('refname') + ref['refid'] = footnote['id'] + footnote.add_backref(ref['id']) + self.doctree.note_refid(ref) + ref.resolved = 1 + else: + footnote['name'] = label + self.doctree.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.doctree.autofootnote_refs: + if ref.resolved or ref.hasattr('refid'): + continue + try: + label = self.autofootnote_labels[i] + except IndexError: + msg = self.doctree.reporter.error( + 'Too many autonumbered footnote references: only %s ' + 'corresponding footnotes available.' + % len(self.autofootnote_labels)) + msgid = self.doctree.set_id(msg) + self.doctree.messages += msg + for ref in self.doctree.autofootnote_refs[i:]: + if ref.resolved or ref.hasattr('refname'): + continue + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + break + ref += nodes.Text(label) + footnote = self.doctree.explicit_targets[label] + ref['refid'] = footnote['id'] + self.doctree.note_refid(ref) + footnote.add_backref(ref['id']) + ref.resolved = 1 + i += 1 + + def symbolize_footnotes(self): + """Add symbols indexes to "[*]"-style footnotes and references.""" + labels = [] + for footnote in self.doctree.symbol_footnotes: + reps, index = divmod(self.doctree.symbol_footnote_start, + len(self.symbols)) + labeltext = self.symbols[index] * (reps + 1) + labels.append(labeltext) + footnote.insert(0, nodes.label('', labeltext)) + self.doctree.symbol_footnote_start += 1 + self.doctree.set_id(footnote) + i = 0 + for ref in self.doctree.symbol_footnote_refs: + try: + ref += nodes.Text(labels[i]) + except IndexError: + msg = self.doctree.reporter.error( + 'Too many symbol footnote references: only %s ' + 'corresponding footnotes available.' % len(labels)) + msgid = self.set_id(msg) + self.doctree.messages += msg + for ref in self.doctree.symbol_footnote_refs[i:]: + if ref.resolved or ref.hasattr('refid'): + continue + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + break + footnote = self.doctree.symbol_footnotes[i] + ref['refid'] = footnote['id'] + self.doctree.note_refid(ref) + footnote.add_backref(ref['id']) + i += 1 + + def resolve_footnotes_and_citations(self): + """ + Link manually-labeled footnotes and citations to/from their references. + """ + for footnote in self.doctree.footnotes: + label = footnote['name'] + if self.doctree.footnote_refs.has_key(label): + reflist = self.doctree.footnote_refs[label] + self.resolve_references(footnote, reflist) + for citation in self.doctree.citations: + label = citation['name'] + if self.doctree.citation_refs.has_key(label): + reflist = self.doctree.citation_refs[label] + self.resolve_references(citation, reflist) + + def resolve_references(self, note, reflist): + id = note['id'] + for ref in reflist: + if ref.resolved: + continue + ref.delattr('refname') + ref['refid'] = id + note.add_backref(ref['id']) + ref.resolved = 1 + note.resolved = 1 + + +class Substitutions(Transform): + + """ + Given the following ``doctree`` 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"> + """ + + def transform(self): + defs = self.doctree.substitution_defs + for refname, refs in self.doctree.substitution_refs.items(): + for ref in refs: + if defs.has_key(refname): + ref.parent.replace(ref, defs[refname].getchildren()) + else: + msg = self.doctree.reporter.error( + 'Undefined substitution referenced: "%s".' % refname) + msgid = self.doctree.set_id(msg) + self.doctree.messages += msg + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + self.doctree.substitution_refs = None # release replaced references diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py new file mode 100644 index 000000000..1cebcc9db --- /dev/null +++ b/docutils/transforms/universal.py @@ -0,0 +1,149 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger, Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Transforms needed by most or all documents: + +- `Messages`: Placement of system messages stored in + `nodes.document.messages`. +- `TestMessages`: Like `Messages`, used on test runs. +- `FinalReferences`: Resolve remaining references. +- `Pending`: Execute pending transforms (abstract base class; + `FirstReaderPending`, `LastReaderPending`, `FirstWriterPending`, and + `LastWriterPending` are its concrete subclasses). +""" + +__docformat__ = 'reStructuredText' + +import re +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +class Messages(Transform): + + """ + Place any system messages generated after parsing into a dedicated section + of the document. + """ + + def transform(self): + # @@@ filter out msgs below threshold? + if len(self.doctree.messages) > 0: + section = nodes.section(CLASS='system-messages') + # @@@ get this from the language module? + section += nodes.title('', 'Docutils System Messages') + section += self.doctree.messages.getchildren() + self.doctree.messages[:] = [] + self.doctree += section + + +class TestMessages(Transform): + + """ + Append all system messages to the end of the doctree. + """ + + def transform(self): + self.doctree += self.doctree.messages.getchildren() + + +class FinalChecks(Transform): + + """ + Perform last-minute checks. + + - Check for dangling references (incl. footnote & citation). + """ + + def transform(self): + visitor = FinalCheckVisitor(self.doctree) + self.doctree.walk(visitor) + + +class FinalCheckVisitor(nodes.NodeVisitor): + + def unknown_visit(self, node): + pass + + def visit_reference(self, node): + if node.resolved or not node.hasattr('refname'): + return + refname = node['refname'] + try: + id = self.doctree.nameids[refname] + except KeyError: + msg = self.doctree.reporter.error( + 'Unknown target name: "%s".' % (node['refname'])) + self.doctree.messages += msg + msgid = self.doctree.set_id(msg) + prb = nodes.problematic( + node.rawsource, node.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + node.parent.replace(node, prb) + return + del node['refname'] + node['refid'] = id + self.doctree.ids[id].referenced = 1 + node.resolved = 1 + + visit_footnote_reference = visit_citation_reference = visit_reference + + +class Pending(Transform): + + """ + Execute pending transforms. + """ + + stage = None + """The stage of processing applicable to this transform; match with + `nodes.pending.stage`. Possible values include 'first_reader', + 'last_reader', 'first_writer', and 'last_writer'. Override in + subclasses.""" + + def transform(self): + for pending in self.doctree.pending: + if pending.stage == self.stage: + pending.transform(self.doctree, pending).transform() + + +class FirstReaderPending(Pending): + + stage = 'first_reader' + + +class LastReaderPending(Pending): + + stage = 'last_reader' + + +class FirstWriterPending(Pending): + + stage = 'first_writer' + + +class LastWriterPending(Pending): + + stage = 'last_writer' + + +test_transforms = (TestMessages,) +"""Universal transforms to apply to the raw doctree when testing.""" + +first_reader_transforms = (FirstReaderPending,) +"""Universal transforms to apply before any other Reader transforms.""" + +last_reader_transforms = (LastReaderPending,) +"""Universal transforms to apply after all other Reader transforms.""" + +first_writer_transforms = (FirstWriterPending,) +"""Universal transforms to apply before any other Writer transforms.""" + +last_writer_transforms = (LastWriterPending, FinalChecks, Messages) +"""Universal transforms to apply after all other Writer transforms.""" diff --git a/docutils/urischemes.py b/docutils/urischemes.py new file mode 100644 index 000000000..367217ad4 --- /dev/null +++ b/docutils/urischemes.py @@ -0,0 +1,94 @@ +""" +`schemes` is a dictionary with lowercase URI addressing schemes as +keys and descriptions as values. It was compiled from the index at +http://www.w3.org/Addressing/schemes.html, revised 2001-08-20. Many +values are blank and should be filled in with useful descriptions. +""" + +schemes = { + 'about': 'provides information on Navigator', + 'acap': 'application configuration access protocol', + 'addbook': "To add vCard entries to Communicator's Address Book", + 'afp': 'Apple Filing Protocol', + 'afs': 'Andrew File System global file names', + 'aim': 'AOL Instant Messenger', + 'callto': 'for NetMeeting links', + 'castanet': 'Castanet Tuner URLs for Netcaster', + 'chttp': 'cached HTTP supported by RealPlayer', + 'cid': 'content identifier', + 'data': 'allows inclusion of small data items as "immediate" data; RFC-2397', + 'dav': 'Distributed Authoring and Versioning Protocol; RFC 2518', + 'dns': 'Domain Name System resources', + 'eid': ('External ID; non-URL data; general escape mechanism to allow ' + 'access to information for applications that are too ' + 'specialized to justify their own schemes'), + 'fax': '', + 'file': 'Host-specific file names', + 'finger': '', + 'freenet': '', + 'ftp': 'File Transfer Protocol', + 'gopher': 'The Gopher Protocol', + 'gsm-sms': '', + 'h323': '', + 'h324': '', + 'hdl': '', + 'hnews': '', + 'http': 'Hypertext Transfer Protocol', + 'https': '', + 'iioploc': '', + 'ilu': '', + 'imap': 'internet message access protocol', + 'ior': '', + 'ipp': '', + 'irc': 'Internet Relay Chat', + 'jar': '', + 'javascript': 'JavaScript code; evaluates the expression after the colon', + 'jdbc': '', + 'ldap': 'Lightweight Directory Access Protocol', + 'lifn': '', + 'livescript': '', + 'lrq': '', + 'mailbox': 'Mail folder access', + 'mailserver': 'Access to data available from mail servers', + 'mailto': 'Electronic mail address', + 'md5': '', + 'mid': 'message identifier', + 'mocha': '', + 'modem': '', + 'news': 'USENET news', + 'nfs': 'network file system protocol', + 'nntp': 'USENET news using NNTP access', + 'opaquelocktoken': '', + 'phone': '', + 'pop': 'Post Office Protocol', + 'pop3': 'Post Office Protocol v3', + 'printer': '', + 'prospero': 'Prospero Directory Service', + 'res': '', + 'rtsp': 'real time streaming protocol', + 'rvp': '', + 'rwhois': '', + 'rx': 'Remote Execution', + 'sdp': '', + 'service': 'service location', + 'sip': 'session initiation protocol', + 'smb': '', + 'snews': 'For NNTP postings via SSL', + 't120': '', + 'tcp': '', + 'tel': 'telephone', + 'telephone': 'telephone', + 'telnet': 'Reference to interactive sessions', + 'tip': 'Transaction Internet Protocol', + 'tn3270': 'Interactive 3270 emulation sessions', + 'tv': '', + 'urn': 'Uniform Resource Name', + 'uuid': '', + 'vemmi': 'versatile multimedia interface', + 'videotex': '', + 'view-source': 'displays HTML code that was generated with JavaScript', + 'wais': 'Wide Area Information Servers', + 'whodp': '', + 'whois++': 'Distributed directory service.', + 'z39.50r': 'Z39.50 Retrieval', + 'z39.50s': 'Z39.50 Session',} diff --git a/docutils/utils.py b/docutils/utils.py new file mode 100644 index 000000000..a92c8fb97 --- /dev/null +++ b/docutils/utils.py @@ -0,0 +1,373 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Miscellaneous utilities for the documentation utilities. +""" + +import sys, re +import nodes + + +class SystemMessage(Exception): + + def __init__(self, system_message): + Exception.__init__(self, system_message.astext()) + + +class Reporter: + + """ + Info/warning/error reporter and ``system_message`` element generator. + + Five levels of system messages are defined, along with corresponding + methods: `debug()`, `info()`, `warning()`, `error()`, and `severe()`. + + There is typically one Reporter object per process. A Reporter object is + instantiated with thresholds for generating warnings and errors (raising + exceptions), a switch to turn debug output on or off, and an I/O stream + for warnings. These are stored in the default reporting category, '' + (zero-length string). + + Multiple reporting categories [#]_ may be set, each with its own warning + and error thresholds, debugging switch, and warning stream (collectively a + `ConditionSet`). Categories are hierarchically-named strings that look + like attribute references: 'spam', 'spam.eggs', 'neeeow.wum.ping'. The + 'spam' category is the ancestor of 'spam.bacon.eggs'. Unset categories + inherit stored conditions from their closest ancestor category that has + been set. + + When a system message is generated, the stored conditions from its + category (or ancestor if unset) are retrieved. The system message level is + compared to the thresholds stored in the category, and a warning or error + is generated as appropriate. Debug messages are produced iff the stored + debug switch is on. Message output is sent to the stored warning stream. + + The default category is '' (empty string). By convention, Writers should + retrieve reporting conditions from the 'writer' category (which, unless + explicitly set, defaults to the conditions of the default category). + + .. [#] The concept of "categories" was inspired by the log4j project: + http://jakarta.apache.org/log4j/. + """ + + levels = 'DEBUG INFO WARNING ERROR SEVERE'.split() + """List of names for system message levels, indexed by level.""" + + def __init__(self, warninglevel, errorlevel, stream=None, debug=0): + """ + Initialize the `ConditionSet` forthe `Reporter`'s default category. + + :Parameters: + + - `warninglevel`: The level at or above which warning output will + be sent to `stream`. + - `errorlevel`: The level at or above which `SystemMessage` + exceptions will be raised. + - `debug`: Show debug (level=0) system messages? + - `stream`: Where warning output is sent (`None` implies + `sys.stderr`). + """ + + if stream is None: + stream = sys.stderr + + self.categories = {'': ConditionSet(debug, warninglevel, errorlevel, + stream)} + """Mapping of category names to conditions. Default category is ''.""" + + def setconditions(self, category, warninglevel, errorlevel, + stream=None, debug=0): + if stream is None: + stream = sys.stderr + self.categories[category] = ConditionSet(debug, warninglevel, + errorlevel, stream) + + def unsetconditions(self, category): + if category and self.categories.has_key(category): + del self.categories[category] + + __delitem__ = unsetconditions + + def getconditions(self, category): + while not self.categories.has_key(category): + category = category[:category.rfind('.') + 1][:-1] + return self.categories[category] + + __getitem__ = getconditions + + def system_message(self, level, comment=None, category='', + *children, **attributes): + """ + Return a system_message object. + + Raise an exception or generate a warning if appropriate. + """ + msg = nodes.system_message(comment, level=level, + type=self.levels[level], + *children, **attributes) + debug, warninglevel, errorlevel, stream = self[category].astuple() + if level >= warninglevel or debug and level == 0: + if category: + print >>stream, 'Reporter "%s":' % category, msg.astext() + else: + print >>stream, 'Reporter:', msg.astext() + if level >= errorlevel: + raise SystemMessage(msg) + return msg + + def debug(self, comment=None, category='', *children, **attributes): + """ + Level-0, "DEBUG": an internal reporting issue. Typically, there is no + effect on the processing. Level-0 system messages are handled + separately from the others. + """ + return self.system_message( + 0, comment, category, *children, **attributes) + + def info(self, comment=None, category='', *children, **attributes): + """ + Level-1, "INFO": a minor issue that can be ignored. Typically there is + no effect on processing, and level-1 system messages are not reported. + """ + return self.system_message( + 1, comment, category, *children, **attributes) + + def warning(self, comment=None, category='', *children, **attributes): + """ + Level-2, "WARNING": an issue that should be addressed. If ignored, + there may be unpredictable problems with the output. + """ + return self.system_message( + 2, comment, category, *children, **attributes) + + def error(self, comment=None, category='', *children, **attributes): + """ + Level-3, "ERROR": an error that should be addressed. If ignored, the + output will contain errors. + """ + return self.system_message( + 3, comment, category, *children, **attributes) + + def severe(self, comment=None, category='', *children, **attributes): + """ + Level-4, "SEVERE": a severe error that must be addressed. If ignored, + the output will contain severe errors. Typically level-4 system + messages are turned into exceptions which halt processing. + """ + return self.system_message( + 4, comment, category, *children, **attributes) + + +class ConditionSet: + + """ + A set of thresholds, switches, and streams corresponding to one `Reporter` + category. + """ + + def __init__(self, debug, warninglevel, errorlevel, stream): + self.debug = debug + self.warninglevel = warninglevel + self.errorlevel = errorlevel + self.stream = stream + + def astuple(self): + return (self.debug, self.warninglevel, self.errorlevel, + self.stream) + + +class ExtensionAttributeError(Exception): pass +class BadAttributeError(ExtensionAttributeError): pass +class BadAttributeDataError(ExtensionAttributeError): pass +class DuplicateAttributeError(ExtensionAttributeError): pass + + +def extract_extension_attributes(field_list, attribute_spec): + """ + Return a dictionary mapping extension attribute names to converted values. + + :Parameters: + - `field_list`: A flat field list without field arguments, where each + field body consists of a single paragraph only. + - `attribute_spec`: Dictionary mapping known attribute names to a + conversion function such as `int` or `float`. + + :Exceptions: + - `KeyError` for unknown attribute names. + - `ValueError` for invalid attribute values (raised by the conversion + function). + - `DuplicateAttributeError` for duplicate attributes. + - `BadAttributeError` for invalid fields. + - `BadAttributeDataError` for invalid attribute data (missing name, + missing data, bad quotes, etc.). + """ + attlist = extract_attributes(field_list) + attdict = assemble_attribute_dict(attlist, attribute_spec) + return attdict + +def extract_attributes(field_list): + """ + Return a list of attribute (name, value) pairs from field names & bodies. + + :Parameter: + `field_list`: A flat field list without field arguments, where each + field body consists of a single paragraph only. + + :Exceptions: + - `BadAttributeError` for invalid fields. + - `BadAttributeDataError` for invalid attribute data (missing name, + missing data, bad quotes, etc.). + """ + attlist = [] + for field in field_list: + if len(field) != 2: + raise BadAttributeError( + 'extension attribute field may not contain field arguments') + name = field[0].astext().lower() + body = field[1] + if len(body) == 0: + data = None + elif len(body) > 1 or not isinstance(body[0], nodes.paragraph) \ + or len(body[0]) != 1 or not isinstance(body[0][0], nodes.Text): + raise BadAttributeDataError( + 'extension attribute field body may contain\n' + 'a single paragraph only (attribute "%s")' % name) + else: + data = body[0][0].astext() + attlist.append((name, data)) + return attlist + +def assemble_attribute_dict(attlist, attspec): + """ + Return a mapping of attribute names to values. + + :Parameters: + - `attlist`: A list of (name, value) pairs (the output of + `extract_attributes()`). + - `attspec`: Dictionary mapping known attribute names to a + conversion function such as `int` or `float`. + + :Exceptions: + - `KeyError` for unknown attribute names. + - `DuplicateAttributeError` for duplicate attributes. + - `ValueError` for invalid attribute values (raised by conversion + function). + """ + attributes = {} + for name, value in attlist: + convertor = attspec[name] # raises KeyError if unknown + if attributes.has_key(name): + raise DuplicateAttributeError('duplicate attribute "%s"' % name) + try: + attributes[name] = convertor(value) + except (ValueError, TypeError), detail: + raise detail.__class__('(attribute "%s", value "%r") %s' + % (name, value, detail)) + return attributes + + +class NameValueError(Exception): pass + + +def extract_name_value(line): + """ + Return a list of (name, value) from a line of the form "name=value ...". + + :Exception: + `NameValueError` for invalid input (missing name, missing data, bad + quotes, etc.). + """ + attlist = [] + while line: + equals = line.find('=') + if equals == -1: + raise NameValueError('missing "="') + attname = line[:equals].strip() + if equals == 0 or not attname: + raise NameValueError( + 'missing attribute name before "="') + line = line[equals+1:].lstrip() + if not line: + raise NameValueError( + 'missing value after "%s="' % attname) + if line[0] in '\'"': + endquote = line.find(line[0], 1) + if endquote == -1: + raise NameValueError( + 'attribute "%s" missing end quote (%s)' + % (attname, line[0])) + if len(line) > endquote + 1 and line[endquote + 1].strip(): + raise NameValueError( + 'attribute "%s" end quote (%s) not followed by ' + 'whitespace' % (attname, line[0])) + data = line[1:endquote] + line = line[endquote+1:].lstrip() + else: + space = line.find(' ') + if space == -1: + data = line + line = '' + else: + data = line[:space] + line = line[space+1:].lstrip() + attlist.append((attname.lower(), data)) + return attlist + + +def normname(name): + """Return a case- and whitespace-normalized name.""" + return ' '.join(name.lower().split()) + +def id(string): + """ + Convert `string` into an identifier and return it. + + Docutils identifiers will conform to the regular expression + ``[a-z][-a-z0-9]*``. For CSS compatibility, identifiers (the "class" and + "id" attributes) should have no underscores, colons, or periods. Hyphens + may be used. + + - The `HTML 4.01 spec`_ defines identifiers based on SGML tokens: + + ID and NAME tokens must begin with a letter ([A-Za-z]) and may be + followed by any number of letters, digits ([0-9]), hyphens ("-"), + underscores ("_"), colons (":"), and periods ("."). + + - However the `CSS1 spec`_ defines identifiers based on the "name" token, + a tighter interpretation ("flex" tokenizer notation; "latin1" and + "escape" 8-bit characters have been replaced with entities):: + + unicode \\[0-9a-f]{1,4} + latin1 [¡-ÿ] + escape {unicode}|\\[ -~¡-ÿ] + nmchar [-a-z0-9]|{latin1}|{escape} + name {nmchar}+ + + The CSS1 "nmchar" rule does not include underscores ("_"), colons (":"), + or periods ("."), therefore "class" and "id" attributes should not contain + these characters. They should be replaced with hyphens ("-"). Combined + with HTML's requirements (the first character must be a letter; no + "unicode", "latin1", or "escape" characters), this results in the + ``[a-z][-a-z0-9]*`` pattern. + + .. _HTML 4.01 spec: http://www.w3.org/TR/html401 + .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 + """ + id = non_id_chars.sub('-', normname(string)) + id = non_id_at_ends.sub('', id) + return str(id) + +non_id_chars = re.compile('[^a-z0-9]+') +non_id_at_ends = re.compile('^[-0-9]+|-+$') + +def newdocument(languagecode='en', warninglevel=2, errorlevel=4, + stream=None, debug=0): + reporter = Reporter(warninglevel, errorlevel, stream, debug) + document = nodes.document(languagecode=languagecode, reporter=reporter) + return document diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py new file mode 100644 index 000000000..6d9d7c226 --- /dev/null +++ b/docutils/writers/__init__.py @@ -0,0 +1,104 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +This package contains Docutils Writer modules. +""" + +__docformat__ = 'reStructuredText' + + +import sys +from docutils import languages +from docutils.transforms import universal + + +class Writer: + + """ + Abstract base class for docutils Writers. + + Each writer module or package must export a subclass also called 'Writer'. + + Call `write()` to process a document. + """ + + document = None + """The document to write.""" + + language = None + """Language module for the document.""" + + destination = None + """Where to write the document.""" + + transforms = () + """Ordered list of transform classes (each with a ``transform()`` method). + Populated by subclasses. `Writer.transform()` instantiates & runs them.""" + + def __init__(self): + """Initialize the Writer instance.""" + + self.transforms = list(self.transforms) + """Instance copy of `Writer.transforms`; may be modified by client.""" + + def write(self, document, destination): + self.document = document + self.language = languages.getlanguage(document.languagecode) + self.destination = destination + self.transform() + self.translate() + self.record() + + def transform(self): + """Run all of the transforms defined for this Writer.""" + for xclass in (universal.first_writer_transforms + + tuple(self.transforms) + + universal.last_writer_transforms): + xclass(self.document).transform() + + def translate(self): + """Override to do final document tree translation.""" + raise NotImplementedError('subclass must override this method') + + def record(self): + """Override to record `document` to `destination`.""" + raise NotImplementedError('subclass must override this method') + + def recordfile(self, output, destination): + """ + Write `output` to a single file. + + Parameters: + + - `output`: Data to write. + - `destination`: one of: + + (a) a file-like object, which is written directly; + (b) a path to a file, which is opened and then written; or + (c) `None`, which implies `sys.stdout`. + """ + output = output.encode('raw-unicode-escape') # @@@ temporary + if hasattr(self.destination, 'write'): + destination.write(output) + elif self.destination: + open(self.destination, 'w').write(output) + else: + sys.stdout.write(output) + + +_writer_aliases = { + 'html': 'html4css1',} + +def get_writer_class(writername): + """Return the Writer class from the `writername` module.""" + writername = writername.lower() + if _writer_aliases.has_key(writername): + writername = _writer_aliases[writername] + module = __import__(writername, globals(), locals()) + return module.Writer diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py new file mode 100644 index 000000000..dde26f7d0 --- /dev/null +++ b/docutils/writers/html4css1.py @@ -0,0 +1,759 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Simple HyperText Markup Language document tree Writer. + +The output uses the HTML 4.01 Transitional DTD (*almost* strict) and +contains a minimum of formatting information. A cascading style sheet +"default.css" is required for proper viewing with a browser. +""" + +__docformat__ = 'reStructuredText' + + +import time +from types import ListType +from docutils import writers, nodes, languages + + +class Writer(writers.Writer): + + output = None + """Final translated form of `document`.""" + + def translate(self): + visitor = HTMLTranslator(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + + def record(self): + self.recordfile(self.output, self.destination) + + +class HTMLTranslator(nodes.NodeVisitor): + + def __init__(self, doctree): + nodes.NodeVisitor.__init__(self, doctree) + self.language = languages.getlanguage(doctree.languagecode) + self.head = ['<!DOCTYPE HTML PUBLIC' + ' "-//W3C//DTD HTML 4.01 Transitional//EN"\n' + ' "http://www.w3.org/TR/html4/loose.dtd">\n', + '<HTML LANG="%s">\n<HEAD>\n' % doctree.languagecode, + '<LINK REL="StyleSheet" HREF="default.css"' + ' TYPE="text/css">\n'] + self.body = ['</HEAD>\n<BODY>\n'] + self.foot = ['</BODY>\n</HTML>\n'] + self.sectionlevel = 0 + self.context = [] + self.topic_class = '' + + def astext(self): + return ''.join(self.head + self.body + self.foot) + + def encode(self, text): + """Encode special characters in `text` & return.""" + text = text.replace("&", "&") + text = text.replace("<", "<") + text = text.replace('"', """) + text = text.replace(">", ">") + return text + + def starttag(self, node, tagname, suffix='\n', **attributes): + atts = {} + for (name, value) in attributes.items(): + atts[name.lower()] = value + for att in ('class',): # append to node attribute + if node.has_key(att): + if atts.has_key(att): + atts[att] = node[att] + ' ' + atts[att] + for att in ('id',): # node attribute overrides + if node.has_key(att): + atts[att] = node[att] + attlist = atts.items() + attlist.sort() + parts = [tagname.upper()] + for name, value in attlist: + if value is None: # boolean attribute + parts.append(name.upper()) + elif isinstance(value, ListType): + values = [str(v) for v in value] + parts.append('%s="%s"' % (name.upper(), + self.encode(' '.join(values)))) + else: + parts.append('%s="%s"' % (name.upper(), + self.encode(str(value)))) + return '<%s>%s' % (' '.join(parts), suffix) + + def visit_Text(self, node): + self.body.append(self.encode(node.astext())) + + def depart_Text(self, node): + pass + + def visit_admonition(self, node, name): + self.body.append(self.starttag(node, 'div', CLASS=name)) + self.body.append('<P CLASS="admonition-title">' + self.language.labels[name] + '</P>\n') + + def depart_admonition(self): + self.body.append('</DIV>\n') + + def visit_attention(self, node): + self.visit_admonition(node, 'attention') + + def depart_attention(self, node): + self.depart_admonition() + + def visit_author(self, node): + self.visit_docinfo_item(node, 'author') + + def depart_author(self, node): + self.depart_docinfo_item() + + def visit_authors(self, node): + pass + + def depart_authors(self, node): + pass + + def visit_block_quote(self, node): + self.body.append(self.starttag(node, 'blockquote')) + + def depart_block_quote(self, node): + self.body.append('</BLOCKQUOTE>\n') + + def visit_bullet_list(self, node): + if self.topic_class == 'contents': + self.body.append(self.starttag(node, 'ul', compact=None)) + else: + self.body.append(self.starttag(node, 'ul')) + + def depart_bullet_list(self, node): + self.body.append('</UL>\n') + + def visit_caption(self, node): + self.body.append(self.starttag(node, 'p', '', CLASS='caption')) + + def depart_caption(self, node): + self.body.append('</P>\n') + + def visit_caution(self, node): + self.visit_admonition(node, 'caution') + + def depart_caution(self, node): + self.depart_admonition() + + def visit_citation(self, node): + self.body.append(self.starttag(node, 'table', CLASS='citation', + frame="void", rules="none")) + self.body.append('<COL CLASS="label">\n' + '<COL>\n' + '<TBODY VALIGN="top">\n' + '<TR><TD>\n') + + def depart_citation(self, node): + self.body.append('</TD></TR>\n' + '</TBODY>\n</TABLE>\n') + + def visit_citation_reference(self, node): + href = '' + if node.has_key('refid'): + href = '#' + node['refid'] + elif node.has_key('refname'): + href = '#' + self.doctree.nameids[node['refname']] + self.body.append(self.starttag(node, 'a', '[', href=href, #node['refid'], + CLASS='citation-reference')) + + def depart_citation_reference(self, node): + self.body.append(']</A>') + + def visit_classifier(self, node): + self.body.append(' <SPAN CLASS="classifier-delimiter">:</SPAN> ') + self.body.append(self.starttag(node, 'span', '', CLASS='classifier')) + + def depart_classifier(self, node): + self.body.append('</SPAN>') + + def visit_colspec(self, node): + atts = {} + #if node.has_key('colwidth'): + # atts['width'] = str(node['colwidth']) + '*' + self.body.append(self.starttag(node, 'col', **atts)) + + def depart_colspec(self, node): + pass + + def visit_comment(self, node): + self.body.append('<!-- ') + + def depart_comment(self, node): + self.body.append(' -->\n') + + def visit_contact(self, node): + self.visit_docinfo_item(node, 'contact') + + def depart_contact(self, node): + self.depart_docinfo_item() + + def visit_copyright(self, node): + self.visit_docinfo_item(node, 'copyright') + + def depart_copyright(self, node): + self.depart_docinfo_item() + + def visit_danger(self, node): + self.visit_admonition(node, 'danger') + + def depart_danger(self, node): + self.depart_admonition() + + def visit_date(self, node): + self.visit_docinfo_item(node, 'date') + + def depart_date(self, node): + self.depart_docinfo_item() + + def visit_definition(self, node): + self.body.append('</DT>\n') + self.body.append(self.starttag(node, 'dd')) + + def depart_definition(self, node): + self.body.append('</DD>\n') + + def visit_definition_list(self, node): + self.body.append(self.starttag(node, 'dl')) + + def depart_definition_list(self, node): + self.body.append('</DL>\n') + + def visit_definition_list_item(self, node): + pass + + def depart_definition_list_item(self, node): + pass + + def visit_description(self, node): + self.body.append('<TD>\n') + + def depart_description(self, node): + self.body.append('</TD>') + + def visit_docinfo(self, node): + self.body.append(self.starttag(node, 'table', CLASS='docinfo', + frame="void", rules="none")) + self.body.append('<COL CLASS="docinfo-name">\n' + '<COL CLASS="docinfo-content">\n' + '<TBODY VALIGN="top">\n') + + def depart_docinfo(self, node): + self.body.append('</TBODY>\n</TABLE>\n') + + def visit_docinfo_item(self, node, name): + self.head.append('<META NAME="%s" CONTENT="%s">\n' + % (name, self.encode(node.astext()))) + self.body.append(self.starttag(node, 'tr', '')) + self.body.append('<TD>\n' + '<P CLASS="docinfo-name">%s:</P>\n' + '</TD><TD>\n' + '<P>' % self.language.labels[name]) + + def depart_docinfo_item(self): + self.body.append('</P>\n</TD></TR>') + + def visit_doctest_block(self, node): + self.body.append(self.starttag(node, 'pre', CLASS='doctest-block')) + + def depart_doctest_block(self, node): + self.body.append('</PRE>\n') + + def visit_document(self, node): + self.body.append(self.starttag(node, 'div', CLASS='document')) + + def depart_document(self, node): + self.body.append('</DIV>\n') + #self.body.append( + # '<P CLASS="credits">HTML generated from <CODE>%s</CODE> on %s ' + # 'by <A HREF="http://docutils.sourceforge.net/">Docutils</A>.' + # '</P>\n' % (node['source'], time.strftime('%Y-%m-%d'))) + + def visit_emphasis(self, node): + self.body.append('<EM>') + + def depart_emphasis(self, node): + self.body.append('</EM>') + + def visit_entry(self, node): + if isinstance(node.parent.parent, nodes.thead): + tagname = 'th' + else: + tagname = 'td' + atts = {} + if node.has_key('morerows'): + atts['rowspan'] = node['morerows'] + 1 + if node.has_key('morecols'): + atts['colspan'] = node['morecols'] + 1 + self.body.append(self.starttag(node, tagname, **atts)) + self.context.append('</%s>' % tagname.upper()) + if len(node) == 0: # empty cell + self.body.append(' ') + + def depart_entry(self, node): + self.body.append(self.context.pop()) + + def visit_enumerated_list(self, node): + """ + The 'start' attribute does not conform to HTML 4.01's strict.dtd, but + CSS1 doesn't help. CSS2 isn't widely enough supported yet to be + usable. + """ + atts = {} + if node.has_key('start'): + atts['start'] = node['start'] + if node.has_key('enumtype'): + atts['class'] = node['enumtype'] + # @@@ To do: prefix, suffix. How? Change prefix/suffix to a + # single "format" attribute? Use CSS2? + self.body.append(self.starttag(node, 'ol', **atts)) + + def depart_enumerated_list(self, node): + self.body.append('</OL>\n') + + def visit_error(self, node): + self.visit_admonition(node, 'error') + + def depart_error(self, node): + self.depart_admonition() + + def visit_field(self, node): + self.body.append(self.starttag(node, 'tr', CLASS='field')) + + def depart_field(self, node): + self.body.append('</TR>\n') + + def visit_field_argument(self, node): + self.body.append(' ') + self.body.append(self.starttag(node, 'span', '', + CLASS='field-argument')) + + def depart_field_argument(self, node): + self.body.append('</SPAN>') + + def visit_field_body(self, node): + self.body.append(':</P>\n</TD><TD>') + self.body.append(self.starttag(node, 'div', CLASS='field-body')) + + def depart_field_body(self, node): + self.body.append('</DIV></TD>\n') + + def visit_field_list(self, node): + self.body.append(self.starttag(node, 'table', frame='void', + rules='none')) + self.body.append('<COL CLASS="field-name">\n' + '<COL CLASS="field-body">\n' + '<TBODY VALIGN="top">\n') + + def depart_field_list(self, node): + self.body.append('</TBODY>\n</TABLE>\n') + + def visit_field_name(self, node): + self.body.append('<TD>\n') + self.body.append(self.starttag(node, 'p', '', CLASS='field-name')) + + def depart_field_name(self, node): + """ + Leave the end tag to `self.visit_field_body()`, in case there are any + field_arguments. + """ + pass + + def visit_figure(self, node): + self.body.append(self.starttag(node, 'div', CLASS='figure')) + + def depart_figure(self, node): + self.body.append('</DIV>\n') + + def visit_footnote(self, node): + self.body.append(self.starttag(node, 'table', CLASS='footnote', + frame="void", rules="none")) + self.body.append('<COL CLASS="label">\n' + '<COL>\n' + '<TBODY VALIGN="top">\n' + '<TR><TD>\n') + + def depart_footnote(self, node): + self.body.append('</TD></TR>\n' + '</TBODY>\n</TABLE>\n') + + def visit_footnote_reference(self, node): + href = '' + if node.has_key('refid'): + href = '#' + node['refid'] + elif node.has_key('refname'): + href = '#' + self.doctree.nameids[node['refname']] + self.body.append(self.starttag(node, 'a', '', href=href, #node['refid'], + CLASS='footnote-reference')) + + def depart_footnote_reference(self, node): + self.body.append('</A>') + + def visit_hint(self, node): + self.visit_admonition(node, 'hint') + + def depart_hint(self, node): + self.depart_admonition() + + def visit_image(self, node): + atts = node.attributes.copy() + atts['src'] = atts['uri'] + del atts['uri'] + if not atts.has_key('alt'): + atts['alt'] = atts['src'] + self.body.append(self.starttag(node, 'img', '', **atts)) + + def depart_image(self, node): + pass + + def visit_important(self, node): + self.visit_admonition(node, 'important') + + def depart_important(self, node): + self.depart_admonition() + + def visit_interpreted(self, node): + self.body.append('<SPAN class="interpreted">') + + def depart_interpreted(self, node): + self.body.append('</SPAN>') + + def visit_label(self, node): + self.body.append(self.starttag(node, 'p', '[', CLASS='label')) + + def depart_label(self, node): + self.body.append(']</P>\n' + '</TD><TD>\n') + + def visit_legend(self, node): + self.body.append(self.starttag(node, 'div', CLASS='legend')) + + def depart_legend(self, node): + self.body.append('</DIV>\n') + + def visit_list_item(self, node): + self.body.append(self.starttag(node, 'li')) + + def depart_list_item(self, node): + self.body.append('</LI>\n') + + def visit_literal(self, node): + self.body.append('<CODE>') + + def depart_literal(self, node): + self.body.append('</CODE>') + + def visit_literal_block(self, node): + self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) + + def depart_literal_block(self, node): + self.body.append('</PRE>\n') + + def visit_meta(self, node): + self.head.append(self.starttag(node, 'meta', **node.attributes)) + + def depart_meta(self, node): + pass + + def visit_note(self, node): + self.visit_admonition(node, 'note') + + def depart_note(self, node): + self.depart_admonition() + + def visit_option(self, node): + if self.context[-1]: + self.body.append(', ') + + def depart_option(self, node): + self.context[-1] += 1 + + def visit_option_argument(self, node): + self.body.append(node.get('delimiter', ' ')) + self.body.append(self.starttag(node, 'span', '', + CLASS='option-argument')) + + def depart_option_argument(self, node): + self.body.append('</SPAN>') + + def visit_option_group(self, node): + atts = {} + if len(node.astext()) > 14: + atts['colspan'] = 2 + self.context.append('</TR>\n<TR><TD> </TD>') + else: + self.context.append('') + self.body.append(self.starttag(node, 'td', **atts)) + self.body.append('<P><CODE>') + self.context.append(0) + + def depart_option_group(self, node): + self.context.pop() + self.body.append('</CODE></P>\n</TD>') + self.body.append(self.context.pop()) + + def visit_option_list(self, node): + self.body.append( + self.starttag(node, 'table', CLASS='option-list', + frame="void", rules="none", cellspacing=12)) + self.body.append('<COL CLASS="option">\n' + '<COL CLASS="description">\n' + '<TBODY VALIGN="top">\n') + + def depart_option_list(self, node): + self.body.append('</TBODY>\n</TABLE>\n') + + def visit_option_list_item(self, node): + self.body.append(self.starttag(node, 'tr', '')) + + def depart_option_list_item(self, node): + self.body.append('</TR>\n') + + def visit_option_string(self, node): + self.body.append(self.starttag(node, 'span', '', CLASS='option')) + + def depart_option_string(self, node): + self.body.append('</SPAN>') + + def visit_organization(self, node): + self.visit_docinfo_item(node, 'organization') + + def depart_organization(self, node): + self.depart_docinfo_item() + + def visit_paragraph(self, node): + if not self.topic_class == 'contents': + self.body.append(self.starttag(node, 'p', '')) + + def depart_paragraph(self, node): + if self.topic_class == 'contents': + self.body.append('\n') + else: + self.body.append('</P>\n') + + def visit_problematic(self, node): + if node.hasattr('refid'): + self.body.append('<A HREF="#%s">' % node['refid']) + self.context.append('</A>') + else: + self.context.append('') + self.body.append(self.starttag(node, 'span', '', CLASS='problematic')) + + def depart_problematic(self, node): + self.body.append('</SPAN>') + self.body.append(self.context.pop()) + + def visit_raw(self, node): + if node.has_key('format') and node['format'] == 'html': + self.body.append(node.astext()) + raise nodes.SkipNode + + def visit_reference(self, node): + if node.has_key('refuri'): + href = node['refuri'] + elif node.has_key('refid'): + #else: + href = '#' + node['refid'] + elif node.has_key('refname'): + # @@@ Check for non-existent mappings. Here or in a transform? + href = '#' + self.doctree.nameids[node['refname']] + self.body.append(self.starttag(node, 'a', '', href=href, + CLASS='reference')) + + def depart_reference(self, node): + self.body.append('</A>') + + def visit_revision(self, node): + self.visit_docinfo_item(node, 'revision') + + def depart_revision(self, node): + self.depart_docinfo_item() + + def visit_row(self, node): + self.body.append(self.starttag(node, 'tr', '')) + + def depart_row(self, node): + self.body.append('</TR>\n') + + def visit_section(self, node): + self.sectionlevel += 1 + self.body.append(self.starttag(node, 'div', CLASS='section')) + + def depart_section(self, node): + self.sectionlevel -= 1 + self.body.append('</DIV>\n') + + def visit_status(self, node): + self.visit_docinfo_item(node, 'status') + + def depart_status(self, node): + self.depart_docinfo_item() + + def visit_strong(self, node): + self.body.append('<STRONG>') + + def depart_strong(self, node): + self.body.append('</STRONG>') + + def visit_substitution_definition(self, node): + raise nodes.SkipChildren + + def depart_substitution_definition(self, node): + pass + + def visit_substitution_reference(self, node): + self.unimplemented_visit(node) + + def visit_subtitle(self, node): + self.body.append(self.starttag(node, 'H2', '', CLASS='subtitle')) + + def depart_subtitle(self, node): + self.body.append('</H1>\n') + + def visit_system_message(self, node): + if node['level'] < self.doctree.reporter['writer'].warninglevel: + raise nodes.SkipNode + self.body.append(self.starttag(node, 'div', CLASS='system-message')) + self.body.append('<P CLASS="system-message-title">') + if node.hasattr('backrefs'): + backrefs = node['backrefs'] + if len(backrefs) == 1: + self.body.append('<A HREF="#%s">%s</A> ' + '(level %s system message)</P>\n' + % (backrefs[0], node['type'], node['level'])) + else: + i = 1 + backlinks = [] + for backref in backrefs: + backlinks.append('<A HREF="#%s">%s</A>' % (backref, i)) + i += 1 + self.body.append('%s (%s; level %s system message)</P>\n' + % (node['type'], '|'.join(backlinks), + node['level'])) + else: + self.body.append('%s (level %s system message)</P>\n' + % (node['type'], node['level'])) + + def depart_system_message(self, node): + self.body.append('</DIV>\n') + + def visit_table(self, node): + self.body.append( + self.starttag(node, 'table', frame='border', rules='all')) + + def depart_table(self, node): + self.body.append('</TABLE>\n') + + def visit_target(self, node): + if not (node.has_key('refuri') or node.has_key('refid') + or node.has_key('refname')): + self.body.append(self.starttag(node, 'a', '', CLASS='target')) + self.context.append('</A>') + else: + self.context.append('') + + def depart_target(self, node): + self.body.append(self.context.pop()) + + def visit_tbody(self, node): + self.body.append(self.context.pop()) # '</COLGROUP>\n' or '' + self.body.append(self.starttag(node, 'tbody', valign='top')) + + def depart_tbody(self, node): + self.body.append('</TBODY>\n') + + def visit_term(self, node): + self.body.append(self.starttag(node, 'dt', '')) + + def depart_term(self, node): + """ + Leave the end tag to `self.visit_definition()`, in case there's a + classifier. + """ + pass + + def visit_tgroup(self, node): + self.body.append(self.starttag(node, 'colgroup')) + self.context.append('</COLGROUP>\n') + + def depart_tgroup(self, node): + pass + + def visit_thead(self, node): + self.body.append(self.context.pop()) # '</COLGROUP>\n' + self.context.append('') + self.body.append(self.starttag(node, 'thead', valign='bottom')) + + def depart_thead(self, node): + self.body.append('</THEAD>\n') + + def visit_tip(self, node): + self.visit_admonition(node, 'tip') + + def depart_tip(self, node): + self.depart_admonition() + + def visit_title(self, node): + """Only 6 section levels are supported by HTML.""" + if isinstance(node.parent, nodes.topic): + self.body.append( + self.starttag(node, 'P', '', CLASS='topic-title')) + self.context.append('</P>\n') + elif self.sectionlevel == 0: + self.head.append('<TITLE>%s\n' + % self.encode(node.astext())) + self.body.append(self.starttag(node, 'H1', '', CLASS='title')) + self.context.append('\n') + else: + self.body.append( + self.starttag(node, 'H%s' % self.sectionlevel, '')) + context = '' + if node.hasattr('refid'): + self.body.append('' % node['refid']) + context = '' + self.context.append('%s\n' % (context, self.sectionlevel)) + + def depart_title(self, node): + self.body.append(self.context.pop()) + + def visit_topic(self, node): + self.body.append(self.starttag(node, 'div', CLASS='topic')) + self.topic_class = node.get('class') + + def depart_topic(self, node): + self.body.append('\n') + self.topic_class = '' + + def visit_transition(self, node): + self.body.append(self.starttag(node, 'hr')) + + def depart_transition(self, node): + pass + + def visit_version(self, node): + self.visit_docinfo_item(node, 'version') + + def depart_version(self, node): + self.depart_docinfo_item() + + def visit_warning(self, node): + self.visit_admonition(node, 'warning') + + def depart_warning(self, node): + self.depart_admonition() + + def unimplemented_visit(self, node): + raise NotImplementedError('visiting unimplemented node type: %s' + % node.__class__.__name__) diff --git a/docutils/writers/pprint.py b/docutils/writers/pprint.py new file mode 100644 index 000000000..a34c2a920 --- /dev/null +++ b/docutils/writers/pprint.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Simple internal document tree Writer, writes indented pseudo-XML. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import writers + + +class Writer(writers.Writer): + + output = None + """Final translated form of `document`.""" + + def translate(self): + self.output = self.document.pformat() + + def record(self): + self.recordfile(self.output, self.destination) diff --git a/install.py b/install.py new file mode 100755 index 000000000..be9ed238b --- /dev/null +++ b/install.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# $Id$ + +""" +This is a quick & dirty installation shortcut. It is equivalent to the +command:: + + python setup.py install + +However, the shortcut lacks error checking! +""" + +from distutils import core +from setup import do_setup + +if __name__ == '__main__' : + core._setup_stop_after = 'config' + dist = do_setup() + dist.commands = ['install'] + dist.run_commands() diff --git a/setup.py b/setup.py new file mode 100755 index 000000000..23aa0ce4a --- /dev/null +++ b/setup.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# $Id$ + +from distutils.core import setup + +def do_setup(): + dist = setup( + name = 'Docutils', + description = 'Python Documentation Utilities', + #long_description = '', + url = 'http://docutils.sourceforge.net/', + version = 'pre-0.1', + author = 'David Goodger', + author_email = 'goodger@users.sourceforge.net', + license = 'public domain, Python (see COPYING.txt)', + packages = ['docutils', 'docutils.readers', 'docutils.writers', + 'docutils.transforms', 'docutils.languages', + 'docutils.parsers', 'docutils.parsers.restructuredtext', + 'docutils.parsers.restructuredtext.directives', + 'docutils.parsers.restructuredtext.languages']) + return dist + +if __name__ == '__main__' : + do_setup() diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py new file mode 100644 index 000000000..766eafde6 --- /dev/null +++ b/test/DocutilsTestSupport.py @@ -0,0 +1,379 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger; Garth Kidd +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Exports the following: + +:Modules: + - `statemachine` is 'docutils.statemachine' + - `nodes` is 'docutils.nodes' + - `urischemes` is 'docutils.urischemes' + - `utils` is 'docutils.utils' + - `transforms` is 'docutils.transforms' + - `states` is 'docutils.parsers.rst.states' + - `tableparser` is 'docutils.parsers.rst.tableparser' + +:Classes: + - `CustomTestSuite` + - `CustomTestCase` + - `ParserTestSuite` + - `ParserTestCase` + - `TableParserTestSuite` + - `TableParserTestCase` +""" +__docformat__ = 'reStructuredText' + +import UnitTestFolder +import sys, os, unittest, difflib, inspect, os, sys +from pprint import pformat +import docutils +from docutils import statemachine, nodes, urischemes, utils, transforms +from docutils.transforms import universal +from docutils.parsers import rst +from docutils.parsers.rst import states, tableparser, directives, languages +from docutils.statemachine import string2lines + +try: + import mypdb as pdb +except: + import pdb + + +class CustomTestSuite(unittest.TestSuite): + + """ + A collection of custom TestCases. + + """ + + id = '' + """Identifier for the TestSuite. Prepended to the + TestCase identifiers to make identification easier.""" + + nextTestCaseId = 0 + """The next identifier to use for non-identified test cases.""" + + def __init__(self, tests=(), id=None): + """ + Initialize the CustomTestSuite. + + Arguments: + + id -- identifier for the suite, prepended to test cases. + """ + unittest.TestSuite.__init__(self, tests) + if id is None: + outerframes = inspect.getouterframes(inspect.currentframe()) + mypath = outerframes[0][1] + for outerframe in outerframes[1:]: + if outerframe[3] != '__init__': + callerpath = outerframe[1] + break + mydir, myname = os.path.split(mypath) + if not mydir: + mydir = os.curdir + if callerpath.startswith(mydir): + self.id = callerpath[len(mydir) + 1:] # caller's module + else: + self.id = callerpath + else: + self.id = id + + def addTestCase(self, testCaseClass, methodName, input, expected, + id=None, runInDebugger=0, shortDescription=None, + **kwargs): + """ + Create a custom TestCase in the CustomTestSuite. + Also return it, just in case. + + Arguments: + + testCaseClass -- + methodName -- + input -- input to the parser. + expected -- expected output from the parser. + id -- unique test identifier, used by the test framework. + runInDebugger -- if true, run this test under the pdb debugger. + shortDescription -- override to default test description. + """ + if id is None: # generate id if required + id = self.nextTestCaseId + self.nextTestCaseId += 1 + # test identifier will become suiteid.testid + tcid = '%s: %s' % (self.id, id) + # generate and add test case + tc = testCaseClass(methodName, input, expected, tcid, + runInDebugger=runInDebugger, + shortDescription=shortDescription, + **kwargs) + self.addTest(tc) + return tc + + +class CustomTestCase(unittest.TestCase): + + compare = difflib.Differ().compare + """Comparison method shared by all subclasses.""" + + def __init__(self, methodName, input, expected, id, + runInDebugger=0, shortDescription=None): + """ + Initialise the CustomTestCase. + + Arguments: + + methodName -- name of test method to run. + input -- input to the parser. + expected -- expected output from the parser. + id -- unique test identifier, used by the test framework. + runInDebugger -- if true, run this test under the pdb debugger. + shortDescription -- override to default test description. + """ + self.id = id + self.input = input + self.expected = expected + self.runInDebugger = runInDebugger + # Ring your mother. + unittest.TestCase.__init__(self, methodName) + + def __str__(self): + """ + Return string conversion. Overridden to give test id, in addition to + method name. + """ + return '%s; %s' % (self.id, unittest.TestCase.__str__(self)) + + def compareOutput(self, input, output, expected): + """`input`, `output`, and `expected` should all be strings.""" + try: + self.assertEquals('\n' + output, '\n' + expected) + except AssertionError: + print >>sys.stderr, '\n%s\ninput:' % (self,) + print >>sys.stderr, input + print >>sys.stderr, '-: expected\n+: output' + print >>sys.stderr, ''.join(self.compare(expected.splitlines(1), + output.splitlines(1))) + raise + + +class TransformTestSuite(CustomTestSuite): + + """ + A collection of TransformTestCases. + + A TransformTestSuite instance manufactures TransformTestCases, + keeps track of them, and provides a shared test fixture (a-la + setUp and tearDown). + """ + + def __init__(self, parser): + self.parser = parser + """Parser shared by all test cases.""" + + CustomTestSuite.__init__(self) + + def generateTests(self, dict, dictname='totest', + testmethod='test_transforms'): + """ + Stock the suite with test cases generated from a test data dictionary. + + Each dictionary key (test type's name) maps to a list of transform + classes and list of tests. Each test is a list: input, expected + output, optional modifier. The optional third entry, a behavior + modifier, can be 0 (temporarily disable this test) or 1 (run this test + under the pdb debugger). Tests should be self-documenting and not + require external comments. + """ + for name, (transforms, cases) in dict.items(): + for casenum in range(len(cases)): + case = cases[casenum] + runInDebugger = 0 + if len(case)==3: + if case[2]: + runInDebugger = 1 + else: + continue + self.addTestCase( + TransformTestCase, testmethod, + transforms=transforms, parser=self.parser, + input=case[0], expected=case[1], + id='%s[%r][%s]' % (dictname, name, casenum), + runInDebugger=runInDebugger) + + +class TransformTestCase(CustomTestCase): + + """ + Output checker for the transform. + + Should probably be called TransformOutputChecker, but I can deal with + that later when/if someone comes up with a category of transform test + cases that have nothing to do with the input and output of the transform. + """ + + def __init__(self, *args, **kwargs): + self.transforms = kwargs['transforms'] + """List of transforms to perform for this test case.""" + + self.parser = kwargs['parser'] + """Input parser for this test case.""" + + del kwargs['transforms'], kwargs['parser'] # only wanted here + CustomTestCase.__init__(self, *args, **kwargs) + + def test_transforms(self): + if self.runInDebugger: + pdb.set_trace() + doctree = utils.newdocument(warninglevel=5, errorlevel=5, + debug=UnitTestFolder.debug) + self.parser.parse(self.input, doctree) + for transformClass in (self.transforms + universal.test_transforms): + transformClass(doctree).transform() + output = doctree.pformat() + self.compareOutput(self.input, output, self.expected) + + def test_transforms_verbosely(self): + if self.runInDebugger: + pdb.set_trace() + print '\n', self.id + print '-' * 70 + print self.input + doctree = utils.newdocument(warninglevel=5, errorlevel=5, + debug=UnitTestFolder.debug) + self.parser.parse(self.input, doctree) + print '-' * 70 + print doctree.pformat() + for transformClass in self.transforms: + transformClass(doctree).transform() + output = doctree.pformat() + print '-' * 70 + print output + self.compareOutput(self.input, output, self.expected) + + +class ParserTestSuite(CustomTestSuite): + + """ + A collection of ParserTestCases. + + A ParserTestSuite instance manufactures ParserTestCases, + keeps track of them, and provides a shared test fixture (a-la + setUp and tearDown). + """ + + def generateTests(self, dict, dictname='totest'): + """ + Stock the suite with test cases generated from a test data dictionary. + + Each dictionary key (test type name) maps to a list of tests. Each + test is a list: input, expected output, optional modifier. The + optional third entry, a behavior modifier, can be 0 (temporarily + disable this test) or 1 (run this test under the pdb debugger). Tests + should be self-documenting and not require external comments. + """ + for name, cases in dict.items(): + for casenum in range(len(cases)): + case = cases[casenum] + runInDebugger = 0 + if len(case)==3: + if case[2]: + runInDebugger = 1 + else: + continue + self.addTestCase( + ParserTestCase, 'test_parser', + input=case[0], expected=case[1], + id='%s[%r][%s]' % (dictname, name, casenum), + runInDebugger=runInDebugger) + + +class ParserTestCase(CustomTestCase): + + """ + Output checker for the parser. + + Should probably be called ParserOutputChecker, but I can deal with + that later when/if someone comes up with a category of parser test + cases that have nothing to do with the input and output of the parser. + """ + + parser = rst.Parser() + """Parser shared by all ParserTestCases.""" + + def test_parser(self): + if self.runInDebugger: + pdb.set_trace() + document = utils.newdocument(warninglevel=5, errorlevel=5, + debug=UnitTestFolder.debug) + self.parser.parse(self.input, document) + output = document.pformat() + self.compareOutput(self.input, output, self.expected) + + +class TableParserTestSuite(CustomTestSuite): + + """ + A collection of TableParserTestCases. + + A TableParserTestSuite instance manufactures TableParserTestCases, + keeps track of them, and provides a shared test fixture (a-la + setUp and tearDown). + """ + + def generateTests(self, dict, dictname='totest'): + """ + Stock the suite with test cases generated from a test data dictionary. + + Each dictionary key (test type name) maps to a list of tests. Each + test is a list: an input table, expected output from parsegrid(), + expected output from parse(), optional modifier. The optional fourth + entry, a behavior modifier, can be 0 (temporarily disable this test) + or 1 (run this test under the pdb debugger). Tests should be + self-documenting and not require external comments. + """ + for name, cases in dict.items(): + for casenum in range(len(cases)): + case = cases[casenum] + runInDebugger = 0 + if len(case) == 4: + if case[3]: + runInDebugger = 1 + else: + continue + self.addTestCase(TableParserTestCase, 'test_parsegrid', + input=case[0], expected=case[1], + id='%s[%r][%s]' % (dictname, name, casenum), + runInDebugger=runInDebugger) + self.addTestCase(TableParserTestCase, 'test_parse', + input=case[0], expected=case[2], + id='%s[%r][%s]' % (dictname, name, casenum), + runInDebugger=runInDebugger) + + +class TableParserTestCase(CustomTestCase): + + parser = tableparser.TableParser() + + def test_parsegrid(self): + self.parser.setup(string2lines(self.input)) + try: + self.parser.findheadbodysep() + self.parser.parsegrid() + output = self.parser.cells + except Exception, details: + output = '%s: %s' % (details.__class__.__name__, details) + self.compareOutput(self.input, pformat(output) + '\n', + pformat(self.expected) + '\n') + + def test_parse(self): + try: + output = self.parser.parse(string2lines(self.input)) + except Exception, details: + output = '%s: %s' % (details.__class__.__name__, details) + self.compareOutput(self.input, pformat(output) + '\n', + pformat(self.expected) + '\n') diff --git a/test/UnitTestFolder.py b/test/UnitTestFolder.py new file mode 100644 index 000000000..529d8c7e8 --- /dev/null +++ b/test/UnitTestFolder.py @@ -0,0 +1,135 @@ +#! /usr/bin/env python + +""" +:Author: Garth Kidd +:Contact: garth@deadlybloodyserious.com +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. +""" + +import sys, os, getopt, types, unittest, re + + +# So that individual test modules can share a bit of state, +# `UnitTestFolder` acts as an intermediary for the following +# variables: +debug = 0 +verbosity = 1 + +USAGE = """\ +Usage: test_whatever [options] + +Options: + -h, --help Show this message + -v, --verbose Verbose output + -q, --quiet Minimal output + -d, --debug Debug mode +""" + +def usageExit(msg=None): + """Print usage and exit.""" + if msg: + print msg + print USAGE + sys.exit(2) + +def parseArgs(argv=sys.argv): + """Parse command line arguments and set TestFramework state. + + State is to be acquired by test_* modules by a grotty hack: + ``from TestFramework import *``. For this stylistic + transgression, I expect to be first up against the wall + when the revolution comes. --Garth""" + global verbosity, debug + try: + options, args = getopt.getopt(argv[1:], 'hHvqd', + ['help', 'verbose', 'quiet', 'debug']) + for opt, value in options: + if opt in ('-h', '-H', '--help'): + usageExit() + if opt in ('-q', '--quiet'): + verbosity = 0 + if opt in ('-v', '--verbose'): + verbosity = 2 + if opt in ('-d', '--debug'): + debug =1 + if len(args) != 0: + usageExit("No command-line arguments supported yet.") + except getopt.error, msg: + self.usageExit(msg) + +def loadModulesFromFolder(path, name='', subfolders=None): + """ + Return a test suite composed of all the tests from modules in a folder. + + Search for modules in directory `path`, beginning with `name`. If + `subfolders` is true, search subdirectories (also beginning with `name`) + recursively. + """ + testLoader = unittest.defaultTestLoader + testSuite = unittest.TestSuite() + testModules = [] + paths = [path] + while paths: + p = paths.pop(0) + if not p: + p = os.curdir + files = os.listdir(p) + for filename in files: + if filename.startswith(name): + fullpath = os.path.join(p, filename) + if filename.endswith('.py'): + testModules.append(fullpath) + elif subfolders and os.path.isdir(fullpath): + paths.append(fullpath) + sys.path.insert(0, '') + # Import modules and add their tests to the suite. + for modpath in testModules: + if debug: + print >>sys.stderr, "importing %s" % modpath + sys.path[0], filename = os.path.split(modpath) + modname = filename[:-3] # strip off the '.py' + module = __import__(modname) + # if there's a suite defined, incorporate its contents + try: + suite = getattr(module, 'suite') + except AttributeError: + # Look for individual tests + moduleTests = testLoader.loadTestsFromModule(module) + # unittest.TestSuite.addTests() doesn't work as advertised, + # as it can't load tests from another TestSuite, so we have + # to cheat: + testSuite.addTest(moduleTests) + continue + if type(suite) == types.FunctionType: + testSuite.addTest(suite()) + elif type(suite) == types.InstanceType \ + and isinstance(suite, unittest.TestSuite): + testSuite.addTest(suite) + else: + raise AssertionError, "don't understand suite (%s)" % modpath + return testSuite + + +def main(suite=None): + """ + Shared `main` for any individual test_* file. + + suite -- TestSuite to run. If not specified, look for any globally defined + tests and run them. + """ + parseArgs() + if suite is None: + # Load any globally defined tests. + suite = unittest.defaultTestLoader.loadTestsFromModule( + __import__('__main__')) + if debug: + print >>sys.stderr, "Debug: Suite=%s" % suite + testRunner = unittest.TextTestRunner(verbosity=verbosity) + # run suites (if we were called from test_all) or suite... + if type(suite) == type([]): + for s in suite: + testRunner.run(s) + else: + testRunner.run(suite) diff --git a/test/alltests.py b/test/alltests.py new file mode 100755 index 000000000..930cbdc1b --- /dev/null +++ b/test/alltests.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. +""" + +import time +start = time.time() + +import sys, os + + +class Tee: + + """Write to a file and a stream (default: stdout) simultaneously.""" + + def __init__(self, filename, stream=sys.__stdout__): + self.file = open(filename, 'w') + self.stream = stream + + def write(self, string): + string = string.encode('raw-unicode-escape') + self.stream.write(string) + self.file.write(string) + +# must redirect stderr *before* first import of unittest +sys.stdout = sys.stderr = Tee('alltests.out') + +import UnitTestFolder + + +if __name__ == '__main__': + path, script = os.path.split(sys.argv[0]) + suite = UnitTestFolder.loadModulesFromFolder(path, 'test_', subfolders=1) + UnitTestFolder.main(suite) + finish = time.time() + print 'Elapsed time: %.3f seconds' % (finish - start) diff --git a/test/difflib.py b/test/difflib.py new file mode 100644 index 000000000..a41d4d5ba --- /dev/null +++ b/test/difflib.py @@ -0,0 +1,1089 @@ +#! /usr/bin/env python + +""" +Module difflib -- helpers for computing deltas between objects. + +Function get_close_matches(word, possibilities, n=3, cutoff=0.6): + Use SequenceMatcher to return list of the best "good enough" matches. + +Function ndiff(a, b): + Return a delta: the difference between `a` and `b` (lists of strings). + +Function restore(delta, which): + Return one of the two sequences that generated an ndiff delta. + +Class SequenceMatcher: + A flexible class for comparing pairs of sequences of any type. + +Class Differ: + For producing human-readable deltas from sequences of lines of text. +""" + +__all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher', + 'Differ'] + +TRACE = 0 + +class SequenceMatcher: + + """ + SequenceMatcher is a flexible class for comparing pairs of sequences of + any type, so long as the sequence elements are hashable. The basic + algorithm predates, and is a little fancier than, an algorithm + published in the late 1980's by Ratcliff and Obershelp under the + hyperbolic name "gestalt pattern matching". The basic idea is to find + the longest contiguous matching subsequence that contains no "junk" + elements (R-O doesn't address junk). The same idea is then applied + recursively to the pieces of the sequences to the left and to the right + of the matching subsequence. This does not yield minimal edit + sequences, but does tend to yield matches that "look right" to people. + + SequenceMatcher tries to compute a "human-friendly diff" between two + sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the + longest *contiguous* & junk-free matching subsequence. That's what + catches peoples' eyes. The Windows(tm) windiff has another interesting + notion, pairing up elements that appear uniquely in each sequence. + That, and the method here, appear to yield more intuitive difference + reports than does diff. This method appears to be the least vulnerable + to synching up on blocks of "junk lines", though (like blank lines in + ordinary text files, or maybe "

" lines in HTML files). That may be + because this is the only method of the 3 that has a *concept* of + "junk" . + + Example, comparing two strings, and considering blanks to be "junk": + + >>> s = SequenceMatcher(lambda x: x == " ", + ... "private Thread currentThread;", + ... "private volatile Thread currentThread;") + >>> + + .ratio() returns a float in [0, 1], measuring the "similarity" of the + sequences. As a rule of thumb, a .ratio() value over 0.6 means the + sequences are close matches: + + >>> print round(s.ratio(), 3) + 0.866 + >>> + + If you're only interested in where the sequences match, + .get_matching_blocks() is handy: + + >>> for block in s.get_matching_blocks(): + ... print "a[%d] and b[%d] match for %d elements" % block + a[0] and b[0] match for 8 elements + a[8] and b[17] match for 6 elements + a[14] and b[23] match for 15 elements + a[29] and b[38] match for 0 elements + + Note that the last tuple returned by .get_matching_blocks() is always a + dummy, (len(a), len(b), 0), and this is the only case in which the last + tuple element (number of elements matched) is 0. + + If you want to know how to change the first sequence into the second, + use .get_opcodes(): + + >>> for opcode in s.get_opcodes(): + ... print "%6s a[%d:%d] b[%d:%d]" % opcode + equal a[0:8] b[0:8] + insert a[8:8] b[8:17] + equal a[8:14] b[17:23] + equal a[14:29] b[23:38] + + See the Differ class for a fancy human-friendly file differencer, which + uses SequenceMatcher both to compare sequences of lines, and to compare + sequences of characters within similar (near-matching) lines. + + See also function get_close_matches() in this module, which shows how + simple code building on SequenceMatcher can be used to do useful work. + + Timing: Basic R-O is cubic time worst case and quadratic time expected + case. SequenceMatcher is quadratic time for the worst case and has + expected-case behavior dependent in a complicated way on how many + elements the sequences have in common; best case time is linear. + + Methods: + + __init__(isjunk=None, a='', b='') + Construct a SequenceMatcher. + + set_seqs(a, b) + Set the two sequences to be compared. + + set_seq1(a) + Set the first sequence to be compared. + + set_seq2(b) + Set the second sequence to be compared. + + find_longest_match(alo, ahi, blo, bhi) + Find longest matching block in a[alo:ahi] and b[blo:bhi]. + + get_matching_blocks() + Return list of triples describing matching subsequences. + + get_opcodes() + Return list of 5-tuples describing how to turn a into b. + + ratio() + Return a measure of the sequences' similarity (float in [0,1]). + + quick_ratio() + Return an upper bound on .ratio() relatively quickly. + + real_quick_ratio() + Return an upper bound on ratio() very quickly. + """ + + def __init__(self, isjunk=None, a='', b=''): + """Construct a SequenceMatcher. + + Optional arg isjunk is None (the default), or a one-argument + function that takes a sequence element and returns true iff the + element is junk. None is equivalent to passing "lambda x: 0", i.e. + no elements are considered to be junk. For example, pass + lambda x: x in " \\t" + if you're comparing lines as sequences of characters, and don't + want to synch up on blanks or hard tabs. + + Optional arg a is the first of two sequences to be compared. By + default, an empty string. The elements of a must be hashable. See + also .set_seqs() and .set_seq1(). + + Optional arg b is the second of two sequences to be compared. By + default, an empty string. The elements of b must be hashable. See + also .set_seqs() and .set_seq2(). + """ + + # Members: + # a + # first sequence + # b + # second sequence; differences are computed as "what do + # we need to do to 'a' to change it into 'b'?" + # b2j + # for x in b, b2j[x] is a list of the indices (into b) + # at which x appears; junk elements do not appear + # b2jhas + # b2j.has_key + # fullbcount + # for x in b, fullbcount[x] == the number of times x + # appears in b; only materialized if really needed (used + # only for computing quick_ratio()) + # matching_blocks + # a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k]; + # ascending & non-overlapping in i and in j; terminated by + # a dummy (len(a), len(b), 0) sentinel + # opcodes + # a list of (tag, i1, i2, j1, j2) tuples, where tag is + # one of + # 'replace' a[i1:i2] should be replaced by b[j1:j2] + # 'delete' a[i1:i2] should be deleted + # 'insert' b[j1:j2] should be inserted + # 'equal' a[i1:i2] == b[j1:j2] + # isjunk + # a user-supplied function taking a sequence element and + # returning true iff the element is "junk" -- this has + # subtle but helpful effects on the algorithm, which I'll + # get around to writing up someday <0.9 wink>. + # DON'T USE! Only __chain_b uses this. Use isbjunk. + # isbjunk + # for x in b, isbjunk(x) == isjunk(x) but much faster; + # it's really the has_key method of a hidden dict. + # DOES NOT WORK for x in a! + + self.isjunk = isjunk + self.a = self.b = None + self.set_seqs(a, b) + + def set_seqs(self, a, b): + """Set the two sequences to be compared. + + >>> s = SequenceMatcher() + >>> s.set_seqs("abcd", "bcde") + >>> s.ratio() + 0.75 + """ + + self.set_seq1(a) + self.set_seq2(b) + + def set_seq1(self, a): + """Set the first sequence to be compared. + + The second sequence to be compared is not changed. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.set_seq1("bcde") + >>> s.ratio() + 1.0 + >>> + + SequenceMatcher computes and caches detailed information about the + second sequence, so if you want to compare one sequence S against + many sequences, use .set_seq2(S) once and call .set_seq1(x) + repeatedly for each of the other sequences. + + See also set_seqs() and set_seq2(). + """ + + if a is self.a: + return + self.a = a + self.matching_blocks = self.opcodes = None + + def set_seq2(self, b): + """Set the second sequence to be compared. + + The first sequence to be compared is not changed. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.set_seq2("abcd") + >>> s.ratio() + 1.0 + >>> + + SequenceMatcher computes and caches detailed information about the + second sequence, so if you want to compare one sequence S against + many sequences, use .set_seq2(S) once and call .set_seq1(x) + repeatedly for each of the other sequences. + + See also set_seqs() and set_seq1(). + """ + + if b is self.b: + return + self.b = b + self.matching_blocks = self.opcodes = None + self.fullbcount = None + self.__chain_b() + + # For each element x in b, set b2j[x] to a list of the indices in + # b where x appears; the indices are in increasing order; note that + # the number of times x appears in b is len(b2j[x]) ... + # when self.isjunk is defined, junk elements don't show up in this + # map at all, which stops the central find_longest_match method + # from starting any matching block at a junk element ... + # also creates the fast isbjunk function ... + # note that this is only called when b changes; so for cross-product + # kinds of matches, it's best to call set_seq2 once, then set_seq1 + # repeatedly + + def __chain_b(self): + # Because isjunk is a user-defined (not C) function, and we test + # for junk a LOT, it's important to minimize the number of calls. + # Before the tricks described here, __chain_b was by far the most + # time-consuming routine in the whole module! If anyone sees + # Jim Roskind, thank him again for profile.py -- I never would + # have guessed that. + # The first trick is to build b2j ignoring the possibility + # of junk. I.e., we don't call isjunk at all yet. Throwing + # out the junk later is much cheaper than building b2j "right" + # from the start. + b = self.b + self.b2j = b2j = {} + self.b2jhas = b2jhas = b2j.has_key + for i in xrange(len(b)): + elt = b[i] + if b2jhas(elt): + b2j[elt].append(i) + else: + b2j[elt] = [i] + + # Now b2j.keys() contains elements uniquely, and especially when + # the sequence is a string, that's usually a good deal smaller + # than len(string). The difference is the number of isjunk calls + # saved. + isjunk, junkdict = self.isjunk, {} + if isjunk: + for elt in b2j.keys(): + if isjunk(elt): + junkdict[elt] = 1 # value irrelevant; it's a set + del b2j[elt] + + # Now for x in b, isjunk(x) == junkdict.has_key(x), but the + # latter is much faster. Note too that while there may be a + # lot of junk in the sequence, the number of *unique* junk + # elements is probably small. So the memory burden of keeping + # this dict alive is likely trivial compared to the size of b2j. + self.isbjunk = junkdict.has_key + + def find_longest_match(self, alo, ahi, blo, bhi): + """Find longest matching block in a[alo:ahi] and b[blo:bhi]. + + If isjunk is not defined: + + Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where + alo <= i <= i+k <= ahi + blo <= j <= j+k <= bhi + and for all (i',j',k') meeting those conditions, + k >= k' + i <= i' + and if i == i', j <= j' + + In other words, of all maximal matching blocks, return one that + starts earliest in a, and of all those maximal matching blocks that + start earliest in a, return the one that starts earliest in b. + + >>> s = SequenceMatcher(None, " abcd", "abcd abcd") + >>> s.find_longest_match(0, 5, 0, 9) + (0, 4, 5) + + If isjunk is defined, first the longest matching block is + determined as above, but with the additional restriction that no + junk element appears in the block. Then that block is extended as + far as possible by matching (only) junk elements on both sides. So + the resulting block never matches on junk except as identical junk + happens to be adjacent to an "interesting" match. + + Here's the same example as before, but considering blanks to be + junk. That prevents " abcd" from matching the " abcd" at the tail + end of the second sequence directly. Instead only the "abcd" can + match, and matches the leftmost "abcd" in the second sequence: + + >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") + >>> s.find_longest_match(0, 5, 0, 9) + (1, 0, 4) + + If no blocks match, return (alo, blo, 0). + + >>> s = SequenceMatcher(None, "ab", "c") + >>> s.find_longest_match(0, 2, 0, 1) + (0, 0, 0) + """ + + # CAUTION: stripping common prefix or suffix would be incorrect. + # E.g., + # ab + # acab + # Longest matching block is "ab", but if common prefix is + # stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + # strip, so ends up claiming that ab is changed to acab by + # inserting "ca" in the middle. That's minimal but unintuitive: + # "it's obvious" that someone inserted "ac" at the front. + # Windiff ends up at the same place as diff, but by pairing up + # the unique 'b's and then matching the first two 'a's. + + a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk + besti, bestj, bestsize = alo, blo, 0 + # find longest junk-free match + # during an iteration of the loop, j2len[j] = length of longest + # junk-free match ending with a[i-1] and b[j] + j2len = {} + nothing = [] + for i in xrange(alo, ahi): + # look at all instances of a[i] in b; note that because + # b2j has no junk keys, the loop is skipped if a[i] is junk + j2lenget = j2len.get + newj2len = {} + for j in b2j.get(a[i], nothing): + # a[i] matches b[j] + if j < blo: + continue + if j >= bhi: + break + k = newj2len[j] = j2lenget(j-1, 0) + 1 + if k > bestsize: + besti, bestj, bestsize = i-k+1, j-k+1, k + j2len = newj2len + + # Now that we have a wholly interesting match (albeit possibly + # empty!), we may as well suck up the matching junk on each + # side of it too. Can't think of a good reason not to, and it + # saves post-processing the (possibly considerable) expense of + # figuring out what to do with it. In the case of an empty + # interesting match, this is clearly the right thing to do, + # because no other kind of match is possible in the regions. + while besti > alo and bestj > blo and \ + isbjunk(b[bestj-1]) and \ + a[besti-1] == b[bestj-1]: + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + while besti+bestsize < ahi and bestj+bestsize < bhi and \ + isbjunk(b[bestj+bestsize]) and \ + a[besti+bestsize] == b[bestj+bestsize]: + bestsize = bestsize + 1 + + if TRACE: + print "get_matching_blocks", alo, ahi, blo, bhi + print " returns", besti, bestj, bestsize + return besti, bestj, bestsize + + def get_matching_blocks(self): + """Return list of triples describing matching subsequences. + + Each triple is of the form (i, j, n), and means that + a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in + i and in j. + + The last triple is a dummy, (len(a), len(b), 0), and is the only + triple with n==0. + + >>> s = SequenceMatcher(None, "abxcd", "abcd") + >>> s.get_matching_blocks() + [(0, 0, 2), (3, 2, 2), (5, 4, 0)] + """ + + if self.matching_blocks is not None: + return self.matching_blocks + self.matching_blocks = [] + la, lb = len(self.a), len(self.b) + self.__helper(0, la, 0, lb, self.matching_blocks) + self.matching_blocks.append( (la, lb, 0) ) + if TRACE: + print '*** matching blocks', self.matching_blocks + return self.matching_blocks + + # builds list of matching blocks covering a[alo:ahi] and + # b[blo:bhi], appending them in increasing order to answer + + def __helper(self, alo, ahi, blo, bhi, answer): + i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi) + # a[alo:i] vs b[blo:j] unknown + # a[i:i+k] same as b[j:j+k] + # a[i+k:ahi] vs b[j+k:bhi] unknown + if k: + if alo < i and blo < j: + self.__helper(alo, i, blo, j, answer) + answer.append(x) + if i+k < ahi and j+k < bhi: + self.__helper(i+k, ahi, j+k, bhi, answer) + + def get_opcodes(self): + """Return list of 5-tuples describing how to turn a into b. + + Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple + has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the + tuple preceding it, and likewise for j1 == the previous j2. + + The tags are strings, with these meanings: + + 'replace': a[i1:i2] should be replaced by b[j1:j2] + 'delete': a[i1:i2] should be deleted. + Note that j1==j2 in this case. + 'insert': b[j1:j2] should be inserted at a[i1:i1]. + Note that i1==i2 in this case. + 'equal': a[i1:i2] == b[j1:j2] + + >>> a = "qabxcd" + >>> b = "abycdf" + >>> s = SequenceMatcher(None, a, b) + >>> for tag, i1, i2, j1, j2 in s.get_opcodes(): + ... print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" % + ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2])) + delete a[0:1] (q) b[0:0] () + equal a[1:3] (ab) b[0:2] (ab) + replace a[3:4] (x) b[2:3] (y) + equal a[4:6] (cd) b[3:5] (cd) + insert a[6:6] () b[5:6] (f) + """ + + if self.opcodes is not None: + return self.opcodes + i = j = 0 + self.opcodes = answer = [] + for ai, bj, size in self.get_matching_blocks(): + # invariant: we've pumped out correct diffs to change + # a[:i] into b[:j], and the next matching block is + # a[ai:ai+size] == b[bj:bj+size]. So we need to pump + # out a diff to change a[i:ai] into b[j:bj], pump out + # the matching block, and move (i,j) beyond the match + tag = '' + if i < ai and j < bj: + tag = 'replace' + elif i < ai: + tag = 'delete' + elif j < bj: + tag = 'insert' + if tag: + answer.append( (tag, i, ai, j, bj) ) + i, j = ai+size, bj+size + # the list of matching blocks is terminated by a + # sentinel with size 0 + if size: + answer.append( ('equal', ai, i, bj, j) ) + return answer + + def ratio(self): + """Return a measure of the sequences' similarity (float in [0,1]). + + Where T is the total number of elements in both sequences, and + M is the number of matches, this is 2,0*M / T. + Note that this is 1 if the sequences are identical, and 0 if + they have nothing in common. + + .ratio() is expensive to compute if you haven't already computed + .get_matching_blocks() or .get_opcodes(), in which case you may + want to try .quick_ratio() or .real_quick_ratio() first to get an + upper bound. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.quick_ratio() + 0.75 + >>> s.real_quick_ratio() + 1.0 + """ + + matches = reduce(lambda sum, triple: sum + triple[-1], + self.get_matching_blocks(), 0) + return 2.0 * matches / (len(self.a) + len(self.b)) + + def quick_ratio(self): + """Return an upper bound on ratio() relatively quickly. + + This isn't defined beyond that it is an upper bound on .ratio(), and + is faster to compute. + """ + + # viewing a and b as multisets, set matches to the cardinality + # of their intersection; this counts the number of matches + # without regard to order, so is clearly an upper bound + if self.fullbcount is None: + self.fullbcount = fullbcount = {} + for elt in self.b: + fullbcount[elt] = fullbcount.get(elt, 0) + 1 + fullbcount = self.fullbcount + # avail[x] is the number of times x appears in 'b' less the + # number of times we've seen it in 'a' so far ... kinda + avail = {} + availhas, matches = avail.has_key, 0 + for elt in self.a: + if availhas(elt): + numb = avail[elt] + else: + numb = fullbcount.get(elt, 0) + avail[elt] = numb - 1 + if numb > 0: + matches = matches + 1 + return 2.0 * matches / (len(self.a) + len(self.b)) + + def real_quick_ratio(self): + """Return an upper bound on ratio() very quickly. + + This isn't defined beyond that it is an upper bound on .ratio(), and + is faster to compute than either .ratio() or .quick_ratio(). + """ + + la, lb = len(self.a), len(self.b) + # can't have more matches than the number of elements in the + # shorter sequence + return 2.0 * min(la, lb) / (la + lb) + +def get_close_matches(word, possibilities, n=3, cutoff=0.6): + """Use SequenceMatcher to return list of the best "good enough" matches. + + word is a sequence for which close matches are desired (typically a + string). + + possibilities is a list of sequences against which to match word + (typically a list of strings). + + Optional arg n (default 3) is the maximum number of close matches to + return. n must be > 0. + + Optional arg cutoff (default 0.6) is a float in [0, 1]. Possibilities + that don't score at least that similar to word are ignored. + + The best (no more than n) matches among the possibilities are returned + in a list, sorted by similarity score, most similar first. + + >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"]) + ['apple', 'ape'] + >>> import keyword as _keyword + >>> get_close_matches("wheel", _keyword.kwlist) + ['while'] + >>> get_close_matches("apple", _keyword.kwlist) + [] + >>> get_close_matches("accept", _keyword.kwlist) + ['except'] + """ + + if not n > 0: + raise ValueError("n must be > 0: " + `n`) + if not 0.0 <= cutoff <= 1.0: + raise ValueError("cutoff must be in [0.0, 1.0]: " + `cutoff`) + result = [] + s = SequenceMatcher() + s.set_seq2(word) + for x in possibilities: + s.set_seq1(x) + if s.real_quick_ratio() >= cutoff and \ + s.quick_ratio() >= cutoff and \ + s.ratio() >= cutoff: + result.append((s.ratio(), x)) + # Sort by score. + result.sort() + # Retain only the best n. + result = result[-n:] + # Move best-scorer to head of list. + result.reverse() + # Strip scores. + return [x for score, x in result] + + +def _count_leading(line, ch): + """ + Return number of `ch` characters at the start of `line`. + + Example: + + >>> _count_leading(' abc', ' ') + 3 + """ + + i, n = 0, len(line) + while i < n and line[i] == ch: + i += 1 + return i + +class Differ: + r""" + Differ is a class for comparing sequences of lines of text, and + producing human-readable differences or deltas. Differ uses + SequenceMatcher both to compare sequences of lines, and to compare + sequences of characters within similar (near-matching) lines. + + Each line of a Differ delta begins with a two-letter code: + + '- ' line unique to sequence 1 + '+ ' line unique to sequence 2 + ' ' line common to both sequences + '? ' line not present in either input sequence + + Lines beginning with '? ' attempt to guide the eye to intraline + differences, and were not present in either input sequence. These lines + can be confusing if the sequences contain tab characters. + + Note that Differ makes no claim to produce a *minimal* diff. To the + contrary, minimal diffs are often counter-intuitive, because they synch + up anywhere possible, sometimes accidental matches 100 pages apart. + Restricting synch points to contiguous matches preserves some notion of + locality, at the occasional cost of producing a longer diff. + + Example: Comparing two texts. + + First we set up the texts, sequences of individual single-line strings + ending with newlines (such sequences can also be obtained from the + `readlines()` method of file-like objects): + + >>> text1 = ''' 1. Beautiful is better than ugly. + ... 2. Explicit is better than implicit. + ... 3. Simple is better than complex. + ... 4. Complex is better than complicated. + ... '''.splitlines(1) + >>> len(text1) + 4 + >>> text1[0][-1] + '\n' + >>> text2 = ''' 1. Beautiful is better than ugly. + ... 3. Simple is better than complex. + ... 4. Complicated is better than complex. + ... 5. Flat is better than nested. + ... '''.splitlines(1) + + Next we instantiate a Differ object: + + >>> d = Differ() + + Note that when instantiating a Differ object we may pass functions to + filter out line and character 'junk'. See Differ.__init__ for details. + + Finally, we compare the two: + + >>> result = d.compare(text1, text2) + + 'result' is a list of strings, so let's pretty-print it: + + >>> from pprint import pprint as _pprint + >>> _pprint(result) + [' 1. Beautiful is better than ugly.\n', + '- 2. Explicit is better than implicit.\n', + '- 3. Simple is better than complex.\n', + '+ 3. Simple is better than complex.\n', + '? ++\n', + '- 4. Complex is better than complicated.\n', + '? ^ ---- ^\n', + '+ 4. Complicated is better than complex.\n', + '? ++++ ^ ^\n', + '+ 5. Flat is better than nested.\n'] + + As a single multi-line string it looks like this: + + >>> print ''.join(result), + 1. Beautiful is better than ugly. + - 2. Explicit is better than implicit. + - 3. Simple is better than complex. + + 3. Simple is better than complex. + ? ++ + - 4. Complex is better than complicated. + ? ^ ---- ^ + + 4. Complicated is better than complex. + ? ++++ ^ ^ + + 5. Flat is better than nested. + + Methods: + + __init__(linejunk=None, charjunk=None) + Construct a text differencer, with optional filters. + + compare(a, b) + Compare two sequences of lines; return the resulting delta (list). + """ + + def __init__(self, linejunk=None, charjunk=None): + """ + Construct a text differencer, with optional filters. + + The two optional keyword parameters are for filter functions: + + - `linejunk`: A function that should accept a single string argument, + and return true iff the string is junk. The module-level function + `IS_LINE_JUNK` may be used to filter out lines without visible + characters, except for at most one splat ('#'). + + - `charjunk`: A function that should accept a string of length 1. The + module-level function `IS_CHARACTER_JUNK` may be used to filter out + whitespace characters (a blank or tab; **note**: bad idea to include + newline in this!). + """ + + self.linejunk = linejunk + self.charjunk = charjunk + self.results = [] + + def compare(self, a, b): + r""" + Compare two sequences of lines; return the resulting delta (list). + + Each sequence must contain individual single-line strings ending with + newlines. Such sequences can be obtained from the `readlines()` method + of file-like objects. The list returned is also made up of + newline-terminated strings, ready to be used with the `writelines()` + method of a file-like object. + + Example: + + >>> print ''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1))), + - one + ? ^ + + ore + ? ^ + - two + - three + ? - + + tree + + emu + """ + + cruncher = SequenceMatcher(self.linejunk, a, b) + for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): + if tag == 'replace': + self._fancy_replace(a, alo, ahi, b, blo, bhi) + elif tag == 'delete': + self._dump('-', a, alo, ahi) + elif tag == 'insert': + self._dump('+', b, blo, bhi) + elif tag == 'equal': + self._dump(' ', a, alo, ahi) + else: + raise ValueError, 'unknown tag ' + `tag` + results = self.results + self.results = [] + return results + + def _dump(self, tag, x, lo, hi): + """Store comparison results for a same-tagged range.""" + for i in xrange(lo, hi): + self.results.append('%s %s' % (tag, x[i])) + + def _plain_replace(self, a, alo, ahi, b, blo, bhi): + assert alo < ahi and blo < bhi + # dump the shorter block first -- reduces the burden on short-term + # memory if the blocks are of very different sizes + if bhi - blo < ahi - alo: + self._dump('+', b, blo, bhi) + self._dump('-', a, alo, ahi) + else: + self._dump('-', a, alo, ahi) + self._dump('+', b, blo, bhi) + + def _fancy_replace(self, a, alo, ahi, b, blo, bhi): + r""" + When replacing one block of lines with another, search the blocks + for *similar* lines; the best-matching pair (if any) is used as a + synch point, and intraline difference marking is done on the + similar pair. Lots of work, but often worth it. + + Example: + + >>> d = Differ() + >>> d._fancy_replace(['abcDefghiJkl\n'], 0, 1, ['abcdefGhijkl\n'], 0, 1) + >>> print ''.join(d.results), + - abcDefghiJkl + ? ^ ^ ^ + + abcdefGhijkl + ? ^ ^ ^ + """ + + if TRACE: + self.results.append('*** _fancy_replace %s %s %s %s\n' + % (alo, ahi, blo, bhi)) + self._dump('>', a, alo, ahi) + self._dump('<', b, blo, bhi) + + # don't synch up unless the lines have a similarity score of at + # least cutoff; best_ratio tracks the best score seen so far + best_ratio, cutoff = 0.74, 0.75 + cruncher = SequenceMatcher(self.charjunk) + eqi, eqj = None, None # 1st indices of equal lines (if any) + + # search for the pair that matches best without being identical + # (identical lines must be junk lines, & we don't want to synch up + # on junk -- unless we have to) + for j in xrange(blo, bhi): + bj = b[j] + cruncher.set_seq2(bj) + for i in xrange(alo, ahi): + ai = a[i] + if ai == bj: + if eqi is None: + eqi, eqj = i, j + continue + cruncher.set_seq1(ai) + # computing similarity is expensive, so use the quick + # upper bounds first -- have seen this speed up messy + # compares by a factor of 3. + # note that ratio() is only expensive to compute the first + # time it's called on a sequence pair; the expensive part + # of the computation is cached by cruncher + if cruncher.real_quick_ratio() > best_ratio and \ + cruncher.quick_ratio() > best_ratio and \ + cruncher.ratio() > best_ratio: + best_ratio, best_i, best_j = cruncher.ratio(), i, j + if best_ratio < cutoff: + # no non-identical "pretty close" pair + if eqi is None: + # no identical pair either -- treat it as a straight replace + self._plain_replace(a, alo, ahi, b, blo, bhi) + return + # no close pair, but an identical pair -- synch up on that + best_i, best_j, best_ratio = eqi, eqj, 1.0 + else: + # there's a close pair, so forget the identical pair (if any) + eqi = None + + # a[best_i] very similar to b[best_j]; eqi is None iff they're not + # identical + if TRACE: + self.results.append('*** best_ratio %s %s %s %s\n' + % (best_ratio, best_i, best_j)) + self._dump('>', a, best_i, best_i+1) + self._dump('<', b, best_j, best_j+1) + + # pump out diffs from before the synch point + self._fancy_helper(a, alo, best_i, b, blo, best_j) + + # do intraline marking on the synch pair + aelt, belt = a[best_i], b[best_j] + if eqi is None: + # pump out a '-', '?', '+', '?' quad for the synched lines + atags = btags = "" + cruncher.set_seqs(aelt, belt) + for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes(): + la, lb = ai2 - ai1, bj2 - bj1 + if tag == 'replace': + atags += '^' * la + btags += '^' * lb + elif tag == 'delete': + atags += '-' * la + elif tag == 'insert': + btags += '+' * lb + elif tag == 'equal': + atags += ' ' * la + btags += ' ' * lb + else: + raise ValueError, 'unknown tag ' + `tag` + self._qformat(aelt, belt, atags, btags) + else: + # the synch pair is identical + self.results.append(' ' + aelt) + + # pump out diffs from after the synch point + self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi) + + def _fancy_helper(self, a, alo, ahi, b, blo, bhi): + if alo < ahi: + if blo < bhi: + self._fancy_replace(a, alo, ahi, b, blo, bhi) + else: + self._dump('-', a, alo, ahi) + elif blo < bhi: + self._dump('+', b, blo, bhi) + + def _qformat(self, aline, bline, atags, btags): + r""" + Format "?" output and deal with leading tabs. + + Example: + + >>> d = Differ() + >>> d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', '+ ^ ^ ^ ') + >>> for line in d.results: print repr(line) + ... + '- \tabcDefghiJkl\n' + '? \t ^ ^ ^\n' + '+ \t\tabcdefGhijkl\n' + '? \t ^ ^ ^\n' + """ + + # Can hurt, but will probably help most of the time. + common = min(_count_leading(aline, "\t"), + _count_leading(bline, "\t")) + common = min(common, _count_leading(atags[:common], " ")) + atags = atags[common:].rstrip() + btags = btags[common:].rstrip() + + self.results.append("- " + aline) + if atags: + self.results.append("? %s%s\n" % ("\t" * common, atags)) + + self.results.append("+ " + bline) + if btags: + self.results.append("? %s%s\n" % ("\t" * common, btags)) + +# With respect to junk, an earlier version of ndiff simply refused to +# *start* a match with a junk element. The result was cases like this: +# before: private Thread currentThread; +# after: private volatile Thread currentThread; +# If you consider whitespace to be junk, the longest contiguous match +# not starting with junk is "e Thread currentThread". So ndiff reported +# that "e volatil" was inserted between the 't' and the 'e' in "private". +# While an accurate view, to people that's absurd. The current version +# looks for matching blocks that are entirely junk-free, then extends the +# longest one of those as far as possible but only with matching junk. +# So now "currentThread" is matched, then extended to suck up the +# preceding blank; then "private" is matched, and extended to suck up the +# following blank; then "Thread" is matched; and finally ndiff reports +# that "volatile " was inserted before "Thread". The only quibble +# remaining is that perhaps it was really the case that " volatile" +# was inserted after "private". I can live with that . + +import re + +def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): + r""" + Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + + Examples: + + >>> IS_LINE_JUNK('\n') + 1 + >>> IS_LINE_JUNK(' # \n') + 1 + >>> IS_LINE_JUNK('hello\n') + 0 + """ + + return pat(line) is not None + +def IS_CHARACTER_JUNK(ch, ws=" \t"): + r""" + Return 1 for ignorable character: iff `ch` is a space or tab. + + Examples: + + >>> IS_CHARACTER_JUNK(' ') + 1 + >>> IS_CHARACTER_JUNK('\t') + 1 + >>> IS_CHARACTER_JUNK('\n') + 0 + >>> IS_CHARACTER_JUNK('x') + 0 + """ + + return ch in ws + +del re + +def ndiff(a, b, linejunk=IS_LINE_JUNK, charjunk=IS_CHARACTER_JUNK): + r""" + Compare `a` and `b` (lists of strings); return a `Differ`-style delta. + + Optional keyword parameters `linejunk` and `charjunk` are for filter + functions (or None): + + - linejunk: A function that should accept a single string argument, and + return true iff the string is junk. The default is module-level function + IS_LINE_JUNK, which filters out lines without visible characters, except + for at most one splat ('#'). + + - charjunk: A function that should accept a string of length 1. The + default is module-level function IS_CHARACTER_JUNK, which filters out + whitespace characters (a blank or tab; note: bad idea to include newline + in this!). + + Tools/scripts/ndiff.py is a command-line front-end to this function. + + Example: + + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> print ''.join(diff), + - one + ? ^ + + ore + ? ^ + - two + - three + ? - + + tree + + emu + """ + return Differ(linejunk, charjunk).compare(a, b) + +def restore(delta, which): + r""" + Return one of the two sequences that generated a delta. + + Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract + lines originating from file 1 or 2 (parameter `which`), stripping off line + prefixes. + + Examples: + + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> print ''.join(restore(diff, 1)), + one + two + three + >>> print ''.join(restore(diff, 2)), + ore + tree + emu + """ + try: + tag = {1: "- ", 2: "+ "}[int(which)] + except KeyError: + raise ValueError, ('unknown delta choice (must be 1 or 2): %r' + % which) + prefixes = (" ", tag) + results = [] + for line in delta: + if line[:2] in prefixes: + results.append(line[2:]) + return results + +def _test(): + import doctest, difflib + return doctest.testmod(difflib) + +if __name__ == "__main__": + _test() diff --git a/test/test_nodes.py b/test/test_nodes.py new file mode 100755 index 000000000..15e633357 --- /dev/null +++ b/test/test_nodes.py @@ -0,0 +1,83 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Test module for nodes.py. +""" + +import unittest +from DocutilsTestSupport import nodes + +debug = 0 + + +class TextTests(unittest.TestCase): + + def setUp(self): + self.text = nodes.Text('Line 1.\nLine 2.') + + def test_repr(self): + self.assertEquals(repr(self.text), r"<#text: 'Line 1.\nLine 2.'>") + + def test_str(self): + self.assertEquals(str(self.text), 'Line 1.\nLine 2.') + + def test_asdom(self): + dom = self.text.asdom() + self.assertEquals(dom.toxml(), 'Line 1.\nLine 2.') + dom.unlink() + + def test_astext(self): + self.assertEquals(self.text.astext(), 'Line 1.\nLine 2.') + + def test_pformat(self): + self.assertEquals(self.text.pformat(), 'Line 1.\nLine 2.\n') + + +class ElementTests(unittest.TestCase): + + def test_empty(self): + element = nodes.Element() + self.assertEquals(repr(element), '') + self.assertEquals(str(element), '') + dom = element.asdom() + self.assertEquals(dom.toxml(), '') + dom.unlink() + element['attr'] = '1' + self.assertEquals(repr(element), '') + self.assertEquals(str(element), '') + dom = element.asdom() + self.assertEquals(dom.toxml(), '') + dom.unlink() + self.assertEquals(element.pformat(), '\n') + + def test_withtext(self): + element = nodes.Element('text\nmore', nodes.Text('text\nmore')) + self.assertEquals(repr(element), r">") + self.assertEquals(str(element), 'text\nmore') + dom = element.asdom() + self.assertEquals(dom.toxml(), 'text\nmore') + dom.unlink() + element['attr'] = '1' + self.assertEquals(repr(element), r">") + self.assertEquals(str(element), + 'text\nmore') + dom = element.asdom() + self.assertEquals(dom.toxml(), + 'text\nmore') + dom.unlink() + self.assertEquals(element.pformat(), +"""\ + + text + more +""") + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_parsers/test_rst/test_TableParser.py b/test/test_parsers/test_rst/test_TableParser.py new file mode 100755 index 000000000..ed6083d50 --- /dev/null +++ b/test/test_parsers/test_rst/test_TableParser.py @@ -0,0 +1,197 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for states.py. +""" + +import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.TableParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['tables'] = [ +["""\ ++-------------------------------------+ +| A table with one cell and one line. | ++-------------------------------------+ +""", +[(0, 0, 2, 38, ['A table with one cell and one line.'])], +([37], + [], + [[(0, 0, 1, ['A table with one cell and one line.'])]])], +["""\ ++--------------+--------------+ +| A table with | two columns. | ++--------------+--------------+ +""", +[(0, 0, 2, 15, ['A table with']), + (0, 15, 2, 30, ['two columns.'])], +([14, 14], + [], + [[(0, 0, 1, ['A table with']), + (0, 0, 1, ['two columns.'])]])], +["""\ ++--------------+-------------+ +| A table with | two columns | ++--------------+-------------+ +| and | two rows. | ++--------------+-------------+ +""", +[(0, 0, 2, 15, ['A table with']), + (0, 15, 2, 29, ['two columns']), + (2, 0, 4, 15, ['and']), + (2, 15, 4, 29, ['two rows.'])], +([14, 13], + [], + [[(0, 0, 1, ['A table with']), + (0, 0, 1, ['two columns'])], + [(0, 0, 3, ['and']), + (0, 0, 3, ['two rows.'])]])], +["""\ ++--------------------------+ +| A table with three rows, | ++------------+-------------+ +| and two | columns. | ++------------+-------------+ +| First and last rows | +| contain column spans. | ++--------------------------+ +""", +[(0, 0, 2, 27, ['A table with three rows,']), + (2, 0, 4, 13, ['and two']), + (2, 13, 4, 27, ['columns.']), + (4, 0, 7, 27, ['First and last rows', 'contain column spans.'])], +([12, 13], + [], + [[(0, 1, 1, ['A table with three rows,']), + None], + [(0, 0, 3, ['and two']), + (0, 0, 3, ['columns.'])], + [(0, 1, 5, ['First and last rows', 'contain column spans.']), + None]])], +["""\ ++------------+-------------+---------------+ +| A table | two rows in | and row spans | +| with three +-------------+ to left and | +| columns, | the middle, | right. | ++------------+-------------+---------------+ +""", +[(0, 0, 4, 13, ['A table', 'with three', 'columns,']), + (0, 13, 2, 27, ['two rows in']), + (0, 27, 4, 43, ['and row spans', 'to left and', 'right.']), + (2, 13, 4, 27, ['the middle,'])], +([12, 13, 15], + [], + [[(1, 0, 1, ['A table', 'with three', 'columns,']), + (0, 0, 1, ['two rows in']), + (1, 0, 1, ['and row spans', 'to left and', 'right.'])], + [None, + (0, 0, 3, ['the middle,']), + None]])], +["""\ ++------------+-------------+---------------+ +| A table | | two rows in | and funny | +| with 3 +--+-------------+-+ stuff. | +| columns, | the middle, | | | ++------------+-------------+---------------+ +""", +[(0, 0, 4, 13, ['A table |', 'with 3 +--', 'columns,']), + (0, 13, 2, 27, ['two rows in']), + (0, 27, 4, 43, [' and funny', '-+ stuff.', ' |']), + (2, 13, 4, 27, ['the middle,'])], +([12, 13, 15], + [], + [[(1, 0, 1, ['A table |', 'with 3 +--', 'columns,']), + (0, 0, 1, ['two rows in']), + (1, 0, 1, [' and funny', '-+ stuff.', ' |'])], + [None, + (0, 0, 3, ['the middle,']), + None]])], +["""\ ++-----------+-------------------------+ +| W/NW cell | N/NE cell | +| +-------------+-----------+ +| | Middle cell | E/SE cell | ++-----------+-------------+ | +| S/SE cell | | ++-------------------------+-----------+ +""", +[(0, 0, 4, 12, ['W/NW cell', '', '']), + (0, 12, 2, 38, ['N/NE cell']), + (2, 12, 4, 26, ['Middle cell']), + (2, 26, 6, 38, ['E/SE cell', '', '']), + (4, 0, 6, 26, ['S/SE cell'])], +([11, 13, 11], + [], + [[(1, 0, 1, ['W/NW cell', '', '']), + (0, 1, 1, ['N/NE cell']), + None], + [None, + (0, 0, 3, ['Middle cell']), + (1, 0, 3, ['E/SE cell', '', ''])], + [(0, 1, 5, ['S/SE cell']), + None, + None]])], +["""\ ++--------------+-------------+ +| A bad table. | | ++--------------+ | +| Cells must be rectangles. | ++----------------------------+ +""", +'TableMarkupError: Malformed table; parse incomplete.', +'TableMarkupError: Malformed table; parse incomplete.'], +["""\ ++-------------------------------+ +| A table with two header rows, | ++------------+------------------+ +| the first | with a span. | ++============+==================+ +| Two body | rows, | ++------------+------------------+ +| the second with a span. | ++-------------------------------+ +""", +[(0, 0, 2, 32, ['A table with two header rows,']), + (2, 0, 4, 13, ['the first']), + (2, 13, 4, 32, ['with a span.']), + (4, 0, 6, 13, ['Two body']), + (4, 13, 6, 32, ['rows,']), + (6, 0, 8, 32, ['the second with a span.'])], +([12, 18], + [[(0, 1, 1, ['A table with two header rows,']), + None], + [(0, 0, 3, ['the first']), + (0, 0, 3, ['with a span.'])]], + [[(0, 0, 5, ['Two body']), + (0, 0, 5, ['rows,'])], + [(0, 1, 7, ['the second with a span.']), + None]])], +["""\ ++-------------------------------+ +| A table with two head/body | ++=============+=================+ +| row | separators. | ++=============+=================+ +| That's bad. | | ++-------------+-----------------+ +""", +'TableMarkupError: Multiple head/body row separators in table ' +'(at line offset 2 and 4); only one allowed.', +'TableMarkupError: Multiple head/body row separators in table ' +'(at line offset 2 and 4); only one allowed.'], +] + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_block_quotes.py b/test/test_parsers/test_rst/test_block_quotes.py new file mode 100755 index 000000000..e047d0e92 --- /dev/null +++ b/test/test_parsers/test_rst/test_block_quotes.py @@ -0,0 +1,124 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for states.py. +""" + +import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['block_quotes'] = [ +["""\ +Line 1. +Line 2. + + Indented. +""", +"""\ + + + Line 1. + Line 2. + + + Indented. +"""], +["""\ +Line 1. +Line 2. + + Indented 1. + + Indented 2. +""", +"""\ + + + Line 1. + Line 2. + + + Indented 1. + + + Indented 2. +"""], +["""\ +Line 1. +Line 2. + Unexpectedly indented. +""", +"""\ + + + Line 1. + Line 2. + + + Unexpected indentation at line 3. + + + Unexpectedly indented. +"""], +["""\ +Line 1. +Line 2. + + Indented. +no blank line +""", +"""\ + + + Line 1. + Line 2. + + + Indented. + + + Unindent without blank line at line 5. + + no blank line +"""], +["""\ +Here is a paragraph. + + Indent 8 spaces. + + Indent 4 spaces. + +Is this correct? Should it generate a warning? +Yes, it is correct, no warning necessary. +""", +"""\ + + + Here is a paragraph. + + + + Indent 8 spaces. + + Indent 4 spaces. + + Is this correct? Should it generate a warning? + Yes, it is correct, no warning necessary. +"""], +] + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_bullet_lists.py b/test/test_parsers/test_rst/test_bullet_lists.py new file mode 100755 index 000000000..b9552042e --- /dev/null +++ b/test/test_parsers/test_rst/test_bullet_lists.py @@ -0,0 +1,181 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for states.py. +""" + +import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['bullet_lists'] = [ +["""\ +- item +""", +"""\ + + + + + item +"""], +["""\ +* item 1 + +* item 2 +""", +"""\ + + + + + item 1 + + + item 2 +"""], +["""\ +No blank line between: + ++ item 1 ++ item 2 +""", +"""\ + + + No blank line between: + + + + item 1 + + + item 2 +"""], +["""\ +- item 1, para 1. + + item 1, para 2. + +- item 2 +""", +"""\ + + + + + item 1, para 1. + + item 1, para 2. + + + item 2 +"""], +["""\ +- item 1, line 1 + item 1, line 2 +- item 2 +""", +"""\ + + + + + item 1, line 1 + item 1, line 2 + + + item 2 +"""], +["""\ +Different bullets: + +- item 1 + ++ item 2 + +* item 3 +- item 4 +""", +"""\ + + + Different bullets: + + + + item 1 + + + + item 2 + + + + item 3 + + + Unindent without blank line at line 8. + + + + item 4 +"""], +["""\ +- item +no blank line +""", +"""\ + + + + + item + + + Unindent without blank line at line 2. + + no blank line +"""], +["""\ +- + +empty item above +""", +"""\ + + + + + empty item above +"""], +["""\ +- +empty item above, no blank line +""", +"""\ + + + + + + Unindent without blank line at line 2. + + empty item above, no blank line +"""], +] + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_citations.py b/test/test_parsers/test_rst/test_citations.py new file mode 100755 index 000000000..15568c1fd --- /dev/null +++ b/test/test_parsers/test_rst/test_citations.py @@ -0,0 +1,139 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for states.py. +""" + +import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['citations'] = [ +["""\ +.. [citation] This is a citation. +""", +"""\ + + +

http://docutils.sourceforge.net/docs/rst/quickref.html
Being a cheat-sheet for reStructuredText
Version 0.8 of 2002-04-19 @@ -153,7 +153,7 @@ (with backslash) or quote them (with double backquotes; i.e. use inline literals). -

In detail, the reStructuredText specifications says that in +

In detail, the reStructuredText specifications says that in inline markup:

  1. The start-string must start a text block or be @@ -165,7 +165,7 @@ followed by whitespace,  ' " . , : ; ! ? - ) ] } or  >.
  2. If a start-string is immediately preceded by one of  - ' " ( [ { or  <, it must not be + ' " ( [ { or  <, it must not be immediately followed by the corresponding character from  ' " ) ] } or  >.
  3. An end-string must be separated by at least one @@ -610,7 +610,7 @@ This means that something like:

    Doctest blocks are interactive Python sessions. They begin with ">>>" and end with a blank line. - +

    >>> print "This is a doctest block."
    This is a doctest block.
    @@ -700,9 +700,9 @@ A transition marker is a horizontal line

    A transition marker is a horizontal line of 4 or more repeated punctuation characters.

    - +
    - +

    A transition should not begin or end a section or document, nor should two transitions be immediately adjacent. @@ -766,7 +766,7 @@ A transition marker is a horizontal line

    They may be assigned 'autonumber labels' - for instance, 4 and 3. - +

    \n' '\n' '\n' @@ -519,8 +533,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'p', '[', CLASS='label')) def depart_label(self, node): - self.body.append(']

    \n' - '

    diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index be9139d60..1de7abf59 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -168,7 +168,7 @@ after a blank line. Unlike the other two, the definition lists consist of a term, and the definition of that term. The format of a definition list is:: - what + what Definition lists associate a term with a definition. *how* @@ -178,7 +178,7 @@ after a blank line. Results in: - what + what Definition lists associate a term with a definition. *how* @@ -222,7 +222,7 @@ from the output:: :: - This is preformatted text, and the + This is preformatted text, and the last "::" paragraph is removed Results in: -- cgit v1.2.1 From 54237d053858226234c32fdd8a3faa00e2a849df Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 14:47:14 +0000 Subject: - Added ``ApplicationError`` and ``DataError``, for use throughout the package. - Added ``Component`` base class for Docutils components; implements the ``supports`` method. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@69 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docutils/__init__.py b/docutils/__init__.py index 0ee88d94a..e70a33167 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -49,3 +49,20 @@ Subpackages: """ __docformat__ = 'reStructuredText' + + +class ApplicationError(StandardError): pass +class DataError(ApplicationError): pass + + +class Component: + + """ + Base class for Docutils components. + """ + + names = () + """Names for this component. Override in subclasses.""" + + def supports(self, format): + return format in self.supported -- cgit v1.2.1 From a99117d36a613c76c4cea42c04f29d3cb41c1ad2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 14:49:10 +0000 Subject: - Added ``TreeCopyVisitor`` class. - Added a ``copy`` method to ``Node`` and subclasses. - Added a ``SkipDeparture`` exception for visitors. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@70 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 163 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 53 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index ece182c85..803fbc82e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -16,7 +16,7 @@ element classes. Classes in lower_case_with_underscores are element classes, matching the XML element generic identifiers in the DTD_. -.. _DTD: http://docstring.sourceforge.net/spec/gpdi.dtd +.. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd """ import sys, os @@ -50,6 +50,10 @@ class Node: """Return an indented pseudo-XML representation, for test purposes.""" raise NotImplementedError + def copy(self): + """Return a copy of self.""" + raise NotImplementedError + def walk(self, visitor): """ Traverse a tree of `Node` objects, calling ``visit_...`` methods of @@ -65,16 +69,18 @@ class Node: """ name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) - visitor.doctree.reporter.debug(name, category='nodes.Node.walk') + visitor.document.reporter.debug(name, category='nodes.Node.walk') try: method(self) - children = self.getchildren() - try: - for i in range(len(children)): - children[i].walk(visitor) - except SkipSiblings: - pass except (SkipChildren, SkipNode): + return + except SkipDeparture: # not applicable; ignore + pass + children = self.getchildren() + try: + for i in range(len(children)): + children[i].walk(visitor) + except SkipSiblings: pass def walkabout(self, visitor): @@ -87,11 +93,17 @@ class Node: Parameter `visitor`: A `NodeVisitor` object, containing ``visit_...`` and ``depart_...`` methods for each `Node` subclass encountered. """ + call_depart = 1 name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) - visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') + visitor.document.reporter.debug(name, category='nodes.Node.walkabout') try: - method(self) + try: + method(self) + except SkipNode: + return + except SkipDeparture: + call_depart = 0 children = self.getchildren() try: for i in range(len(children)): @@ -100,12 +112,12 @@ class Node: pass except SkipChildren: pass - except SkipNode: - return - name = 'depart_' + self.__class__.__name__ - method = getattr(visitor, name, visitor.unknown_departure) - visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') - method(self) + if call_depart: + name = 'depart_' + self.__class__.__name__ + method = getattr(visitor, name, visitor.unknown_departure) + visitor.document.reporter.debug( + name, category='nodes.Node.walkabout') + method(self) class Text(Node, MutableString): @@ -133,6 +145,9 @@ class Text(Node, MutableString): def astext(self): return self.data + def copy(self): + return self.__class__(self.data) + def pformat(self, indent=' ', level=0): result = [] indent = indent * level @@ -186,7 +201,7 @@ class Element(Node): self.children = [] """List of child nodes (elements and/or `Text`).""" - self.extend(children) # extend self.children w/ attributes + self.extend(children) # maintain parent info self.attributes = {} """Dictionary of attribute {name: value}.""" @@ -425,6 +440,9 @@ class Element(Node): """Return this element's children.""" return self.children + def copy(self): + return self.__class__(**self.attributes) + class TextElement(Element): @@ -489,11 +507,11 @@ class Admonition(Body): pass class Special(Body): - """Special internal body elements, not true document components.""" + """Special internal body elements.""" pass -class Component: pass +class Part: pass class Inline: pass @@ -513,13 +531,13 @@ class Targetable(Resolvable): class document(Root, Structural, Element): - def __init__(self, reporter, languagecode, *args, **kwargs): + def __init__(self, reporter, language_code, *args, **kwargs): Element.__init__(self, *args, **kwargs) self.reporter = reporter """System message generator.""" - self.languagecode = languagecode + self.language_code = language_code """ISO 639 2-letter language identifier.""" self.explicit_targets = {} @@ -763,6 +781,10 @@ class document(Root, Structural, Element): def note_pending(self, pending): self.pending.append(pending) + def copy(self): + return self.__class__(self.reporter, self.language_code, + **self.attributes) + # ================ # Title Elements @@ -820,31 +842,31 @@ class transition(Structural, Element): pass class paragraph(General, TextElement): pass class bullet_list(Sequential, Element): pass class enumerated_list(Sequential, Element): pass -class list_item(Component, Element): pass +class list_item(Part, Element): pass class definition_list(Sequential, Element): pass -class definition_list_item(Component, Element): pass -class term(Component, TextElement): pass -class classifier(Component, TextElement): pass -class definition(Component, Element): pass +class definition_list_item(Part, Element): pass +class term(Part, TextElement): pass +class classifier(Part, TextElement): pass +class definition(Part, Element): pass class field_list(Sequential, Element): pass -class field(Component, Element): pass -class field_name(Component, TextElement): pass -class field_argument(Component, TextElement): pass -class field_body(Component, Element): pass +class field(Part, Element): pass +class field_name(Part, TextElement): pass +class field_argument(Part, TextElement): pass +class field_body(Part, Element): pass -class option(Component, Element): +class option(Part, Element): child_text_separator = '' -class option_argument(Component, TextElement): +class option_argument(Part, TextElement): def astext(self): return self.get('delimiter', ' ') + TextElement.astext(self) -class option_group(Component, Element): +class option_group(Part, Element): child_text_separator = ', ' @@ -852,13 +874,13 @@ class option_group(Component, Element): class option_list(Sequential, Element): pass -class option_list_item(Component, Element): +class option_list_item(Part, Element): child_text_separator = ' ' -class option_string(Component, TextElement): pass -class description(Component, Element): pass +class option_string(Part, TextElement): pass +class description(Part, Element): pass class literal_block(General, TextElement): pass class block_quote(General, Element): pass class doctest_block(General, TextElement): pass @@ -876,17 +898,17 @@ class substitution_definition(Special, TextElement): pass class target(Special, Inline, TextElement, Targetable): pass class footnote(General, Element, BackLinkable): pass class citation(General, Element, BackLinkable): pass -class label(Component, TextElement): pass +class label(Part, TextElement): pass class figure(General, Element): pass -class caption(Component, TextElement): pass -class legend(Component, Element): pass +class caption(Part, TextElement): pass +class legend(Part, Element): pass class table(General, Element): pass -class tgroup(Component, Element): pass -class colspec(Component, Element): pass -class thead(Component, Element): pass -class tbody(Component, Element): pass -class row(Component, Element): pass -class entry(Component, Element): pass +class tgroup(Part, Element): pass +class colspec(Part, Element): pass +class thead(Part, Element): pass +class tbody(Part, Element): pass +class row(Part, Element): pass +class entry(Part, Element): pass class system_message(Special, PreBibliographic, Element, BackLinkable): @@ -956,12 +978,22 @@ class pending(Special, PreBibliographic, Element): internals.append('%7s%s:' % ('', key)) internals.extend(['%9s%s' % ('', line) for line in value.pformat().splitlines()]) + elif value and type(value) == ListType \ + and isinstance(value[0], Node): + internals.append('%7s%s:' % ('', key)) + for v in value: + internals.extend(['%9s%s' % ('', line) + for line in v.pformat().splitlines()]) else: internals.append('%7s%s: %r' % ('', key, value)) return (Element.pformat(self, indent, level) + ''.join([(' %s%s\n' % (indent * level, line)) for line in internals])) + def copy(self): + return self.__class__(self.transform, self.stage, self.details, + **self.attributes) + class raw(Special, Inline, PreBibliographic, TextElement): @@ -991,7 +1023,7 @@ class image(General, Inline, TextElement): def astext(self): return self.get('alt', '') - + class problematic(Inline, TextElement): pass @@ -1043,8 +1075,8 @@ class NodeVisitor: 1995. """ - def __init__(self, doctree): - self.doctree = doctree + def __init__(self, document): + self.document = document def unknown_visit(self, node): """ @@ -1078,12 +1110,12 @@ class GenericNodeVisitor(NodeVisitor): Unless overridden, each ``visit_...`` method calls `default_visit()`, and each ``depart_...`` method (when using `Node.walkabout()`) calls - `default_departure()`. `default_visit()` (`default_departure()`) must be - overridden in subclasses. + `default_departure()`. `default_visit()` (and `default_departure()`) must + be overridden in subclasses. - Define fully generic visitors by overriding `default_visit()` - (`default_departure()`) only. Define semi-generic visitors by overriding - individual ``visit_...()`` (``depart_...()``) methods also. + Define fully generic visitors by overriding `default_visit()` (and + `default_departure()`) only. Define semi-generic visitors by overriding + individual ``visit_...()`` (and ``depart_...()``) methods also. `NodeVisitor.unknown_visit()` (`NodeVisitor.unknown_departure()`) should be overridden for default behavior. @@ -1110,3 +1142,28 @@ class VisitorException(Exception): pass class SkipChildren(VisitorException): pass class SkipSiblings(VisitorException): pass class SkipNode(VisitorException): pass +class SkipDeparture(VisitorException): pass + + +class TreeCopyVisitor(GenericNodeVisitor): + + """ + Make a complete copy of a tree or branch, including element attributes. + """ + + def __init__(self, document): + GenericNodeVisitor.__init__(self, document) + self.parent_stack = [[]] + + def get_tree_copy(self): + return self.parent_stack[0][0] + + def default_visit(self, node): + """""" + newnode = node.copy() + self.parent_stack[-1].append(newnode) + self.parent_stack.append(newnode) + + def default_departure(self, node): + """""" + self.parent_stack.pop() -- cgit v1.2.1 From 73710935431dbf51b075781b9a5409eea6c41393 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:15:54 +0000 Subject: renamed parts.py from compontents.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@71 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/components.py | 59 ------------------------- docutils/parsers/rst/directives/parts.py | 62 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 59 deletions(-) delete mode 100644 docutils/parsers/rst/directives/components.py create mode 100644 docutils/parsers/rst/directives/parts.py diff --git a/docutils/parsers/rst/directives/components.py b/docutils/parsers/rst/directives/components.py deleted file mode 100644 index 8463f41b0..000000000 --- a/docutils/parsers/rst/directives/components.py +++ /dev/null @@ -1,59 +0,0 @@ -#! /usr/bin/env python - -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -Document component directives. -""" - -__docformat__ = 'reStructuredText' - - -from docutils import nodes -import docutils.transforms.components - - -contents_attribute_spec = {'depth': int, - 'local': (lambda x: x)} - -def contents(match, typename, data, state, statemachine, attributes): - lineno = statemachine.abslineno() - lineoffset = statemachine.lineoffset - datablock, indent, offset, blankfinish = \ - statemachine.getfirstknownindented(match.end(), uptoblank=1) - blocktext = '\n'.join(statemachine.inputlines[ - lineoffset : lineoffset + len(datablock) + 1]) - for i in range(len(datablock)): - if datablock[i][:1] == ':': - attlines = datablock[i:] - datablock = datablock[:i] - break - else: - attlines = [] - i = 0 - titletext = ' '.join([line.strip() for line in datablock]) - if titletext: - textnodes, messages = state.inline_text(titletext, lineno) - title = nodes.title(titletext, '', *textnodes) - else: - messages = [] - title = None - pending = nodes.pending(docutils.transforms.components.Contents, - 'last_reader', {'title': title}, blocktext) - if attlines: - success, data, blankfinish = state.parse_extension_attributes( - contents_attribute_spec, attlines, blankfinish) - if success: # data is a dict of attributes - pending.details.update(data) - else: # data is an error string - error = statemachine.memo.reporter.error( - 'Error in "%s" directive attributes at line %s:\n%s.' - % (match.group(1), lineno, data), '', - nodes.literal_block(blocktext, blocktext)) - return [error] + messages, blankfinish - statemachine.memo.document.note_pending(pending) - return [pending] + messages, blankfinish diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py new file mode 100644 index 000000000..7b3d63697 --- /dev/null +++ b/docutils/parsers/rst/directives/parts.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Directives for document parts. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes +from docutils.transforms import parts + + +def unchanged(arg): + return arg # unchanged! + +contents_attribute_spec = {'depth': int, + 'local': unchanged, + 'qa': unchanged} + +def contents(match, type_name, data, state, state_machine, attributes): + lineno = state_machine.abs_line_number() + line_offset = state_machine.line_offset + datablock, indent, offset, blank_finish = \ + state_machine.get_first_known_indented(match.end(), until_blank=1) + blocktext = '\n'.join(state_machine.input_lines[ + line_offset : line_offset + len(datablock) + 1]) + for i in range(len(datablock)): + if datablock[i][:1] == ':': + attlines = datablock[i:] + datablock = datablock[:i] + break + else: + attlines = [] + i = 0 + titletext = ' '.join([line.strip() for line in datablock]) + if titletext: + textnodes, messages = state.inline_text(titletext, lineno) + title = nodes.title(titletext, '', *textnodes) + else: + messages = [] + title = None + pending = nodes.pending(parts.Contents, 'last reader', {'title': title}, + blocktext) + if attlines: + success, data, blank_finish = state.parse_extension_attributes( + contents_attribute_spec, attlines, blank_finish) + if success: # data is a dict of attributes + pending.details.update(data) + else: # data is an error string + error = state_machine.reporter.error( + 'Error in "%s" directive attributes at line %s:\n%s.' + % (match.group(1), lineno, data), '', + nodes.literal_block(blocktext, blocktext)) + return [error] + messages, blank_finish + state_machine.document.note_pending(pending) + return [pending] + messages, blank_finish -- cgit v1.2.1 From f51354f5a1a68947246017a9c0e27644419d49bf Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:16:56 +0000 Subject: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@72 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/html.py | 74 ++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index d971300e0..262a124c8 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -15,32 +15,33 @@ __docformat__ = 'reStructuredText' from docutils import nodes, utils from docutils.parsers.rst import states +from docutils.transforms import components -def meta(match, typename, data, state, statemachine, attributes): - lineoffset = statemachine.lineoffset - block, indent, offset, blankfinish = \ - statemachine.getfirstknownindented(match.end(), uptoblank=1) +def meta(match, type_name, data, state, state_machine, attributes): + line_offset = state_machine.line_offset + block, indent, offset, blank_finish = \ + state_machine.get_first_known_indented(match.end(), until_blank=1) node = nodes.Element() if block: - newlineoffset, blankfinish = state.nestedlistparse( - block, offset, node, initialstate='MetaBody', - blankfinish=blankfinish, statemachinekwargs=metaSMkwargs) - if (newlineoffset - offset) != len(block): # incomplete parse of block? - blocktext = '\n'.join(statemachine.inputlines[ - lineoffset : statemachine.lineoffset+1]) - msg = statemachine.memo.reporter.error( + new_line_offset, blank_finish = state.nested_list_parse( + block, offset, node, initial_state='MetaBody', + blank_finish=blank_finish, state_machine_kwargs=metaSMkwargs) + if (new_line_offset - offset) != len(block): # incomplete parse of block? + blocktext = '\n'.join(state_machine.input_lines[ + line_offset : state_machine.line_offset+1]) + msg = state_machine.reporter.error( 'Invalid meta directive at line %s.' - % statemachine.abslineno(), '', + % state_machine.abs_line_number(), '', nodes.literal_block(blocktext, blocktext)) node += msg else: - msg = statemachine.memo.reporter.error( - 'Empty meta directive at line %s.' % statemachine.abslineno()) + msg = state_machine.reporter.error('Empty meta directive at line %s.' + % state_machine.abs_line_number()) node += msg - return node.getchildren(), blankfinish + return node.getchildren(), blank_finish -def imagemap(match, typename, data, state, statemachine, attributes): +def imagemap(match, type_name, data, state, state_machine, attributes): return [], 0 @@ -50,24 +51,27 @@ class MetaBody(states.SpecializedBody): """HTML-specific "meta" element.""" pass - def field_marker(self, match, context, nextstate): + def field_marker(self, match, context, next_state): """Meta element.""" - node, blankfinish = self.parsemeta(match) - self.statemachine.node += node - return [], nextstate, [] + node, blank_finish = self.parsemeta(match) + self.parent += node + return [], next_state, [] def parsemeta(self, match): name, args = self.parse_field_marker(match) - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) node = self.meta() + pending = nodes.pending(components.Filter, 'first writer', + {'writer': 'html', 'nodes': [node]}) node['content'] = ' '.join(indented) if not indented: - line = self.statemachine.line - msg = self.statemachine.memo.reporter.info( - 'No content for meta tag "%s".' % name, '', - nodes.literal_block(line, line)) - self.statemachine.node += msg + line = self.state_machine.line + msg = self.reporter.info( + 'No content for meta tag "%s" at line %s.' + % (name, self.state_machine.abs_line_number()), + '', nodes.literal_block(line, line)) + return msg, blank_finish try: attname, val = utils.extract_name_value(name)[0] node[attname.lower()] = val @@ -78,12 +82,14 @@ class MetaBody(states.SpecializedBody): attname, val = utils.extract_name_value(arg)[0] node[attname.lower()] = val except utils.NameValueError, detail: - line = self.statemachine.line - msg = self.statemachine.memo.reporter.error( - 'Error parsing meta tag attribute "%s": %s' - % (arg, detail), '', nodes.literal_block(line, line)) - self.statemachine.node += msg - return node, blankfinish + line = self.state_machine.line + msg = self.reporter.error( + 'Error parsing meta tag attribute "%s" at line %s: %s.' + % (arg, self.state_machine.abs_line_number(), detail), + '', nodes.literal_block(line, line)) + return msg, blank_finish + self.document.note_pending(pending) + return pending, blank_finish -metaSMkwargs = {'stateclasses': (MetaBody,)} +metaSMkwargs = {'state_classes': (MetaBody,)} -- cgit v1.2.1 From e13920cf12052d05709108e6c787817b8b36c42e Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:19:18 +0000 Subject: refactored; improved compound names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@73 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 63 ++++++++++++++------------ docutils/languages/__init__.py | 10 ++-- docutils/parsers/__init__.py | 25 +++++----- docutils/parsers/rst/__init__.py | 38 +++++++++------- docutils/parsers/rst/directives/__init__.py | 19 ++++---- docutils/parsers/rst/directives/admonitions.py | 12 ++--- docutils/parsers/rst/directives/images.py | 60 ++++++++++++------------ docutils/parsers/rst/directives/misc.py | 22 ++++----- 8 files changed, 130 insertions(+), 119 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index b553b07b7..a578fef5f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -7,27 +7,30 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. - +Calling the `publish` convenience function (or instantiating a +`Publisher` object) with component names will result in default +behavior. For custom behavior (setting component options), create +custom component objects first, and pass *them* to +`publish`/`Publisher`. """ __docformat__ = 'reStructuredText' - import readers, parsers, writers, utils class Publisher: """ - Publisher encapsulates the high-level logic of a Docutils system. + A facade encapsulating the high-level logic of a Docutils system. """ reporter = None """A `utils.Reporter` instance used for all document processing.""" def __init__(self, reader=None, parser=None, writer=None, reporter=None, - languagecode='en', warninglevel=2, errorlevel=4, - warningstream=None, debug=0): + language_code='en', warning_level=2, error_level=4, + warning_stream=None, debug=0): """ Initial setup. If any of `reader`, `parser`, or `writer` are not specified, the corresponding 'set*' method should be @@ -37,26 +40,27 @@ class Publisher: self.parser = parser self.writer = writer if not reporter: - reporter = utils.Reporter(warninglevel, errorlevel, warningstream, - debug) + reporter = utils.Reporter(warning_level, error_level, + warning_stream, debug) self.reporter = reporter - self.languagecode = languagecode + self.language_code = language_code - def setreader(self, readername, languagecode=None): + def set_reader(self, reader_name, parser, parser_name, + language_code=None): """Set `self.reader` by name.""" - readerclass = readers.get_reader_class(readername) - self.reader = readerclass(self.reporter, - languagecode or self.languagecode) + reader_class = readers.get_reader_class(reader_name) + self.reader = reader_class(self.reporter, parser, parser_name, + language_code or self.language_code) - def setparser(self, parsername): + def set_parser(self, parser_name): """Set `self.parser` by name.""" - parserclass = parsers.get_parser_class(parsername) - self.parser = parserclass() + parser_class = parsers.get_parser_class(parser_name) + self.parser = parser_class() - def setwriter(self, writername): + def set_writer(self, writer_name): """Set `self.writer` by name.""" - writerclass = writers.get_writer_class(writername) - self.writer = writerclass() + writer_class = writers.get_writer_class(writer_name) + self.writer = writer_class() def publish(self, source, destination): """ @@ -68,18 +72,17 @@ class Publisher: def publish(source=None, destination=None, - reader=None, readername='standalone', - parser=None, parsername='restructuredtext', - writer=None, writername='pprint', - reporter=None, languagecode='en', - warninglevel=2, errorlevel=4, warningstream=None, debug=0): - """Set up & run a `Publisher`.""" - pub = Publisher(reader, parser, writer, reporter, languagecode, - warninglevel, errorlevel, warningstream, debug) + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='pseudoxml', + reporter=None, language_code='en', + warning_level=2, error_level=4, warning_stream=None, debug=0): + """A convenience function; set up & run a `Publisher`.""" + pub = Publisher(reader, parser, writer, reporter, language_code, + warning_level, error_level, warning_stream, debug) if reader is None: - pub.setreader(readername) - if parser is None: - pub.setparser(parsername) + pub.set_reader(reader_name, parser, parser_name) if writer is None: - pub.setwriter(writername) + pub.set_writer(writer_name) pub.publish(source, destination) + diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py index 4c10d9124..0de3674d7 100644 --- a/docutils/languages/__init__.py +++ b/docutils/languages/__init__.py @@ -14,9 +14,9 @@ __docformat__ = 'reStructuredText' _languages = {} -def getlanguage(languagecode): - if _languages.has_key(languagecode): - return _languages[languagecode] - module = __import__(languagecode, globals(), locals()) - _languages[languagecode] = module +def getlanguage(language_code): + if _languages.has_key(language_code): + return _languages[language_code] + module = __import__(language_code, globals(), locals()) + _languages[language_code] = module return module diff --git a/docutils/parsers/__init__.py b/docutils/parsers/__init__.py index 72e2e4e49..0294da0f8 100644 --- a/docutils/parsers/__init__.py +++ b/docutils/parsers/__init__.py @@ -10,28 +10,31 @@ __docformat__ = 'reStructuredText' +from docutils import Component -class Parser: - def parse(self, inputstring, docroot): - """Override to parse `inputstring` into document tree `docroot`.""" +class Parser(Component): + + def parse(self, inputstring, document): + """Override to parse `inputstring` into document tree `document`.""" raise NotImplementedError('subclass must override this method') - def setup_parse(self, inputstring, docroot): + def setup_parse(self, inputstring, document): """Initial setup, used by `parse()`.""" self.inputstring = inputstring - self.docroot = docroot + self.document = document _parser_aliases = { 'restructuredtext': 'rst', 'rest': 'rst', + 'restx': 'rst', 'rtxt': 'rst',} -def get_parser_class(parsername): - """Return the Parser class from the `parsername` module.""" - parsername = parsername.lower() - if _parser_aliases.has_key(parsername): - parsername = _parser_aliases[parsername] - module = __import__(parsername, globals(), locals()) +def get_parser_class(parser_name): + """Return the Parser class from the `parser_name` module.""" + parser_name = parser_name.lower() + if _parser_aliases.has_key(parser_name): + parser_name = _parser_aliases[parser_name] + module = __import__(parser_name, globals(), locals()) return module.Parser diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index bbe7dfee6..506a9e9fb 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -7,8 +7,7 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -This is ``the docutils.parsers.restructuredtext`` package. It exports a single -class, `Parser`. +This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`. Usage ===== @@ -27,13 +26,13 @@ Usage 3. Create a new empty `docutils.nodes.document` tree:: - docroot = docutils.utils.newdocument() + document = docutils.utils.new_document() - See `docutils.utils.newdocument()` for parameter details. + See `docutils.utils.new_document()` for parameter details. 4. Run the parser, populating the document tree:: - document = parser.parse(input, docroot) + parser.parse(input, document) Parser Overview =============== @@ -56,20 +55,25 @@ class Parser(docutils.parsers.Parser): """The reStructuredText parser.""" - def __init__(self, rfc2822=None): + supported = ('restructuredtext', 'rst', 'rest', 'restx', 'rtxt', 'rstx') + """Aliases this parser supports.""" + + def __init__(self, rfc2822=None, inliner=None): if rfc2822: - self.initialstate = 'RFC2822Body' + self.initial_state = 'RFC2822Body' else: - self.initialstate = 'Body' - - def parse(self, inputstring, docroot): - """Parse `inputstring` and populate `docroot`, a document tree.""" - self.setup_parse(inputstring, docroot) - debug = docroot.reporter[''].debug + self.initial_state = 'Body' + self.state_classes = states.state_classes + self.inliner = inliner + + def parse(self, inputstring, document): + """Parse `inputstring` and populate `document`, a document tree.""" + self.setup_parse(inputstring, document) + debug = document.reporter[''].debug self.statemachine = states.RSTStateMachine( - stateclasses=states.stateclasses, - initialstate=self.initialstate, + state_classes=self.state_classes, + initial_state=self.initial_state, debug=debug) inputlines = docutils.statemachine.string2lines( - inputstring, convertwhitespace=1) - self.statemachine.run(inputlines, docroot) + inputstring, convert_whitespace=1) + self.statemachine.run(inputlines, document, inliner=self.inliner) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 43b0c1dd3..89d273651 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -11,17 +11,17 @@ This package contains directive implementation modules. The interface for directive functions is as follows:: - def directivefn(match, type, data, state, statemachine, attributes) + def directivefn(match, type_name, data, state, state_machine, attributes) Where: - ``match`` is a regular expression match object which matched the first line of the directive. ``match.group(1)`` gives the directive name. -- ``type`` is the directive type or name. +- ``type_name`` is the directive type or name. - ``data`` contains the remainder of the first line of the directive after the "::". - ``state`` is the state which called the directive function. -- ``statemachine`` is the state machine which controls the state which called +- ``state_machine`` is the state machine which controls the state which called the directive function. - ``attributes`` is a dictionary of extra attributes which may be added to the element the directive produces. Currently, only an "alt" attribute is passed @@ -42,15 +42,16 @@ _directive_registry = { 'tip': ('admonitions', 'tip'), 'hint': ('admonitions', 'hint'), 'warning': ('admonitions', 'warning'), + 'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), - 'contents': ('components', 'contents'), - 'footnotes': ('components', 'footnotes'), - 'citations': ('components', 'citations'), - 'topic': ('components', 'topic'), + 'contents': ('parts', 'contents'), + #'footnotes': ('parts', 'footnotes'), + #'citations': ('parts', 'citations'), + #'topic': ('parts', 'topic'), 'meta': ('html', 'meta'), - 'imagemap': ('html', 'imagemap'), - 'raw': ('misc', 'raw'), + #'imagemap': ('html', 'imagemap'), + #'raw': ('misc', 'raw'), 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} """Mapping of directive name to (module name, function name). The directive 'name' is canonical & must be lowercase; language-dependent names are defined diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index f594cd431..9e6b0ebf7 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -17,15 +17,15 @@ from docutils.parsers.rst import states from docutils import nodes -def admonition(nodeclass, match, typename, data, state, statemachine, +def admonition(node_class, match, type_name, data, state, state_machine, attributes): - indented, indent, lineoffset, blankfinish \ - = statemachine.getfirstknownindented(match.end()) + indented, indent, line_offset, blank_finish \ + = state_machine.get_first_known_indented(match.end()) text = '\n'.join(indented) - admonitionnode = nodeclass(text) + admonition_node = node_class(text) if text: - state.nestedparse(indented, lineoffset, admonitionnode) - return [admonitionnode], blankfinish + state.nested_parse(indented, line_offset, admonition_node) + return [admonition_node], blank_finish def attention(*args, **kwargs): return admonition(nodes.attention, *args, **kwargs) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 7a719333b..76e5d6f47 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -25,13 +25,13 @@ image_attribute_spec = {'alt': unchanged, 'width': int, 'scale': int} -def image(match, typename, data, state, statemachine, attributes): - lineno = statemachine.abslineno() - lineoffset = statemachine.lineoffset - datablock, indent, offset, blankfinish = \ - statemachine.getfirstknownindented(match.end(), uptoblank=1) - blocktext = '\n'.join(statemachine.inputlines[ - lineoffset : lineoffset + len(datablock) + 1]) +def image(match, type_name, data, state, state_machine, attributes): + lineno = state_machine.abs_line_number() + line_offset = state_machine.line_offset + datablock, indent, offset, blank_finish = \ + state_machine.get_first_known_indented(match.end(), until_blank=1) + blocktext = '\n'.join(state_machine.input_lines[ + line_offset : line_offset + len(datablock) + 1]) for i in range(len(datablock)): if datablock[i][:1] == ':': attlines = datablock[i:] @@ -40,58 +40,58 @@ def image(match, typename, data, state, statemachine, attributes): else: attlines = [] if not datablock: - error = statemachine.memo.reporter.error( + error = state_machine.reporter.error( 'Missing image URI argument at line %s.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - return [error], blankfinish - attoffset = lineoffset + i + return [error], blank_finish + attoffset = line_offset + i reference = ''.join([line.strip() for line in datablock]) if reference.find(' ') != -1: - error = statemachine.memo.reporter.error( + error = state_machine.reporter.error( 'Image URI at line %s contains whitespace.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - return [error], blankfinish + return [error], blank_finish if attlines: - success, data, blankfinish = state.parse_extension_attributes( - image_attribute_spec, attlines, blankfinish) + success, data, blank_finish = state.parse_extension_attributes( + image_attribute_spec, attlines, blank_finish) if success: # data is a dict of attributes attributes.update(data) else: # data is an error string - error = statemachine.memo.reporter.error( + error = state_machine.reporter.error( 'Error in "%s" directive attributes at line %s:\n%s.' % (match.group(1), lineno, data), '', nodes.literal_block(blocktext, blocktext)) - return [error], blankfinish + return [error], blank_finish attributes['uri'] = reference imagenode = nodes.image(blocktext, **attributes) - return [imagenode], blankfinish + return [imagenode], blank_finish -def figure(match, typename, data, state, statemachine, attributes): - lineoffset = statemachine.lineoffset - (imagenode,), blankfinish = image(match, typename, data, state, - statemachine, attributes) - indented, indent, offset, blankfinish \ - = statemachine.getfirstknownindented(sys.maxint) - blocktext = '\n'.join(statemachine.inputlines[lineoffset: - statemachine.lineoffset+1]) +def figure(match, type_name, data, state, state_machine, attributes): + line_offset = state_machine.line_offset + (imagenode,), blank_finish = image(match, type_name, data, state, + state_machine, attributes) + indented, indent, offset, blank_finish \ + = state_machine.get_first_known_indented(sys.maxint) + blocktext = '\n'.join(state_machine.input_lines[line_offset: + state_machine.line_offset+1]) if isinstance(imagenode, nodes.system_message): if indented: imagenode[-1] = nodes.literal_block(blocktext, blocktext) - return [imagenode], blankfinish + return [imagenode], blank_finish figurenode = nodes.figure('', imagenode) if indented: node = nodes.Element() # anonymous container for parsing - state.nestedparse(indented, lineoffset, node) + state.nested_parse(indented, line_offset, node) firstnode = node[0] if isinstance(firstnode, nodes.paragraph): caption = nodes.caption(firstnode.rawsource, '', *firstnode.children) figurenode += caption elif not (isinstance(firstnode, nodes.comment) and len(firstnode) == 0): - error = statemachine.memo.reporter.error( + error = state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', '', nodes.literal_block(blocktext, blocktext)) - return [figurenode, error], blankfinish + return [figurenode, error], blank_finish if len(node) > 1: figurenode += nodes.legend('', *node[1:]) - return [figurenode], blankfinish + return [figurenode], blank_finish diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index f8a9d5217..3a23f9226 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -16,24 +16,24 @@ __docformat__ = 'reStructuredText' from docutils import nodes -def raw(match, typename, data, state, statemachine, attributes): +def raw(match, type_name, data, state, state_machine, attributes): return [], 1 -def directive_test_function(match, typename, data, state, statemachine, +def directive_test_function(match, type_name, data, state, state_machine, attributes): try: - statemachine.nextline() - indented, indent, offset, blankfinish = statemachine.getindented() + state_machine.next_line() + indented, indent, offset, blank_finish = state_machine.get_indented() text = '\n'.join(indented) except IndexError: text = '' - blankfinish = 1 + blank_finish = 1 if text: - info = statemachine.memo.reporter.info( + info = state_machine.reporter.info( 'Directive processed. Type="%s", data="%s", directive block:' - % (typename, data), '', nodes.literal_block(text, text)) + % (type_name, data), '', nodes.literal_block(text, text)) else: - info = statemachine.memo.reporter.info( - 'Directive processed. Type="%s", data="%s", directive block: None' - % (typename, data)) - return [info], blankfinish + info = state_machine.reporter.info( + 'Directive processed. Type="%s", data="%s", directive block: ' + 'None' % (type_name, data)) + return [info], blank_finish -- cgit v1.2.1 From 409668ba1ca8fbe197893dd7874acdf5f81c41eb Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:19:26 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@74 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 7bacf99cd..3f7575040 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -19,9 +19,10 @@ __docformat__ = 'reStructuredText' import re +from docutils import DataError -class TableMarkupError(Exception): pass +class TableMarkupError(DataError): pass class TableParser: -- cgit v1.2.1 From c854d0803dd10573ea908840b85d12499904b060 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:22:30 +0000 Subject: - Added underscores to improve many awkward names. - 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. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@75 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 1787 +++++++++++++++++++++------------------- 1 file changed, 919 insertions(+), 868 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index efce3b4f1..d2a133198 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -31,13 +31,14 @@ the reStructuredText parser. It defines the following: :Exception classes: - `MarkupError` - `ParserError` + - `MarkupMismatch` :Functions: - `escape2null()`: Return a string, escape-backslashes converted to nulls. - `unescape()`: Return a string, nulls removed or restored to backslashes. :Attributes: - - `stateclasses`: set of State classes used with `RSTStateMachine`. + - `state_classes`: set of State classes used with `RSTStateMachine`. Parser Overview =============== @@ -102,15 +103,17 @@ __docformat__ = 'reStructuredText' import sys, re, string -from docutils import nodes, statemachine, utils, roman, urischemes +from docutils import nodes, statemachine, utils, roman, urischemes, \ + ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS -from docutils.utils import normname +from docutils.utils import normalize_name import directives, languages from tableparser import TableParser, TableMarkupError -class MarkupError(Exception): pass -class ParserError(Exception): pass +class MarkupError(DataError): pass +class ParserError(ApplicationError): pass +class MarkupMismatch(Exception): pass class Stuff: @@ -129,24 +132,30 @@ class RSTStateMachine(StateMachineWS): The entry point to reStructuredText parsing is the `run()` method. """ - def run(self, inputlines, docroot, inputoffset=0, matchtitles=1): + def run(self, input_lines, document, input_offset=0, match_titles=1, + inliner=None): """ - Parse `inputlines` and return a `docutils.nodes.document` instance. + Parse `input_lines` and return a `docutils.nodes.document` instance. Extend `StateMachineWS.run()`: set up parse-global data, run the StateMachine, and return the resulting document. """ - self.language = languages.getlanguage(docroot.languagecode) - self.matchtitles = matchtitles - self.memo = Stuff(document=docroot, - reporter=docroot.reporter, + self.language = languages.getlanguage(document.language_code) + self.match_titles = match_titles + if inliner is None: + inliner = Inliner() + self.memo = Stuff(document=document, + reporter=document.reporter, language=self.language, - titlestyles=[], - sectionlevel=0) - self.node = docroot - results = StateMachineWS.run(self, inputlines, inputoffset) - assert results == [], 'RSTStateMachine.run() results should be empty.' + title_styles=[], + section_level=0, + inliner=inliner) + self.document = self.memo.document + self.reporter = self.memo.reporter + self.node = document + results = StateMachineWS.run(self, input_lines, input_offset) + assert results == [], 'RSTStateMachine.run() results should be empty!' self.node = self.memo = None # remove unneeded references @@ -157,17 +166,20 @@ class NestedStateMachine(StateMachineWS): document structures. """ - def run(self, inputlines, inputoffset, memo, node, matchtitles=1): + def run(self, input_lines, input_offset, memo, node, match_titles=1): """ - Parse `inputlines` and populate a `docutils.nodes.document` instance. + Parse `input_lines` and populate a `docutils.nodes.document` instance. Extend `StateMachineWS.run()`: set up document-wide data. """ - self.matchtitles = matchtitles + self.match_titles = match_titles self.memo = memo + self.document = memo.document + self.reporter = memo.reporter self.node = node - results = StateMachineWS.run(self, inputlines, inputoffset) - assert results == [], 'NestedStateMachine.run() results should be empty' + results = StateMachineWS.run(self, input_lines, input_offset) + assert results == [], ('NestedStateMachine.run() results should be ' + 'empty!') return results @@ -179,17 +191,28 @@ class RSTState(StateWS): Contains methods used by all State subclasses. """ - nestedSM = NestedStateMachine + nested_sm = NestedStateMachine - def __init__(self, statemachine, debug=0): - self.nestedSMkwargs = {'stateclasses': stateclasses, - 'initialstate': 'Body'} - StateWS.__init__(self, statemachine, debug) + def __init__(self, state_machine, debug=0): + self.nested_sm_kwargs = {'state_classes': state_classes, + 'initial_state': 'Body'} + StateWS.__init__(self, state_machine, debug) - def gotoline(self, abslineoffset): - """Jump to input line `abslineoffset`, ignoring jumps past the end.""" + def runtime_init(self): + StateWS.runtime_init(self) + memo = self.state_machine.memo + self.memo = memo + self.reporter = memo.reporter + self.inliner = memo.inliner + self.document = memo.document + self.parent = self.state_machine.node + + def goto_line(self, abs_line_offset): + """ + Jump to input line `abs_line_offset`, ignoring jumps past the end. + """ try: - self.statemachine.gotoline(abslineoffset) + self.state_machine.goto_line(abs_line_offset) except IndexError: pass @@ -197,126 +220,131 @@ class RSTState(StateWS): """Called at beginning of file.""" return [], [] - def nestedparse(self, block, inputoffset, node, matchtitles=0, - statemachineclass=None, statemachinekwargs=None): + def nested_parse(self, block, input_offset, node, match_titles=0, + state_machine_class=None, state_machine_kwargs=None): """ Create a new StateMachine rooted at `node` and run it over the input `block`. """ - if statemachineclass is None: - statemachineclass = self.nestedSM - if statemachinekwargs is None: - statemachinekwargs = self.nestedSMkwargs - statemachine = statemachineclass(debug=self.debug, **statemachinekwargs) - statemachine.run(block, inputoffset, memo=self.statemachine.memo, - node=node, matchtitles=matchtitles) - statemachine.unlink() - return statemachine.abslineoffset() - - def nestedlistparse(self, block, inputoffset, node, initialstate, - blankfinish, blankfinishstate=None, extrasettings={}, - matchtitles=0, statemachineclass=None, - statemachinekwargs=None): + if state_machine_class is None: + state_machine_class = self.nested_sm + if state_machine_kwargs is None: + state_machine_kwargs = self.nested_sm_kwargs + state_machine = state_machine_class(debug=self.debug, + **state_machine_kwargs) + state_machine.run(block, input_offset, memo=self.memo, + node=node, match_titles=match_titles) + state_machine.unlink() + return state_machine.abs_line_offset() + + def nested_list_parse(self, block, input_offset, node, initial_state, + blank_finish, + blank_finish_state=None, + extra_settings={}, + match_titles=0, + state_machine_class=None, + state_machine_kwargs=None): """ Create a new StateMachine rooted at `node` and run it over the input `block`. Also keep track of optional intermdediate blank lines and the required final one. """ - if statemachineclass is None: - statemachineclass = self.nestedSM - if statemachinekwargs is None: - statemachinekwargs = self.nestedSMkwargs.copy() - statemachinekwargs['initialstate'] = initialstate - statemachine = statemachineclass(debug=self.debug, **statemachinekwargs) - if blankfinishstate is None: - blankfinishstate = initialstate - statemachine.states[blankfinishstate].blankfinish = blankfinish - for key, value in extrasettings.items(): - setattr(statemachine.states[initialstate], key, value) - statemachine.run(block, inputoffset, memo=self.statemachine.memo, - node=node, matchtitles=matchtitles) - blankfinish = statemachine.states[blankfinishstate].blankfinish - statemachine.unlink() - return statemachine.abslineoffset(), blankfinish + if state_machine_class is None: + state_machine_class = self.nested_sm + if state_machine_kwargs is None: + state_machine_kwargs = self.nested_sm_kwargs.copy() + state_machine_kwargs['initial_state'] = initial_state + state_machine = state_machine_class(debug=self.debug, + **state_machine_kwargs) + if blank_finish_state is None: + blank_finish_state = initial_state + state_machine.states[blank_finish_state].blank_finish = blank_finish + for key, value in extra_settings.items(): + setattr(state_machine.states[initial_state], key, value) + state_machine.run(block, input_offset, memo=self.memo, + node=node, match_titles=match_titles) + blank_finish = state_machine.states[blank_finish_state].blank_finish + state_machine.unlink() + return state_machine.abs_line_offset(), blank_finish def section(self, title, source, style, lineno): + """Check for a valid subsection and create one if it checks out.""" + if self.check_subsection(source, style, lineno): + self.new_subsection(title, lineno) + + def check_subsection(self, source, style, lineno): """ + Check for a valid subsection header. Return 1 (true) or None (false). + When a new section is reached that isn't a subsection of the current - section, back up the line count (use previousline(-x)), then raise - EOFError. The current StateMachine will finish, then the calling - StateMachine can re-examine the title. This will work its way back up - the calling chain until the correct section level isreached. + section, back up the line count (use ``previous_line(-x)``), then + ``raise EOFError``. The current StateMachine will finish, then the + calling StateMachine can re-examine the title. This will work its way + back up the calling chain until the correct section level isreached. - Alternative: Evaluate the title, store the title info & level, and - back up the chain until that level is reached. Store in memo? Or + @@@ Alternative: Evaluate the title, store the title info & level, and + back up the chain until that level is reached. Store in memo? Or return in results? - """ - if self.checksubsection(source, style, lineno): - self.newsubsection(title, lineno) - - def checksubsection(self, source, style, lineno): - """ - Check for a valid subsection header. Return 1 (true) or None (false). :Exception: `EOFError` when a sibling or supersection encountered. """ - memo = self.statemachine.memo - titlestyles = memo.titlestyles - mylevel = memo.sectionlevel + memo = self.memo + title_styles = memo.title_styles + mylevel = memo.section_level try: # check for existing title style - level = titlestyles.index(style) + 1 + level = title_styles.index(style) + 1 except ValueError: # new title style - if len(titlestyles) == memo.sectionlevel: # new subsection - titlestyles.append(style) + if len(title_styles) == memo.section_level: # new subsection + title_styles.append(style) return 1 else: # not at lowest level - self.statemachine.node += self.titleinconsistent(source, lineno) + self.parent += self.title_inconsistent(source, lineno) return None if level <= mylevel: # sibling or supersection - memo.sectionlevel = level # bubble up to parent section + memo.section_level = level # bubble up to parent section # back up 2 lines for underline title, 3 for overline title - self.statemachine.previousline(len(style) + 1) + self.state_machine.previous_line(len(style) + 1) raise EOFError # let parent section re-evaluate if level == mylevel + 1: # immediate subsection return 1 else: # invalid subsection - self.statemachine.node += self.titleinconsistent(source, lineno) + self.parent += self.title_inconsistent(source, lineno) return None - def titleinconsistent(self, sourcetext, lineno): + def title_inconsistent(self, sourcetext, lineno): literalblock = nodes.literal_block('', sourcetext) - error = self.statemachine.memo.reporter.severe( - 'Title level inconsistent at line %s:' % lineno, '', literalblock) + error = self.reporter.severe('Title level inconsistent at line %s:' + % lineno, '', literalblock) return error - def newsubsection(self, title, lineno): + def new_subsection(self, title, lineno): """Append new subsection to document tree. On return, check level.""" - memo = self.statemachine.memo - mylevel = memo.sectionlevel - memo.sectionlevel += 1 + memo = self.memo + mylevel = memo.section_level + memo.section_level += 1 sectionnode = nodes.section() - self.statemachine.node += sectionnode + self.parent += sectionnode textnodes, messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) - name = normname(titlenode.astext()) + name = normalize_name(titlenode.astext()) sectionnode['name'] = name sectionnode += titlenode sectionnode += messages - memo.document.note_implicit_target(sectionnode, sectionnode) - offset = self.statemachine.lineoffset + 1 - absoffset = self.statemachine.abslineoffset() + 1 - newabsoffset = self.nestedparse( - self.statemachine.inputlines[offset:], inputoffset=absoffset, - node=sectionnode, matchtitles=1) - self.gotoline(newabsoffset) - if memo.sectionlevel <= mylevel: # can't handle next section? + self.document.note_implicit_target(sectionnode, sectionnode) + offset = self.state_machine.line_offset + 1 + absoffset = self.state_machine.abs_line_offset() + 1 + newabsoffset = self.nested_parse( + self.state_machine.input_lines[offset:], input_offset=absoffset, + node=sectionnode, match_titles=1) + self.goto_line(newabsoffset) + if memo.section_level <= mylevel: # can't handle next section? raise EOFError # bubble up to supersection - # reset sectionlevel; next pass will detect it properly - memo.sectionlevel = mylevel + # reset section_level; next pass will detect it properly + memo.section_level = mylevel def paragraph(self, lines, lineno): """ - Return a list (paragraph & messages) and a boolean: literal_block next? + Return a list (paragraph & messages) & a boolean: literal_block next? """ data = '\n'.join(lines).rstrip() if data[-2:] == '::': @@ -334,143 +362,203 @@ class RSTState(StateWS): p = nodes.paragraph(data, '', *textnodes) return [p] + messages, literalnext - inline = Stuff() - """Patterns and constants used for inline markup recognition.""" - - inline.openers = '\'"([{<' - inline.closers = '\'")]}>' - inline.start_string_prefix = (r'(?:(?<=^)|(?<=[ \n%s]))' - % re.escape(inline.openers)) - inline.end_string_suffix = (r'(?:(?=$)|(?=[- \n.,:;!?%s]))' - % re.escape(inline.closers)) - inline.non_whitespace_before = r'(?' + start_string_prefix = (r'(?:(?<=^)|(?<=[ \n%s]))' + % re.escape(openers)) + end_string_suffix = (r'(?:(?=$)|(?=[- \n.,:;!?%s]))' + % re.escape(closers)) + non_whitespace_before = r'(? 0: - textnodes.append(nodes.Text(unescape( - remainder[:match.start(whole)]))) - if match.group(email): - addscheme = 'mailto:' - else: - addscheme = '' - text = match.group(whole) - unescaped = unescape(text, 0) - textnodes.append( - nodes.reference(unescape(text, 1), unescaped, - refuri=addscheme + unescaped)) - remainder = remainder[match.end(whole):] - start = 0 - else: # not a valid scheme - start = match.end(whole) + def standalone_uri(self, match, lineno): + scheme = self.groups.uri.scheme + if not match.group(scheme) or urischemes.schemes.has_key( + match.group(scheme).lower()): + if match.group(self.groups.uri.email): + addscheme = 'mailto:' else: - if remainder: - textnodes.append(nodes.Text(unescape(remainder))) - break - return textnodes - - inline.dispatch = {'*': emphasis, - '**': strong, - '`': interpreted_or_phrase_ref, - '``': literal, - '_`': inline_target, - ']_': footnote_reference, - '|': substitution_reference, - '_': reference, - '__': anonymous_reference} - - def inline_text(self, text, lineno): + addscheme = '' + text = match.group(self.groups.uri.whole) + unescaped = unescape(text, 0) + return [nodes.reference(unescape(text, 1), unescaped, + refuri=addscheme + unescaped)] + else: # not a valid scheme + raise MarkupMismatch + + implicit = ((patterns.uri, standalone_uri),) + """List of (pattern, dispatch method) pairs.""" + + def implicit_inline(self, text, lineno): """ - Return 2 lists: nodes (text and inline elements), and system_messages. - - Using a `pattern` matching start-strings (for emphasis, strong, - interpreted, phrase reference, literal, substitution reference, and - inline target) or complete constructs (simple reference, footnote - reference) we search for a candidate. When one is found, we check for - validity (e.g., not a quoted '*' character). If valid, search for the - corresponding end string if applicable, and check for validity. If not - found or invalid, generate a warning and ignore the start-string. - Standalone hyperlinks are found last. + Check each of the patterns in `self.implicit` for a match, and + dispatch to the stored method for the pattern. Recursively check the + text before and after the match. """ - pattern = self.inline.patterns.initial - dispatch = self.inline.dispatch - start = self.inline.groups.initial.start - 1 - backquote = self.inline.groups.initial.backquote - 1 - refend = self.inline.groups.initial.refend - 1 - fnend = self.inline.groups.initial.fnend - 1 - remaining = escape2null(text) - processed = [] - unprocessed = [] - messages = [] - while remaining: - match = pattern.search(remaining) + if not text: + return [] + for pattern, dispatch in self.implicit: + match = pattern.search(text) if match: - groups = match.groups() - before, inlines, remaining, sysmessages = \ - dispatch[groups[start] or groups[backquote] - or groups[refend] - or groups[fnend]](self, match, lineno) - unprocessed.append(before) - messages += sysmessages - if inlines: - processed += self.standalone_uri(''.join(unprocessed), - lineno) - processed += inlines - unprocessed = [] - else: - break - remaining = ''.join(unprocessed) + remaining - if remaining: - processed += self.standalone_uri(remaining, lineno) - return processed, messages - - def unindent_warning(self, node_name): - return self.statemachine.memo.reporter.warning( - ('%s ends without a blank line; unexpected unindent at line %s.' - % (node_name, self.statemachine.abslineno() + 1))) + try: + return (self.implicit_inline(text[:match.start()], lineno) + + dispatch(self, match, lineno) + + self.implicit_inline(text[match.end():], lineno)) + except MarkupMismatch: + pass + return [nodes.Text(unescape(text))] + + dispatch = {'*': emphasis, + '**': strong, + '`': interpreted_or_phrase_ref, + '``': literal, + '_`': inline_target, + ']_': footnote_reference, + '|': substitution_reference, + '_': reference, + '__': anonymous_reference} class Body(RSTState): @@ -830,10 +870,10 @@ class Body(RSTState): enum.sequenceregexps = {} for sequence in enum.sequences: - enum.sequenceregexps[sequence] = re.compile(enum.sequencepats[sequence] - + '$') + enum.sequenceregexps[sequence] = re.compile( + enum.sequencepats[sequence] + '$') - tabletoppat = re.compile(r'\+-[-+]+-\+ *$') + table_top_pat = re.compile(r'\+-[-+]+-\+ *$') """Matches the top (& bottom) of a table).""" tableparser = TableParser() @@ -856,114 +896,116 @@ class Body(RSTState): format, re.escape(enum.formatinfo[format].prefix), pats['enum'], re.escape(enum.formatinfo[format].suffix)) - patterns = {'bullet': r'[-+*]( +|$)', - 'enumerator': r'(%(parens)s|%(rparen)s|%(period)s)( +|$)' - % pats, - 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', - 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, - 'doctest': r'>>>( +|$)', - 'tabletop': tabletoppat, - 'explicit_markup': r'\.\.( +|$)', - 'anonymous': r'__( +|$)', - 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, - 'text': r''} - initialtransitions = ['bullet', - 'enumerator', - 'field_marker', - 'option_marker', - 'doctest', - 'tabletop', - 'explicit_markup', - 'anonymous', - 'line', - 'text'] - - def indent(self, match, context, nextstate): + patterns = { + 'bullet': r'[-+*]( +|$)', + 'enumerator': r'(%(parens)s|%(rparen)s|%(period)s)( +|$)' % pats, + 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', + 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, + 'doctest': r'>>>( +|$)', + 'table_top': table_top_pat, + 'explicit_markup': r'\.\.( +|$)', + 'anonymous': r'__( +|$)', + 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, + 'text': r''} + initial_transitions = ( + 'bullet', + 'enumerator', + 'field_marker', + 'option_marker', + 'doctest', + 'table_top', + 'explicit_markup', + 'anonymous', + 'line', + 'text') + + def indent(self, match, context, next_state): """Block quote.""" - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getindented() - blockquote = self.block_quote(indented, lineoffset) - self.statemachine.node += blockquote - if not blankfinish: - self.statemachine.node += self.unindent_warning('Block quote') - return context, nextstate, [] - - def block_quote(self, indented, lineoffset): + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_indented() + blockquote = self.block_quote(indented, line_offset) + self.parent += blockquote + if not blank_finish: + self.parent += self.unindent_warning('Block quote') + return context, next_state, [] + + def block_quote(self, indented, line_offset): blockquote = nodes.block_quote() - self.nestedparse(indented, lineoffset, blockquote) + self.nested_parse(indented, line_offset, blockquote) return blockquote - def bullet(self, match, context, nextstate): + def bullet(self, match, context, next_state): """Bullet list item.""" bulletlist = nodes.bullet_list() - self.statemachine.node += bulletlist + self.parent += bulletlist bulletlist['bullet'] = match.string[0] - i, blankfinish = self.list_item(match.end()) + i, blank_finish = self.list_item(match.end()) bulletlist += i - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=bulletlist, initialstate='BulletList', - blankfinish=blankfinish) - if not blankfinish: - self.statemachine.node += self.unindent_warning('Bullet list') - self.gotoline(newlineoffset) - return [], nextstate, [] + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=bulletlist, initial_state='BulletList', + blank_finish=blank_finish) + if not blank_finish: + self.parent += self.unindent_warning('Bullet list') + self.goto_line(newline_offset) + return [], next_state, [] def list_item(self, indent): - indented, lineoffset, blankfinish = \ - self.statemachine.getknownindented(indent) + indented, line_offset, blank_finish = \ + self.state_machine.get_known_indented(indent) listitem = nodes.list_item('\n'.join(indented)) if indented: - self.nestedparse(indented, inputoffset=lineoffset, node=listitem) - return listitem, blankfinish + self.nested_parse(indented, input_offset=line_offset, + node=listitem) + return listitem, blank_finish - def enumerator(self, match, context, nextstate): + def enumerator(self, match, context, next_state): """Enumerated List Item""" format, sequence, text, ordinal = self.parse_enumerator(match) if ordinal is None: - msg = self.statemachine.memo.reporter.error( + msg = self.reporter.error( ('Enumerated list start value invalid at line %s: ' - '%r (sequence %r)' % (self.statemachine.abslineno(), + '%r (sequence %r)' % (self.state_machine.abs_line_number(), text, sequence))) - self.statemachine.node += msg - indented, lineoffset, blankfinish = \ - self.statemachine.getknownindented(match.end()) - bq = self.block_quote(indented, lineoffset) - self.statemachine.node += bq - if not blankfinish: - self.statemachine.node += self.unindent_warning( + self.parent += msg + indented, line_offset, blank_finish = \ + self.state_machine.get_known_indented(match.end()) + bq = self.block_quote(indented, line_offset) + self.parent += bq + if not blank_finish: + self.parent += self.unindent_warning( 'Enumerated list') - return [], nextstate, [] + return [], next_state, [] if ordinal != 1: - msg = self.statemachine.memo.reporter.info( + msg = self.reporter.info( ('Enumerated list start value not ordinal-1 at line %s: ' - '%r (ordinal %s)' % (self.statemachine.abslineno(), - text, ordinal))) - self.statemachine.node += msg + '%r (ordinal %s)' % (self.state_machine.abs_line_number(), + text, ordinal))) + self.parent += msg enumlist = nodes.enumerated_list() - self.statemachine.node += enumlist + self.parent += enumlist enumlist['enumtype'] = sequence if ordinal != 1: enumlist['start'] = ordinal enumlist['prefix'] = self.enum.formatinfo[format].prefix enumlist['suffix'] = self.enum.formatinfo[format].suffix - listitem, blankfinish = self.list_item(match.end()) + listitem, blank_finish = self.list_item(match.end()) enumlist += listitem - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=enumlist, initialstate='EnumeratedList', - blankfinish=blankfinish, - extrasettings={'lastordinal': ordinal, 'format': format}) - if not blankfinish: - self.statemachine.node += self.unindent_warning('Enumerated list') - self.gotoline(newlineoffset) - return [], nextstate, [] - - def parse_enumerator(self, match, expectedsequence=None): + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=enumlist, initial_state='EnumeratedList', + blank_finish=blank_finish, + extra_settings={'lastordinal': ordinal, 'format': format}) + if not blank_finish: + self.parent += self.unindent_warning('Enumerated list') + self.goto_line(newline_offset) + return [], next_state, [] + + def parse_enumerator(self, match, expected_sequence=None): """ Analyze an enumerator and return the results. @@ -975,7 +1017,7 @@ class Body(RSTState): ``None`` is returned for invalid enumerator text). The enumerator format has already been determined by the regular - expression match. If `expectedsequence` is given, that sequence is + expression match. If `expected_sequence` is given, that sequence is tried first. If not, we check for Roman numeral 1. This way, single-character Roman numerals (which are also alphabetical) can be matched. If no sequence has been matched, all sequences are checked in @@ -990,10 +1032,10 @@ class Body(RSTState): raise ParserError, 'enumerator format not matched' text = groupdict[format][self.enum.formatinfo[format].start :self.enum.formatinfo[format].end] - if expectedsequence: + if expected_sequence: try: - if self.enum.sequenceregexps[expectedsequence].match(text): - sequence = expectedsequence + if self.enum.sequenceregexps[expected_sequence].match(text): + sequence = expected_sequence except KeyError: # shouldn't happen raise ParserError, 'unknown sequence: %s' % sequence else: @@ -1013,27 +1055,27 @@ class Body(RSTState): ordinal = None return format, sequence, text, ordinal - def field_marker(self, match, context, nextstate): + def field_marker(self, match, context, next_state): """Field list item.""" fieldlist = nodes.field_list() - self.statemachine.node += fieldlist - field, blankfinish = self.field(match) + self.parent += fieldlist + field, blank_finish = self.field(match) fieldlist += field - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=fieldlist, initialstate='FieldList', - blankfinish=blankfinish) - if not blankfinish: - self.statemachine.node += self.unindent_warning('Field list') - self.gotoline(newlineoffset) - return [], nextstate, [] + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=fieldlist, initial_state='FieldList', + blank_finish=blank_finish) + if not blank_finish: + self.parent += self.unindent_warning('Field list') + self.goto_line(newline_offset) + return [], next_state, [] def field(self, match): name, args = self.parse_field_marker(match) - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) fieldnode = nodes.field() fieldnode += nodes.field_name(name, name) for arg in args: @@ -1041,8 +1083,9 @@ class Body(RSTState): fieldbody = nodes.field_body('\n'.join(indented)) fieldnode += fieldbody if indented: - self.nestedparse(indented, inputoffset=lineoffset, node=fieldbody) - return fieldnode, blankfinish + self.nested_parse(indented, input_offset=line_offset, + node=fieldbody) + return fieldnode, blank_finish def parse_field_marker(self, match): """Extract & return name & argument list from a field marker match.""" @@ -1051,48 +1094,50 @@ class Body(RSTState): tokens = field.split() return tokens[0], tokens[1:] # first == name, others == args - def option_marker(self, match, context, nextstate): + def option_marker(self, match, context, next_state): """Option list item.""" optionlist = nodes.option_list() try: - listitem, blankfinish = self.option_list_item(match) - except MarkupError, detail: # shouldn't happen; won't match pattern - msg = self.statemachine.memo.reporter.error( + listitem, blank_finish = self.option_list_item(match) + except MarkupError, detail: # shouldn't happen; won't match pattern + msg = self.reporter.error( ('Invalid option list marker at line %s: %s' - % (self.statemachine.abslineno(), detail))) - self.statemachine.node += msg - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) - blockquote = self.block_quote(indented, lineoffset) - self.statemachine.node += blockquote - if not blankfinish: - self.statemachine.node += self.unindent_warning('Option list') - return [], nextstate, [] - self.statemachine.node += optionlist + % (self.state_machine.abs_line_number(), detail))) + self.parent += msg + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) + blockquote = self.block_quote(indented, line_offset) + self.parent += blockquote + if not blank_finish: + self.parent += self.unindent_warning('Option list') + return [], next_state, [] + self.parent += optionlist optionlist += listitem - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=optionlist, initialstate='OptionList', - blankfinish=blankfinish) - if not blankfinish: - self.statemachine.node += self.unindent_warning('Option list') - self.gotoline(newlineoffset) - return [], nextstate, [] + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=optionlist, initial_state='OptionList', + blank_finish=blank_finish) + if not blank_finish: + self.parent += self.unindent_warning('Option list') + self.goto_line(newline_offset) + return [], next_state, [] def option_list_item(self, match): options = self.parse_option_marker(match) - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) if not indented: # not an option list item raise statemachine.TransitionCorrection('text') option_group = nodes.option_group('', *options) description = nodes.description('\n'.join(indented)) - option_list_item = nodes.option_list_item('', option_group, description) + option_list_item = nodes.option_list_item('', option_group, + description) if indented: - self.nestedparse(indented, inputoffset=lineoffset, node=description) - return option_list_item, blankfinish + self.nested_parse(indented, input_offset=line_offset, + node=description) + return option_list_item, blank_finish def parse_option_marker(self, match): """ @@ -1123,84 +1168,85 @@ class Body(RSTState): optionstring)) return optlist - def doctest(self, match, context, nextstate): - data = '\n'.join(self.statemachine.gettextblock()) - self.statemachine.node += nodes.doctest_block(data, data) - return [], nextstate, [] + def doctest(self, match, context, next_state): + data = '\n'.join(self.state_machine.get_text_block()) + self.parent += nodes.doctest_block(data, data) + return [], next_state, [] - def tabletop(self, match, context, nextstate): + def table_top(self, match, context, next_state): """Top border of a table.""" - nodelist, blankfinish = self.table() - self.statemachine.node += nodelist - if not blankfinish: - msg = self.statemachine.memo.reporter.warning( + nodelist, blank_finish = self.table() + self.parent += nodelist + if not blank_finish: + msg = self.reporter.warning( 'Blank line required after table at line %s.' - % (self.statemachine.abslineno() + 1)) - self.statemachine.node += msg - return [], nextstate, [] + % (self.state_machine.abs_line_number() + 1)) + self.parent += msg + return [], next_state, [] def table(self): """Parse a table.""" - block, messages, blankfinish = self.isolatetable() + block, messages, blank_finish = self.isolate_table() if block: try: tabledata = self.tableparser.parse(block) - tableline = self.statemachine.abslineno() - len(block) + 1 - table = self.buildtable(tabledata, tableline) + tableline = (self.state_machine.abs_line_number() - len(block) + + 1) + table = self.build_table(tabledata, tableline) nodelist = [table] + messages except TableMarkupError, detail: - nodelist = self.malformedtable(block, str(detail)) + messages + nodelist = self.malformed_table(block, str(detail)) + messages else: nodelist = messages - return nodelist, blankfinish + return nodelist, blank_finish - def isolatetable(self): + def isolate_table(self): messages = [] - blankfinish = 1 + blank_finish = 1 try: - block = self.statemachine.getunindented() + block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: block, lineno = instance.args - messages.append(self.statemachine.memo.reporter.error( + messages.append(self.reporter.error( 'Unexpected indentation at line %s.' % lineno)) - blankfinish = 0 + blank_finish = 0 width = len(block[0].strip()) for i in range(len(block)): block[i] = block[i].strip() if block[i][0] not in '+|': # check left edge - blankfinish = 0 - self.statemachine.previousline(len(block) - i) + blank_finish = 0 + self.state_machine.previous_line(len(block) - i) del block[i:] break - if not self.tabletoppat.match(block[-1]): # find bottom - blankfinish = 0 + if not self.table_top_pat.match(block[-1]): # find bottom + blank_finish = 0 # from second-last to third line of table: for i in range(len(block) - 2, 1, -1): - if self.tabletoppat.match(block[i]): - self.statemachine.previousline(len(block) - i + 1) + if self.table_top_pat.match(block[i]): + self.state_machine.previous_line(len(block) - i + 1) del block[i+1:] break else: - messages.extend(self.malformedtable(block)) - return [], messages, blankfinish + messages.extend(self.malformed_table(block)) + return [], messages, blank_finish for i in range(len(block)): # check right edge if len(block[i]) != width or block[i][-1] not in '+|': - messages.extend(self.malformedtable(block)) - return [], messages, blankfinish - return block, messages, blankfinish + messages.extend(self.malformed_table(block)) + return [], messages, blank_finish + return block, messages, blank_finish - def malformedtable(self, block, detail=''): + def malformed_table(self, block, detail=''): data = '\n'.join(block) message = 'Malformed table at line %s; formatting as a ' \ - 'literal block.' % (self.statemachine.abslineno() + 'literal block.' % (self.state_machine.abs_line_number() - len(block) + 1) if detail: message += '\n' + detail - nodelist = [self.statemachine.memo.reporter.error(message), + nodelist = [self.reporter.error(message), nodes.literal_block(data, data)] return nodelist - def buildtable(self, tabledata, tableline): + def build_table(self, tabledata, tableline): colspecs, headrows, bodyrows = tabledata table = nodes.table() tgroup = nodes.tgroup(cols=len(colspecs)) @@ -1211,14 +1257,14 @@ class Body(RSTState): thead = nodes.thead() tgroup += thead for row in headrows: - thead += self.buildtablerow(row, tableline) + thead += self.build_table_row(row, tableline) tbody = nodes.tbody() tgroup += tbody for row in bodyrows: - tbody += self.buildtablerow(row, tableline) + tbody += self.build_table_row(row, tableline) return table - def buildtablerow(self, rowdata, tableline): + def build_table_row(self, rowdata, tableline): row = nodes.row() for cell in rowdata: if cell is None: @@ -1232,8 +1278,8 @@ class Body(RSTState): entry = nodes.entry(**attributes) row += entry if ''.join(cellblock): - self.nestedparse(cellblock, inputoffset=tableline+offset, - node=entry) + self.nested_parse(cellblock, input_offset=tableline+offset, + node=entry) return row @@ -1257,8 +1303,8 @@ class Body(RSTState): : # end of reference name (?:[ ]+|$) # followed by whitespace """ - % (RSTState.inline.non_whitespace_escape_before, - RSTState.inline.non_whitespace_escape_before), + % (Inliner.non_whitespace_escape_before, + Inliner.non_whitespace_escape_before), re.VERBOSE), reference=re.compile(r""" (?: @@ -1268,12 +1314,12 @@ class Body(RSTState): (?![ ]) # not space (.+?) # hyperlink phrase %s # not whitespace or escape - `_ # close backquote & reference mark + `_ # close backquote, reference mark ) $ # end of string """ % - (RSTState.inline.simplename, - RSTState.inline.non_whitespace_escape_before,), + (Inliner.simplename, + Inliner.non_whitespace_escape_before,), re.VERBOSE), substitution=re.compile(r""" (?: @@ -1284,7 +1330,7 @@ class Body(RSTState): ) (?:[ ]+|$) # followed by whitespace """ % - RSTState.inline.non_whitespace_escape_before, + Inliner.non_whitespace_escape_before, re.VERBOSE),) explicit.groups = Stuff( target=Stuff(quote=1, name=2), @@ -1292,53 +1338,53 @@ class Body(RSTState): substitution=Stuff(name=1)) def footnote(self, match): - indented, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) label = match.group(1) - name = normname(label) + name = normalize_name(label) footnote = nodes.footnote('\n'.join(indented)) if name[0] == '#': # auto-numbered name = name[1:] # autonumber label footnote['auto'] = 1 if name: footnote['name'] = name - self.statemachine.memo.document.note_autofootnote(footnote) + self.document.note_autofootnote(footnote) elif name == '*': # auto-symbol name = '' footnote['auto'] = '*' - self.statemachine.memo.document.note_symbol_footnote(footnote) + self.document.note_symbol_footnote(footnote) else: # manually numbered footnote += nodes.label('', label) footnote['name'] = name - self.statemachine.memo.document.note_footnote(footnote) + self.document.note_footnote(footnote) if name: - self.statemachine.memo.document.note_explicit_target(footnote, + self.document.note_explicit_target(footnote, footnote) if indented: - self.nestedparse(indented, inputoffset=offset, node=footnote) - return [footnote], blankfinish + self.nested_parse(indented, input_offset=offset, node=footnote) + return [footnote], blank_finish def citation(self, match): - indented, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) label = match.group(1) - name = normname(label) + name = normalize_name(label) citation = nodes.citation('\n'.join(indented)) citation += nodes.label('', label) citation['name'] = name - self.statemachine.memo.document.note_citation(citation) - self.statemachine.memo.document.note_explicit_target(citation, citation) + self.document.note_citation(citation) + self.document.note_explicit_target(citation, citation) if indented: - self.nestedparse(indented, inputoffset=offset, node=citation) - return [citation], blankfinish + self.nested_parse(indented, input_offset=offset, node=citation) + return [citation], blank_finish def hyperlink_target(self, match): pattern = self.explicit.patterns.target namegroup = self.explicit.groups.target.name - lineno = self.statemachine.abslineno() - block, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end(), uptoblank=1, - stripindent=0) + lineno = self.state_machine.abs_line_number() + block, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented( + match.end(), until_blank=1, strip_indent=0) blocktext = match.string[:match.end()] + '\n'.join(block) block = [escape2null(line) for line in block] escaped = block[0] @@ -1357,58 +1403,58 @@ class Body(RSTState): block[0] = (block[0] + ' ')[targetmatch.end()-len(escaped)-1:].strip() if block and block[-1].strip()[-1:] == '_': # possible indirect target reference = ' '.join([line.strip() for line in block]) - refname = self.isreference(reference) + refname = self.is_reference(reference) if refname: target = nodes.target(blocktext, '', refname=refname) - self.addtarget(targetmatch.group(namegroup), '', target) - self.statemachine.memo.document.note_indirect_target(target) - return [target], blankfinish + self.add_target(targetmatch.group(namegroup), '', target) + self.document.note_indirect_target(target) + return [target], blank_finish nodelist = [] reference = ''.join([line.strip() for line in block]) if reference.find(' ') != -1: - warning = self.statemachine.memo.reporter.warning( + warning = self.reporter.warning( 'Hyperlink target at line %s contains whitespace. ' 'Perhaps a footnote was intended?' - % (self.statemachine.abslineno() - len(block) + 1), '', - nodes.literal_block(blocktext, blocktext)) + % (self.state_machine.abs_line_number() - len(block) + 1), + '', nodes.literal_block(blocktext, blocktext)) nodelist.append(warning) else: unescaped = unescape(reference) target = nodes.target(blocktext, '') - self.addtarget(targetmatch.group(namegroup), unescaped, target) + self.add_target(targetmatch.group(namegroup), unescaped, target) nodelist.append(target) - return nodelist, blankfinish + return nodelist, blank_finish - def isreference(self, reference): - match = self.explicit.patterns.reference.match(normname(reference)) + def is_reference(self, reference): + match = self.explicit.patterns.reference.match(normalize_name(reference)) if not match: return None return unescape(match.group(self.explicit.groups.reference.simple) or match.group(self.explicit.groups.reference.phrase)) - def addtarget(self, targetname, refuri, target): + def add_target(self, targetname, refuri, target): if targetname: - name = normname(unescape(targetname)) + name = normalize_name(unescape(targetname)) target['name'] = name if refuri: target['refuri'] = refuri - self.statemachine.memo.document.note_external_target(target) + self.document.note_external_target(target) else: - self.statemachine.memo.document.note_internal_target(target) - self.statemachine.memo.document.note_explicit_target( - target, self.statemachine.node) + self.document.note_internal_target(target) + self.document.note_explicit_target( + target, self.parent) else: # anonymous target if refuri: target['refuri'] = refuri target['anonymous'] = 1 - self.statemachine.memo.document.note_anonymous_target(target) + self.document.note_anonymous_target(target) - def substitutiondef(self, match): + def substitution_def(self, match): pattern = self.explicit.patterns.substitution - lineno = self.statemachine.abslineno() - block, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end(), - stripindent=0) + lineno = self.state_machine.abs_line_number() + block, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end(), + strip_indent=0) blocktext = (match.string[:match.end()] + '\n'.join(block)) block = [escape2null(line) for line in block] escaped = block[0].rstrip() @@ -1429,65 +1475,66 @@ class Body(RSTState): del block[0] offset += 1 subname = subdefmatch.group(self.explicit.groups.substitution.name) - name = normname(subname) + name = normalize_name(subname) substitutionnode = nodes.substitution_definition( blocktext, name=name, alt=subname) if block: block[0] = block[0].strip() - newabsoffset, blankfinish = self.nestedlistparse( - block, inputoffset=offset, node=substitutionnode, - initialstate='SubstitutionDef', blankfinish=blankfinish) - self.statemachine.previousline( + newabsoffset, blank_finish = self.nested_list_parse( + block, input_offset=offset, node=substitutionnode, + initial_state='SubstitutionDef', blank_finish=blank_finish) + self.state_machine.previous_line( len(block) + offset - newabsoffset - 1) i = 0 for node in substitutionnode[:]: if not (isinstance(node, nodes.Inline) or isinstance(node, nodes.Text)): - self.statemachine.node += substitutionnode[i] + self.parent += substitutionnode[i] del substitutionnode[i] else: i += 1 if len(substitutionnode) == 0: - msg = self.statemachine.memo.reporter.warning( + msg = self.reporter.warning( 'Substitution definition "%s" empty or invalid at line ' - '%s.' % (subname, self.statemachine.abslineno()), '', - nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg + '%s.' % (subname, self.state_machine.abs_line_number()), + '', nodes.literal_block(blocktext, blocktext)) + self.parent += msg else: del substitutionnode['alt'] - self.statemachine.memo.document.note_substitution_def( - substitutionnode, self.statemachine.node) - return [substitutionnode], blankfinish + self.document.note_substitution_def( + substitutionnode, self.parent) + return [substitutionnode], blank_finish else: - msg = self.statemachine.memo.reporter.warning( + msg = self.reporter.warning( 'Substitution definition "%s" missing contents at line %s.' - % (subname, self.statemachine.abslineno()), '', + % (subname, self.state_machine.abs_line_number()), '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg - return [], blankfinish + self.parent += msg + return [], blank_finish def directive(self, match, **attributes): - typename = match.group(1) - directivefunction = directives.directive( - typename, self.statemachine.memo.language) + type_name = match.group(1) + directivefunction = directives.directive(type_name, + self.memo.language) data = match.string[match.end():].strip() if directivefunction: - return directivefunction(match, typename, data, self, - self.statemachine, attributes) + return directivefunction(match, type_name, data, self, + self.state_machine, attributes) else: - return self.unknowndirective(typename, data) + return self.unknown_directive(type_name, data) - def unknowndirective(self, typename, data): - lineno = self.statemachine.abslineno() - indented, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(0, stripindent=0) + def unknown_directive(self, type_name, data): + lineno = self.state_machine.abs_line_number() + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(0, strip_indent=0) text = '\n'.join(indented) - error = self.statemachine.memo.reporter.error( - 'Unknown directive type "%s" at line %s.' % (typename, lineno), + error = self.reporter.error( + 'Unknown directive type "%s" at line %s.' % (type_name, lineno), '', nodes.literal_block(text, text)) - return [error], blankfinish + return [error], blank_finish - def parse_extension_attributes(self, attribute_spec, datalines, blankfinish): + def parse_extension_attributes(self, attribute_spec, datalines, + blank_finish): """ Parse `datalines` for a field list containing extension attributes matching `attribute_spec`. @@ -1496,37 +1543,38 @@ class Body(RSTState): - `attribute_spec`: a mapping of attribute name to conversion function, which should raise an exception on bad input. - `datalines`: a list of input strings. - - `blankfinish`: + - `blank_finish`: :Return: - Success value, 1 or 0. - An attribute dictionary on success, an error string on failure. - - Updated `blankfinish` flag. + - Updated `blank_finish` flag. """ node = nodes.field_list() - newlineoffset, blankfinish = self.nestedlistparse( - datalines, 0, node, initialstate='FieldList', - blankfinish=blankfinish) - if newlineoffset != len(datalines): # incomplete parse of block - return 0, 'invalid attribute block', blankfinish + newline_offset, blank_finish = self.nested_list_parse( + datalines, 0, node, initial_state='FieldList', + blank_finish=blank_finish) + if newline_offset != len(datalines): # incomplete parse of block + return 0, 'invalid attribute block', blank_finish try: - attributes = utils.extract_extension_attributes(node, attribute_spec) + attributes = utils.extract_extension_attributes(node, + attribute_spec) except KeyError, detail: - return 0, ('unknown attribute: "%s"' % detail), blankfinish + return 0, ('unknown attribute: "%s"' % detail), blank_finish except (ValueError, TypeError), detail: - return 0, ('invalid attribute value:\n%s' % detail), blankfinish + return 0, ('invalid attribute value:\n%s' % detail), blank_finish except utils.ExtensionAttributeError, detail: - return 0, ('invalid attribute data: %s' % detail), blankfinish - return 1, attributes, blankfinish + return 0, ('invalid attribute data: %s' % detail), blank_finish + return 1, attributes, blank_finish def comment(self, match): if not match.string[match.end():].strip() \ - and self.statemachine.nextlineblank(): # an empty comment? + and self.state_machine.is_next_line_blank(): # an empty comment? return [nodes.comment()], 1 # "A tiny but practical wart." - indented, indent, offset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) text = '\n'.join(indented) - return [nodes.comment(text, text)], blankfinish + return [nodes.comment(text, text)], blank_finish explicit.constructs = [ (footnote, @@ -1544,20 +1592,20 @@ class Body(RSTState): ) \] (?:[ ]+|$) # whitespace or end of line - """ % RSTState.inline.simplename, re.VERBOSE)), + """ % Inliner.simplename, re.VERBOSE)), (citation, re.compile(r""" \.\.[ ]+ # explicit markup start \[(%s)\] # citation label (?:[ ]+|$) # whitespace or end of line - """ % RSTState.inline.simplename, re.VERBOSE)), + """ % Inliner.simplename, re.VERBOSE)), (hyperlink_target, re.compile(r""" \.\.[ ]+ # explicit markup start _ # target indicator (?![ ]) # first char. not space """, re.VERBOSE)), - (substitutiondef, + (substitution_def, re.compile(r""" \.\.[ ]+ # explicit markup start \| # substitution indicator @@ -1569,14 +1617,14 @@ class Body(RSTState): (%s) # directive name :: # directive delimiter (?:[ ]+|$) # whitespace or end of line - """ % RSTState.inline.simplename, re.VERBOSE))] + """ % Inliner.simplename, re.VERBOSE))] - def explicit_markup(self, match, context, nextstate): + def explicit_markup(self, match, context, next_state): """Footnotes, hyperlink targets, directives, comments.""" - nodelist, blankfinish = self.explicit_construct(match) - self.statemachine.node += nodelist - self.explicitlist(blankfinish) - return [], nextstate, [] + nodelist, blank_finish = self.explicit_construct(match) + self.parent += nodelist + self.explicit_list(blank_finish) + return [], next_state, [] def explicit_construct(self, match): """Determine which explicit construct this is, parse & return it.""" @@ -1588,80 +1636,81 @@ class Body(RSTState): return method(self, expmatch) except MarkupError, detail: # never reached? errors.append( - self.statemachine.memo.reporter.warning('%s: %s' + self.reporter.warning('%s: %s' % (detail.__class__.__name__, detail))) break - nodelist, blankfinish = self.comment(match) - return nodelist + errors, blankfinish + nodelist, blank_finish = self.comment(match) + return nodelist + errors, blank_finish - def explicitlist(self, blankfinish): + def explicit_list(self, blank_finish): """ Create a nested state machine for a series of explicit markup constructs (including anonymous hyperlink targets). """ - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=self.statemachine.node, initialstate='Explicit', - blankfinish=blankfinish) - self.gotoline(newlineoffset) - if not blankfinish: - self.statemachine.node += self.unindent_warning('Explicit markup') - - def anonymous(self, match, context, nextstate): + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=self.parent, initial_state='Explicit', + blank_finish=blank_finish) + self.goto_line(newline_offset) + if not blank_finish: + self.parent += self.unindent_warning('Explicit markup') + + def anonymous(self, match, context, next_state): """Anonymous hyperlink targets.""" - nodelist, blankfinish = self.anonymous_target(match) - self.statemachine.node += nodelist - self.explicitlist(blankfinish) - return [], nextstate, [] + nodelist, blank_finish = self.anonymous_target(match) + self.parent += nodelist + self.explicit_list(blank_finish) + return [], next_state, [] def anonymous_target(self, match): - block, indent, offset, blankfinish \ - = self.statemachine.getfirstknownindented(match.end(), - uptoblank=1) + block, indent, offset, blank_finish \ + = self.state_machine.get_first_known_indented(match.end(), + until_blank=1) blocktext = match.string[:match.end()] + '\n'.join(block) if block and block[-1].strip()[-1:] == '_': # possible indirect target - reference = escape2null(' '.join([line.strip() for line in block])) - refname = self.isreference(reference) + reference = escape2null(' '.join([line.strip() + for line in block])) + refname = self.is_reference(reference) if refname: target = nodes.target(blocktext, '', refname=refname, anonymous=1) - self.statemachine.memo.document.note_anonymous_target(target) - self.statemachine.memo.document.note_indirect_target(target) - return [target], blankfinish + self.document.note_anonymous_target(target) + self.document.note_indirect_target(target) + return [target], blank_finish nodelist = [] reference = escape2null(''.join([line.strip() for line in block])) if reference.find(' ') != -1: - warning = self.statemachine.memo.reporter.warning( - 'Anonymous hyperlink target at line %s contains whitespace. ' - 'Perhaps a footnote was intended?' - % (self.statemachine.abslineno() - len(block) + 1), '', - nodes.literal_block(blocktext, blocktext)) + warning = self.reporter.warning( + 'Anonymous hyperlink target at line %s contains ' + 'whitespace. Perhaps a footnote was intended?' + % (self.state_machine.abs_line_number() - len(block) + 1), + '', nodes.literal_block(blocktext, blocktext)) nodelist.append(warning) else: target = nodes.target(blocktext, '', anonymous=1) if reference: unescaped = unescape(reference) target['refuri'] = unescaped - self.statemachine.memo.document.note_anonymous_target(target) + self.document.note_anonymous_target(target) nodelist.append(target) - return nodelist, blankfinish + return nodelist, blank_finish - def line(self, match, context, nextstate): + def line(self, match, context, next_state): """Section title overline or transition marker.""" - if self.statemachine.matchtitles: + if self.state_machine.match_titles: return [match.string], 'Line', [] else: - blocktext = self.statemachine.line - msg = self.statemachine.memo.reporter.severe( + blocktext = self.state_machine.line + msg = self.reporter.severe( 'Unexpected section title or transition at line %s.' - % self.statemachine.abslineno(), '', + % self.state_machine.abs_line_number(), '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg - return [], nextstate, [] + self.parent += msg + return [], next_state, [] - def text(self, match, context, nextstate): + def text(self, match, context, next_state): """Titles, definition lists, paragraphs.""" return [match.string], 'Text', [] @@ -1675,38 +1724,40 @@ class RFC2822Body(Body): patterns = Body.patterns.copy() # can't modify the original patterns['rfc2822'] = r'[!-9;-~]+:( +|$)' - initialtransitions = [(name, 'Body') for name in Body.initialtransitions] - initialtransitions.insert(-1, ('rfc2822', 'Body')) # just before 'text' + initial_transitions = [(name, 'Body') + for name in Body.initial_transitions] + initial_transitions.insert(-1, ('rfc2822', 'Body')) # just before 'text' - def rfc2822(self, match, context, nextstate): + def rfc2822(self, match, context, next_state): """RFC2822-style field list item.""" - fieldlist = nodes.field_list() - self.statemachine.node += fieldlist - field, blankfinish = self.rfc2822_field(match) + fieldlist = nodes.field_list(CLASS='rfc2822') + self.parent += fieldlist + field, blank_finish = self.rfc2822_field(match) fieldlist += field - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=fieldlist, initialstate='RFC2822List', - blankfinish=blankfinish) - if not blankfinish: - self.statemachine.node += self.unindent_warning( + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=fieldlist, initial_state='RFC2822List', + blank_finish=blank_finish) + if not blank_finish: + self.parent += self.unindent_warning( 'RFC2822-style field list') - self.gotoline(newlineoffset) - return [], nextstate, [] + self.goto_line(newline_offset) + return [], next_state, [] def rfc2822_field(self, match): name = match.string[:match.string.find(':')] - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) fieldnode = nodes.field() fieldnode += nodes.field_name(name, name) fieldbody = nodes.field_body('\n'.join(indented)) fieldnode += fieldbody if indented: - self.nestedparse(indented, inputoffset=lineoffset, node=fieldbody) - return fieldnode, blankfinish + self.nested_parse(indented, input_offset=line_offset, + node=fieldbody) + return fieldnode, blank_finish class SpecializedBody(Body): @@ -1718,9 +1769,9 @@ class SpecializedBody(Body): subclasses to re-enable. """ - def invalid_input(self, match=None, context=None, nextstate=None): + def invalid_input(self, match=None, context=None, next_state=None): """Not a compound element member. Abort this state machine.""" - self.statemachine.previousline() # back up so parent SM can reassess + self.state_machine.previous_line() # back up so parent SM can reassess raise EOFError indent = invalid_input @@ -1729,7 +1780,7 @@ class SpecializedBody(Body): field_marker = invalid_input option_marker = invalid_input doctest = invalid_input - tabletop = invalid_input + table_top = invalid_input explicit_markup = invalid_input anonymous = invalid_input line = invalid_input @@ -1740,14 +1791,14 @@ class BulletList(SpecializedBody): """Second and subsequent bullet_list list_items.""" - def bullet(self, match, context, nextstate): + def bullet(self, match, context, next_state): """Bullet list item.""" - if match.string[0] != self.statemachine.node['bullet']: + if match.string[0] != self.parent['bullet']: # different bullet: new list self.invalid_input() - listitem, blankfinish = self.list_item(match.end()) - self.statemachine.node += listitem - self.blankfinish = blankfinish + listitem, blank_finish = self.list_item(match.end()) + self.parent += listitem + self.blank_finish = blank_finish return [], 'BulletList', [] @@ -1755,7 +1806,7 @@ class DefinitionList(SpecializedBody): """Second and subsequent definition_list_items.""" - def text(self, match, context, nextstate): + def text(self, match, context, next_state): """Definition lists.""" return [match.string], 'Definition', [] @@ -1764,18 +1815,18 @@ class EnumeratedList(SpecializedBody): """Second and subsequent enumerated_list list_items.""" - def enumerator(self, match, context, nextstate): + def enumerator(self, match, context, next_state): """Enumerated list item.""" format, sequence, text, ordinal = self.parse_enumerator( - match, self.statemachine.node['enumtype']) - if (sequence != self.statemachine.node['enumtype'] or + match, self.parent['enumtype']) + if (sequence != self.parent['enumtype'] or format != self.format or ordinal != self.lastordinal + 1): # different enumeration: new list self.invalid_input() - listitem, blankfinish = self.list_item(match.end()) - self.statemachine.node += listitem - self.blankfinish = blankfinish + listitem, blank_finish = self.list_item(match.end()) + self.parent += listitem + self.blank_finish = blank_finish self.lastordinal = ordinal return [], 'EnumeratedList', [] @@ -1784,11 +1835,11 @@ class FieldList(SpecializedBody): """Second and subsequent field_list fields.""" - def field_marker(self, match, context, nextstate): + def field_marker(self, match, context, next_state): """Field list field.""" - field, blankfinish = self.field(match) - self.statemachine.node += field - self.blankfinish = blankfinish + field, blank_finish = self.field(match) + self.parent += field + self.blank_finish = blank_finish return [], 'FieldList', [] @@ -1796,14 +1847,14 @@ class OptionList(SpecializedBody): """Second and subsequent option_list option_list_items.""" - def option_marker(self, match, context, nextstate): + def option_marker(self, match, context, next_state): """Option list item.""" try: - option_list_item, blankfinish = self.option_list_item(match) + option_list_item, blank_finish = self.option_list_item(match) except MarkupError, detail: self.invalid_input() - self.statemachine.node += option_list_item - self.blankfinish = blankfinish + self.parent += option_list_item + self.blank_finish = blank_finish return [], 'OptionList', [] @@ -1812,13 +1863,13 @@ class RFC2822List(SpecializedBody, RFC2822Body): """Second and subsequent RFC2822-style field_list fields.""" patterns = RFC2822Body.patterns - initialtransitions = RFC2822Body.initialtransitions + initial_transitions = RFC2822Body.initial_transitions - def rfc2822(self, match, context, nextstate): + def rfc2822(self, match, context, next_state): """RFC2822-style field list item.""" - field, blankfinish = self.rfc2822_field(match) - self.statemachine.node += field - self.blankfinish = blankfinish + field, blank_finish = self.rfc2822_field(match) + self.parent += field + self.blank_finish = blank_finish return [], 'RFC2822List', [] blank = SpecializedBody.invalid_input @@ -1828,19 +1879,19 @@ class Explicit(SpecializedBody): """Second and subsequent explicit markup construct.""" - def explicit_markup(self, match, context, nextstate): + def explicit_markup(self, match, context, next_state): """Footnotes, hyperlink targets, directives, comments.""" - nodelist, blankfinish = self.explicit_construct(match) - self.statemachine.node += nodelist - self.blankfinish = blankfinish - return [], nextstate, [] + nodelist, blank_finish = self.explicit_construct(match) + self.parent += nodelist + self.blank_finish = blank_finish + return [], next_state, [] - def anonymous(self, match, context, nextstate): + def anonymous(self, match, context, next_state): """Anonymous hyperlink targets.""" - nodelist, blankfinish = self.anonymous_target(match) - self.statemachine.node += nodelist - self.blankfinish = blankfinish - return [], nextstate, [] + nodelist, blank_finish = self.anonymous_target(match) + self.parent += nodelist + self.blank_finish = blank_finish + return [], next_state, [] class SubstitutionDef(Body): @@ -1850,24 +1901,24 @@ class SubstitutionDef(Body): """ patterns = { - 'embedded_directive': r'(%s)::( +|$)' % RSTState.inline.simplename, + 'embedded_directive': r'(%s)::( +|$)' % Inliner.simplename, 'text': r''} - initialtransitions = ['embedded_directive', 'text'] + initial_transitions = ['embedded_directive', 'text'] - def embedded_directive(self, match, context, nextstate): - if self.statemachine.node.has_key('alt'): - attributes = {'alt': self.statemachine.node['alt']} + def embedded_directive(self, match, context, next_state): + if self.parent.has_key('alt'): + attributes = {'alt': self.parent['alt']} else: attributes = {} - nodelist, blankfinish = self.directive(match, **attributes) - self.statemachine.node += nodelist - if not self.statemachine.ateof(): - self.blankfinish = blankfinish + nodelist, blank_finish = self.directive(match, **attributes) + self.parent += nodelist + if not self.state_machine.at_eof(): + self.blank_finish = blank_finish raise EOFError - def text(self, match, context, nextstate): - if not self.statemachine.ateof(): - self.blankfinish = self.statemachine.nextlineblank() + def text(self, match, context, next_state): + if not self.state_machine.at_eof(): + self.blank_finish = self.state_machine.is_next_line_blank() raise EOFError @@ -1881,123 +1932,123 @@ class Text(RSTState): patterns = {'underline': Body.patterns['line'], 'text': r''} - initialtransitions = [('underline', 'Body'), ('text', 'Body')] + initial_transitions = [('underline', 'Body'), ('text', 'Body')] - def blank(self, match, context, nextstate): + def blank(self, match, context, next_state): """End of paragraph.""" paragraph, literalnext = self.paragraph( - context, self.statemachine.abslineno() - 1) - self.statemachine.node += paragraph + context, self.state_machine.abs_line_number() - 1) + self.parent += paragraph if literalnext: - self.statemachine.node += self.literal_block() + self.parent += self.literal_block() return [], 'Body', [] def eof(self, context): if context: paragraph, literalnext = self.paragraph( - context, self.statemachine.abslineno() - 1) - self.statemachine.node += paragraph + context, self.state_machine.abs_line_number() - 1) + self.parent += paragraph if literalnext: - self.statemachine.node += self.literal_block() + self.parent += self.literal_block() return [] - def indent(self, match, context, nextstate): + def indent(self, match, context, next_state): """Definition list item.""" definitionlist = nodes.definition_list() - definitionlistitem, blankfinish = self.definition_list_item(context) + definitionlistitem, blank_finish = self.definition_list_item(context) definitionlist += definitionlistitem - self.statemachine.node += definitionlist - offset = self.statemachine.lineoffset + 1 # next line - newlineoffset, blankfinish = self.nestedlistparse( - self.statemachine.inputlines[offset:], - inputoffset=self.statemachine.abslineoffset() + 1, - node=definitionlist, initialstate='DefinitionList', - blankfinish=blankfinish, blankfinishstate='Definition') - if not blankfinish: - self.statemachine.node += self.unindent_warning('Definition list') - self.gotoline(newlineoffset) + self.parent += definitionlist + offset = self.state_machine.line_offset + 1 # next line + newline_offset, blank_finish = self.nested_list_parse( + self.state_machine.input_lines[offset:], + input_offset=self.state_machine.abs_line_offset() + 1, + node=definitionlist, initial_state='DefinitionList', + blank_finish=blank_finish, blank_finish_state='Definition') + if not blank_finish: + self.parent += self.unindent_warning('Definition list') + self.goto_line(newline_offset) return [], 'Body', [] - def underline(self, match, context, nextstate): + def underline(self, match, context, next_state): """Section title.""" - lineno = self.statemachine.abslineno() - if not self.statemachine.matchtitles: - blocktext = context[0] + '\n' + self.statemachine.line - msg = self.statemachine.memo.reporter.severe( + lineno = self.state_machine.abs_line_number() + if not self.state_machine.match_titles: + blocktext = context[0] + '\n' + self.state_machine.line + msg = self.reporter.severe( 'Unexpected section title at line %s.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg - return [], nextstate, [] + self.parent += msg + return [], next_state, [] title = context[0].rstrip() underline = match.string.rstrip() source = title + '\n' + underline if len(title) > len(underline): - blocktext = context[0] + '\n' + self.statemachine.line - msg = self.statemachine.memo.reporter.info( + blocktext = context[0] + '\n' + self.state_machine.line + msg = self.reporter.info( 'Title underline too short at line %s.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg + self.parent += msg style = underline[0] context[:] = [] self.section(title, source, style, lineno - 1) - return [], nextstate, [] + return [], next_state, [] - def text(self, match, context, nextstate): + def text(self, match, context, next_state): """Paragraph.""" - startline = self.statemachine.abslineno() - 1 + startline = self.state_machine.abs_line_number() - 1 msg = None try: - block = self.statemachine.getunindented() + block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: block, lineno = instance.args - msg = self.statemachine.memo.reporter.error( + msg = self.reporter.error( 'Unexpected indentation at line %s.' % lineno) lines = context + block paragraph, literalnext = self.paragraph(lines, startline) - self.statemachine.node += paragraph - self.statemachine.node += msg + self.parent += paragraph + self.parent += msg if literalnext: try: - self.statemachine.nextline() + self.state_machine.next_line() except IndexError: pass - self.statemachine.node += self.literal_block() - return [], nextstate, [] + self.parent += self.literal_block() + return [], next_state, [] def literal_block(self): """Return a list of nodes.""" - indented, indent, offset, blankfinish = \ - self.statemachine.getindented() + indented, indent, offset, blank_finish = \ + self.state_machine.get_indented() nodelist = [] while indented and not indented[-1].strip(): indented.pop() if indented: data = '\n'.join(indented) nodelist.append(nodes.literal_block(data, data)) - if not blankfinish: + if not blank_finish: nodelist.append(self.unindent_warning('Literal block')) else: - nodelist.append(self.statemachine.memo.reporter.warning( + nodelist.append(self.reporter.warning( 'Literal block expected at line %s; none found.' - % self.statemachine.abslineno())) + % self.state_machine.abs_line_number())) return nodelist def definition_list_item(self, termline): - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getindented() + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_indented() definitionlistitem = nodes.definition_list_item('\n'.join(termline + indented)) - termlist, messages = self.term(termline, - self.statemachine.abslineno() - 1) + termlist, messages = self.term( + termline, self.state_machine.abs_line_number() - 1) definitionlistitem += termlist definition = nodes.definition('', *messages) definitionlistitem += definition if termline[0][-2:] == '::': - definition += self.statemachine.memo.reporter.info( + definition += self.reporter.info( 'Blank line missing before literal block? Interpreted as a ' - 'definition list item. At line %s.' % (lineoffset + 1)) - self.nestedparse(indented, inputoffset=lineoffset, node=definition) - return definitionlistitem, blankfinish + 'definition list item. At line %s.' % (line_offset + 1)) + self.nested_parse(indented, input_offset=line_offset, node=definition) + return definitionlistitem, blank_finish def term(self, lines, lineno): """Return a definition_list's term and optional classifier.""" @@ -2028,7 +2079,7 @@ class SpecializedText(Text): """Incomplete construct.""" return [] - def invalid_input(self, match=None, context=None, nextstate=None): + def invalid_input(self, match=None, context=None, next_state=None): """Not a compound element member. Abort this state machine.""" raise EOFError @@ -2044,14 +2095,14 @@ class Definition(SpecializedText): def eof(self, context): """Not a definition.""" - self.statemachine.previousline(2) # back up so parent SM can reassess + self.state_machine.previous_line(2) # so parent SM can reassess return [] - def indent(self, match, context, nextstate): + def indent(self, match, context, next_state): """Definition list item.""" - definitionlistitem, blankfinish = self.definition_list_item(context) - self.statemachine.node += definitionlistitem - self.blankfinish = blankfinish + definitionlistitem, blank_finish = self.definition_list_item(context) + self.parent += definitionlistitem + self.blank_finish = blank_finish return [], 'DefinitionList', [] @@ -2066,67 +2117,67 @@ class Line(SpecializedText): """Transition marker at end of section or document.""" if self.eofcheck: # ignore EOFError with sections transition = nodes.transition(context[0]) - self.statemachine.node += transition - msg = self.statemachine.memo.reporter.error( + self.parent += transition + msg = self.reporter.error( 'Document or section may not end with a transition ' - '(line %s).' % (self.statemachine.abslineno() - 1)) - self.statemachine.node += msg + '(line %s).' % (self.state_machine.abs_line_number() - 1)) + self.parent += msg self.eofcheck = 1 return [] - def blank(self, match, context, nextstate): + def blank(self, match, context, next_state): """Transition marker.""" transition = nodes.transition(context[0]) - if len(self.statemachine.node) == 0: - msg = self.statemachine.memo.reporter.error( + if len(self.parent) == 0: + msg = self.reporter.error( 'Document or section may not begin with a transition ' - '(line %s).' % (self.statemachine.abslineno() - 1)) - self.statemachine.node += msg - elif isinstance(self.statemachine.node[-1], nodes.transition): - msg = self.statemachine.memo.reporter.error( + '(line %s).' % (self.state_machine.abs_line_number() - 1)) + self.parent += msg + elif isinstance(self.parent[-1], nodes.transition): + msg = self.reporter.error( 'At least one body element must separate transitions; ' 'adjacent transitions at line %s.' - % (self.statemachine.abslineno() - 1)) - self.statemachine.node += msg - self.statemachine.node += transition + % (self.state_machine.abs_line_number() - 1)) + self.parent += msg + self.parent += transition return [], 'Body', [] - def text(self, match, context, nextstate): + def text(self, match, context, next_state): """Potential over- & underlined title.""" - lineno = self.statemachine.abslineno() - 1 + lineno = self.state_machine.abs_line_number() - 1 overline = context[0] title = match.string underline = '' try: - underline = self.statemachine.nextline() + underline = self.state_machine.next_line() except IndexError: blocktext = overline + '\n' + title - msg = self.statemachine.memo.reporter.severe( + msg = self.reporter.severe( 'Incomplete section title at line %s.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg + self.parent += msg return [], 'Body', [] source = '%s\n%s\n%s' % (overline, title, underline) overline = overline.rstrip() underline = underline.rstrip() if not self.transitions['underline'][0].match(underline): - msg = self.statemachine.memo.reporter.severe( + msg = self.reporter.severe( 'Missing underline for overline at line %s.' % lineno, '', nodes.literal_block(source, source)) - self.statemachine.node += msg + self.parent += msg return [], 'Body', [] elif overline != underline: - msg = self.statemachine.memo.reporter.severe( - 'Title overline & underline mismatch at ' 'line %s.' % lineno, - '', nodes.literal_block(source, source)) - self.statemachine.node += msg + msg = self.reporter.severe( + 'Title overline & underline mismatch at ' 'line %s.' + % lineno, '', nodes.literal_block(source, source)) + self.parent += msg return [], 'Body', [] title = title.rstrip() if len(title) > len(overline): - msg = self.statemachine.memo.reporter.info( + msg = self.reporter.info( 'Title overline too short at line %s.'% lineno, '', nodes.literal_block(source, source)) - self.statemachine.node += msg + self.parent += msg style = (overline[0], underline[0]) self.eofcheck = 0 # @@@ not sure this is correct self.section(title.lstrip(), source, style, lineno + 1) @@ -2135,19 +2186,19 @@ class Line(SpecializedText): indent = text # indented title - def underline(self, match=None, context=None, nextstate=None): - blocktext = context[0] + '\n' + self.statemachine.line - msg = self.statemachine.memo.reporter.error( + def underline(self, match=None, context=None, next_state=None): + blocktext = context[0] + '\n' + self.state_machine.line + msg = self.reporter.error( 'Invalid section title or transition marker at line %s.' - % (self.statemachine.abslineno() - 1), '', + % (self.state_machine.abs_line_number() - 1), '', nodes.literal_block(blocktext, blocktext)) - self.statemachine.node += msg + self.parent += msg return [], 'Body', [] -stateclasses = [Body, BulletList, DefinitionList, EnumeratedList, FieldList, - OptionList, Explicit, Text, Definition, Line, SubstitutionDef, - RFC2822Body, RFC2822List] +state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, + OptionList, Explicit, Text, Definition, Line, + SubstitutionDef, RFC2822Body, RFC2822List) """Standard set of State classes used to start `RSTStateMachine`.""" @@ -2164,9 +2215,9 @@ def escape2null(text): parts.append('\x00' + text[found+1:found+2]) start = found + 2 # skip character after escape -def unescape(text, restorebackslashes=0): +def unescape(text, restore_backslashes=0): """Return a string with nulls removed or restored to backslashes.""" - if restorebackslashes: - return text.translate(RSTState.inline.null2backslash) + if restore_backslashes: + return text.translate(Inliner.null2backslash) else: - return text.translate(RSTState.inline.identity, '\x00') + return text.translate(Inliner.identity, '\x00') -- cgit v1.2.1 From 9f85d5f3a15e46003ea3228608373d639a2e67e3 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:24:19 +0000 Subject: renamed parts.py from old components.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@76 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/components.py | 85 --------------------------- docutils/transforms/parts.py | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 85 deletions(-) delete mode 100644 docutils/transforms/components.py create mode 100644 docutils/transforms/parts.py diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py deleted file mode 100644 index 2cfe4d2a8..000000000 --- a/docutils/transforms/components.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python -""" -:Authors: David Goodger, Ueli Schlaepfer -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -Transforms related to document components. - -- `Contents`: Used to build a table of contents. -""" - -__docformat__ = 'reStructuredText' - - -import re -from docutils import nodes, utils -from docutils.transforms import TransformError, Transform - - -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". A title is - either explicitly specified, taken from the appropriate language module, - or omitted (local table of contents). The depth may be specified. - Two-way references between the table of contents and section titles are - generated (requires Writer support). - - This transform requires a startnode, which which contains generation - options and provides the location for the generated table of contents (the - startnode is replaced by the table of contents "topic"). - """ - - def transform(self): - topic = nodes.topic(CLASS='contents') - title = self.startnode.details['title'] - if self.startnode.details.has_key('local'): - startnode = self.startnode.parent - # @@@ generate an error if the startnode (directive) not at - # section/document top-level? Drag it up until it is? - while not isinstance(startnode, nodes.Structural): - startnode = startnode.parent - if not title: - title = [] - else: - startnode = self.doctree - if not title: - title = nodes.title('', self.language.labels['contents']) - contents = self.build_contents(startnode) - if len(contents): - topic += title - topic += contents - self.startnode.parent.replace(self.startnode, topic) - else: - self.startnode.parent.remove(self.startnode) - - def build_contents(self, node, level=0): - level += 1 - sections = [] - i = len(node) - 1 - while i >= 0 and isinstance(node[i], nodes.section): - sections.append(node[i]) - i -= 1 - sections.reverse() - entries = [] - for section in sections: - title = section[0] - reference = nodes.reference('', '', refid=section['id'], - *title.getchildren()) - entry = nodes.paragraph('', '', reference) - item = nodes.list_item('', entry) - itemid = self.doctree.set_id(item) - title['refid'] = itemid - if (not self.startnode.details.has_key('depth')) \ - or level < self.startnode.details['depth']: - subsects = self.build_contents(section, level) - item += subsects - entries.append(item) - if entries: - entries = nodes.bullet_list('', *entries) - return entries diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py new file mode 100644 index 000000000..50667a1fa --- /dev/null +++ b/docutils/transforms/parts.py @@ -0,0 +1,117 @@ +#! /usr/bin/env python +""" +:Authors: David Goodger, Ueli Schlaepfer +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Transforms related to document parts. + +- `Contents`: Used to build a table of contents. +""" + +__docformat__ = 'reStructuredText' + + +import re, sys +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +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". A title is + either explicitly specified, taken from the appropriate language module, + or omitted (local table of contents). The depth may be specified. + Two-way references between the table of contents and section titles are + generated (requires Writer support). + + This transform requires a startnode, which which contains generation + options and provides the location for the generated table of contents (the + startnode is replaced by the table of contents "topic"). + """ + + def transform(self): + topic = nodes.topic(CLASS='contents') + title = self.startnode.details['title'] + if self.startnode.details.has_key('local'): + startnode = self.startnode.parent + # @@@ generate an error if the startnode (directive) not at + # section/document top-level? Drag it up until it is? + while not isinstance(startnode, nodes.Structural): + startnode = startnode.parent + if not title: + title = [] + else: + startnode = self.document + if not title: + title = nodes.title('', self.language.labels['contents']) + contents = self.build_contents(startnode) + if len(contents): + topic += title + topic += contents + self.startnode.parent.replace(self.startnode, topic) + else: + self.startnode.parent.remove(self.startnode) + + def build_contents(self, node, level=0): + level += 1 + sections = [] + i = len(node) - 1 + while i >= 0 and isinstance(node[i], nodes.section): + sections.append(node[i]) + i -= 1 + sections.reverse() + entries = [] + depth = self.startnode.details.get('depth', sys.maxint) + for section in sections: + title = section[0] + entrytext = self.copy_and_filter(title) + reference = nodes.reference('', '', refid=section['id'], + *entrytext) + entry = nodes.paragraph('', '', reference) + item = nodes.list_item('', entry) + itemid = self.document.set_id(item) + title['refid'] = itemid + if level < depth: + subsects = self.build_contents(section, level) + item += subsects + entries.append(item) + if entries: + entries = nodes.bullet_list('', *entries) + return entries + + 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().getchildren() + + 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_stack[-1].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 -- cgit v1.2.1 From 82bf628c5790a1cc17855199c88d07094b4dbbfa Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:26:09 +0000 Subject: Docutils component-related transforms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@77 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/components.py | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docutils/transforms/components.py diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py new file mode 100644 index 000000000..b0d1ae48f --- /dev/null +++ b/docutils/transforms/components.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Docutils component-related transforms. +""" + +__docformat__ = 'reStructuredText' + +import sys, os, re, time +from docutils import nodes, utils, 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 a key matching the dependency component + type (e.g. ``details['writer']`` for a "pending" element whose ``stage`` + attribute is 'last writer'). The value is the name of a specific format + or context of that component (e.g. ``details['writer'] = 'html'``). If + the Docutils component which called this transform supports that format or + context, the "pending" element is replaced by the nodes in + ``details['nodes']``; otherwise, the "pending" element is removed. + + For example, the reStructuredText "meta" directive creates a "pending" + element containing a "meta" element. Only writers supporting the "html" + format will include the "meta" element; it will be deleted from the output + of all other writers. + """ + + def transform(self): + pending = self.startnode + component_name = pending.details[pending.stage.split()[-1]] + if self.component.supports(component_name): + pending.parent.replace(pending, pending.details['nodes']) + else: + pending.parent.remove(pending) -- cgit v1.2.1 From 913e7e2cbd89dee2e8ba5fccca1e3ed774577911 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:26:53 +0000 Subject: Transforms for PEP processing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@78 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 99 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docutils/transforms/peps.py diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py new file mode 100644 index 000000000..d3dca5b0e --- /dev/null +++ b/docutils/transforms/peps.py @@ -0,0 +1,99 @@ +#! /usr/bin/env python +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +: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. +""" + +__docformat__ = 'reStructuredText' + +import sys, os, re, time +from docutils import nodes, utils, ApplicationError, DataError +from docutils.transforms import Transform, TransformError +import mypdb as pdb + + +class Headers(Transform): + + """ + """ + + pep_cvs_url = ('http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/' + 'python/nondist/peps/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 transform(self): + if not len(self.document): + raise DataError('Document tree is empty.') + header = self.document[0] + if not isinstance(header, nodes.field_list) or \ + header.get('class') != 'rfc2822': + raise DataError('Document does not begin with an RFC-2822 ' + 'header; it is not a PEP.') + pep = title = None + #pdb.set_trace() + for field in header: + if field[0].astext().lower() == 'pep': # should be the first field + pep = int(field[1].astext()) + break + if pep is None: + raise DataError('Document does not contain an RFC-2822 "PEP" ' + 'header.') + for field in header: + name = field[0].astext().lower() + body = field[1] + print >>sys.stderr, 'name=%s, body=%s' % (name, body.astext()) ; sys.stderr.flush() + if len(body) > 1: + raise DataError('PEP header field body contains multiple ' + 'elements:\n%s' % field.pformat(level=1)) + elif len(body): + 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])) + body += nodes.paragraph() + uri = self.pep_cvs_url % int(pep) + body[0][:] = [nodes.reference('', date, refuri=uri)] + else: + continue + para = body[0] + if name == 'title': + title = body.astext() + # @@@ Insert a "pending" element here, since we don't really want a separate document title? + elif name in ('author', 'discussions-to'): + for node in para: + if isinstance(node, nodes.reference) \ + and node.has_key('refuri') \ + and node['refuri'][:7] == 'mailto:': + node['refuri'] += '?subject=PEP%%20%s' % pep + elif name in ('replaces', 'replaced-by'): + newbody = [] + space = nodes.Text(' ') + for refpep in body.astext().split(): + pepno = int(refpep) + newbody.append(nodes.reference( + refpep, refpep, refuri='pep-%04d.html' % pepno)) + newbody.append(space) + para[:] = newbody[:-1] # drop trailing space + elif name == 'last-modified': + #pdb.set_trace() + utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) + date = para.astext() + uri = self.pep_cvs_url % int(pep) + para[:] = [nodes.reference('', date, refuri=uri)] + elif name == 'version' and len(body): + utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) + print >>sys.stderr, 'name=%s, body=%s' % (name, body.astext()) ; sys.stderr.flush() -- cgit v1.2.1 From 9f927b22539072acd91336c84dbd2e120bfe6d28 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:27:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@79 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/en.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 2b1c52649..370c34d12 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -24,15 +24,18 @@ directives = { 'note': 'note', 'tip': 'tip', 'warning': 'warning', + 'questions': 'questions', + 'qa': 'questions', + 'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', 'image': 'image', 'figure': 'figure', + #'raw': 'raw', 'contents': 'contents', - 'footnotes': 'footnotes', - 'citations': 'citations', - 'topic': 'topic', - 'meta': 'meta', - 'imagemap': 'imagemap', - 'raw': 'raw', + #'footnotes': 'footnotes', + #'citations': 'citations', + #'topic': 'topic', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From dd4471f257e8b3119631d076171fa5eba77a55cf Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:28:32 +0000 Subject: Python Enhancement Proposal (PEP) Reader. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@80 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 docutils/readers/pep.py diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py new file mode 100644 index 000000000..113b2705e --- /dev/null +++ b/docutils/readers/pep.py @@ -0,0 +1,77 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Python Enhancement Proposal (PEP) Reader. +""" + +__docformat__ = 'reStructuredText' + + +import sys, os, re +from docutils import nodes +from docutils.readers import standalone +from docutils.transforms import peps, references +from docutils.parsers import rst + + +class Reader(standalone.Reader): + + supported = ('pep',) + """Contexts this reader supports.""" + + transforms = (references.Substitutions, + peps.Headers, + references.Footnotes, + references.Hyperlinks,) + + def __init__(self, reporter, parser, parser_name, language_code): + """`parser` should be ``None``.""" + if parser is None: + parser = rst.Parser(rfc2822=1, inliner=Inliner()) + standalone.Reader.__init__( + self, reporter, parser, '', language_code) + + +class Inliner(rst.states.Inliner): + + """ + Extend `rst.Inliner` to also parse standalone PEP & RFC references. + """ + + rfc_url = 'http://www.faqs.org/rfcs/rfc%d.html' + pep_url = 'pep-%04d.html' + pep_ref_pattern = re.compile(r""" + ( + (pep-\d+(.txt)?) + | + (PEP\s+(?P\d+)) + | + (RFC(-|\s+)?(?P\d+)) + ) + """, re.VERBOSE) + + def standalone_refs(self, match, lineno): + text = match.group(0) + if text.startswith('pep-'): + ref = os.path.splitext(text)[0] + ".html" + elif text.startswith('PEP'): + pepnum = int(match.group('pepnum')) + ref = self.pep_url % pepnum + elif text.startswith('RFC'): + rfcnum = int(match.group('rfcnum')) + ref = self.rfc_url % rfcnum + else: + raise MarkupMismatch + unescaped = rst.states.unescape(text, 0) + return [nodes.reference(rst.states.unescape(text, 1), unescaped, + refuri=ref)] + + implicit = (rst.states.Inliner.implicit + + ((pep_ref_pattern, standalone_refs),)) + """PEP-specific list of (pattern, dispatch method) pairs.""" -- cgit v1.2.1 From da7652441d6e9b5480a3d02363e3463fea0a6390 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:29:39 +0000 Subject: Gave Readers more control over choosing and instantiating Parsers. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@81 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 9b8d38654..0ade6dbe3 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -14,11 +14,11 @@ __docformat__ = 'reStructuredText' import sys -from docutils import nodes, utils +from docutils import nodes, utils, parsers, Component from docutils.transforms import universal -class Reader: +class Reader(Component): """ Abstract base class for docutils Readers. @@ -33,7 +33,7 @@ class Reader: """Ordered tuple of transform classes (each with a ``transform()`` method). Populated by subclasses. `Reader.transform()` instantiates & runs them.""" - def __init__(self, reporter, languagecode): + def __init__(self, reporter, parser, parser_name, language_code): """ Initialize the Reader instance. @@ -41,12 +41,19 @@ class Reader: Subclasses may use these attributes as they wish. """ - self.languagecode = languagecode + self.language_code = language_code """Default language for new documents.""" self.reporter = reporter """A `utils.Reporter` instance shared by all doctrees.""" + self.parser = parser + """A `parsers.Parser` instance shared by all doctrees. May be left + unspecified if the document source determines the parser.""" + + if parser is None and parser_name: + self.set_parser(parser_name) + self.source = None """Path to the source of raw input.""" @@ -54,12 +61,15 @@ class Reader: """Raw text input; either a single string or, for more complex cases, a collection of strings.""" - self.transforms = tuple(self.transforms) - """Instance copy of `Reader.transforms`; may be modified by client.""" + def set_parser(self, parser_name): + """Set `self.parser` by name.""" + parser_class = parsers.get_parser_class(parser_name) + self.parser = parser_class() def read(self, source, parser): self.source = source - self.parser = parser + if not self.parser: + self.parser = parser self.scan() # may modify self.parser, depending on input self.parse() self.transform() @@ -69,7 +79,7 @@ class Reader: """Override to read `self.input` from `self.source`.""" raise NotImplementedError('subclass must override this method') - def scanfile(self, source): + def scan_file(self, source): """ Scan a single file and return the raw data. @@ -87,7 +97,7 @@ class Reader: def parse(self): """Parse `self.input` into a document tree.""" - self.document = self.newdocument() + self.document = self.new_document() self.parser.parse(self.input, self.document) def transform(self): @@ -95,24 +105,28 @@ class Reader: for xclass in (universal.first_reader_transforms + tuple(self.transforms) + universal.last_reader_transforms): - xclass(self.document).transform() + xclass(self.document, self).transform() - def newdocument(self, languagecode=None): + def new_document(self, language_code=None): """Create and return a new empty document tree (root node).""" document = nodes.document( - languagecode=(languagecode or self.languagecode), + language_code=(language_code or self.language_code), reporter=self.reporter) document['source'] = self.source return document -_reader_aliases = {'rtxt': 'standalone', - 'restructuredtext': 'standalone'} +_reader_aliases = { + 'rst': 'standalone', + 'rest': 'standalone', + 'restx': 'standalone', + 'rtxt': 'standalone', + 'restructuredtext': 'standalone'} -def get_reader_class(readername): - """Return the Reader class from the `readername` module.""" - readername = readername.lower() - if _reader_aliases.has_key(readername): - readername = _reader_aliases[readername] - module = __import__(readername, globals(), locals()) +def get_reader_class(reader_name): + """Return the Reader class from the `reader_name` module.""" + reader_name = reader_name.lower() + if _reader_aliases.has_key(reader_name): + reader_name = _reader_aliases[reader_name] + module = __import__(reader_name, globals(), locals()) return module.Reader -- cgit v1.2.1 From 6a9b95ff6113f2c57b5f64817072a571cb8fe829 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:30:19 +0000 Subject: - Added ``runtime_init`` method to ``StateMachine`` and ``State``. - Added underscores to improve many awkward names. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@82 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 581 ++++++++++++++++++++++++----------------------- 1 file changed, 300 insertions(+), 281 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 9410cb956..8c4cddb81 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -3,7 +3,6 @@ """ :Author: David Goodger :Contact: goodger@users.sourceforge.net -:Version: 1.3 :Revision: $Revision$ :Date: $Date$ :Copyright: This module has been placed in the public domain. @@ -32,7 +31,7 @@ Exception classes: Functions: - `string2lines()`: split a multi-line string into a list of one-line strings -- `extractindented()`: return indented lines with minimum indentation removed +- `extract_indented()`: return indented lines with minimum indentation removed How To Use This Module ====================== @@ -53,18 +52,18 @@ How To Use This Module patterns = {'atransition': r'pattern', ...} b) Include a list of initial transitions to be set up automatically, in - `State.initialtransitions`:: + `State.initial_transitions`:: - initialtransitions = ['atransition', ...] + initial_transitions = ['atransition', ...] c) Define a method for each transition, with the same name as the transition pattern:: - def atransition(self, match, context, nextstate): + def atransition(self, match, context, next_state): # do something result = [...] # a list - return context, nextstate, result - # context, nextstate may be altered + return context, next_state, result + # context, next_state may be altered Transition methods may raise an `EOFError` to cut processing short. @@ -72,31 +71,32 @@ How To Use This Module transition methods, which handle the beginning- and end-of-file. e) In order to handle nested processing, you may wish to override the - attributes `State.nestedSM` and/or `State.nestedSMkwargs`. + attributes `State.nested_sm` and/or `State.nested_sm_kwargs`. If you are using `StateWS` as a base class, in order to handle nested indented blocks, you may wish to: - - override the attributes `StateWS.indentSM`, `StateWS.indentSMkwargs`, - `StateWS.knownindentSM`, and/or `StateWS.knownindentSMkwargs`; + - override the attributes `StateWS.indent_sm`, `StateWS.indent_sm_kwargs`, + `StateWS.known_indent_sm`, and/or `StateWS.known_indent_sm_kwargs`; - override the `StateWS.blank()` method; and/or - - override or extend the `StateWS.indent()`, `StateWS.knownindent()`, - and/or `StateWS.firstknownindent()` methods. + - override or extend the `StateWS.indent()`, `StateWS.known_indent()`, + and/or `StateWS.firstknown_indent()` methods. 3. Create a state machine object:: - sm = StateMachine(stateclasses=[MyState, ...], initialstate='MyState') + sm = StateMachine(state_classes=[MyState, ...], + initial_state='MyState') 4. Obtain the input text, which needs to be converted into a tab-free list of one-line strings. For example, to read text from a file called 'inputfile':: - inputstring = open('inputfile').read() - inputlines = statemachine.string2lines(inputstring) + input_string = open('inputfile').read() + input_lines = statemachine.string2lines(input_string) 6. Run the state machine on the input text and collect the results, a list:: - results = sm.run(inputlines) + results = sm.run(input_lines) 7. Remove any lingering circular references:: @@ -122,42 +122,42 @@ class StateMachine: results of processing in a list. """ - def __init__(self, stateclasses, initialstate, debug=0): + def __init__(self, state_classes, initial_state, debug=0): """ Initialize a `StateMachine` object; add state objects. Parameters: - - `stateclasses`: a list of `State` (sub)classes. - - `initialstate`: a string, the class name of the initial state. + - `state_classes`: a list of `State` (sub)classes. + - `initial_state`: a string, the class name of the initial state. - `debug`: a boolean; produce verbose output if true (nonzero). """ - self.inputlines = None + self.input_lines = None """List of strings (without newlines). Filled by `self.run()`.""" - self.inputoffset = 0 - """Offset of `self.inputlines` from the beginning of the file.""" + self.input_offset = 0 + """Offset of `self.input_lines` from the beginning of the file.""" self.line = None """Current input line.""" - self.lineoffset = None - """Current input line offset from beginning of `self.inputlines`.""" + self.line_offset = None + """Current input line offset from beginning of `self.input_lines`.""" self.debug = debug """Debugging mode on/off.""" - self.initialstate = initialstate + self.initial_state = initial_state """The name of the initial state (key to `self.states`).""" - self.currentstate = initialstate + self.current_state = initial_state """The name of the current state (key to `self.states`).""" self.states = {} """Mapping of {state_name: State_object}.""" - self.addstates(stateclasses) + self.add_states(state_classes) def unlink(self): """Remove circular references to objects no longer required.""" @@ -165,11 +165,11 @@ class StateMachine: state.unlink() self.states = None - def run(self, inputlines, inputoffset=0): + def run(self, input_lines, input_offset=0): """ - Run the state machine on `inputlines`. Return results (a list). + Run the state machine on `input_lines`. Return results (a list). - Reset `self.lineoffset` and `self.currentstate`. Run the + Reset `self.line_offset` and `self.current_state`. Run the beginning-of-file transition. Input one line at a time and check for a matching transition. If a match is found, call the transition method and possibly change the state. Store the context returned by the @@ -180,20 +180,21 @@ class StateMachine: Parameters: - - `inputlines`: a list of strings without newlines. - - `inputoffset`: the line offset of `inputlines` from the beginning of - the file. + - `input_lines`: a list of strings without newlines. + - `input_offset`: the line offset of `input_lines` from the beginning + of the file. """ - self.inputlines = inputlines - self.inputoffset = inputoffset - self.lineoffset = -1 - self.currentstate = self.initialstate + self.runtime_init() + self.input_lines = input_lines + self.input_offset = input_offset + self.line_offset = -1 + self.current_state = self.initial_state if self.debug: - print >>sys.stderr, ('\nStateMachine.run: inputlines:\n| %s' % - '\n| '.join(self.inputlines)) + print >>sys.stderr, ('\nStateMachine.run: input_lines:\n| %s' % + '\n| '.join(self.input_lines)) context = None results = [] - state = self.getstate() + state = self.get_state() try: if self.debug: print >>sys.stderr, ('\nStateMachine.run: bof transition') @@ -201,17 +202,18 @@ class StateMachine: results.extend(result) while 1: try: - self.nextline() + self.next_line() if self.debug: print >>sys.stderr, ('\nStateMachine.run: line:\n| %s' % self.line) except IndexError: break try: - context, nextstate, result = self.checkline(context, state) + context, next_state, result = self.check_line(context, + state) except EOFError: break - state = self.getstate(nextstate) + state = self.get_state(next_state) results.extend(result) if self.debug: print >>sys.stderr, ('\nStateMachine.run: eof transition') @@ -222,96 +224,89 @@ class StateMachine: raise return results - def getstate(self, nextstate=None): + def get_state(self, next_state=None): """ - Return current state object; set it first if `nextstate` given. + Return current state object; set it first if `next_state` given. - Parameter `nextstate`: a string, the name of the next state. + Parameter `next_state`: a string, the name of the next state. - Exception: `UnknownStateError` raised if `nextstate` unknown. + Exception: `UnknownStateError` raised if `next_state` unknown. """ - if nextstate: - if self.debug and nextstate != self.currentstate: + if next_state: + if self.debug and next_state != self.current_state: print >>sys.stderr, \ - ('\nStateMachine.getstate: Changing state from ' + ('\nStateMachine.get_state: Changing state from ' '"%s" to "%s" (input line %s).' - % (self.currentstate, nextstate, self.abslineno())) - self.currentstate = nextstate + % (self.current_state, next_state, + self.abs_line_number())) + self.current_state = next_state try: - return self.states[self.currentstate] + return self.states[self.current_state] except KeyError: - raise UnknownStateError(self.currentstate) + raise UnknownStateError(self.current_state) - def nextline(self, n=1): + def next_line(self, n=1): """Load `self.line` with the `n`'th next line and return it.""" - self.lineoffset += n - self.line = self.inputlines[self.lineoffset] + self.line_offset += n + self.line = self.input_lines[self.line_offset] return self.line - def nextlineblank(self): + def is_next_line_blank(self): """Return 1 if the next line is blank or non-existant.""" try: - return not self.inputlines[self.lineoffset + 1].strip() + return not self.input_lines[self.line_offset + 1].strip() except IndexError: return 1 - def ateof(self): + def at_eof(self): """Return 1 if the input is at or past end-of-file.""" - return self.lineoffset >= len(self.inputlines) - 1 + return self.line_offset >= len(self.input_lines) - 1 - def atbof(self): + def at_bof(self): """Return 1 if the input is at or before beginning-of-file.""" - return self.lineoffset <= 0 + return self.line_offset <= 0 - def previousline(self, n=1): + def previous_line(self, n=1): """Load `self.line` with the `n`'th previous line and return it.""" - self.lineoffset -= n - self.line = self.inputlines[self.lineoffset] + self.line_offset -= n + self.line = self.input_lines[self.line_offset] return self.line - def gotoline(self, lineoffset): - """Jump to absolute line offset `lineoffset`, load and return it.""" - self.lineoffset = lineoffset - self.inputoffset - self.line = self.inputlines[self.lineoffset] + def goto_line(self, line_offset): + """Jump to absolute line offset `line_offset`, load and return it.""" + self.line_offset = line_offset - self.input_offset + self.line = self.input_lines[self.line_offset] return self.line - def abslineoffset(self): + def abs_line_offset(self): """Return line offset of current line, from beginning of file.""" - return self.lineoffset + self.inputoffset + return self.line_offset + self.input_offset - def abslineno(self): + def abs_line_number(self): """Return line number of current line (counting from 1).""" - return self.lineoffset + self.inputoffset + 1 + return self.line_offset + self.input_offset + 1 - def gettextblock(self): - """Return a contiguous block of text.""" - block = [] - for line in self.inputlines[self.lineoffset:]: - if not line.strip(): - break - block.append(line) - self.nextline(len(block) - 1) # advance to last line of block - return block - - def getunindented(self): + def get_text_block(self, flush_left=0): """ - Return a contiguous, flush-left block of text. + Return a contiguous block of text. - Raise `UnexpectedIndentationError` if an indented line is encountered - before the text block ends (with a blank line). + If `flush_left` is true, raise `UnexpectedIndentationError` if an + indented line is encountered before the text block ends (with a blank + line). """ - block = [self.line] - for line in self.inputlines[self.lineoffset + 1:]: + block = [] + for line in self.input_lines[self.line_offset:]: if not line.strip(): break - if line[0] == ' ': - self.nextline(len(block) - 1) # advance to last line of block - raise UnexpectedIndentationError(block, self.abslineno() + 1) + if flush_left and (line[0] == ' '): + self.next_line(len(block) - 1) # advance to last line of block + raise UnexpectedIndentationError(block, + self.abs_line_number() + 1) block.append(line) - self.nextline(len(block) - 1) # advance to last line of block + self.next_line(len(block) - 1) # advance to last line of block return block - def checkline(self, context, state): + def check_line(self, context, state): """ Examine one line of input for a transition match. @@ -327,13 +322,13 @@ class StateMachine: - the result output of the transition, a list. """ if self.debug: - print >>sys.stdout, ('\nStateMachine.checkline: ' + print >>sys.stdout, ('\nStateMachine.check_line: ' 'context "%s", state "%s"' % (context, state.__class__.__name__)) - context, nextstate, result = self.matchtransition(context, state) - return context, nextstate, result + context, next_state, result = self.match_transition(context, state) + return context, next_state, result - def matchtransition(self, context, state): + def match_transition(self, context, state): """ Try to match the current line to a transition & execute its method. @@ -351,25 +346,25 @@ class StateMachine: """ if self.debug: print >>sys.stderr, ( - '\nStateMachine.matchtransition: state="%s", transitions=%r.' - % (state.__class__.__name__, state.transitionorder)) - for name in state.transitionorder: + '\nStateMachine.match_transition: state="%s", transitions=' + '%r.' % (state.__class__.__name__, state.transition_order)) + for name in state.transition_order: while 1: - pattern, method, nextstate = state.transitions[name] + pattern, method, next_state = state.transitions[name] if self.debug: print >>sys.stderr, ( - '\nStateMachine.matchtransition: Trying transition ' - '"%s" in state "%s".' + '\nStateMachine.match_transition: Trying ' + 'transition "%s" in state "%s".' % (name, state.__class__.__name__)) match = self.match(pattern) if match: if self.debug: print >>sys.stderr, ( - '\nStateMachine.matchtransition: Matched ' + '\nStateMachine.match_transition: Matched ' 'transition "%s" in state "%s".' % (name, state.__class__.__name__)) try: - return method(match, context, nextstate) + return method(match, context, next_state) except TransitionCorrection, detail: name = str(detail) continue # try again with new transition name @@ -385,29 +380,37 @@ class StateMachine: """ return pattern.match(self.line) - def addstate(self, stateclass): + def add_state(self, state_class): """ - Initialize & add a `stateclass` (`State` subclass) object. + Initialize & add a `state_class` (`State` subclass) object. - Exception: `DuplicateStateError` raised if `stateclass` already added. + Exception: `DuplicateStateError` raised if `state_class` was already + added. """ - statename = stateclass.__name__ + statename = state_class.__name__ if self.states.has_key(statename): raise DuplicateStateError(statename) - self.states[statename] = stateclass(self, self.debug) + self.states[statename] = state_class(self, self.debug) + + def add_states(self, state_classes): + """ + Add `state_classes` (a list of `State` subclasses). + """ + for state_class in state_classes: + self.add_state(state_class) - def addstates(self, stateclasses): + def runtime_init(self): """ - Add `stateclasses` (a list of `State` subclasses). + Initialize `self.states`. """ - for stateclass in stateclasses: - self.addstate(stateclass) + for state in self.states.values(): + state.runtime_init() def error(self): """Report error details.""" - type, value, module, line, function = _exceptiondata() + type, value, module, line, function = _exception_data() print >>sys.stderr, '%s: %s' % (type, value) - print >>sys.stderr, 'input line %s' % (self.abslineno()) + print >>sys.stderr, 'input line %s' % (self.abs_line_number()) print >>sys.stderr, ('module %s, line %s, function %s' % (module, line, function)) @@ -448,47 +451,48 @@ class State: final processing result. Typical applications need only subclass `State` (or a subclass), set the - `patterns` and `initialtransitions` class attributes, and provide + `patterns` and `initial_transitions` class attributes, and provide corresponding transition methods. The default object initialization will take care of constructing the list of transitions. """ patterns = None """ - {Name: pattern} mapping, used by `maketransition()`. Each pattern may + {Name: pattern} mapping, used by `make_transition()`. Each pattern may be a string or a compiled `re` pattern. Override in subclasses. """ - initialtransitions = None + initial_transitions = None """ A list of transitions to initialize when a `State` is instantiated. Each entry is either a transition name string, or a (transition name, next - state name) pair. See `maketransitions()`. Override in subclasses. + state name) pair. See `make_transitions()`. Override in subclasses. """ - nestedSM = None + nested_sm = None """ The `StateMachine` class for handling nested processing. - If left as ``None``, `nestedSM` defaults to the class of the state's + If left as ``None``, `nested_sm` defaults to the class of the state's controlling state machine. Override it in subclasses to avoid the default. """ - nestedSMkwargs = None + nested_sm_kwargs = None """ - Keyword arguments dictionary, passed to the `nestedSM` constructor. + Keyword arguments dictionary, passed to the `nested_sm` constructor. Two keys must have entries in the dictionary: - - Key 'stateclasses' must be set to a list of `State` classes. - - Key 'initialstate' must be set to the name of the initial state class. + - Key 'state_classes' must be set to a list of `State` classes. + - Key 'initial_state' must be set to the name of the initial state class. - If `nestedSMkwargs` is left as ``None``, 'stateclasses' defaults to the - class of the current state, and 'initialstate' defaults to the name of the - class of the current state. Override in subclasses to avoid the defaults. + If `nested_sm_kwargs` is left as ``None``, 'state_classes' defaults to the + class of the current state, and 'initial_state' defaults to the name of + the class of the current state. Override in subclasses to avoid the + defaults. """ - def __init__(self, statemachine, debug=0): + def __init__(self, state_machine, debug=0): """ Initialize a `State` object; make & add initial transitions. @@ -498,7 +502,7 @@ class State: - `debug`: a boolean; produce verbose output if true (nonzero). """ - self.transitionorder = [] + self.transition_order = [] """A list of transition names in search order.""" self.transitions = {} @@ -510,27 +514,35 @@ class State: or other classes. """ - if self.initialtransitions: - names, transitions = self.maketransitions(self.initialtransitions) - self.addtransitions(names, transitions) + if self.initial_transitions: + names, transitions = self.make_transitions( + self.initial_transitions) + self.add_transitions(names, transitions) - self.statemachine = statemachine + self.state_machine = state_machine """A reference to the controlling `StateMachine` object.""" self.debug = debug """Debugging mode on/off.""" - if self.nestedSM is None: - self.nestedSM = self.statemachine.__class__ - if self.nestedSMkwargs is None: - self.nestedSMkwargs = {'stateclasses': [self.__class__], - 'initialstate': self.__class__.__name__} + if self.nested_sm is None: + self.nested_sm = self.state_machine.__class__ + if self.nested_sm_kwargs is None: + self.nested_sm_kwargs = {'state_classes': [self.__class__], + 'initial_state': self.__class__.__name__} + + def runtime_init(self): + """ + Initialize this `State` before running the state machine; called from + `self.state_machine.run()`. + """ + pass def unlink(self): """Remove circular references to objects no longer required.""" - self.statemachine = None + self.state_machine = None - def addtransitions(self, names, transitions): + def add_transitions(self, names, transitions): """ Add a list of transitions to the start of the transition list. @@ -546,10 +558,10 @@ class State: raise DuplicateTransitionError(name) if not transitions.has_key(name): raise UnknownTransitionError(name) - self.transitionorder[:0] = names + self.transition_order[:0] = names self.transitions.update(transitions) - def addtransition(self, name, transition): + def add_transition(self, name, transition): """ Add a transition to the start of the transition list. @@ -559,10 +571,10 @@ class State: """ if self.transitions.has_key(name): raise DuplicateTransitionError(name) - self.transitionorder[:0] = [name] + self.transition_order[:0] = [name] self.transitions[name] = transition - def removetransition(self, name): + def remove_transition(self, name): """ Remove a transition by `name`. @@ -570,11 +582,11 @@ class State: """ try: del self.transitions[name] - self.transitionorder.remove(name) + self.transition_order.remove(name) except: raise UnknownTransitionError(name) - def maketransition(self, name, nextstate=None): + def make_transition(self, name, next_state=None): """ Make & return a transition tuple based on `name`. @@ -585,14 +597,14 @@ class State: - `name`: a string, the name of the transition pattern & method. This `State` object must have a method called '`name`', and a dictionary `self.patterns` containing a key '`name`'. - - `nextstate`: a string, the name of the next `State` object for this + - `next_state`: a string, the name of the next `State` object for this transition. A value of ``None`` (or absent) implies no state change (i.e., continue with the same state). Exceptions: `TransitionPatternNotFound`, `TransitionMethodNotFound`. """ - if nextstate is None: - nextstate = self.__class__.__name__ + if next_state is None: + next_state = self.__class__.__name__ try: pattern = self.patterns[name] if not hasattr(pattern, 'match'): @@ -605,25 +617,25 @@ class State: except AttributeError: raise TransitionMethodNotFound( '%s.%s' % (self.__class__.__name__, name)) - return (pattern, method, nextstate) + return (pattern, method, next_state) - def maketransitions(self, namelist): + def make_transitions(self, name_list): """ Return a list of transition names and a transition mapping. - Parameter `namelist`: a list, where each entry is either a + Parameter `name_list`: a list, where each entry is either a transition name string, or a 1- or 2-tuple (transition name, optional next state name). """ stringtype = type('') names = [] transitions = {} - for namestate in namelist: + for namestate in name_list: if type(namestate) is stringtype: - transitions[namestate] = self.maketransition(namestate) + transitions[namestate] = self.make_transition(namestate) names.append(namestate) else: - transitions[namestate[0]] = self.maketransition(*namestate) + transitions[namestate[0]] = self.make_transition(*namestate) names.append(namestate[0]) return names, transitions @@ -647,14 +659,14 @@ class State: """ return [] - def nop(self, match, context, nextstate): + def nop(self, match, context, next_state): """ A "do nothing" transition method. - Return unchanged `context` & `nextstate`, empty result. Useful for + Return unchanged `context` & `next_state`, empty result. Useful for simple state changes (actionless transitions). """ - return context, nextstate, [] + return context, next_state, [] class StateMachineWS(StateMachine): @@ -668,32 +680,32 @@ class StateMachineWS(StateMachine): methods. There are three methods provided for extracting indented text blocks: - - `getindented()`: use when the indent is unknown. - - `getknownindented()`: use when the indent is known for all lines. - - `getfirstknownindented()`: use when only the first line's indent is + - `get_indented()`: use when the indent is unknown. + - `get_known_indented()`: use when the indent is known for all lines. + - `get_first_known_indented()`: use when only the first line's indent is known. """ spaces = re.compile(' *') """Indentation recognition pattern.""" - def checkline(self, context, state): + def check_line(self, context, state): """ Examine one line of input for whitespace first, then transitions. - Extends `StateMachine.checkline()`. + Extends `StateMachine.check_line()`. """ if self.debug: - print >>sys.stdout, ('\nStateMachineWS.checkline: ' + print >>sys.stdout, ('\nStateMachineWS.check_line: ' 'context "%s", state "%s"' % (context, state.__class__.__name__)) - context, nextstate, result = self.checkwhitespace(context, state) - if nextstate == '': # no whitespace match - return StateMachine.checkline(self, context, state) + context, next_state, result = self.check_whitespace(context, state) + if next_state == '': # no whitespace match + return StateMachine.check_line(self, context, state) else: - return context, nextstate, result + return context, next_state, result - def checkwhitespace(self, context, state): + def check_whitespace(self, context, state): """ Check for a blank line or increased indent. Call the state's transition method if a match is found. @@ -711,33 +723,35 @@ class StateMachineWS(StateMachine): - the result output of the transition, a list (empty if no match). """ if self.debug: - print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + print >>sys.stdout, ('\nStateMachineWS.check_whitespace: ' 'context "%s", state "%s"' % (context, state.__class__.__name__)) match = self.spaces.match(self.line) indent = match.end() if indent == len(self.line): if self.debug: - print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + print >>sys.stdout, ('\nStateMachineWS.check_whitespace: ' 'implicit transition "blank" matched') - return state.blank(match, context, self.currentstate) + return state.blank(match, context, self.current_state) elif indent: if self.debug: - print >>sys.stdout, ('\nStateMachineWS.checkwhitespace: ' + print >>sys.stdout, ('\nStateMachineWS.check_whitespace: ' 'implicit transition "indent" matched') - return state.indent(match, context, self.currentstate) + return state.indent(match, context, self.current_state) else: return context, '', [] # neither blank line nor indented - def getindented(self, uptoblank=0, stripindent=1): + def get_indented(self, until_blank=0, strip_indent=1): """ - Return a indented lines of text and info. + Return a block of indented lines of text, and info. Extract an indented block where the indent is unknown for all lines. :Parameters: - - `uptoblank`: Stop collecting at the first blank line if true (1). - - `stripindent`: Strip common leading indent if true (1, default). + - `until_blank`: Stop collecting at the first blank line if true + (1). + - `strip_indent`: Strip common leading indent if true (1, + default). :Return: - the indented block (a list of lines of text), @@ -745,17 +759,17 @@ class StateMachineWS(StateMachine): - its first line offset from BOF, and - whether or not it finished with a blank line. """ - offset = self.abslineoffset() - indented, indent, blankfinish = extractindented( - self.inputlines[self.lineoffset:], uptoblank, stripindent) + offset = self.abs_line_offset() + indented, indent, blank_finish = extract_indented( + self.input_lines[self.line_offset:], until_blank, strip_indent) if indented: - self.nextline(len(indented) - 1) # advance to last indented line + self.next_line(len(indented) - 1) # advance to last indented line while indented and not indented[0].strip(): indented.pop(0) offset += 1 - return indented, indent, offset, blankfinish + return indented, indent, offset, blank_finish - def getknownindented(self, indent, uptoblank=0, stripindent=1): + def get_known_indented(self, indent, until_blank=0, strip_indent=1): """ Return an indented block and info. @@ -766,8 +780,9 @@ class StateMachineWS(StateMachine): :Parameters: - `indent`: The number of indent columns/characters. - - `uptoblank`: Stop collecting at the first blank line if true (1). - - `stripindent`: Strip `indent` characters of indentation if true + - `until_blank`: Stop collecting at the first blank line if true + (1). + - `strip_indent`: Strip `indent` characters of indentation if true (1, default). :Return: @@ -775,29 +790,29 @@ class StateMachineWS(StateMachine): - its first line offset from BOF, and - whether or not it finished with a blank line. """ - offset = self.abslineoffset() + offset = self.abs_line_offset() indented = [self.line[indent:]] - for line in self.inputlines[self.lineoffset + 1:]: + for line in self.input_lines[self.line_offset + 1:]: if line[:indent].strip(): - blankfinish = not indented[-1].strip() and len(indented) > 1 + blank_finish = not indented[-1].strip() and len(indented) > 1 break - if uptoblank and line.strip(): - blankfinish = 1 + if until_blank and line.strip(): + blank_finish = 1 break - if stripindent: + if strip_indent: indented.append(line[indent:]) else: indented.append(line) else: - blankfinish = 1 + blank_finish = 1 if indented: - self.nextline(len(indented) - 1) # advance to last indented line + self.next_line(len(indented) - 1) # advance to last indented line while indented and not indented[0].strip(): indented.pop(0) offset += 1 - return indented, offset, blankfinish + return indented, offset, blank_finish - def getfirstknownindented(self, indent, uptoblank=0, stripindent=1): + def get_first_known_indented(self, indent, until_blank=0, strip_indent=1): """ Return an indented block and info. @@ -806,8 +821,9 @@ class StateMachineWS(StateMachine): :Parameters: - `indent`: The first line's indent (# of columns/characters). - - `uptoblank`: Stop collecting at the first blank line if true (1). - - `stripindent`: Strip `indent` characters of indentation if true + - `until_blank`: Stop collecting at the first blank line if true + (1). + - `strip_indent`: Strip `indent` characters of indentation if true (1, default). :Return: @@ -816,15 +832,16 @@ class StateMachineWS(StateMachine): - its first line offset from BOF, and - whether or not it finished with a blank line. """ - offset = self.abslineoffset() + offset = self.abs_line_offset() indented = [self.line[indent:]] - indented[1:], indent, blankfinish = extractindented( - self.inputlines[self.lineoffset + 1:], uptoblank, stripindent) - self.nextline(len(indented) - 1) # advance to last indented line + indented[1:], indent, blank_finish = extract_indented( + self.input_lines[self.line_offset + 1:], until_blank, + strip_indent) + self.next_line(len(indented) - 1) # advance to last indented line while indented and not indented[0].strip(): indented.pop(0) offset += 1 - return indented, indent, offset, blankfinish + return indented, indent, offset, blank_finish class StateWS(State): @@ -835,111 +852,113 @@ class StateWS(State): Use this class with `StateMachineWS`. The transition method `blank()` handles blank lines and `indent()` handles nested indented blocks. Indented blocks trigger a new state machine to be created by `indent()` - and run. The class of the state machine to be created is in `indentSM`, + and run. The class of the state machine to be created is in `indent_sm`, and the constructor keyword arguments are in the dictionary - `indentSMkwargs`. + `indent_sm_kwargs`. - The methods `knownindent()` and `firstknownindent()` are provided for + The methods `known_indent()` and `firstknown_indent()` are provided for indented blocks where the indent (all lines' and first line's only, respectively) is known to the transition method, along with the attributes - `knownindentSM` and `knownindentSMkwargs`. Neither transition method is - triggered automatically. + `known_indent_sm` and `known_indent_sm_kwargs`. Neither transition method + is triggered automatically. """ - indentSM = None + indent_sm = None """ The `StateMachine` class handling indented text blocks. - If left as ``None``, `indentSM` defaults to the value of `State.nestedSM`. - Override it in subclasses to avoid the default. + If left as ``None``, `indent_sm` defaults to the value of + `State.nested_sm`. Override it in subclasses to avoid the default. """ - indentSMkwargs = None + indent_sm_kwargs = None """ - Keyword arguments dictionary, passed to the `indentSM` constructor. + Keyword arguments dictionary, passed to the `indent_sm` constructor. - If left as ``None``, `indentSMkwargs` defaults to the value of - `State.nestedSMkwargs`. Override it in subclasses to avoid the default. + If left as ``None``, `indent_sm_kwargs` defaults to the value of + `State.nested_sm_kwargs`. Override it in subclasses to avoid the default. """ - knownindentSM = None + known_indent_sm = None """ The `StateMachine` class handling known-indented text blocks. - If left as ``None``, `knownindentSM` defaults to the value of `indentSM`. - Override it in subclasses to avoid the default. + If left as ``None``, `known_indent_sm` defaults to the value of + `indent_sm`. Override it in subclasses to avoid the default. """ - knownindentSMkwargs = None + known_indent_sm_kwargs = None """ - Keyword arguments dictionary, passed to the `knownindentSM` constructor. + Keyword arguments dictionary, passed to the `known_indent_sm` constructor. - If left as ``None``, `knownindentSMkwargs` defaults to the value of - `indentSMkwargs`. Override it in subclasses to avoid the default. + If left as ``None``, `known_indent_sm_kwargs` defaults to the value of + `indent_sm_kwargs`. Override it in subclasses to avoid the default. """ - def __init__(self, statemachine, debug=0): + def __init__(self, state_machine, debug=0): """ Initialize a `StateSM` object; extends `State.__init__()`. Check for indent state machine attributes, set defaults if not set. """ - State.__init__(self, statemachine, debug) - if self.indentSM is None: - self.indentSM = self.nestedSM - if self.indentSMkwargs is None: - self.indentSMkwargs = self.nestedSMkwargs - if self.knownindentSM is None: - self.knownindentSM = self.indentSM - if self.knownindentSMkwargs is None: - self.knownindentSMkwargs = self.indentSMkwargs - - def blank(self, match, context, nextstate): + State.__init__(self, state_machine, debug) + if self.indent_sm is None: + self.indent_sm = self.nested_sm + if self.indent_sm_kwargs is None: + self.indent_sm_kwargs = self.nested_sm_kwargs + if self.known_indent_sm is None: + self.known_indent_sm = self.indent_sm + if self.known_indent_sm_kwargs is None: + self.known_indent_sm_kwargs = self.indent_sm_kwargs + + def blank(self, match, context, next_state): """Handle blank lines. Does nothing. Override in subclasses.""" - return self.nop(match, context, nextstate) + return self.nop(match, context, next_state) - def indent(self, match, context, nextstate): + def indent(self, match, context, next_state): """ Handle an indented text block. Extend or override in subclasses. Recursively run the registered state machine for indented blocks - (`self.indentSM`). + (`self.indent_sm`). """ - indented, indent, lineoffset, blankfinish = \ - self.statemachine.getindented() - sm = self.indentSM(debug=self.debug, **self.indentSMkwargs) - results = sm.run(indented, inputoffset=lineoffset) - return context, nextstate, results + indented, indent, line_offset, blank_finish = \ + self.state_machine.get_indented() + sm = self.indent_sm(debug=self.debug, **self.indent_sm_kwargs) + results = sm.run(indented, input_offset=line_offset) + return context, next_state, results - def knownindent(self, match, context, nextstate): + def known_indent(self, match, context, next_state): """ Handle a known-indent text block. Extend or override in subclasses. Recursively run the registered state machine for known-indent indented - blocks (`self.knownindentSM`). The indent is the length of the match, + blocks (`self.known_indent_sm`). The indent is the length of the match, ``match.end()``. """ - indented, lineoffset, blankfinish = \ - self.statemachine.getknownindented(match.end()) - sm = self.knownindentSM(debug=self.debug, **self.knownindentSMkwargs) - results = sm.run(indented, inputoffset=lineoffset) - return context, nextstate, results - - def firstknownindent(self, match, context, nextstate): + indented, line_offset, blank_finish = \ + self.state_machine.get_known_indented(match.end()) + sm = self.known_indent_sm(debug=self.debug, + **self.known_indent_sm_kwargs) + results = sm.run(indented, input_offset=line_offset) + return context, next_state, results + + def first_known_indent(self, match, context, next_state): """ Handle an indented text block (first line's indent known). Extend or override in subclasses. Recursively run the registered state machine for known-indent indented - blocks (`self.knownindentSM`). The indent is the length of the match, - ``match.end()``. + blocks (`self.known_indent_sm`). The indent is the length of the + match, ``match.end()``. """ - indented, lineoffset, blankfinish = \ - self.statemachine.getfirstknownindented(match.end()) - sm = self.knownindentSM(debug=self.debug, **self.knownindentSMkwargs) - results = sm.run(indented, inputoffset=lineoffset) - return context, nextstate, results + indented, line_offset, blank_finish = \ + self.state_machine.get_first_known_indented(match.end()) + sm = self.known_indent_sm(debug=self.debug, + **self.known_indent_sm_kwargs) + results = sm.run(indented, input_offset=line_offset) + return context, next_state, results class _SearchOverride: @@ -993,36 +1012,36 @@ class TransitionCorrection(Exception): _whitespace_conversion_table = string.maketrans('\v\f', ' ') -def string2lines(astring, tabwidth=8, convertwhitespace=0): +def string2lines(astring, tab_width=8, convert_whitespace=0): """ Return a list of one-line strings with tabs expanded and no newlines. - Each tab is expanded with between 1 and `tabwidth` spaces, so that the - next character's index becomes a multiple of `tabwidth` (8 by default). + Each tab is expanded with between 1 and `tab_width` spaces, so that the + next character's index becomes a multiple of `tab_width` (8 by default). Parameters: - `astring`: a multi-line string. - - `tabwidth`: the number of columns between tab stops. - - `convertwhitespace`: convert form feeds and vertical tabs to spaces? + - `tab_width`: the number of columns between tab stops. + - `convert_whitespace`: convert form feeds and vertical tabs to spaces? """ - if convertwhitespace: + if convert_whitespace: astring = astring.translate(_whitespace_conversion_table) - return [s.expandtabs(tabwidth) for s in astring.splitlines()] + return [s.expandtabs(tab_width) for s in astring.splitlines()] -def extractindented(lines, uptoblank=0, stripindent=1): +def extract_indented(lines, until_blank=0, strip_indent=1): """ Extract and return a list of indented lines of text. Collect all lines with indentation, determine the minimum indentation, remove the minimum indentation from all indented lines (unless - `stripindent` is false), and return them. All lines up to but not + `strip_indent` is false), and return them. All lines up to but not including the first unindented line will be returned. :Parameters: - `lines`: a list of one-line strings without newlines. - - `uptoblank`: Stop collecting at the first blank line if true (1). - - `stripindent`: Strip common leading indent if true (1, default). + - `until_blank`: Stop collecting at the first blank line if true (1). + - `strip_indent`: Strip common leading indent if true (1, default). :Return: - a list of indented lines with mininum indent removed; @@ -1035,11 +1054,11 @@ def extractindented(lines, uptoblank=0, stripindent=1): for line in lines: if line and line[0] != ' ': # line not indented # block finished properly iff the last indented line was blank - blankfinish = len(source) and not source[-1].strip() + blank_finish = len(source) and not source[-1].strip() break stripped = line.lstrip() - if uptoblank and not stripped: # blank line - blankfinish = 1 + if until_blank and not stripped: # blank line + blank_finish = 1 break source.append(line) if not stripped: # blank line @@ -1050,15 +1069,15 @@ def extractindented(lines, uptoblank=0, stripindent=1): else: indent = min(indent, lineindent) else: - blankfinish = 1 # block ends at end of lines + blank_finish = 1 # block ends at end of lines if indent: - if stripindent: + if strip_indent: source = [s[indent:] for s in source] - return source, indent, blankfinish + return source, indent, blank_finish else: - return [], 0, blankfinish + return [], 0, blank_finish -def _exceptiondata(): +def _exception_data(): """ Return exception information: -- cgit v1.2.1 From 9c5bc6ca7bedb2a9ebdd40ae9db57a38cdb183a5 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:31:17 +0000 Subject: Changed ``Messages`` transform to properly filter out system messages below the warning threshold. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@83 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 63 +++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 1cebcc9db..145a89b01 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -19,7 +19,7 @@ Transforms needed by most or all documents: __docformat__ = 'reStructuredText' -import re +import re, sys from docutils import nodes, utils from docutils.transforms import TransformError, Transform @@ -32,24 +32,29 @@ class Messages(Transform): """ def transform(self): - # @@@ filter out msgs below threshold? - if len(self.doctree.messages) > 0: + unfiltered = self.document.messages.getchildren() + threshold = self.document.reporter['writer'].warning_level + messages = [] + for msg in unfiltered: + if msg['level'] >= threshold: + messages.append(msg) + if len(messages) > 0: section = nodes.section(CLASS='system-messages') # @@@ get this from the language module? section += nodes.title('', 'Docutils System Messages') - section += self.doctree.messages.getchildren() - self.doctree.messages[:] = [] - self.doctree += section + section += messages + self.document.messages[:] = [] + self.document += section class TestMessages(Transform): """ - Append all system messages to the end of the doctree. + Append all system messages to the end of the document. """ def transform(self): - self.doctree += self.doctree.messages.getchildren() + self.document += self.document.messages.getchildren() class FinalChecks(Transform): @@ -61,8 +66,8 @@ class FinalChecks(Transform): """ def transform(self): - visitor = FinalCheckVisitor(self.doctree) - self.doctree.walk(visitor) + visitor = FinalCheckVisitor(self.document) + self.document.walk(visitor) class FinalCheckVisitor(nodes.NodeVisitor): @@ -75,21 +80,21 @@ class FinalCheckVisitor(nodes.NodeVisitor): return refname = node['refname'] try: - id = self.doctree.nameids[refname] + id = self.document.nameids[refname] except KeyError: - msg = self.doctree.reporter.error( + msg = self.document.reporter.error( 'Unknown target name: "%s".' % (node['refname'])) - self.doctree.messages += msg - msgid = self.doctree.set_id(msg) + self.document.messages += msg + msgid = self.document.set_id(msg) prb = nodes.problematic( node.rawsource, node.rawsource, refid=msgid) - prbid = self.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) node.parent.replace(node, prb) return del node['refname'] node['refid'] = id - self.doctree.ids[id].referenced = 1 + self.document.ids[id].referenced = 1 node.resolved = 1 visit_footnote_reference = visit_citation_reference = visit_reference @@ -98,43 +103,47 @@ class FinalCheckVisitor(nodes.NodeVisitor): class Pending(Transform): """ - Execute pending transforms. + Base class for the execution of pending transforms. + + `nodes.pending` element objects each contain a "stage" attribute; the + stage of the pending element must match the `stage` of this transform. """ stage = None """The stage of processing applicable to this transform; match with - `nodes.pending.stage`. Possible values include 'first_reader', - 'last_reader', 'first_writer', and 'last_writer'. Override in - subclasses.""" + `nodes.pending.stage`. Possible values include 'first reader', + 'last reader', 'first writer', and 'last writer'. Overriden in + subclasses (below).""" def transform(self): - for pending in self.doctree.pending: + for pending in self.document.pending: if pending.stage == self.stage: - pending.transform(self.doctree, pending).transform() + pending.transform(self.document, self.component, + pending).transform() class FirstReaderPending(Pending): - stage = 'first_reader' + stage = 'first reader' class LastReaderPending(Pending): - stage = 'last_reader' + stage = 'last reader' class FirstWriterPending(Pending): - stage = 'first_writer' + stage = 'first writer' class LastWriterPending(Pending): - stage = 'last_writer' + stage = 'last writer' test_transforms = (TestMessages,) -"""Universal transforms to apply to the raw doctree when testing.""" +"""Universal transforms to apply to the raw document when testing.""" first_reader_transforms = (FirstReaderPending,) """Universal transforms to apply before any other Reader transforms.""" -- cgit v1.2.1 From 1391b104c8e096918cb1f12ed4befe4a3f9bdc11 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:34:56 +0000 Subject: renamed pseudoxml.py from pprint.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@84 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pprint.py | 28 ---------------------------- docutils/writers/pseudoxml.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 28 deletions(-) delete mode 100644 docutils/writers/pprint.py create mode 100644 docutils/writers/pseudoxml.py diff --git a/docutils/writers/pprint.py b/docutils/writers/pprint.py deleted file mode 100644 index a34c2a920..000000000 --- a/docutils/writers/pprint.py +++ /dev/null @@ -1,28 +0,0 @@ -#! /usr/bin/env python - -""" -:Authors: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -Simple internal document tree Writer, writes indented pseudo-XML. -""" - -__docformat__ = 'reStructuredText' - - -from docutils import writers - - -class Writer(writers.Writer): - - output = None - """Final translated form of `document`.""" - - def translate(self): - self.output = self.document.pformat() - - def record(self): - self.recordfile(self.output, self.destination) diff --git a/docutils/writers/pseudoxml.py b/docutils/writers/pseudoxml.py new file mode 100644 index 000000000..a0cf5ea14 --- /dev/null +++ b/docutils/writers/pseudoxml.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Simple internal document tree Writer, writes indented pseudo-XML. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import writers + + +class Writer(writers.Writer): + + supported = ('pprint', 'pformat', 'pseudoxml') + """Formats this writer supports.""" + + output = None + """Final translated form of `document`.""" + + def translate(self): + self.output = self.document.pformat() + + def record(self): + self.recordfile(self.output, self.destination) + + def supports(self, format): + """This writer supports all format-specific elements.""" + return 1 -- cgit v1.2.1 From 8964493e1cc53888f581d21c6edcc29891c1b84a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:35:35 +0000 Subject: - Made XHTML-compatible (switched to lowercase element & attribute names; empty tag format). - Escape double-dashes in comment text. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@85 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a911719ab..0390502d2 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -24,8 +24,8 @@ from docutils import writers, nodes, languages class Writer(writers.Writer): - names = ('html', 'html4css1', 'xhtml') - """Names this writer answers to.""" + supported = ('html', 'html4css1', 'xhtml') + """Formats this writer supports.""" output = None """Final translated form of `document`.""" @@ -41,13 +41,13 @@ class Writer(writers.Writer): class HTMLTranslator(nodes.NodeVisitor): - def __init__(self, doctree): - nodes.NodeVisitor.__init__(self, doctree) - self.language = languages.getlanguage(doctree.languagecode) + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.language = languages.getlanguage(document.language_code) self.head = ['\n', - '\n\n' % doctree.languagecode, + '\n\n' % document.language_code, '\n'] self.body = ['\n\n'] @@ -187,7 +187,7 @@ class HTMLTranslator(nodes.NodeVisitor): if node.has_key('refid'): href = '#' + node['refid'] elif node.has_key('refname'): - href = '#' + self.doctree.nameids[node['refname']] + href = '#' + self.document.nameids[node['refname']] self.body.append(self.starttag(node, 'a', '[', href=href, CLASS='citation-reference')) @@ -417,7 +417,7 @@ class HTMLTranslator(nodes.NodeVisitor): if node.has_key('refid'): href = '#' + node['refid'] elif node.has_key('refname'): - href = '#' + self.doctree.nameids[node['refname']] + href = '#' + self.document.nameids[node['refname']] self.body.append(self.starttag(node, 'a', '', href=href, CLASS='footnote-reference')) @@ -589,7 +589,7 @@ class HTMLTranslator(nodes.NodeVisitor): elif node.has_key('refid'): href = '#' + node['refid'] elif node.has_key('refname'): - href = '#' + self.doctree.nameids[node['refname']] + href = '#' + self.document.nameids[node['refname']] self.body.append(self.starttag(node, 'a', '', href=href, CLASS='reference')) @@ -644,7 +644,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_system_message(self, node): - if node['level'] < self.doctree.reporter['writer'].warninglevel: + if node['level'] < self.document.reporter['writer'].warning_level: raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) self.body.append('

    ') -- cgit v1.2.1 From 23a164fa2084631177b50039af76e424b16db2d1 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:36:03 +0000 Subject: refactored; improved compound names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@86 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/standalone.py | 7 +- docutils/transforms/__init__.py | 17 ++-- docutils/transforms/frontmatter.py | 69 ++++++------- docutils/transforms/references.py | 193 +++++++++++++++++-------------------- docutils/utils.py | 66 +++++++------ docutils/writers/__init__.py | 26 ++--- 6 files changed, 188 insertions(+), 190 deletions(-) diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 27c0ded6b..e6108f569 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -1,7 +1,7 @@ #! /usr/bin/env python """ -:Authors: David Goodger +:Author: David Goodger :Contact: goodger@users.sourceforge.net :Revision: $Revision$ :Date: $Date$ @@ -21,6 +21,9 @@ from docutils.parsers.rst import Parser class Reader(readers.Reader): + supported = ('standalone',) + """Contexts this reader supports.""" + document = None """A single document tree.""" @@ -31,4 +34,4 @@ class Reader(readers.Reader): references.Hyperlinks,) def scan(self): - self.input = self.scanfile(self.source) + self.input = self.scan_file(self.source) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 6c2ae279f..ddf92cb65 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -29,32 +29,37 @@ these standard transforms. __docformat__ = 'reStructuredText' -from docutils import languages +from docutils import languages, ApplicationError, Component -class TransformError(Exception): pass +class TransformError(ApplicationError): pass -class Transform: +class Transform(Component): """ Docutils transform component abstract base class. """ - def __init__(self, doctree, startnode=None): + def __init__(self, document, component, startnode=None): """ Initial setup for in-place document transforms. """ - self.doctree = doctree + self.document = document """The document tree to transform.""" + self.component = component + """The Docutils component running this transform. Transforms can + query their controlling components with calls to + `docutils.Component.supports()`.""" + 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.getlanguage(doctree.languagecode) + self.language = languages.getlanguage(document.language_code) """Language module local to this document.""" def transform(self): diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 0a8068fad..d4bfce832 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -111,13 +111,13 @@ class DocTitle(Transform): section, index = self.candidate_index() if index is None: return None - doctree = self.doctree + document = self.document # Transfer the section's attributes to the document element (at root): - doctree.attributes.update(section.attributes) - doctree[:] = (section[:1] # section title - + doctree[:index] # everything that was in the document - # before the section - + section[1:]) # everything that was in the section + document.attributes.update(section.attributes) + document[:] = (section[:1] # section title + + document[:index] # everything that was in the + # document before the section + + section[1:]) # everything that was in the section return 1 def promote_document_subtitle(self): @@ -129,10 +129,10 @@ class DocTitle(Transform): subtitle.attributes.update(subsection.attributes) # Transfer the contents of the subsection's title to the subtitle: subtitle[:] = subsection[0][:] - doctree = self.doctree - doctree[:] = (doctree[:1] # document title + document = self.document + document[:] = (document[:1] # document title + [subtitle] - + doctree[1:index] # everything that was in the document + + document[1:index] # everything that was in the document # before the section + subsection[1:]) # everything that was in the subsection return 1 @@ -143,13 +143,13 @@ class DocTitle(Transform): Return (None, None) if no valid candidate was found. """ - doctree = self.doctree - index = doctree.findnonclass(nodes.PreBibliographic) - if index is None or len(doctree) > (index + 1) or \ - not isinstance(doctree[index], nodes.section): + document = self.document + index = document.findnonclass(nodes.PreBibliographic) + if index is None or len(document) > (index + 1) or \ + not isinstance(document[index], nodes.section): return None, None else: - return doctree[index], index + return document[index], index class DocInfo(Transform): @@ -224,19 +224,19 @@ class DocInfo(Transform): """ def transform(self): - doctree = self.doctree - index = doctree.findnonclass(nodes.PreBibliographic) + document = self.document + index = document.findnonclass(nodes.PreBibliographic) if index is None: return - candidate = doctree[index] + candidate = document[index] if isinstance(candidate, nodes.field_list): - biblioindex = doctree.findnonclass(nodes.Titular) + biblioindex = document.findnonclass(nodes.Titular) nodelist, remainder = self.extract_bibliographic(candidate) if remainder: - doctree[index] = remainder + document[index] = remainder else: - del doctree[index] - doctree[biblioindex:biblioindex] = nodelist + del document[index] + document[biblioindex:biblioindex] = nodelist return def extract_bibliographic(self, field_list): @@ -247,7 +247,7 @@ class DocInfo(Transform): for field in field_list: try: name = field[0][0].astext() - normedname = utils.normname(name) + normedname = utils.normalize_name(name) if not (len(field) == 2 and bibliofields.has_key(normedname) and self.check_empty_biblio_field(field, name)): raise TransformError @@ -255,14 +255,15 @@ class DocInfo(Transform): if issubclass(biblioclass, nodes.TextElement): if not self.check_compound_biblio_field(field, name): raise TransformError - self.filter_rcs_keywords(field[1][0]) + utils.clean_rcs_keywords( + field[1][0], self.rcs_keyword_substitutions) docinfo.append(biblioclass('', '', *field[1][0])) else: # multiple body elements possible if issubclass(biblioclass, nodes.authors): self.extract_authors(field, name, docinfo) elif issubclass(biblioclass, nodes.topic): if abstract: - field[-1] += self.doctree.reporter.warning( + field[-1] += self.document.reporter.warning( 'There can only be one abstract.') raise TransformError title = nodes.title( @@ -287,18 +288,18 @@ class DocInfo(Transform): def check_empty_biblio_field(self, field, name): if len(field[1]) < 1: - field[-1] += self.doctree.reporter.warning( + field[-1] += self.document.reporter.warning( 'Cannot extract empty bibliographic field "%s".' % name) return None return 1 def check_compound_biblio_field(self, field, name): if len(field[1]) > 1: - field[-1] += self.doctree.reporter.warning( + field[-1] += self.document.reporter.warning( 'Cannot extract compound bibliographic field "%s".' % name) return None if not isinstance(field[1][0], nodes.paragraph): - field[-1] += self.doctree.reporter.warning( + field[-1] += self.document.reporter.warning( 'Cannot extract bibliographic field "%s" containing anything ' 'other than a single paragraph.' % name) @@ -308,19 +309,9 @@ class DocInfo(Transform): rcs_keyword_substitutions = [ (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$', re.IGNORECASE), r'\1-\2-\3'), - (re.compile(r'\$' r'RCSfile: (.+),v \$$', - re.IGNORECASE), r'\1'), + (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'), (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] - def filter_rcs_keywords(self, paragraph): - if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): - textnode = paragraph[0] - for pattern, substitution in self.rcs_keyword_substitutions: - match = pattern.match(textnode.data) - if match: - textnode.data = pattern.sub(substitution, textnode.data) - return - def extract_authors(self, field, name, docinfo): try: if len(field[1]) == 1: @@ -336,7 +327,7 @@ class DocInfo(Transform): for author in authors if author] docinfo.append(nodes.authors('', *authornodes)) except TransformError: - field[-1] += self.doctree.reporter.warning( + 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 ' diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index c2ff9189b..107bdfdee 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -25,22 +25,11 @@ class Hyperlinks(Transform): """Resolve the various types of hyperlink targets and references.""" def transform(self): - stages = [] - #stages.append('Beginning of references.Hyperlinks.transform()\n' + self.doctree.pformat()) self.resolve_chained_targets() - #stages.append('After references.Hyperlinks.resolve_chained_targets()\n' + self.doctree.pformat()) self.resolve_anonymous() - #stages.append('After references.Hyperlinks.resolve_anonymous()\n' + self.doctree.pformat()) self.resolve_indirect() - #stages.append('After references.Hyperlinks.resolve_indirect()\n' + self.doctree.pformat()) self.resolve_external_targets() - #stages.append('After references.Hyperlinks.resolve_external_references()\n' + self.doctree.pformat()) self.resolve_internal_targets() - #stages.append('After references.Hyperlinks.resolve_internal_references()\n' + self.doctree.pformat()) - #import difflib - #compare = difflib.Differ().compare - #for i in range(len(stages) - 1): - # print ''.join(compare(stages[i].splitlines(1), stages[i+1].splitlines(1))) def resolve_chained_targets(self): """ @@ -48,8 +37,8 @@ class Hyperlinks(Transform): target up the chain of contiguous adjacent internal targets, using `ChainedTargetResolver`. """ - visitor = ChainedTargetResolver(self.doctree) - self.doctree.walk(visitor) + visitor = ChainedTargetResolver(self.document) + self.document.walk(visitor) def resolve_anonymous(self): """ @@ -74,30 +63,30 @@ class Hyperlinks(Transform): """ - if len(self.doctree.anonymous_refs) \ - != len(self.doctree.anonymous_targets): - msg = self.doctree.reporter.error( + if len(self.document.anonymous_refs) \ + != len(self.document.anonymous_targets): + msg = self.document.reporter.error( 'Anonymous hyperlink mismatch: %s references but %s targets.' - % (len(self.doctree.anonymous_refs), - len(self.doctree.anonymous_targets))) - self.doctree.messages += msg - msgid = self.doctree.set_id(msg) - for ref in self.doctree.anonymous_refs: + % (len(self.document.anonymous_refs), + len(self.document.anonymous_targets))) + self.document.messages += msg + msgid = self.document.set_id(msg) + for ref in self.document.anonymous_refs: prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) - prbid = self.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) return - for i in range(len(self.doctree.anonymous_refs)): - ref = self.doctree.anonymous_refs[i] - target = self.doctree.anonymous_targets[i] + for i in range(len(self.document.anonymous_refs)): + ref = self.document.anonymous_refs[i] + target = self.document.anonymous_targets[i] if target.hasattr('refuri'): ref['refuri'] = target['refuri'] ref.resolved = 1 else: ref['refid'] = target['id'] - self.doctree.note_refid(ref) + self.document.note_refid(ref) target.referenced = 1 def resolve_indirect(self): @@ -150,9 +139,7 @@ class Hyperlinks(Transform): """ - #import mypdb as pdb - #pdb.set_trace() - for target in self.doctree.indirect_targets: + for target in self.document.indirect_targets: if not target.resolved: self.resolve_indirect_target(target) self.resolve_indirect_references(target) @@ -160,10 +147,10 @@ class Hyperlinks(Transform): def resolve_indirect_target(self, target): refname = target['refname'] reftarget = None - if self.doctree.explicit_targets.has_key(refname): - reftarget = self.doctree.explicit_targets[refname] - elif self.doctree.implicit_targets.has_key(refname): - reftarget = self.doctree.implicit_targets[refname] + if self.document.explicit_targets.has_key(refname): + reftarget = self.document.explicit_targets[refname] + elif self.document.implicit_targets.has_key(refname): + reftarget = self.document.implicit_targets[refname] if not reftarget: self.nonexistent_indirect_target(target) return @@ -173,14 +160,14 @@ class Hyperlinks(Transform): if reftarget.hasattr('refuri'): target['refuri'] = reftarget['refuri'] if target.hasattr('name'): - self.doctree.note_external_target(target) + self.document.note_external_target(target) elif reftarget.hasattr('refid'): target['refid'] = reftarget['refid'] - self.doctree.note_refid(target) + self.document.note_refid(target) else: try: target['refid'] = reftarget['id'] - self.doctree.note_refid(target) + self.document.note_refid(target) except KeyError: self.nonexistent_indirect_target(target) return @@ -192,19 +179,19 @@ class Hyperlinks(Transform): naming = '' if target.hasattr('name'): naming = '"%s" ' % target['name'] - reflist = self.doctree.refnames[target['name']] + reflist = self.document.refnames[target['name']] else: - reflist = self.doctree.refnames[target['id']] + reflist = self.document.refnames[target['id']] naming += '(id="%s")' % target['id'] - msg = self.doctree.reporter.warning( + msg = self.document.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' 'which does not exist.' % (naming, target['refname'])) - self.doctree.messages += msg - msgid = self.doctree.set_id(msg) + self.document.messages += msg + msgid = self.document.set_id(msg) for ref in reflist: prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) - prbid = self.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) target.resolved = 1 @@ -213,39 +200,39 @@ class Hyperlinks(Transform): if target.hasattr('refid'): attname = 'refid' call_if_named = 0 - call_method = self.doctree.note_refid + call_method = self.document.note_refid elif target.hasattr('refuri'): attname = 'refuri' call_if_named = 1 - call_method = self.doctree.note_external_target + call_method = self.document.note_external_target else: return attval = target[attname] if target.hasattr('name'): name = target['name'] try: - reflist = self.doctree.refnames[name] + reflist = self.document.refnames[name] except KeyError, instance: if target.referenced: return - msg = self.doctree.reporter.info( + msg = self.document.reporter.info( 'Indirect hyperlink target "%s" is not referenced.' % name) - self.doctree.messages += msg + self.document.messages += msg target.referenced = 1 return delatt = 'refname' else: id = target['id'] try: - reflist = self.doctree.refids[id] + reflist = self.document.refids[id] except KeyError, instance: if target.referenced: return - msg = self.doctree.reporter.info( + msg = self.document.reporter.info( 'Indirect hyperlink target id="%s" is not referenced.' % id) - self.doctree.messages += msg + self.document.messages += msg target.referenced = 1 return delatt = 'refid' @@ -277,19 +264,19 @@ class Hyperlinks(Transform): direct external """ - for target in self.doctree.external_targets: + for target in self.document.external_targets: if target.hasattr('refuri') and target.hasattr('name'): name = target['name'] refuri = target['refuri'] try: - reflist = self.doctree.refnames[name] + reflist = self.document.refnames[name] except KeyError, instance: if target.referenced: continue - msg = self.doctree.reporter.info( + msg = self.document.reporter.info( 'External hyperlink target "%s" is not referenced.' % name) - self.doctree.messages += msg + self.document.messages += msg target.referenced = 1 continue for ref in reflist: @@ -317,21 +304,21 @@ class Hyperlinks(Transform): direct internal """ - for target in self.doctree.internal_targets: + for target in self.document.internal_targets: if target.hasattr('refuri') or target.hasattr('refid') \ or not target.hasattr('name'): continue name = target['name'] refid = target['id'] try: - reflist = self.doctree.refnames[name] + reflist = self.document.refnames[name] except KeyError, instance: if target.referenced: continue - msg = self.doctree.reporter.info( + msg = self.document.reporter.info( 'Internal hyperlink target "%s" is not referenced.' % name) - self.doctree.messages += msg + self.document.messages += msg target.referenced = 1 continue for ref in reflist: @@ -352,7 +339,7 @@ class ChainedTargetResolver(nodes.NodeVisitor): "point to" an external or indirect target. After the transform, all chained targets will effectively point to the same place. - Given the following ``doctree`` as input:: + Given the following ``document`` as input:: @@ -365,7 +352,7 @@ class ChainedTargetResolver(nodes.NodeVisitor): - ``ChainedTargetResolver(doctree).walk()`` will transform the above into:: + ``ChainedTargetResolver(document).walk()`` will transform the above into:: @@ -385,10 +372,10 @@ class ChainedTargetResolver(nodes.NodeVisitor): def visit_target(self, node): if node.hasattr('refuri'): attname = 'refuri' - call_if_named = self.doctree.note_external_target + call_if_named = self.document.note_external_target elif node.hasattr('refname'): attname = 'refname' - call_if_named = self.doctree.note_indirect_target + call_if_named = self.document.note_indirect_target elif node.hasattr('refid'): attname = 'refid' call_if_named = None @@ -414,7 +401,7 @@ class Footnotes(Transform): Assign numbers to autonumbered footnotes, and resolve links to footnotes, citations, and their references. - Given the following ``doctree`` as input:: + Given the following ``document`` as input:: @@ -491,8 +478,8 @@ class Footnotes(Transform): def transform(self): self.autofootnote_labels = [] - startnum = self.doctree.autofootnote_start - self.doctree.autofootnote_start = self.number_footnotes(startnum) + 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() @@ -504,58 +491,58 @@ class Footnotes(Transform): For labeled autonumbered footnotes, copy the number over to corresponding footnote references. """ - for footnote in self.doctree.autofootnotes: + for footnote in self.document.autofootnotes: while 1: label = str(startnum) startnum += 1 - if not self.doctree.explicit_targets.has_key(label): + if not self.document.explicit_targets.has_key(label): break footnote.insert(0, nodes.label('', label)) if footnote.hasattr('dupname'): continue if footnote.hasattr('name'): name = footnote['name'] - for ref in self.doctree.footnote_refs.get(name, []): + for ref in self.document.footnote_refs.get(name, []): ref += nodes.Text(label) ref.delattr('refname') ref['refid'] = footnote['id'] footnote.add_backref(ref['id']) - self.doctree.note_refid(ref) + self.document.note_refid(ref) ref.resolved = 1 else: footnote['name'] = label - self.doctree.note_explicit_target(footnote, footnote) + 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.doctree.autofootnote_refs: + 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.doctree.reporter.error( + msg = self.document.reporter.error( 'Too many autonumbered footnote references: only %s ' 'corresponding footnotes available.' % len(self.autofootnote_labels)) - msgid = self.doctree.set_id(msg) - self.doctree.messages += msg - for ref in self.doctree.autofootnote_refs[i:]: + msgid = self.document.set_id(msg) + self.document.messages += 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.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) break ref += nodes.Text(label) - footnote = self.doctree.explicit_targets[label] + footnote = self.document.explicit_targets[label] ref['refid'] = footnote['id'] - self.doctree.note_refid(ref) + self.document.note_refid(ref) footnote.add_backref(ref['id']) ref.resolved = 1 i += 1 @@ -563,36 +550,36 @@ class Footnotes(Transform): def symbolize_footnotes(self): """Add symbols indexes to "[*]"-style footnotes and references.""" labels = [] - for footnote in self.doctree.symbol_footnotes: - reps, index = divmod(self.doctree.symbol_footnote_start, + 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.doctree.symbol_footnote_start += 1 - self.doctree.set_id(footnote) + self.document.symbol_footnote_start += 1 + self.document.set_id(footnote) i = 0 - for ref in self.doctree.symbol_footnote_refs: + for ref in self.document.symbol_footnote_refs: try: ref += nodes.Text(labels[i]) except IndexError: - msg = self.doctree.reporter.error( + msg = self.document.reporter.error( 'Too many symbol footnote references: only %s ' 'corresponding footnotes available.' % len(labels)) msgid = self.set_id(msg) - self.doctree.messages += msg - for ref in self.doctree.symbol_footnote_refs[i:]: + self.document.messages += 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.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) break - footnote = self.doctree.symbol_footnotes[i] + footnote = self.document.symbol_footnotes[i] ref['refid'] = footnote['id'] - self.doctree.note_refid(ref) + self.document.note_refid(ref) footnote.add_backref(ref['id']) i += 1 @@ -600,15 +587,15 @@ class Footnotes(Transform): """ Link manually-labeled footnotes and citations to/from their references. """ - for footnote in self.doctree.footnotes: + for footnote in self.document.footnotes: label = footnote['name'] - if self.doctree.footnote_refs.has_key(label): - reflist = self.doctree.footnote_refs[label] + if self.document.footnote_refs.has_key(label): + reflist = self.document.footnote_refs[label] self.resolve_references(footnote, reflist) - for citation in self.doctree.citations: + for citation in self.document.citations: label = citation['name'] - if self.doctree.citation_refs.has_key(label): - reflist = self.doctree.citation_refs[label] + if self.document.citation_refs.has_key(label): + reflist = self.document.citation_refs[label] self.resolve_references(citation, reflist) def resolve_references(self, note, reflist): @@ -626,7 +613,7 @@ class Footnotes(Transform): class Substitutions(Transform): """ - Given the following ``doctree`` as input:: + Given the following ``document`` as input:: @@ -652,19 +639,19 @@ class Substitutions(Transform): """ def transform(self): - defs = self.doctree.substitution_defs - for refname, refs in self.doctree.substitution_refs.items(): + defs = self.document.substitution_defs + for refname, refs in self.document.substitution_refs.items(): for ref in refs: if defs.has_key(refname): ref.parent.replace(ref, defs[refname].getchildren()) else: - msg = self.doctree.reporter.error( + msg = self.document.reporter.error( 'Undefined substitution referenced: "%s".' % refname) - msgid = self.doctree.set_id(msg) - self.doctree.messages += msg + msgid = self.document.set_id(msg) + self.document.messages += msg prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) - prbid = self.doctree.set_id(prb) + prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) - self.doctree.substitution_refs = None # release replaced references + self.document.substitution_refs = None # release replaced references diff --git a/docutils/utils.py b/docutils/utils.py index a92c8fb97..0602b8d64 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -12,9 +12,10 @@ Miscellaneous utilities for the documentation utilities. import sys, re import nodes +from docutils import ApplicationError, DataError -class SystemMessage(Exception): +class SystemMessage(ApplicationError): def __init__(self, system_message): Exception.__init__(self, system_message.astext()) @@ -59,15 +60,15 @@ class Reporter: levels = 'DEBUG INFO WARNING ERROR SEVERE'.split() """List of names for system message levels, indexed by level.""" - def __init__(self, warninglevel, errorlevel, stream=None, debug=0): + def __init__(self, warning_level, error_level, stream=None, debug=0): """ Initialize the `ConditionSet` forthe `Reporter`'s default category. :Parameters: - - `warninglevel`: The level at or above which warning output will + - `warning_level`: The level at or above which warning output will be sent to `stream`. - - `errorlevel`: The level at or above which `SystemMessage` + - `error_level`: The level at or above which `SystemMessage` exceptions will be raised. - `debug`: Show debug (level=0) system messages? - `stream`: Where warning output is sent (`None` implies @@ -77,29 +78,29 @@ class Reporter: if stream is None: stream = sys.stderr - self.categories = {'': ConditionSet(debug, warninglevel, errorlevel, + self.categories = {'': ConditionSet(debug, warning_level, error_level, stream)} """Mapping of category names to conditions. Default category is ''.""" - def setconditions(self, category, warninglevel, errorlevel, - stream=None, debug=0): + def set_conditions(self, category, warning_level, error_level, + stream=None, debug=0): if stream is None: stream = sys.stderr - self.categories[category] = ConditionSet(debug, warninglevel, - errorlevel, stream) + self.categories[category] = ConditionSet(debug, warning_level, + error_level, stream) - def unsetconditions(self, category): + def unset_conditions(self, category): if category and self.categories.has_key(category): del self.categories[category] - __delitem__ = unsetconditions + __delitem__ = unset_conditions - def getconditions(self, category): + def get_conditions(self, category): while not self.categories.has_key(category): category = category[:category.rfind('.') + 1][:-1] return self.categories[category] - __getitem__ = getconditions + __getitem__ = get_conditions def system_message(self, level, comment=None, category='', *children, **attributes): @@ -111,13 +112,13 @@ class Reporter: msg = nodes.system_message(comment, level=level, type=self.levels[level], *children, **attributes) - debug, warninglevel, errorlevel, stream = self[category].astuple() - if level >= warninglevel or debug and level == 0: + debug, warning_level, error_level, stream = self[category].astuple() + if level >= warning_level or debug and level == 0: if category: print >>stream, 'Reporter "%s":' % category, msg.astext() else: print >>stream, 'Reporter:', msg.astext() - if level >= errorlevel: + if level >= error_level: raise SystemMessage(msg) return msg @@ -171,18 +172,18 @@ class ConditionSet: category. """ - def __init__(self, debug, warninglevel, errorlevel, stream): + def __init__(self, debug, warning_level, error_level, stream): self.debug = debug - self.warninglevel = warninglevel - self.errorlevel = errorlevel + self.warning_level = warning_level + self.error_level = error_level self.stream = stream def astuple(self): - return (self.debug, self.warninglevel, self.errorlevel, + return (self.debug, self.warning_level, self.error_level, self.stream) -class ExtensionAttributeError(Exception): pass +class ExtensionAttributeError(DataError): pass class BadAttributeError(ExtensionAttributeError): pass class BadAttributeDataError(ExtensionAttributeError): pass class DuplicateAttributeError(ExtensionAttributeError): pass @@ -272,7 +273,7 @@ def assemble_attribute_dict(attlist, attspec): return attributes -class NameValueError(Exception): pass +class NameValueError(DataError): pass def extract_name_value(line): @@ -320,7 +321,7 @@ def extract_name_value(line): return attlist -def normname(name): +def normalize_name(name): """Return a case- and whitespace-normalized name.""" return ' '.join(name.lower().split()) @@ -359,15 +360,24 @@ def id(string): .. _HTML 4.01 spec: http://www.w3.org/TR/html401 .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 """ - id = non_id_chars.sub('-', normname(string)) + id = non_id_chars.sub('-', normalize_name(string)) id = non_id_at_ends.sub('', id) return str(id) non_id_chars = re.compile('[^a-z0-9]+') non_id_at_ends = re.compile('^[-0-9]+|-+$') -def newdocument(languagecode='en', warninglevel=2, errorlevel=4, - stream=None, debug=0): - reporter = Reporter(warninglevel, errorlevel, stream, debug) - document = nodes.document(languagecode=languagecode, reporter=reporter) +def new_document(language_code='en', warning_level=2, error_level=4, + stream=None, debug=0): + reporter = Reporter(warning_level, error_level, stream, debug) + document = nodes.document(language_code=language_code, reporter=reporter) return document + +def clean_rcs_keywords(paragraph, keyword_substitutions): + if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): + textnode = paragraph[0] + for pattern, substitution in keyword_substitutions: + match = pattern.match(textnode.data) + if match: + textnode.data = pattern.sub(substitution, textnode.data) + return diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 6d9d7c226..0f560e7ee 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -14,11 +14,11 @@ __docformat__ = 'reStructuredText' import sys -from docutils import languages +from docutils import languages, Component from docutils.transforms import universal -class Writer: +class Writer(Component): """ Abstract base class for docutils Writers. @@ -49,7 +49,7 @@ class Writer: def write(self, document, destination): self.document = document - self.language = languages.getlanguage(document.languagecode) + self.language = languages.getlanguage(document.language_code) self.destination = destination self.transform() self.translate() @@ -60,7 +60,7 @@ class Writer: for xclass in (universal.first_writer_transforms + tuple(self.transforms) + universal.last_writer_transforms): - xclass(self.document).transform() + xclass(self.document, self).transform() def translate(self): """Override to do final document tree translation.""" @@ -93,12 +93,14 @@ class Writer: _writer_aliases = { - 'html': 'html4css1',} - -def get_writer_class(writername): - """Return the Writer class from the `writername` module.""" - writername = writername.lower() - if _writer_aliases.has_key(writername): - writername = _writer_aliases[writername] - module = __import__(writername, globals(), locals()) + 'html': 'html4css1', + 'pprint': 'pseudoxml', + 'pformat': 'pseudoxml',} + +def get_writer_class(writer_name): + """Return the Writer class from the `writer_name` module.""" + writer_name = writer_name.lower() + if _writer_aliases.has_key(writer_name): + writer_name = _writer_aliases[writer_name] + module = __import__(writer_name, globals(), locals()) return module.Writer -- cgit v1.2.1 From 7dca77f3557441e3579aaba28e4d083615b549eb Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:39:21 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@87 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/pysource.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/pysource.dtd b/docs/dev/pysource.dtd index 463844a68..1a1aa6e8b 100644 --- a/docs/dev/pysource.dtd +++ b/docs/dev/pysource.dtd @@ -92,7 +92,7 @@ http://docutils.sourceforge.net/spec/docutils.dtd. - -- cgit v1.2.1 From b93e27dd4509f9f73df3568cf8a4ee2cd4dbf010 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:42:03 +0000 Subject: Support for PEP extensions to reStructuredText. General improvements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@88 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 54 ++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 6fb710cd0..3b883d49b 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -36,6 +36,7 @@ from docutils import statemachine, nodes, urischemes, utils, transforms from docutils.transforms import universal from docutils.parsers import rst from docutils.parsers.rst import states, tableparser, directives, languages +from docutils.readers import pep from docutils.statemachine import string2lines try: @@ -229,15 +230,19 @@ class TransformTestCase(CustomTestCase): del kwargs['transforms'], kwargs['parser'] # only wanted here CustomTestCase.__init__(self, *args, **kwargs) + def supports(self, format): + return 1 + def test_transforms(self): if self.runInDebugger: pdb.set_trace() - doctree = utils.newdocument(warninglevel=5, errorlevel=5, - debug=package_unittest.debug) - self.parser.parse(self.input, doctree) + document = utils.new_document(warning_level=1, error_level=5, + debug=package_unittest.debug, + stream=DevNull()) + self.parser.parse(self.input, document) for transformClass in (self.transforms + universal.test_transforms): - transformClass(doctree).transform() - output = doctree.pformat() + transformClass(document, self).transform() + output = document.pformat() self.compareOutput(self.input, output, self.expected) def test_transforms_verbosely(self): @@ -246,14 +251,15 @@ class TransformTestCase(CustomTestCase): print '\n', self.id print '-' * 70 print self.input - doctree = utils.newdocument(warninglevel=5, errorlevel=5, - debug=package_unittest.debug) - self.parser.parse(self.input, doctree) + document = utils.new_document(warning_level=1, error_level=5, + debug=package_unittest.debug, + stream=DevNull()) + self.parser.parse(self.input, document) print '-' * 70 - print doctree.pformat() + print document.pformat() for transformClass in self.transforms: - transformClass(doctree).transform() - output = doctree.pformat() + transformClass(document).transform() + output = document.pformat() print '-' * 70 print output self.compareOutput(self.input, output, self.expected) @@ -275,8 +281,8 @@ class ParserTestCase(CustomTestCase): def test_parser(self): if self.runInDebugger: pdb.set_trace() - document = utils.newdocument(warninglevel=5, errorlevel=5, - debug=package_unittest.debug) + document = utils.new_document(warning_level=5, error_level=5, + debug=package_unittest.debug) self.parser.parse(self.input, document) output = document.pformat() self.compareOutput(self.input, output, self.expected) @@ -320,19 +326,19 @@ class ParserTestSuite(CustomTestSuite): runInDebugger=runInDebugger) -class RFC2822ParserTestCase(ParserTestCase): +class PEPParserTestCase(ParserTestCase): - """RFC2822-specific parser test case.""" + """PEP-specific parser test case.""" - parser = rst.Parser(rfc2822=1) - """Parser shared by all RFC2822ParserTestCases.""" + parser = rst.Parser(rfc2822=1, inliner=pep.Inliner()) + """Parser shared by all PEPParserTestCases.""" -class RFC2822ParserTestSuite(ParserTestSuite): +class PEPParserTestSuite(ParserTestSuite): - """A collection of RFC2822ParserTestCases.""" + """A collection of PEPParserTestCases.""" - test_case_class = RFC2822ParserTestCase + test_case_class = PEPParserTestCase class TableParserTestSuite(CustomTestSuite): @@ -397,3 +403,11 @@ class TableParserTestCase(CustomTestCase): output = '%s: %s' % (details.__class__.__name__, details) self.compareOutput(self.input, pformat(output) + '\n', pformat(self.expected) + '\n') + + +class DevNull: + + """Output sink.""" + + def write(self, string): + pass -- cgit v1.2.1 From 569e668836d3f1d6e0337424070adca325690a7a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:44:00 +0000 Subject: PEP testing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@89 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_readers/test_pep/__init__.py | 12 + test/test_readers/test_pep/test_inline_markup.py | 120 ++++++++++ test/test_readers/test_pep/test_rfc2822.py | 267 +++++++++++++++++++++++ 3 files changed, 399 insertions(+) create mode 100644 test/test_readers/test_pep/__init__.py create mode 100644 test/test_readers/test_pep/test_inline_markup.py create mode 100644 test/test_readers/test_pep/test_rfc2822.py diff --git a/test/test_readers/test_pep/__init__.py b/test/test_readers/test_pep/__init__.py new file mode 100644 index 000000000..8df5d4778 --- /dev/null +++ b/test/test_readers/test_pep/__init__.py @@ -0,0 +1,12 @@ +import os, os.path, sys + +sys.path.insert(0, os.path.abspath(os.curdir)) +prev = '' +while sys.path[0] != prev: + try: + import DocutilsTestSupport + break + except ImportError: + prev = sys.path[0] + sys.path[0] = os.path.dirname(prev) +sys.path.pop(0) diff --git a/test/test_readers/test_pep/test_inline_markup.py b/test/test_readers/test_pep/test_inline_markup.py new file mode 100644 index 000000000..a0d19b9fa --- /dev/null +++ b/test/test_readers/test_pep/test_inline_markup.py @@ -0,0 +1,120 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for inline markup in PEPs (readers/pep.py). +""" + +from __init__ import DocutilsTestSupport + + +def suite(): + s = DocutilsTestSupport.PEPParserTestSuite() + s.generateTests(totest) + return s + + +totest = {} + +totest['standalone_references'] = [ +["""\ +See PEP 287 (pep-0287.txt), +and RFC 2822 (which obsoletes RFC822 and RFC-733). +""", +"""\ + + + See \n\ + + PEP 287 + ( + + pep-0287.txt + ), + and \n\ + + RFC 2822 + (which obsoletes \n\ + + RFC822 + and \n\ + + RFC-733 + ). +"""], +["""\ +References split across lines: + +PEP +287 + +RFC +2822 +""", +"""\ + + + References split across lines: + + + PEP + 287 + + + RFC + 2822 +"""], +] + +totest['miscellaneous'] = [ +["""\ +For *completeness*, _`let's` ``test`` **other** forms_ +|of| `inline markup` [*]_. + +.. [*] See http://docutils.sf.net/spec/rst/reStructuredText.html. +""", +"""\ + + + For \n\ + + completeness + , \n\ + + let's + \n\ + + test + \n\ + + other + \n\ + + forms + \n\ + + of + \n\ + + inline markup + \n\ + + . + + + See \n\ + + http://docutils.sf.net/spec/rst/reStructuredText.html + . +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_readers/test_pep/test_rfc2822.py b/test/test_readers/test_pep/test_rfc2822.py new file mode 100644 index 000000000..818e66412 --- /dev/null +++ b/test/test_readers/test_pep/test_rfc2822.py @@ -0,0 +1,267 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for RFC-2822 headers in PEPs (readers/pep.py). +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.PEPParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['rfc2822'] = [ +["""\ +Author: Me +Version: 1 +Date: 2002-04-23 +""", +"""\ + + + + + Author + + + Me + + + Version + + + 1 + + + Date + + + 2002-04-23 +"""], +["""\ + + +Author: Me +Version: 1 +Date: 2002-04-23 + +.. Leading blank lines don't affect RFC-2822 header parsing. +""", +"""\ + + + + + Author + + + Me + + + Version + + + 1 + + + Date + + + 2002-04-23 + + Leading blank lines don't affect RFC-2822 header parsing. +"""], +["""\ +.. A comment should prevent RFC-2822 header parsing. + +Author: Me +Version: 1 +Date: 2002-04-23 +""", +"""\ + + + A comment should prevent RFC-2822 header parsing. + + Author: Me + Version: 1 + Date: 2002-04-23 +"""], +["""\ +Author: Me + +Version: 1 +Date: 2002-04-23 +""", +"""\ + + + + + Author + + + Me + + Version: 1 + Date: 2002-04-23 +"""], +["""\ +field: +empty item above, no blank line +""", +"""\ + + + + + field + + + + RFC2822-style field list ends without a blank line; unexpected unindent at line 2. + + empty item above, no blank line +"""], +["""\ +Author: + Me +Version: + 1 +Date: + 2002-04-23 +""", +"""\ + + + + + Author + + + Me + + + Version + + + 1 + + + Date + + + 2002-04-23 +"""], +["""\ +Authors: Me, + Myself, + and I +Version: 1 + or so +Date: 2002-04-23 + (Tuesday) +""", +"""\ + + + + + Authors + + + Me, + Myself, + and I + + + Version + + + 1 + or so + + + Date + + + 2002-04-23 + (Tuesday) +"""], +["""\ +Authors: Me, + Myself, + and I +Version: 1 + or so +Date: 2002-04-23 + (Tuesday) +""", +"""\ + + + + + Authors + + + Me, + Myself, + and I + + + Version + + + 1 + or so + + + Date + + + 2002-04-23 + (Tuesday) +"""], +["""\ +Authors: - Me + - Myself + - I +Version: +""", +"""\ + + + + + Authors + + + + + Me + + + Myself + + + I + + + Version + +"""], +] + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From a0dbdc530bf765483479cf989752b8ea131549c7 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:46:38 +0000 Subject: moved from test_rst to test_pep git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@90 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_rfc2822.py | 260 ----------------------------- 1 file changed, 260 deletions(-) delete mode 100755 test/test_parsers/test_rst/test_rfc2822.py diff --git a/test/test_parsers/test_rst/test_rfc2822.py b/test/test_parsers/test_rst/test_rfc2822.py deleted file mode 100755 index 754c47586..000000000 --- a/test/test_parsers/test_rst/test_rfc2822.py +++ /dev/null @@ -1,260 +0,0 @@ -#! /usr/bin/env python - -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -Tests for states.py. -""" - -from __init__ import DocutilsTestSupport - -def suite(): - s = DocutilsTestSupport.RFC2822ParserTestSuite() - s.generateTests(totest) - return s - -totest = {} - -totest['rfc2822'] = [ -["""\ -Author: Me -Version: 1 -Date: 2002-04-23 -""", -"""\ - - - - - Author - - - Me - - - Version - - - 1 - - - Date - - - 2002-04-23 -"""], -["""\ -Author: Me -Version: 1 -Date: 2002-04-23 - -Leading blank lines don't affect RFC-2822 header parsing. -""", -"""\ - - - - - Author - - - Me - - - Version - - - 1 - - - Date - - - 2002-04-23 - - Leading blank lines don't affect RFC-2822 header parsing. -"""], -["""\ -.. A comment should prevent RFC-2822 header parsing. - -Author: Me -Version: 1 -Date: 2002-04-23 -""", -"""\ - - - A comment should prevent RFC-2822 header parsing. - - Author: Me - Version: 1 - Date: 2002-04-23 -"""], -["""\ -Author: Me - -Version: 1 -Date: 2002-04-23 -""", -"""\ - - - - - Author - - - Me - - Version: 1 - Date: 2002-04-23 -"""], -["""\ -field: -empty item above, no blank line -""", -"""\ - - - - - field - - - - RFC2822-style field list ends without a blank line; unexpected unindent at line 2. - - empty item above, no blank line -"""], -["""\ -Author: - Me -Version: - 1 -Date: - 2002-04-23 -""", -"""\ - - - - - Author - - - Me - - - Version - - - 1 - - - Date - - - 2002-04-23 -"""], -["""\ -Authors: Me, - Myself, - and I -Version: 1 - or so -Date: 2002-04-23 - (Tuesday) -""", -"""\ - - - - - Authors - - - Me, - Myself, - and I - - - Version - - - 1 - or so - - - Date - - - 2002-04-23 - (Tuesday) -"""], -["""\ -Authors: Me, - Myself, - and I -Version: 1 - or so -Date: 2002-04-23 - (Tuesday) -""", -"""\ - - - - - Authors - - - Me, - Myself, - and I - - - Version - - - 1 - or so - - - Date - - - 2002-04-23 - (Tuesday) -"""], -["""\ -Authors: - Me - - Myself - - I -""", -"""\ - - - - - Authors - - - - - Me - - - Myself - - - I -"""], -] - -if __name__ == '__main__': - import unittest - unittest.main(defaultTest='suite') -- cgit v1.2.1 From 34f7a6d1ac6f52cf920a933aba804f54c7be5525 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 5 May 2002 15:49:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@91 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 190 ++++++++++++--------- docs/peps/pep-0258.txt | 16 +- test/test_nodes.py | 33 +++- .../test_rst/test_directives/test_contents.py | 32 ++-- .../test_rst/test_directives/test_figures.py | 2 +- .../test_rst/test_directives/test_meta.py | 78 +++++++-- test/test_statemachine.py | 171 +++++++++---------- test/test_transforms/test_contents.py | 48 +++++- test/test_transforms/test_final_checks.py | 2 +- test/test_transforms/test_messages.py | 4 +- test/test_transforms/test_substitutions.py | 4 +- test/test_utils.py | 31 ++-- tools/quicktest.py | 2 +- 13 files changed, 385 insertions(+), 228 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5c87d280d..c262f6509 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -9,6 +9,9 @@ To Do ===== +Priority items are marked with "@" symbols. The more @s, the higher +the priority. + General ------- @@ -33,9 +36,6 @@ General checked for correctness and refactored. I'm afraid it's a bit of a spaghetti mess now. - - Change application error exceptions to use "StandardError" as - their base class instead of "Exception". - - Add validation? See http://pytrex.sourceforge.net, RELAX NG. - Ask Python-dev for opinions (GvR for a pronouncement) on special @@ -43,11 +43,6 @@ General pollution. Ask opinions on whether or not Docutils should recognize & use them. -- Provide a mechanism to pass options to Readers, Writers, and Parsers - through docutils.core.publish/Publisher? Or create custom - Reader/Writer/Parser objects first, and pass *them* to - publish/Publisher? - - In reader.get_reader_class (& parser & writer too), should we be importing 'standalone' or 'docutils.readers.standalone'? (This would avoid importing top-level modules if the module name is not in @@ -57,16 +52,14 @@ General permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) -- The "Docutils System Messages" section appears even if no actual - system messages are there. They must be below the threshold. The - transform should be fixed. - -- TOC transform: use alt-text for inline images. +- @@@ Implement a PEP reader. -- Implement a PEP reader. +- @@ Add support for character set encodings on input & output, Unicode + internally. -- Add support for character set encodings on input & output, Unicode - internally. Need a Unicode -> HTML entities codec for HTML writer? + - Use an "encoding" directive, and/or an "encoding" field in field + lists & PEP headers. (The same could apply to "language".) + - Need a Unicode -> HTML entities codec for HTML writer? Specification @@ -101,8 +94,8 @@ reStructuredText Parser - And for the sake of completeness, should definition list terms be allowed to be very long (two or more lines) also? -- Allow hyperlink references to targets in other documents? Not in an - HTML-centric way, though (it's trivial to say +- Support generic hyperlink references to targets in other documents? + Not in an HTML-centric way, though (it's trivial to say ``http://www.whatever.com/doc#name``, and useless in non-HTML contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. @@ -176,18 +169,9 @@ reStructuredText Parser the left edge of the first line if it began on the same line as the field name. -- Allow syntax constructs to be added or disabled at run-time. - - Make footnotes two-way, GNU-style? What if there are multiple references to a single footnote? -- Add RFC-2822 header parsing (for PEP, email Readers). - -- Change ``.. meta::`` to use a "pending" element, only activated for - HTML writers (done). Add reader/writer/parser attributes to pending - elements (done). Figure out a way for transforms to know what - reader/writer is in control (@@@ in docutils.transforms.components). - - Allow for variant styles by interpreting indented lists as if they weren't indented? For example, currently the list below will be parsed as a list within a block quote:: @@ -213,8 +197,11 @@ reStructuredText Parser See the Doc-SIG discussion starting 2001-04-18 with Ed Loper's "Structuring: a summary; and an attempt at EBNF", item 4. -- Make the parser modular. Be able to turn on/off constructs, add - them at run time. Or is subclassing enough? +- Make the parser modular. Allow syntax constructs to be added or + disabled at run-time. Or is subclassing enough? + +- Continue to report (info, level 1) enumerated lists whose start + value is not ordinal-1? Directives @@ -228,41 +215,99 @@ Directives - Implement directives: - - html.imagemap + - html.imagemap (Useful outside of HTML? If not, replace with image + only in non-HTML writers?) - - components.endnotes, .citations, .topic, .sectnum (section - numbering; add support to .contents; could be cmdline option also) + - parts.endnotes, .citations, .topic, .sectnum (section numbering; + add support to .contents; could be cmdline option also) - misc.raw - - misc.include: ``#include`` one file in another. But how to - parse wrt sections, reference names, conflicts? + - misc.include: ``#include`` one file in another. But how to parse + wrt sections, reference names, conflicts? Parse it in the current + document's context (C-preprocessor semantics), or separately and + then merge? + + Use C-preprocessor semantics for locating include files? E.g., + ``.. include:: file.txt`` will read another file into the current + one, relative to the current file's directory, and ``.. include:: + `` will read a standard include file from + ``docutils/include/``. (Should "quotes" be required around + non-standard include files?) - misc.exec: Execute Python code & insert the results. Perhaps dangerous? - misc.eval: Evaluate an expression & insert the text. At parse - time or at substitution time? + time or at substitution time? Dangerous? Perhaps limit to canned + macros; see text.date_ below. + + - @@@ body.qa/faq/questions: Questions & Answers. Implement as a + generic two-column marked list? As a standalone (non-directive) + construct? (Is the markup ambiguous?) Add support to + parts.Contents (optional attribute "qa" done). - - block.qa: Questions & Answers. Implement as a generic two-column - marked list? Or as a standalone construct? + New elements would be required. Perhaps:: - - block.columns: Multi-column table/list, with number of columns as + + + + + + + - body.columns: Multi-column table/list, with number of columns as argument. - - block.verse: Paragraphs with linebreaks preserved. A directive - would be easy; what about a literal-block-like prefix, perhaps - ';;'? E.g.:: + - body.verse: Paragraphs with linebreaks preserved, *and* inline + markup support too. A directive would be easy; what about a + literal-block-like prefix, perhaps ';;'? (It's a semi-literal + block, after all.) Example:: + + Take it away, Eric the Orchestra Leader! ;; + + A one, two, a one two three four + + Half a bee, philosophically, + must, *ipso facto*, half not be. + But half the bee has got to be, + *vis a vis* its entity. D'you see? + + But can a bee be said to be + or not to be an entire bee, + when half the bee is not a bee, + due to some ancient injury? - Take it away, Eric the orchestra leader! ;; + Singing... - Half a bee, - Philosophically, - Must ipso-facto - Half not be. - You see? + New elements would be required. Perhaps:: - ... + + + + + We could get away without "line" elements, treating line breaks + within "stanzas" as significant. But explicit is perhaps better + than implicit. + + Within a "verse" element, should any other constructs be allowed? + Should lists be recognized? The equivalent of block quotes (i.e., + further indented blocks) would be nested verse elements. These + could be "chorus" blocks. + + Perhaps individually indented "continuation lines" should also be + recognized (maybe with a "continuation" attribute on the "line" + element, or significant whitespace in a single "line"):: + + "To Ma Own Beloved Lassie: A Poem on her 17th Birthday", by + Ewan McTeagle (for Lassie O'Shea): ;; + + Lend us a couple of bob till Thursday. + I'm absolutely stint. + But I'm expecting a postal order and I can pay you back + as soon as it comes. + Love, Ewan. - colorize.python: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need @@ -271,9 +316,15 @@ Directives use. Use a factory function "transformFF()" which returns either "HTMLTransform()" instance or "GenericTransform" instance? - - text.date: Datestamp. For substitutions. + - _`text.date`: Datestamp. For substitutions. + + - Combined with misc.include, implement canned macros? E.g.:: + + .. include:: + + Today's date is |date|. - - Combined with misc.include, implement canned macros? + Where "macros" contains ``.. |date| date::``, among others. Unimplemented Transforms @@ -322,37 +373,17 @@ Unimplemented Transforms HTML Writer ----------- -- Considerations for an HTML Writer [#]_: +- @@ Allow for style sheet info to be passed in, either as a , + or as embedded style info. - - Boolean attributes. ```` is good, ```` is bad. Use a special value in attribute - mappings, such as ``None``? +- @ Construct a templating system, as in ht2html/yaptu, using + directives and substitutions for dynamic stuff. - - Escape double-dashes inside comments. - - - Put the language code into an appropriate element's LANG - attribute (?). - - - Docutils identifiers (the "class" and "id" attributes) will - conform to the regular expression ``[a-z][-a-z0-9]*``. See - ``docutils.utils.id()``. - - .. [#] Source: `HTML 4.0 in Netscape and Explorer`__. - __ http://www.webreference.com/dev/html4nsie/index.html - -- Allow for style sheet info to be passed in, either as a , or - as embedded style info. - -- Construct a templating system, as in ht2html/yaptu, using directives - and substitutions for dynamic stuff. - -- Improve the granularity of document parts in the HTML writer, so +- @@ Improve the granularity of document parts in the HTML writer, so that one could just grab the parts needed. -- Return a string instead of writing to a file? Leave all I/O up to - the client? - -- Use lowercase element & attribute names for XHTML compatibility? +- @@ Return a string instead of writing to a file? Leave all I/O up + to the client? Or up to an explicit distributor/filer? Coding Conventions @@ -367,13 +398,14 @@ PEPs, with the following clarifications: lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is O.K.). - Lines should be no more than 78 or 79 characters long. -- "CamelCase" shall be used for class names. +- "CamelCase" shall be used for class names (except for element + classes in docutils.nodes). - Use "lowercase" or "lowercase_with_underscores" for function, method, and variable names. For short names, maximum two joined words, use lowercase (e.g. 'tagname'). For long names with three or more joined words, or where it's hard to parse the split between two words, use lowercase_with_underscores (e.g., 'note_explicit_target', - 'explicit_target'). + 'explicit_target'). If in doubt, use underscores. __ http://www.python.org/peps/pep-0008.html __ http://www.python.org/peps/pep-0257.html diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index cf7fbb6a6..e760a9123 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -282,6 +282,11 @@ Specification method passes its input to its Reader, then passes the resulting document tree through its Writer to its destination. + Calling the "publish" function (or instantiating a "Publisher" + object) with component names will result in default behavior. For + custom behavior (setting component options), create custom + component objects first, and pass *them* to publish/Publisher. + Readers ------- @@ -441,7 +446,8 @@ Specification require anything other than monolithic output. Perhaps merge the HTML "distributor" into "writer" variants? - Perhaps translator/writer instead of writer/distributor? + Perhaps translator/writer instead of writer/distributor? Or + "filer" instead of "distributor"? Responsibilities: @@ -487,7 +493,7 @@ Specification - Package "docutils.parsers": markup parsers_. - - Function "get_parser_class(parsername)" returns a parser + - Function "get_parser_class(parser_name)" returns a parser module by name. Class "Parser" is the base class of specific parsers. (docutils/parsers/__init__.py) @@ -497,7 +503,7 @@ Specification - Package "docutils.readers": context-aware input readers. - - Function "get_reader_class(readername)" returns a reader + - Function "get_reader_class(reader_name)" returns a reader module by name or alias. Class "Reader" is the base class of specific readers. (docutils/readers/__init__.py) @@ -509,11 +515,11 @@ Specification - Package "docutils.writers": output format writers. - - Function "get_writer_class(writername)" returns a writer + - Function "get_writer_class(writer_name)" returns a writer module by name. Class "Writer" is the base class of specific writers. (docutils/writers/__init__.py) - - Module "docutils.writers.pprint" is a simple internal + - Module "docutils.writers.pseudoxml" is a simple internal document tree writer; it writes indented pseudo-XML. - Module "docutils.writers.html4css1" is a simple HyperText diff --git a/test/test_nodes.py b/test/test_nodes.py index 15e633357..1d813b142 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -11,7 +11,7 @@ Test module for nodes.py. """ import unittest -from DocutilsTestSupport import nodes +from DocutilsTestSupport import nodes, utils debug = 0 @@ -79,5 +79,36 @@ class ElementTests(unittest.TestCase): """) +class TreeCopyVisitorTests(unittest.TestCase): + + def setUp(self): + document = utils.new_document() + document += nodes.paragraph('', 'Paragraph 1.') + blist = nodes.bullet_list() + for i in range(1, 6): + item = nodes.list_item() + for j in range(1, 4): + item += nodes.paragraph('', 'Item %s, paragraph %s.' % (i, j)) + blist += item + document += blist + self.document = document + + def compare_trees(self, one, two): + self.assertEquals(one.__class__, two.__class__) + self.assertNotEquals(id(one), id(two)) + children1 = one.getchildren() + children2 = two.getchildren() + self.assertEquals(len(children1), len(children2)) + for i in range(len(children1)): + self.compare_trees(children1[i], children2[i]) + + def test_copy_whole(self): + visitor = nodes.TreeCopyVisitor(self.document) + self.document.walkabout(visitor) + newtree = visitor.get_tree_copy() + self.assertEquals(self.document.pformat(), newtree.pformat()) + self.compare_trees(self.document, newtree) + + if __name__ == '__main__': unittest.main() diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 4743798dc..452a6d222 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -7,7 +7,7 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -Tests for components.py contents directives. +Tests for parts.py contents directive. """ from __init__ import DocutilsTestSupport @@ -27,8 +27,8 @@ totest['contents'] = [ .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: title: None """], @@ -39,8 +39,8 @@ totest['contents'] = [ .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: title: @@ -54,8 +54,8 @@ totest['contents'] = [ <document> <pending> .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: title: <title> @@ -70,8 +70,8 @@ totest['contents'] = [ <document> <pending> .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: title: <title> @@ -84,14 +84,14 @@ totest['contents'] = [ <document> <pending> .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: title: <title> <emphasis> Table - of + of \n\ <literal> Contents """], @@ -104,8 +104,8 @@ totest['contents'] = [ <document> <pending> .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: depth: 2 local: None @@ -120,8 +120,8 @@ totest['contents'] = [ <document> <pending> .. internal attributes: - .transform: docutils.transforms.components.Contents - .stage: 'last_reader' + .transform: docutils.transforms.parts.Contents + .stage: 'last reader' .details: depth: 2 local: None diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index 9e488ceca..32e884932 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -80,7 +80,7 @@ totest['figures'] = [ Image URI at line 1 contains whitespace. <literal_block> .. figure:: not an image URI - + \n\ And a caption. """], ["""\ diff --git a/test/test_parsers/test_rst/test_directives/test_meta.py b/test/test_parsers/test_rst/test_directives/test_meta.py index 8cdc93bd6..55c7328a2 100755 --- a/test/test_parsers/test_rst/test_directives/test_meta.py +++ b/test/test_parsers/test_rst/test_directives/test_meta.py @@ -27,8 +27,22 @@ totest['meta'] = [ """, """\ <document> - <meta content="The reStructuredText plaintext markup language" name="description"> - <meta content="plaintext,markup language" name="keywords"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="The reStructuredText plaintext markup language" name="description"> + writer: 'html' + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="plaintext,markup language" name="keywords"> + writer: 'html' """], ["""\ .. meta:: @@ -37,8 +51,22 @@ totest['meta'] = [ """, """\ <document> - <meta content="An amusing story" lang="en" name="description"> - <meta content="Un histoire amusant" lang="fr" name="description"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="An amusing story" lang="en" name="description"> + writer: 'html' + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="Un histoire amusant" lang="fr" name="description"> + writer: 'html' """], ["""\ .. meta:: @@ -46,7 +74,14 @@ totest['meta'] = [ """, """\ <document> - <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"> + writer: 'html' """], ["""\ .. meta:: @@ -55,7 +90,14 @@ totest['meta'] = [ """, """\ <document> - <meta content="content over multiple lines" name="name"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="content over multiple lines" name="name"> + writer: 'html' """], ["""\ Paragraph @@ -67,7 +109,14 @@ Paragraph <document> <paragraph> Paragraph - <meta content="content" name="name"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="content" name="name"> + writer: 'html' """], ["""\ .. meta:: @@ -86,10 +135,9 @@ Paragraph <document> <system_message level="1" type="INFO"> <paragraph> - No content for meta tag "empty". + No content for meta tag "empty" at line 2. <literal_block> :empty: - <meta content="" name="empty"> """], ["""\ .. meta:: @@ -111,7 +159,14 @@ Paragraph """, """\ <document> - <meta content="content" name="name"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="content" name="name"> + writer: 'html' <system_message level="3" type="ERROR"> <paragraph> Invalid meta directive at line 3. @@ -128,10 +183,9 @@ Paragraph <document> <system_message level="3" type="ERROR"> <paragraph> - Error parsing meta tag attribute "notattval": missing "=" + Error parsing meta tag attribute "notattval" at line 2: missing "=". <literal_block> :name notattval: content - <meta content="content" name="name"> """], ] diff --git a/test/test_statemachine.py b/test/test_statemachine.py index a73a17197..02dd1e69b 100755 --- a/test/test_statemachine.py +++ b/test/test_statemachine.py @@ -12,11 +12,7 @@ Test module for statemachine.py. import unittest, sys, re from DocutilsTestSupport import statemachine -try: - import mypdb as pdb -except: - import pdb -pdb.tracenow = 0 + debug = 0 testtext = statemachine.string2lines("""\ @@ -36,10 +32,10 @@ First paragraph. block Last paragraph.""") -expected = ('StateMachine1 text1 blank1 bullet1 knownindent1 ' +expected = ('StateMachine1 text1 blank1 bullet1 known_indent1 ' 'StateMachine2 text2 text2 blank2 text2 blank2 indent2 ' 'StateMachine3 text3 blank3 finished3 finished2 ' - 'bullet1 knownindent1 ' + 'bullet1 known_indent1 ' 'StateMachine2 text2 blank2 literalblock2(4) finished2 ' 'text1 finished1').split() para1 = testtext[:2] @@ -54,7 +50,7 @@ class MockState(statemachine.StateWS): patterns = {'bullet': re.compile(r'- '), 'text': ''} - initialtransitions = ['bullet', ['text']] + initial_transitions = ['bullet', ['text']] levelholder = [0] def bof(self, context): @@ -63,37 +59,37 @@ class MockState(statemachine.StateWS): if self.debug: print >>sys.stderr, 'StateMachine%s' % self.level return [], ['StateMachine%s' % self.level] - def blank(self, match, context, nextstate): + def blank(self, match, context, next_state): result = ['blank%s' % self.level] if self.debug: print >>sys.stderr, 'blank%s' % self.level if context and context[-1] and context[-1][-2:] == '::': result.extend(self.literalblock()) return [], None, result - def indent(self, match, context, nextstate): + def indent(self, match, context, next_state): if self.debug: print >>sys.stderr, 'indent%s' % self.level - context, nextstate, result = statemachine.StateWS.indent( - self, match, context, nextstate) - return context, nextstate, ['indent%s' % self.level] + result + context, next_state, result = statemachine.StateWS.indent( + self, match, context, next_state) + return context, next_state, ['indent%s' % self.level] + result - def knownindent(self, match, context, nextstate): - if self.debug: print >>sys.stderr, 'knownindent%s' % self.level - context, nextstate, result = statemachine.StateWS.knownindent( - self, match, context, nextstate) - return context, nextstate, ['knownindent%s' % self.level] + result + def known_indent(self, match, context, next_state): + if self.debug: print >>sys.stderr, 'known_indent%s' % self.level + context, next_state, result = statemachine.StateWS.known_indent( + self, match, context, next_state) + return context, next_state, ['known_indent%s' % self.level] + result - def bullet(self, match, context, nextstate): + def bullet(self, match, context, next_state): if self.debug: print >>sys.stderr, 'bullet%s' % self.level - context, nextstate, result \ - = self.knownindent(match, context, nextstate) - return [], nextstate, ['bullet%s' % self.level] + result + context, next_state, result \ + = self.known_indent(match, context, next_state) + return [], next_state, ['bullet%s' % self.level] + result - def text(self, match, context, nextstate): + def text(self, match, context, next_state): if self.debug: print >>sys.stderr, 'text%s' % self.level - return [match.string], nextstate, ['text%s' % self.level] + return [match.string], next_state, ['text%s' % self.level] def literalblock(self): - indented, indent, offset, good = self.statemachine.getindented() + indented, indent, offset, good = self.state_machine.get_indented() if self.debug: print >>sys.stderr, 'literalblock%s(%s)' % (self.level, indent) return ['literalblock%s(%s)' % (self.level, indent)] @@ -108,38 +104,38 @@ class EmptySMTests(unittest.TestCase): def setUp(self): self.sm = statemachine.StateMachine( - stateclasses=[], initialstate='State') + state_classes=[], initial_state='State') self.sm.debug = debug - def test_addstate(self): - self.sm.addstate(statemachine.State) + def test_add_state(self): + self.sm.add_state(statemachine.State) self.assert_(len(self.sm.states) == 1) - self.assertRaises(statemachine.DuplicateStateError, self.sm.addstate, + self.assertRaises(statemachine.DuplicateStateError, self.sm.add_state, statemachine.State) - self.sm.addstate(statemachine.StateWS) + self.sm.add_state(statemachine.StateWS) self.assert_(len(self.sm.states) == 2) - def test_addstates(self): - self.sm.addstates((statemachine.State, statemachine.StateWS)) + def test_add_states(self): + self.sm.add_states((statemachine.State, statemachine.StateWS)) self.assertEqual(len(self.sm.states), 2) - def test_getstate(self): - self.assertRaises(statemachine.UnknownStateError, self.sm.getstate) - self.sm.addstates((statemachine.State, statemachine.StateWS)) - self.assertRaises(statemachine.UnknownStateError, self.sm.getstate, + def test_get_state(self): + self.assertRaises(statemachine.UnknownStateError, self.sm.get_state) + self.sm.add_states((statemachine.State, statemachine.StateWS)) + self.assertRaises(statemachine.UnknownStateError, self.sm.get_state, 'unknownState') - self.assert_(isinstance(self.sm.getstate('State'), + self.assert_(isinstance(self.sm.get_state('State'), statemachine.State)) - self.assert_(isinstance(self.sm.getstate('StateWS'), + self.assert_(isinstance(self.sm.get_state('StateWS'), statemachine.State)) - self.assertEqual(self.sm.currentstate, 'StateWS') + self.assertEqual(self.sm.current_state, 'StateWS') class EmptySMWSTests(EmptySMTests): def setUp(self): self.sm = statemachine.StateMachineWS( - stateclasses=[], initialstate='State') + state_classes=[], initial_state='State') self.sm.debug = debug @@ -158,50 +154,50 @@ class SMWSTests(unittest.TestCase): self.assertEquals(self.sm.states.keys(), ['MockState']) self.assertEquals(len(self.sm.states['MockState'].transitions), 2) - def test_getindented(self): - self.sm.inputlines = testtext - self.sm.lineoffset = -1 - self.sm.nextline(3) - indented, offset, good = self.sm.getknownindented(2) + def test_get_indented(self): + self.sm.input_lines = testtext + self.sm.line_offset = -1 + self.sm.next_line(3) + indented, offset, good = self.sm.get_known_indented(2) self.assertEquals(indented, item1) self.assertEquals(offset, len(para1)) self.failUnless(good) - self.sm.nextline() - indented, offset, good = self.sm.getknownindented(2) + self.sm.next_line() + indented, offset, good = self.sm.get_known_indented(2) self.assertEquals(indented, item2) self.assertEquals(offset, len(para1) + len(item1)) self.failUnless(good) - self.sm.previousline(3) + self.sm.previous_line(3) if self.sm.debug: - print '\ntest_getindented: self.sm.line:\n', self.sm.line - indented, indent, offset, good = self.sm.getindented() + print '\ntest_get_indented: self.sm.line:\n', self.sm.line + indented, indent, offset, good = self.sm.get_indented() if self.sm.debug: - print '\ntest_getindented: indented:\n', indented + print '\ntest_get_indented: indented:\n', indented self.assertEquals(indent, lbindent) self.assertEquals(indented, literalblock) self.assertEquals(offset, (len(para1) + len(item1) + len(item2) - len(literalblock))) self.failUnless(good) - def test_gettextblock(self): - self.sm.inputlines = testtext - self.sm.lineoffset = -1 - self.sm.nextline() - textblock = self.sm.gettextblock() + def test_get_text_block(self): + self.sm.input_lines = testtext + self.sm.line_offset = -1 + self.sm.next_line() + textblock = self.sm.get_text_block() self.assertEquals(textblock, testtext[:1]) - self.sm.nextline(2) - textblock = self.sm.gettextblock() + self.sm.next_line(2) + textblock = self.sm.get_text_block() self.assertEquals(textblock, testtext[2:4]) - def test_getunindented(self): - self.sm.inputlines = testtext - self.sm.lineoffset = -1 - self.sm.nextline() - textblock = self.sm.getunindented() + def test_get_text_block_flush_left(self): + self.sm.input_lines = testtext + self.sm.line_offset = -1 + self.sm.next_line() + textblock = self.sm.get_text_block(flush_left=1) self.assertEquals(textblock, testtext[:1]) - self.sm.nextline() + self.sm.next_line(2) self.assertRaises(statemachine.UnexpectedIndentationError, - self.sm.getunindented) + self.sm.get_text_block, flush_left=1) def test_run(self): self.assertEquals(self.sm.run(testtext), expected) @@ -221,47 +217,48 @@ class EmptyStateTests(unittest.TestCase): 'bogus': 'dummy'} self.state.nop2 = self.state.nop3 = self.state.nop - def test_addtransitions(self): + def test_add_transitions(self): self.assertEquals(len(self.state.transitions), 0) - self.state.addtransitions(['None'], {'None': None}) + self.state.add_transitions(['None'], {'None': None}) self.assertEquals(len(self.state.transitions), 1) self.assertRaises(statemachine.UnknownTransitionError, - self.state.addtransitions, ['bogus'], {}) + self.state.add_transitions, ['bogus'], {}) self.assertRaises(statemachine.DuplicateTransitionError, - self.state.addtransitions, ['None'], {'None': None}) + self.state.add_transitions, ['None'], + {'None': None}) - def test_addtransition(self): + def test_add_transition(self): self.assertEquals(len(self.state.transitions), 0) - self.state.addtransition('None', None) + self.state.add_transition('None', None) self.assertEquals(len(self.state.transitions), 1) self.assertRaises(statemachine.DuplicateTransitionError, - self.state.addtransition, 'None', None) + self.state.add_transition, 'None', None) - def test_removetransition(self): + def test_remove_transition(self): self.assertEquals(len(self.state.transitions), 0) - self.state.addtransition('None', None) + self.state.add_transition('None', None) self.assertEquals(len(self.state.transitions), 1) - self.state.removetransition('None') + self.state.remove_transition('None') self.assertEquals(len(self.state.transitions), 0) self.assertRaises(statemachine.UnknownTransitionError, - self.state.removetransition, 'None') + self.state.remove_transition, 'None') - def test_maketransition(self): + def test_make_transition(self): dummy = re.compile('dummy') - self.assertEquals(self.state.maketransition('nop', 'bogus'), + self.assertEquals(self.state.make_transition('nop', 'bogus'), (dummy, self.state.nop, 'bogus')) - self.assertEquals(self.state.maketransition('nop'), + self.assertEquals(self.state.make_transition('nop'), (dummy, self.state.nop, self.state.__class__.__name__)) self.assertRaises(statemachine.TransitionPatternNotFound, - self.state.maketransition, 'None') + self.state.make_transition, 'None') self.assertRaises(statemachine.TransitionMethodNotFound, - self.state.maketransition, 'bogus') + self.state.make_transition, 'bogus') - def test_maketransitions(self): + def test_make_transitions(self): dummy = re.compile('dummy') - self.assertEquals(self.state.maketransitions(('nop', ['nop2'], - ('nop3', 'bogus'))), + self.assertEquals(self.state.make_transitions(('nop', ['nop2'], + ('nop3', 'bogus'))), (['nop', 'nop2', 'nop3'], {'nop': (dummy, self.state.nop, self.state.__class__.__name__), @@ -284,11 +281,11 @@ class MiscTests(unittest.TestCase): self.assertEquals(statemachine.string2lines(self.s2l_string), self.s2l_expected) - def test_extractindented(self): + def test_extract_indented(self): block = statemachine.string2lines(self.indented_string) - self.assertEquals(statemachine.extractindented(block), + self.assertEquals(statemachine.extract_indented(block), ([s[6:] for s in block], 6, 1)) - self.assertEquals(statemachine.extractindented(self.s2l_expected), + self.assertEquals(statemachine.extract_indented(self.s2l_expected), ([], 0, 0)) diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 05a159796..a05430b3e 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -7,11 +7,13 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -Tests for docutils.transforms.components.Contents. +Tests for `docutils.transforms.parts.Contents` (via +`docutils.transforms.universal.LastReaderPending`). """ from __init__ import DocutilsTestSupport from docutils.transforms.universal import LastReaderPending +from docutils.transforms.references import Substitutions from docutils.parsers.rst import Parser @@ -23,7 +25,7 @@ def suite(): totest = {} -totest['tables_of_contents'] = ((LastReaderPending,), [ +totest['tables_of_contents'] = ((Substitutions, LastReaderPending,), [ ["""\ .. contents:: @@ -126,6 +128,46 @@ Paragraph 2. Paragraph 2. """], ["""\ +.. contents:: There's an image in Title 2 + +Title 1 +======= +Paragraph 1. + +|Title 2| +========= +Paragraph 2. + +.. |Title 2| image:: title2.png +""", +"""\ +<document> + <topic class="contents"> + <title> + There's an image in Title 2 + <bullet_list> + <list_item id="id1"> + <paragraph> + <reference refid="title-1"> + Title 1 + <list_item id="id2"> + <paragraph> + <reference refid="title-2"> + Title 2 + <section id="title-1" name="title 1"> + <title refid="id1"> + Title 1 + <paragraph> + Paragraph 1. + <section id="title-2" name="title 2"> + <title refid="id2"> + <image alt="Title 2" uri="title2.png"> + <paragraph> + Paragraph 2. + <substitution_definition name="title 2"> + <image alt="Title 2" uri="title2.png"> +"""], +["""\ .. contents:: :depth: 2 @@ -190,7 +232,7 @@ Title 1 ======= .. contents:: - :local: + :local: Paragraph 1. diff --git a/test/test_transforms/test_final_checks.py b/test/test_transforms/test_final_checks.py index c74919c56..8b288368c 100755 --- a/test/test_transforms/test_final_checks.py +++ b/test/test_transforms/test_final_checks.py @@ -30,7 +30,7 @@ Unknown reference_. """\ <document> <paragraph> - Unknown + Unknown \n\ <problematic id="id2" refid="id1"> reference_ . diff --git a/test/test_transforms/test_messages.py b/test/test_transforms/test_messages.py index 6751c3ecd..d6912d16e 100755 --- a/test/test_transforms/test_messages.py +++ b/test/test_transforms/test_messages.py @@ -31,7 +31,7 @@ the ``Substitutions`` transform. The ``Messages`` transform will generate a "System Messages" section. (A second copy of the system message is tacked on to the end of the -doctree by the test framework.) +document by the test framework.) """, """\ <document> @@ -50,7 +50,7 @@ doctree by the test framework.) generate a "System Messages" section. <paragraph> (A second copy of the system message is tacked on to the end of the - doctree by the test framework.) + document by the test framework.) <section class="system-messages"> <title> Docutils System Messages diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index c02dd0218..f1cd8aece 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -32,7 +32,7 @@ The |biohazard| symbol is deservedly scary-looking. """\ <document> <paragraph> - The + The \n\ <image alt="biohazard" uri="biohazard.png"> symbol is deservedly scary-looking. <substitution_definition name="biohazard"> @@ -44,7 +44,7 @@ Here's an |unknown| substitution. """\ <document> <paragraph> - Here's an + Here's an \n\ <problematic id="id2" refid="id1"> |unknown| substitution. diff --git a/test/test_utils.py b/test/test_utils.py index 29c926f56..3f3b53db8 100755 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -12,11 +12,6 @@ Test module for utils.py. import unittest, StringIO, sys from DocutilsTestSupport import utils, nodes -try: - import mypdb as pdb -except: - import pdb -pdb.tracenow = 0 class ReporterTests(unittest.TestCase): @@ -137,28 +132,28 @@ class ReporterCategoryTests(unittest.TestCase): self.stream.seek(0) self.stream.truncate() self.reporter = utils.Reporter(2, 4, self.stream, 1) - self.reporter.setconditions('lemon', 1, 3, self.stream, 0) + self.reporter.set_conditions('lemon', 1, 3, self.stream, 0) def test_getset(self): - self.reporter.setconditions('test', 5, 5, None, 0) - self.assertEquals(self.reporter.getconditions('other').astuple(), + self.reporter.set_conditions('test', 5, 5, None, 0) + self.assertEquals(self.reporter.get_conditions('other').astuple(), (1, 2, 4, self.stream)) - self.assertEquals(self.reporter.getconditions('test').astuple(), + self.assertEquals(self.reporter.get_conditions('test').astuple(), (0, 5, 5, sys.stderr)) - self.assertEquals(self.reporter.getconditions('test.dummy').astuple(), + self.assertEquals(self.reporter.get_conditions('test.dummy').astuple(), (0, 5, 5, sys.stderr)) - self.reporter.setconditions('test.dummy.spam', 1, 2, self.stream, 1) + self.reporter.set_conditions('test.dummy.spam', 1, 2, self.stream, 1) self.assertEquals( - self.reporter.getconditions('test.dummy.spam').astuple(), + self.reporter.get_conditions('test.dummy.spam').astuple(), (1, 1, 2, self.stream)) - self.assertEquals(self.reporter.getconditions('test.dummy').astuple(), + self.assertEquals(self.reporter.get_conditions('test.dummy').astuple(), (0, 5, 5, sys.stderr)) self.assertEquals( - self.reporter.getconditions('test.dummy.spam.eggs').astuple(), + self.reporter.get_conditions('test.dummy.spam.eggs').astuple(), (1, 1, 2, self.stream)) - self.reporter.unsetconditions('test.dummy.spam') + self.reporter.unset_conditions('test.dummy.spam') self.assertEquals( - self.reporter.getconditions('test.dummy.spam.eggs').astuple(), + self.reporter.get_conditions('test.dummy.spam.eggs').astuple(), (0, 5, 5, sys.stderr)) def test_debug(self): @@ -304,9 +299,9 @@ class MiscFunctionTests(unittest.TestCase): ('A a A a', 'a a a a'), (' AaA\n\r\naAa\tAaA\t\t', 'aaa aaa aaa')] - def test_normname(self): + def test_normalize_name(self): for input, output in self.names: - normed = utils.normname(input) + normed = utils.normalize_name(input) self.assertEquals(normed, output) ids = [('a', 'a'), ('A', 'a'), ('', ''), ('a b \n c', 'a-b-c'), diff --git a/tools/quicktest.py b/tools/quicktest.py index df295f66a..fab25adce 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -174,7 +174,7 @@ def main(): inputFile, outputFormat, optargs = getArgs() # process cmdline arguments parser = Parser() input = inputFile.read() - document = docutils.utils.newdocument(debug=optargs['debug']) + document = docutils.utils.new_document(debug=optargs['debug']) parser.parse(input, document) output = format(outputFormat, input, document, optargs) print output, -- cgit v1.2.1 From cff9de2e203bbe10708a99c99b1d67672b1ae4a1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 15:50:10 +0000 Subject: simplified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@92 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/html.py | 15 ++++++++++----- tools/publish.py | 13 ++++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/html.py b/tools/html.py index 66f029364..2b9d727ea 100755 --- a/tools/html.py +++ b/tools/html.py @@ -16,16 +16,21 @@ import sys from docutils.core import publish from docutils import utils -reporter = utils.Reporter(2, 4) + +reporter = utils.Reporter(1, 4) #reporter.setconditions('nodes.Node.walkabout', 2, 4, debug=1) if len(sys.argv) == 2: - publish(writername='html', source=sys.argv[1], reporter=reporter) + source = sys.argv[1] + destination = None elif len(sys.argv) == 3: - publish(writername='html', source=sys.argv[1], destination=sys.argv[2], - reporter=reporter) + source = sys.argv[1] + destination = sys.argv[2] elif len(sys.argv) > 3: print >>sys.stderr, 'Maximum 2 arguments allowed.' sys.exit(1) else: - publish() + source = None + destination = None +publish(source=source, destination=destination, reporter=reporter, + writer_name='html') diff --git a/tools/publish.py b/tools/publish.py index 539548911..33655d6b6 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -14,14 +14,21 @@ This module takes advantage of the default values defined in `publish()`. import sys from docutils.core import publish +from docutils import utils +reporter = utils.Reporter(1, 4) + if len(sys.argv) == 2: - publish(source=sys.argv[1]) + source = sys.argv[1] + destination = None elif len(sys.argv) == 3: - publish(source=sys.argv[1], destination=sys.argv[2]) + source = sys.argv[1] + destination = sys.argv[2] elif len(sys.argv) > 3: print >>sys.stderr, 'Maximum 2 arguments allowed.' sys.exit(1) else: - publish() + source = None + destination = None +publish(source=source, destination=destination, reporter=reporter) -- cgit v1.2.1 From 2bd48ed5630100cff43a327e93d134c97fcf43bc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 15:55:33 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@93 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms/test_filter.py | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/test_transforms/test_filter.py diff --git a/test/test_transforms/test_filter.py b/test/test_transforms/test_filter.py new file mode 100644 index 000000000..8417b750e --- /dev/null +++ b/test/test_transforms/test_filter.py @@ -0,0 +1,42 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for docutils.transforms.components.Filter. +""" + +from __init__ import DocutilsTestSupport +from docutils.transforms.universal import FirstWriterPending +from docutils.parsers.rst import Parser + + +def suite(): + parser = Parser() + s = DocutilsTestSupport.TransformTestSuite(parser) + s.generateTests(totest) + return s + +totest = {} + +totest['meta'] = ((FirstWriterPending,), [ +["""\ +.. meta:: + :description: The reStructuredText plaintext markup language + :keywords: plaintext,markup language +""", +"""\ +<document> + <meta content="The reStructuredText plaintext markup language" name="description"> + <meta content="plaintext,markup language" name="keywords"> +"""], +]) + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From b5b64a2fc605d698e4d1b16862e6dd3f16394d82 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 15:56:49 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@94 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- README.txt | 16 +++++----- 2 files changed, 99 insertions(+), 14 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 8559e56cf..654b2fbc1 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -33,25 +33,108 @@ any names; apologies (and please let me know!) if I have. Changes Since 0.1 ======================== +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". + +* docutils/__init__.py: + + - Added ``ApplicationError`` and ``DataError``, for use throughout + the package. + - Added ``Component`` base class for Docutils components; implements + the ``supports`` method. + +* docutils/nodes.py: + + - Added ``TreeCopyVisitor`` class. + - Added a ``copy`` method to ``Node`` and subclasses. + - Added a ``SkipDeparture`` exception for visitors. + +* docutils/statemachine.py: + + - Added ``runtime_init`` method to ``StateMachine`` and ``State``. + - Added underscores to improve many awkward names. + +* 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. + * 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. + +* 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. + +* 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/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. + +* docutils/transforms/components.py: Added to project; transforms + related to Docutils components. + +* docutils/transforms/universal.py: Changed ``Messages`` transform to + properly filter out system messages below the warning threshold. + +* docutils/writers/html4css1.py: + + - Made XHTML-compatible (switched to lowercase element & attribute + names; empty tag format). + - Escape double-dashes in comment text. + +* docutils/writers/pseudoxml.py: Renamed from pprint.py. + +* spec/pep-0257.txt: Clarified prohibition of signature repetition. + +* spec/rst/reStructuredText.txt: + + - Clarified field list usage. + - Updated enumerated list description. + +* spec/rst/alternatives.txt: Expanded auto-enumerated list idea; + thanks to Fred Bremmer. + +* spec/rst/problems.txt: Updated the Enumerated List Markup + discussion. * test: Made test modules standalone (subdirectories became packages). -* test/DocutilsTestSupport.py: Support for RFC-2822 testing. +* test/DocutilsTestSupport.py: Support for PEP extensions to + reStructuredText. * test/package_unittest.py: Renamed from UnitTestFolder.py. - Now supports true packages containing test modules (``__init__.py`` files required); fixes duplicate module name bug. -* spec/pep-0257.txt: Clarified prohibition of signature repetition. - -* spec/rst/reStructuredText.txt: Clarified field list usage. - -* spec/rst/alternatives.txt: Expanded auto-numbered enumerated list - idea; thanks to Fred Bremmer. +* test/test_pep/: Subpackage added to project; PEP testing. Release 0.1 (2002-04-20) diff --git a/README.txt b/README.txt index a860ce4f7..fe979db32 100644 --- a/README.txt +++ b/README.txt @@ -7,12 +7,14 @@ :Date: $Date$ :Web-site: http://docutils.sourceforge.net/ -Thank you for downloading the Python Docutils project arhive. As this -is a work in progress, please check the project website for updated -working files. +Thank you for downloading the Python Docutils project archive. As +this is a work in progress, please check the project website for +updated working files. This project should be considered highly +experimental; APIs are subject to change at any time. -To run the code, Python 2.0 or later must already be installed. You -can get Python from http://www.python.org/. +To run the code, Python 2.0 or later must already be installed. +Python 2.1 or later is required to run the test suite. You can get +Python from http://www.python.org/. Project Files & Directories @@ -33,12 +35,12 @@ Project Files & Directories * docutils: The project source directory, installed as a Python package. -* docs: The project user documentation directory. The docs/rest +* docs: The project user documentation directory. The docs/rst directory contains reStructuredText user docs. * spec: The project specification directory. Contains PEPs (Python Enhancement Proposals), XML DTDs (document type definitions), and - other documents. The spec/rest directory contains the + other documents. The spec/rst directory contains the reStructuredText specification. * tools: Directory for standalone scripts that use reStructuredText. -- cgit v1.2.1 From f6d1d682215cee2501c938cf8389d720ef6118df Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 15:59:03 +0000 Subject: refactored; improved compound names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@95 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index ee36d1148..07b44ea86 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -15,9 +15,9 @@ __docformat__ = 'reStructuredText' _languages = {} -def getlanguage(languagecode): - if _languages.has_key(languagecode): - return _languages[languagecode] - module = __import__(languagecode, globals(), locals()) - _languages[languagecode] = module +def getlanguage(language_code): + if _languages.has_key(language_code): + return _languages[language_code] + module = __import__(language_code, globals(), locals()) + _languages[language_code] = module return module -- cgit v1.2.1 From e46540a319e09246ce45b26776e3b1408d04a7b4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 16:18:00 +0000 Subject: removed some debugging code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@96 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index d3dca5b0e..ba311d488 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -17,7 +17,6 @@ __docformat__ = 'reStructuredText' import sys, os, re, time from docutils import nodes, utils, ApplicationError, DataError from docutils.transforms import Transform, TransformError -import mypdb as pdb class Headers(Transform): @@ -40,7 +39,6 @@ class Headers(Transform): raise DataError('Document does not begin with an RFC-2822 ' 'header; it is not a PEP.') pep = title = None - #pdb.set_trace() for field in header: if field[0].astext().lower() == 'pep': # should be the first field pep = int(field[1].astext()) @@ -51,7 +49,6 @@ class Headers(Transform): for field in header: name = field[0].astext().lower() body = field[1] - print >>sys.stderr, 'name=%s, body=%s' % (name, body.astext()) ; sys.stderr.flush() if len(body) > 1: raise DataError('PEP header field body contains multiple ' 'elements:\n%s' % field.pformat(level=1)) @@ -72,7 +69,8 @@ class Headers(Transform): para = body[0] if name == 'title': title = body.astext() - # @@@ Insert a "pending" element here, since we don't really want a separate document title? + # @@@ Insert a "pending" element here, since we don't really + # want a separate document title? elif name in ('author', 'discussions-to'): for node in para: if isinstance(node, nodes.reference) \ @@ -89,11 +87,9 @@ class Headers(Transform): newbody.append(space) para[:] = newbody[:-1] # drop trailing space elif name == 'last-modified': - #pdb.set_trace() utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) date = para.astext() uri = self.pep_cvs_url % int(pep) para[:] = [nodes.reference('', date, refuri=uri)] elif name == 'version' and len(body): utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) - print >>sys.stderr, 'name=%s, body=%s' % (name, body.astext()) ; sys.stderr.flush() -- cgit v1.2.1 From 6b21c047594ea25b4fa75f903e9b315859735116 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 17:06:02 +0000 Subject: fixed hyperlinks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@97 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/pysource.txt | 7 ++----- docs/ref/rst/introduction.txt | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/dev/pysource.txt b/docs/dev/pysource.txt index a75fd1d4d..93fba9420 100644 --- a/docs/dev/pysource.txt +++ b/docs/dev/pysource.txt @@ -19,8 +19,8 @@ to syntax constructs. .. contents:: -Python Source Reader -==================== +Model +===== The Python Source Reader ("PySource") model that's evolving in my mind goes something like this: @@ -158,9 +158,6 @@ The role may be one of 'package', 'module', 'class', 'method', 'exception_class', 'exception', 'warning_class', or 'warning'. Other roles may be defined. -.. _reStructuredText Markup Specification: - http://docutils.sourceforge.net/spec/rst/reStructuredText.html -.. _Docutils: http://docutils.sourceforge.net/ .. _pysource.dtd: http://docutils.sourceforge.net/spec/pysource.dtd .. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd diff --git a/docs/ref/rst/introduction.txt b/docs/ref/rst/introduction.txt index 3d7cfc5f8..4ffb2d053 100644 --- a/docs/ref/rst/introduction.txt +++ b/docs/ref/rst/introduction.txt @@ -294,7 +294,6 @@ followed. .. _comp.lang.python: news:comp.lang.python .. _Python-dev: http://mail.python.org/pipermail/python-dev/ .. _Docstring Processing System: http://docstring.sourceforge.net/ -.. _Docutils: http://docutils.sourceforge.net/ .. _master PEP repository: http://www.python.org/peps/ -- cgit v1.2.1 From ffc1731fd8a18d2ad70e4201be54aa90f0d69ad1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 5 May 2002 19:30:10 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@98 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 654b2fbc1..cb1761c7a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,16 +14,18 @@ Acknowledgements I would like to acknowledge the people who have made a direct impact on the Docutils project, knowingly or not, in terms of encouragement, -suggestions, criticism, bug reports, code contributions, and related -projects: +suggestions, criticism, bug reports, code contributions, tasty treats, +and related projects: David Ascher, Fred Drake, Jim Fulton, Peter Funk, Doug Hellmann, - Juergen Hermann, Tony Ibbs, Richard Jones, Garth Kidd, Daniel - Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken - Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, - Mark Pilgrim, Tavis Rudd, Ueli Schlaepfer, Bob Tolbert, Laurence - Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping - Yee, Moshe Zadka + Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, Garth + Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward + Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, + Tim Peters, Mark Pilgrim, Tavis Rudd, Ueli Schlaepfer, Bob + Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward + Welbourne, Ka-Ping Yee, Moshe Zadka + +Thank you! (I'm still waiting for contributions of computer equipment and cold hard cash :-).) Hopefully I haven't forgotten anyone or misspelled @@ -40,6 +42,11 @@ General: 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``. + +Specific: + * docutils/__init__.py: - Added ``ApplicationError`` and ``DataError``, for use throughout -- cgit v1.2.1 From c0405e481cc67c4aae4feb3de44696bc13760acd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 03:28:16 +0000 Subject: - Renamed ``TreePruningException`` from ``VisitorException``. - Added docstrings to ``TreePruningException``, subclasses, and ``Nodes.walk()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@99 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 82 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 803fbc82e..00e7d532d 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -59,10 +59,16 @@ class Node: Traverse a tree of `Node` objects, calling ``visit_...`` methods of `visitor` when entering each node. If there is no ``visit_particular_node`` method for a node of type - ``particular_node``, the ``unknown_visit`` method is called. + ``particular_node``, the ``unknown_visit`` method is called. (The + `walkabout()` method is similar, except it also calls ``depart_...`` + methods before exiting each node.) - Doesn't handle arbitrary modification in-place during the traversal. - Replacing one element with one element is OK. + This tree traversal doesn't handle arbitrary in-place tree + modifications. Replacing one element with one element is OK. + + Within ``visit_...`` methods (and ``depart_...`` methods for + `walkabout()`), `TreePruningException` subclasses may be raised + (`SkipChildren`, `SkipSiblings`, `SkipNode`, `SkipDeparture`). Parameter `visitor`: A `NodeVisitor` object, containing a ``visit_...`` method for each `Node` subclass encountered. @@ -85,9 +91,9 @@ class Node: def walkabout(self, visitor): """ - Perform a tree traversal similarly to `Node.walk()`, except also call - ``depart_...`` methods before exiting each node. If there is no - ``depart_particular_node`` method for a node of type + Perform a tree traversal similarly to `Node.walk()` (which see), + except also call ``depart_...`` methods before exiting each node. If + there is no ``depart_particular_node`` method for a node of type ``particular_node``, the ``unknown_departure`` method is called. Parameter `visitor`: A `NodeVisitor` object, containing ``visit_...`` @@ -1138,13 +1144,6 @@ class GenericNodeVisitor(NodeVisitor): del name -class VisitorException(Exception): pass -class SkipChildren(VisitorException): pass -class SkipSiblings(VisitorException): pass -class SkipNode(VisitorException): pass -class SkipDeparture(VisitorException): pass - - class TreeCopyVisitor(GenericNodeVisitor): """ @@ -1159,11 +1158,64 @@ class TreeCopyVisitor(GenericNodeVisitor): return self.parent_stack[0][0] def default_visit(self, node): - """""" + """Copy the current node, and make it the new acting parent.""" newnode = node.copy() self.parent_stack[-1].append(newnode) self.parent_stack.append(newnode) def default_departure(self, node): - """""" + """Restore the previous acting parent.""" self.parent_stack.pop() + + +class TreePruningException(Exception): + + """ + Base class for `NodeVisitor`-related tree pruning exceptions. + + Raise subclasses from within ``visit_...`` or ``depart_...`` methods + called from `Node.walk()` and `Node.walkabout()` tree traversals to prune + the tree traversed. + """ + + pass + + +class SkipChildren(TreePruningException): + + """ + Do not visit any children of the current node. The current node's + siblings and ``depart_...`` method are not affected. + """ + + pass + + +class SkipSiblings(TreePruningException): + + """ + Do not visit any more siblings (to the right) of the current node. The + current node's children and its ``depart_...`` method are not affected. + """ + + pass + + +class SkipNode(TreePruningException): + + """ + Do not visit the current node's children, and do not call the current + node's ``depart_...`` method. + """ + + pass + + +class SkipDeparture(TreePruningException): + + """ + Do not call the current node's ``depart_...`` method. The current node's + children and siblings are not affected. + """ + + pass -- cgit v1.2.1 From d639a557186f9e7493682320b59a9897a07876a3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 04:03:21 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@100 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 +++ docs/dev/todo.txt | 47 +++++++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index cb1761c7a..a153ded26 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -59,6 +59,9 @@ Specific: - 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()``. * docutils/statemachine.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c262f6509..fafddb76b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -215,18 +215,24 @@ Directives - Implement directives: - - html.imagemap (Useful outside of HTML? If not, replace with image - only in non-HTML writers?) + - _`html.imagemap` (Useful outside of HTML? If not, replace with + image only in non-HTML writers?) - - parts.endnotes, .citations, .topic, .sectnum (section numbering; - add support to .contents; could be cmdline option also) + - _`parts.endnotes` + + - _`parts.citations` + + - _`parts.topic` + + - _`parts.sectnum` (section numbering; add support to .contents; + could be cmdline option also) - - misc.raw + - _`misc.raw` - - misc.include: ``#include`` one file in another. But how to parse - wrt sections, reference names, conflicts? Parse it in the current - document's context (C-preprocessor semantics), or separately and - then merge? + - _`misc.include`: ``#include`` one file in another. But how to + parse wrt sections, reference names, conflicts? Parse it in the + current document's context (C-preprocessor semantics), or + separately and then merge? Use C-preprocessor semantics for locating include files? E.g., ``.. include:: file.txt`` will read another file into the current @@ -235,14 +241,14 @@ Directives ``docutils/include/``. (Should "quotes" be required around non-standard include files?) - - misc.exec: Execute Python code & insert the results. Perhaps + - _`misc.exec`: Execute Python code & insert the results. Perhaps dangerous? - - misc.eval: Evaluate an expression & insert the text. At parse + - _`misc.eval`: Evaluate an expression & insert the text. At parse time or at substitution time? Dangerous? Perhaps limit to canned macros; see text.date_ below. - - @@@ body.qa/faq/questions: Questions & Answers. Implement as a + - @@@ _`body.qa`/faq/questions: Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) Add support to parts.Contents (optional attribute "qa" done). @@ -257,11 +263,12 @@ Directives <!ELEMENT question %text.model;> <!ELEMENT answer (%body.elements;)+> - - body.columns: Multi-column table/list, with number of columns as - argument. + - _`body.columns`: Multi-column table/list, with number of columns + as argument. - - body.verse: Paragraphs with linebreaks preserved, *and* inline - markup support too. A directive would be easy; what about a + - _`body.verse`: Paragraphs with linebreaks preserved, *and* inline + markup support too. Use cases: verse (poetry, song lyrics, etc.), + address blocks. A directive would be easy; what about a literal-block-like prefix, perhaps ';;'? (It's a semi-literal block, after all.) Example:: @@ -309,16 +316,16 @@ Directives as soon as it comes. Love, Ewan. - - colorize.python: Colorize Python code. Fine for HTML output, but - what about other formats? Revert to a literal block? Do we need - some kind of "alternate" mechanism? Perhaps use a "pending" + - _`colorize.python`: Colorize Python code. Fine for HTML output, + but what about other formats? Revert to a literal block? Do we + need some kind of "alternate" mechanism? Perhaps use a "pending" transform, which could switch its output based on the "format" in use. Use a factory function "transformFF()" which returns either "HTMLTransform()" instance or "GenericTransform" instance? - _`text.date`: Datestamp. For substitutions. - - Combined with misc.include, implement canned macros? E.g.:: + - Combined with misc.include_, implement canned macros? E.g.:: .. include:: <macros> -- cgit v1.2.1 From 30a6456af9993b056a8f1365d9cb76c1a0cd19bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 04:06:55 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@101 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index fafddb76b..45be4a5c3 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -248,10 +248,10 @@ Directives time or at substitution time? Dangerous? Perhaps limit to canned macros; see text.date_ below. - - @@@ _`body.qa`/faq/questions: Questions & Answers. Implement as a - generic two-column marked list? As a standalone (non-directive) - construct? (Is the markup ambiguous?) Add support to - parts.Contents (optional attribute "qa" done). + - @@@ _`body.qa` (directive a.k.a. "faq" "questions"): Questions & + Answers. Implement as a generic two-column marked list? As a + standalone (non-directive) construct? (Is the markup ambiguous?) + Add support to parts.Contents (optional attribute "qa" done). New elements would be required. Perhaps:: -- cgit v1.2.1 From 6d688c4ee731218a8b027ba32e7f733676fee1f0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 04:11:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@102 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 45be4a5c3..57ccc214e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -269,8 +269,8 @@ Directives - _`body.verse`: Paragraphs with linebreaks preserved, *and* inline markup support too. Use cases: verse (poetry, song lyrics, etc.), address blocks. A directive would be easy; what about a - literal-block-like prefix, perhaps ';;'? (It's a semi-literal - block, after all.) Example:: + literal-block-like prefix, perhaps "``;;``"? (It is a semi- + literal-block, after all.) Example:: Take it away, Eric the Orchestra Leader! ;; -- cgit v1.2.1 From b5cd95550cef5b1e29e52a497acb3dd4b3192f96 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 04:14:46 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@103 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 57ccc214e..2c48bc7e8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -248,7 +248,7 @@ Directives time or at substitution time? Dangerous? Perhaps limit to canned macros; see text.date_ below. - - @@@ _`body.qa` (directive a.k.a. "faq" "questions"): Questions & + - @@@ _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) Add support to parts.Contents (optional attribute "qa" done). @@ -269,8 +269,8 @@ Directives - _`body.verse`: Paragraphs with linebreaks preserved, *and* inline markup support too. Use cases: verse (poetry, song lyrics, etc.), address blocks. A directive would be easy; what about a - literal-block-like prefix, perhaps "``;;``"? (It is a semi- - literal-block, after all.) Example:: + literal-block-like prefix, perhaps "``;;``"? (It is, after all, a + *semi-literal* literal block, no?) Example:: Take it away, Eric the Orchestra Leader! ;; -- cgit v1.2.1 From bb7d59f401c5548c607574294c3ae4e23d4f6a22 Mon Sep 17 00:00:00 2001 From: richard <richard@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 04:53:08 +0000 Subject: Lose the extraneous blank line from the start of literal blocks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@104 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0390502d2..acbf5a66c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -479,7 +479,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</code>') def visit_literal_block(self, node): - self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) + self.body.append(self.starttag(node, 'pre', suffix='', + CLASS='literal-block')) def depart_literal_block(self, node): self.body.append('</pre>\n') -- cgit v1.2.1 From 7cd21ab928fcae9a597ae04c69ae74b41b919ec4 Mon Sep 17 00:00:00 2001 From: richard <richard@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 May 2002 07:45:06 +0000 Subject: ... same goes for doctest blocks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@105 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index acbf5a66c..2e26a785c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -289,7 +289,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</p>\n</td></tr>') def visit_doctest_block(self, node): - self.body.append(self.starttag(node, 'pre', CLASS='doctest-block')) + self.body.append(self.starttag(node, 'pre', suffix='', + CLASS='doctest-block')) def depart_doctest_block(self, node): self.body.append('</pre>\n') -- cgit v1.2.1 From d44e62eb34941a552ee243fef90b529064eda265 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:15:17 +0000 Subject: - Improved boilerplate & modularity of output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@106 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2e26a785c..eb62d6206 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -41,23 +41,37 @@ class Writer(writers.Writer): class HTMLTranslator(nodes.NodeVisitor): + xml_declaration = '<?xml version="1.0" encoding="UTF-8"?>\n' + doctype = '<!DOCTYPE html' \ + ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' \ + ' SYSTEM "http://www.w3.org/TR/xhtml1/DTD/' \ + 'xhtml1-transitional.dtd">\n' + html_head = '<html lang="%s">\n<head>\n' + content_type = '<meta http-equiv=Content-Type content="text/html; ' \ + 'charset=UTF-8">\n', + stylesheet_link = '<link rel="stylesheet" href="default.css"' \ + ' type="text/css" />\n'] + def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - self.language = languages.getlanguage(document.language_code) - self.head = ['<!DOCTYPE html PUBLIC' - ' "-//W3C//DTD HTML 4.01 Transitional//EN"\n' - ' "http://www.w3.org/TR/html4/loose.dtd">\n', - '<html lang="%s">\n<head>\n' % document.language_code, - '<link rel="stylesheet" href="default.css"' - ' type="text/css" />\n'] - self.body = ['</head>\n<body>\n'] - self.foot = ['</body>\n</html>\n'] + self.language = languages.get_language(document.language_code) + self.head_prefix = [ + self.xml_declaration, # @@@ % output_encoding + self.doctype, + self.html_head % document.language_code, + self.content_type, # @@@ % output encoding + self.stylesheet_link] # @@@ % stylesheet + self.head = [] + self.body_prefix = ['</head>\n<body>\n'] + self.body = [] + self.body_suffix = ['</body>\n</html>\n'] self.sectionlevel = 0 self.context = [] self.topic_class = '' def astext(self): - return ''.join(self.head + self.body + self.foot) + return ''.join(self.head_prefix + self.head + + self.body_prefix + self.body + self.body_suffix) def encode(self, text): """Encode special characters in `text` & return.""" @@ -290,7 +304,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_doctest_block(self, node): self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='doctest-block')) + CLASS='doctest-block')) def depart_doctest_block(self, node): self.body.append('</pre>\n') @@ -481,7 +495,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_literal_block(self, node): self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='literal-block')) + CLASS='literal-block')) def depart_literal_block(self, node): self.body.append('</pre>\n') -- cgit v1.2.1 From 5acb5943d2383d82e4e180a49905f6d7f7eb7337 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:18:13 +0000 Subject: - Fixed bug reporting (line #) when no blank line. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@107 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d2a133198..434888417 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -141,7 +141,7 @@ class RSTStateMachine(StateMachineWS): StateMachine, and return the resulting document. """ - self.language = languages.getlanguage(document.language_code) + self.language = languages.get_language(document.language_code) self.match_titles = match_titles if inliner is None: inliner = Inliner() @@ -947,9 +947,9 @@ class Body(RSTState): input_offset=self.state_machine.abs_line_offset() + 1, node=bulletlist, initial_state='BulletList', blank_finish=blank_finish) + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Bullet list') - self.goto_line(newline_offset) return [], next_state, [] def list_item(self, indent): @@ -1000,9 +1000,9 @@ class Body(RSTState): node=enumlist, initial_state='EnumeratedList', blank_finish=blank_finish, extra_settings={'lastordinal': ordinal, 'format': format}) + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Enumerated list') - self.goto_line(newline_offset) return [], next_state, [] def parse_enumerator(self, match, expected_sequence=None): @@ -1067,9 +1067,9 @@ class Body(RSTState): input_offset=self.state_machine.abs_line_offset() + 1, node=fieldlist, initial_state='FieldList', blank_finish=blank_finish) + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Field list') - self.goto_line(newline_offset) return [], next_state, [] def field(self, match): @@ -1119,9 +1119,9 @@ class Body(RSTState): input_offset=self.state_machine.abs_line_offset() + 1, node=optionlist, initial_state='OptionList', blank_finish=blank_finish) + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Option list') - self.goto_line(newline_offset) return [], next_state, [] def option_list_item(self, match): @@ -1740,10 +1740,10 @@ class RFC2822Body(Body): input_offset=self.state_machine.abs_line_offset() + 1, node=fieldlist, initial_state='RFC2822List', blank_finish=blank_finish) + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning( 'RFC2822-style field list') - self.goto_line(newline_offset) return [], next_state, [] def rfc2822_field(self, match): @@ -1964,9 +1964,9 @@ class Text(RSTState): input_offset=self.state_machine.abs_line_offset() + 1, node=definitionlist, initial_state='DefinitionList', blank_finish=blank_finish, blank_finish_state='Definition') + self.goto_line(newline_offset) if not blank_finish: self.parent += self.unindent_warning('Definition list') - self.goto_line(newline_offset) return [], 'Body', [] def underline(self, match, context, next_state): -- cgit v1.2.1 From 56c5b187bf5a81759b2fcbb817824454382a1038 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:19:58 +0000 Subject: - Improved ``TreeCopyVisitor`` class. - Improved names. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@108 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 00e7d532d..275469f6e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -82,7 +82,7 @@ class Node: return except SkipDeparture: # not applicable; ignore pass - children = self.getchildren() + children = self.get_children() try: for i in range(len(children)): children[i].walk(visitor) @@ -110,7 +110,7 @@ class Node: return except SkipDeparture: call_depart = 0 - children = self.getchildren() + children = self.get_children() try: for i in range(len(children)): children[i].walkabout(visitor) @@ -161,7 +161,7 @@ class Text(Node, MutableString): result.append(indent + line + '\n') return ''.join(result) - def getchildren(self): + def get_children(self): """Text nodes have no children. Return [].""" return [] @@ -396,7 +396,7 @@ class Element(Node): elif new is not None: self[index:index+1] = new - def findclass(self, childclass, start=0, end=sys.maxint): + def first_child_matching_class(self, childclass, start=0, end=sys.maxint): """ Return the index of the first child whose class exactly matches. @@ -415,7 +415,8 @@ class Element(Node): return index return None - def findnonclass(self, childclass, start=0, end=sys.maxint): + def first_child_not_matching_class(self, childclass, start=0, + end=sys.maxint): """ Return the index of the first child whose class does *not* match. @@ -442,7 +443,7 @@ class Element(Node): [child.pformat(indent, level+1) for child in self.children]) - def getchildren(self): + def get_children(self): """Return this element's children.""" return self.children @@ -1152,20 +1153,22 @@ class TreeCopyVisitor(GenericNodeVisitor): def __init__(self, document): GenericNodeVisitor.__init__(self, document) - self.parent_stack = [[]] + self.parent_stack = [] + self.parent = [] def get_tree_copy(self): - return self.parent_stack[0][0] + return self.parent[0] def default_visit(self, node): """Copy the current node, and make it the new acting parent.""" newnode = node.copy() - self.parent_stack[-1].append(newnode) - self.parent_stack.append(newnode) + self.parent.append(newnode) + self.parent_stack.append(self.parent) + self.parent = newnode def default_departure(self, node): """Restore the previous acting parent.""" - self.parent_stack.pop() + self.parent = self.parent_stack.pop() class TreePruningException(Exception): -- cgit v1.2.1 From e5744d83bfa217b861297a76840492691f1896d2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:22:10 +0000 Subject: name improvements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@109 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0258.txt | 2 +- docutils/languages/__init__.py | 2 +- docutils/parsers/rst/directives/html.py | 2 +- docutils/parsers/rst/languages/__init__.py | 2 +- docutils/transforms/__init__.py | 2 +- docutils/transforms/frontmatter.py | 9 ++++++--- docutils/transforms/parts.py | 4 ++-- docutils/transforms/references.py | 20 +++++++++++--------- docutils/transforms/universal.py | 4 ++-- docutils/writers/__init__.py | 4 ++-- 10 files changed, 28 insertions(+), 23 deletions(-) diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index e760a9123..4acff1039 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -542,7 +542,7 @@ Specification their language identifier (as defined in `Choice of Docstring Format`_ above), converting dashes to underscores. - - Function "getlanguage(languagecode)", returns matching + - Function "get_language(language_code)", returns matching language module. (docutils/languages/__init__.py) - Module "docutils.languages.en" (English). diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py index 0de3674d7..bdddb5697 100644 --- a/docutils/languages/__init__.py +++ b/docutils/languages/__init__.py @@ -14,7 +14,7 @@ __docformat__ = 'reStructuredText' _languages = {} -def getlanguage(language_code): +def get_language(language_code): if _languages.has_key(language_code): return _languages[language_code] module = __import__(language_code, globals(), locals()) diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index 262a124c8..d21ff0505 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -39,7 +39,7 @@ def meta(match, type_name, data, state, state_machine, attributes): msg = state_machine.reporter.error('Empty meta directive at line %s.' % state_machine.abs_line_number()) node += msg - return node.getchildren(), blank_finish + return node.get_children(), blank_finish def imagemap(match, type_name, data, state, state_machine, attributes): return [], 0 diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index 07b44ea86..4a5441e9e 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -15,7 +15,7 @@ __docformat__ = 'reStructuredText' _languages = {} -def getlanguage(language_code): +def get_language(language_code): if _languages.has_key(language_code): return _languages[language_code] module = __import__(language_code, globals(), locals()) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index ddf92cb65..55e656bff 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -59,7 +59,7 @@ class Transform(Component): apply to the document as a whole, `startnode` is not set (i.e. its value is `None`).""" - self.language = languages.getlanguage(document.language_code) + self.language = languages.get_language(document.language_code) """Language module local to this document.""" def transform(self): diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index d4bfce832..c5aaa0d1e 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -144,7 +144,8 @@ class DocTitle(Transform): Return (None, None) if no valid candidate was found. """ document = self.document - index = document.findnonclass(nodes.PreBibliographic) + index = document.first_child_not_matching_class( + nodes.PreBibliographic) if index is None or len(document) > (index + 1) or \ not isinstance(document[index], nodes.section): return None, None @@ -225,12 +226,14 @@ class DocInfo(Transform): def transform(self): document = self.document - index = document.findnonclass(nodes.PreBibliographic) + 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.findnonclass(nodes.Titular) + biblioindex = document.first_child_not_matching_class( + nodes.Titular) nodelist, remainder = self.extract_bibliographic(candidate) if remainder: document[index] = remainder diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 50667a1fa..ac9ad0466 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -95,7 +95,7 @@ class Contents(Transform): class ContentsFilter(nodes.TreeCopyVisitor): def get_entry_text(self): - return self.get_tree_copy().getchildren() + return self.get_tree_copy().get_children() def visit_citation_reference(self, node): raise nodes.SkipNode @@ -105,7 +105,7 @@ class ContentsFilter(nodes.TreeCopyVisitor): def visit_image(self, node): if node.hasattr('alt'): - self.parent_stack[-1].append(nodes.Text(node['alt'])) + self.parent.append(nodes.Text(node['alt'])) raise nodes.SkipNode def ignore_node_but_process_children(self, node): diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 107bdfdee..15ca5db89 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -66,9 +66,9 @@ class Hyperlinks(Transform): if len(self.document.anonymous_refs) \ != len(self.document.anonymous_targets): msg = self.document.reporter.error( - 'Anonymous hyperlink mismatch: %s references but %s targets.' - % (len(self.document.anonymous_refs), - len(self.document.anonymous_targets))) + 'Anonymous hyperlink mismatch: %s references but %s ' + 'targets.' % (len(self.document.anonymous_refs), + len(self.document.anonymous_targets))) self.document.messages += msg msgid = self.document.set_id(msg) for ref in self.document.anonymous_refs: @@ -101,9 +101,9 @@ class Hyperlinks(Transform): <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):: + 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"> @@ -585,7 +585,8 @@ class Footnotes(Transform): def resolve_footnotes_and_citations(self): """ - Link manually-labeled footnotes and citations to/from their references. + Link manually-labeled footnotes and citations to/from their + references. """ for footnote in self.document.footnotes: label = footnote['name'] @@ -643,10 +644,11 @@ class Substitutions(Transform): for refname, refs in self.document.substitution_refs.items(): for ref in refs: if defs.has_key(refname): - ref.parent.replace(ref, defs[refname].getchildren()) + ref.parent.replace(ref, defs[refname].get_children()) else: msg = self.document.reporter.error( - 'Undefined substitution referenced: "%s".' % refname) + 'Undefined substitution referenced: "%s".' + % refname) msgid = self.document.set_id(msg) self.document.messages += msg prb = nodes.problematic( diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 145a89b01..36c83f003 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -32,7 +32,7 @@ class Messages(Transform): """ def transform(self): - unfiltered = self.document.messages.getchildren() + unfiltered = self.document.messages.get_children() threshold = self.document.reporter['writer'].warning_level messages = [] for msg in unfiltered: @@ -54,7 +54,7 @@ class TestMessages(Transform): """ def transform(self): - self.document += self.document.messages.getchildren() + self.document += self.document.messages.get_children() class FinalChecks(Transform): diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 0f560e7ee..349ea3b24 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -49,7 +49,7 @@ class Writer(Component): def write(self, document, destination): self.document = document - self.language = languages.getlanguage(document.language_code) + self.language = languages.get_language(document.language_code) self.destination = destination self.transform() self.translate() @@ -83,7 +83,7 @@ class Writer(Component): (b) a path to a file, which is opened and then written; or (c) `None`, which implies `sys.stdout`. """ - output = output.encode('raw-unicode-escape') # @@@ temporary + output = output.encode('utf-8') # @@@ temporary; must not hard-code if hasattr(self.destination, 'write'): destination.write(output) elif self.destination: -- cgit v1.2.1 From 9957cf043607b483c6e8e869549911be5ce5a4d0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:23:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@110 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/dev/todo.txt | 15 ++++++------ test/test_nodes.py | 4 ++-- test/test_parsers/test_rst/test_comments.py | 21 ++++++++++++++++ .../test_parsers/test_rst/test_definition_lists.py | 28 ++++++++++++++++++++++ .../test_parsers/test_rst/test_enumerated_lists.py | 8 +++---- test/test_parsers/test_rst/test_field_lists.py | 2 +- 7 files changed, 65 insertions(+), 14 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index a153ded26..e438c3cfd 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -118,6 +118,7 @@ Specific: - Made XHTML-compatible (switched to lowercase element & attribute names; empty tag format). - Escape double-dashes in comment text. + - Improved boilerplate & modularity of output. * docutils/writers/pseudoxml.py: Renamed from pprint.py. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 2c48bc7e8..675b546f8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -57,6 +57,7 @@ General - @@ Add support for character set encodings on input & output, Unicode internally. + - Default UTF-8 on both input & output, overrideable. - Use an "encoding" directive, and/or an "encoding" field in field lists & PEP headers. (The same could apply to "language".) - Need a Unicode -> HTML entities codec for HTML writer? @@ -135,11 +136,11 @@ reStructuredText Parser - issue a warning when processing documents with no default role which contain interpreted text with no explicitly specified role -- Fix the parser's indentation handling to conform with the stricter - definition in the spec. (Explicit markup blocks should be strict or - forgiving?) +- @@ Fix the parser's indentation handling to conform with the + stricter definition in the spec. (Explicit markup blocks should be + strict or forgiving?) -- Tighten up the spec for indentation of "constructs using complex +- @@ Tighten up the spec for indentation of "constructs using complex markers": field lists and option lists? Bodies may begin on the same line as the marker or on a subsequent line (with blank lines optional). Require that for bodies beginning on the same line as @@ -266,9 +267,9 @@ Directives - _`body.columns`: Multi-column table/list, with number of columns as argument. - - _`body.verse`: Paragraphs with linebreaks preserved, *and* inline - markup support too. Use cases: verse (poetry, song lyrics, etc.), - address blocks. A directive would be easy; what about a + - @@ _`body.verse`: Paragraphs with linebreaks preserved, *and* + inline markup support too. Use cases: verse (poetry, song lyrics, + etc.), address blocks. A directive would be easy; what about a literal-block-like prefix, perhaps "``;;``"? (It is, after all, a *semi-literal* literal block, no?) Example:: diff --git a/test/test_nodes.py b/test/test_nodes.py index 1d813b142..ddec58b95 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -96,8 +96,8 @@ class TreeCopyVisitorTests(unittest.TestCase): def compare_trees(self, one, two): self.assertEquals(one.__class__, two.__class__) self.assertNotEquals(id(one), id(two)) - children1 = one.getchildren() - children2 = two.getchildren() + children1 = one.get_children() + children2 = two.get_children() self.assertEquals(len(children1), len(children2)) for i in range(len(children1)): self.compare_trees(children1[i], children2[i]) diff --git a/test/test_parsers/test_rst/test_comments.py b/test/test_parsers/test_rst/test_comments.py index 11cea2a1e..73d83dc7d 100755 --- a/test/test_parsers/test_rst/test_comments.py +++ b/test/test_parsers/test_rst/test_comments.py @@ -93,6 +93,27 @@ Paragraph. Paragraph. """], ["""\ +.. A comment. +.. Another. +no blank line + +Paragraph. +""", +"""\ +<document> + <comment> + A comment. + <comment> + Another. + <system_message level="2" type="WARNING"> + <paragraph> + Explicit markup ends without a blank line; unexpected unindent at line 3. + <paragraph> + no blank line + <paragraph> + Paragraph. +"""], +["""\ .. A comment:: Paragraph. diff --git a/test/test_parsers/test_rst/test_definition_lists.py b/test/test_parsers/test_rst/test_definition_lists.py index c24e582ea..81f71a3c5 100755 --- a/test/test_parsers/test_rst/test_definition_lists.py +++ b/test/test_parsers/test_rst/test_definition_lists.py @@ -135,6 +135,34 @@ term 2 definition 2 """], ["""\ +term 1 + definition 1 (no blank line below) +term 2 + definition 2 +No blank line after the definition list. +""", +"""\ +<document> + <definition_list> + <definition_list_item> + <term> + term 1 + <definition> + <paragraph> + definition 1 (no blank line below) + <definition_list_item> + <term> + term 2 + <definition> + <paragraph> + definition 2 + <system_message level="2" type="WARNING"> + <paragraph> + Definition list ends without a blank line; unexpected unindent at line 5. + <paragraph> + No blank line after the definition list. +"""], +["""\ term 1 definition 1 diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index 0eb599e44..75e6e28f8 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -132,7 +132,7 @@ Skipping item 3: Item 2. <system_message level="2" type="WARNING"> <paragraph> - Enumerated list ends without a blank line; unexpected unindent at line 4. + Enumerated list ends without a blank line; unexpected unindent at line 5. <system_message level="1" type="INFO"> <paragraph> Enumerated list start value not ordinal-1 at line 5: '4' (ordinal 4) @@ -320,7 +320,7 @@ iiii. iiii iii <system_message level="2" type="WARNING"> <paragraph> - Enumerated list ends without a blank line; unexpected unindent at line 4. + Enumerated list ends without a blank line; unexpected unindent at line 6. <system_message level="3" type="ERROR"> <paragraph> Enumerated list start value invalid at line 6: 'iiii' (sequence 'lowerroman') @@ -470,7 +470,7 @@ iii. Item iii. Item I. <system_message level="2" type="WARNING"> <paragraph> - Enumerated list ends without a blank line; unexpected unindent at line 4. + Enumerated list ends without a blank line; unexpected unindent at line 12. <system_message level="1" type="INFO"> <paragraph> Enumerated list start value not ordinal-1 at line 12: 'II' (ordinal 2) @@ -511,7 +511,7 @@ iii. Item iii. Item i. <system_message level="2" type="WARNING"> <paragraph> - Enumerated list ends without a blank line; unexpected unindent at line 16. + Enumerated list ends without a blank line; unexpected unindent at line 24. <system_message level="1" type="INFO"> <paragraph> Enumerated list start value not ordinal-1 at line 24: 'ii' (ordinal 2) diff --git a/test/test_parsers/test_rst/test_field_lists.py b/test/test_parsers/test_rst/test_field_lists.py index 254126af4..082b252d1 100755 --- a/test/test_parsers/test_rst/test_field_lists.py +++ b/test/test_parsers/test_rst/test_field_lists.py @@ -459,7 +459,7 @@ Field: marker is missing its open-colon. Me <system_message level="2" type="WARNING"> <paragraph> - Field list ends without a blank line; unexpected unindent at line 4. + Field list ends without a blank line; unexpected unindent at line 5. <paragraph> No blank line before this paragraph. <field_list> -- cgit v1.2.1 From bd058e6fbfa94584b9026f705cd5cbe73dfa9827 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 May 2002 04:40:43 +0000 Subject: fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@111 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index eb62d6206..c1e3246b5 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -17,7 +17,7 @@ contains a minimum of formatting information. A cascading style sheet __docformat__ = 'reStructuredText' -import time, string, re +import sys, time, string, re from types import ListType from docutils import writers, nodes, languages @@ -48,9 +48,9 @@ class HTMLTranslator(nodes.NodeVisitor): 'xhtml1-transitional.dtd">\n' html_head = '<html lang="%s">\n<head>\n' content_type = '<meta http-equiv=Content-Type content="text/html; ' \ - 'charset=UTF-8">\n', + 'charset=UTF-8">\n' stylesheet_link = '<link rel="stylesheet" href="default.css"' \ - ' type="text/css" />\n'] + ' type="text/css" />\n' def __init__(self, document): nodes.NodeVisitor.__init__(self, document) -- cgit v1.2.1 From aad2f637864a51bff65375083359cdf72652004c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 9 May 2002 04:14:55 +0000 Subject: - Added "pdf" alias in anticipation of Engelbert Gruber's PDF writer. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@114 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 349ea3b24..49eba12da 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -95,7 +95,8 @@ class Writer(Component): _writer_aliases = { 'html': 'html4css1', 'pprint': 'pseudoxml', - 'pformat': 'pseudoxml',} + 'pformat': 'pseudoxml', + 'pdf': 'rlpdf',} def get_writer_class(writer_name): """Return the Writer class from the `writer_name` module.""" -- cgit v1.2.1 From 1ec0693d345f079e7bc24811979021233dd25efe Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 9 May 2002 04:18:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@115 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 + docs/dev/todo.txt | 125 ++++++++++++++++++--- .../test_parsers/test_rst/test_definition_lists.py | 17 +++ 3 files changed, 130 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e438c3cfd..ffbbcb264 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -113,6 +113,9 @@ Specific: * docutils/transforms/universal.py: Changed ``Messages`` transform to properly filter out system messages below the warning threshold. +* 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 @@ -122,6 +125,8 @@ Specific: * docutils/writers/pseudoxml.py: Renamed from pprint.py. +* spec/notes.txt: Continual updates. Added "Project Policies". + * spec/pep-0257.txt: Clarified prohibition of signature repetition. * spec/rst/reStructuredText.txt: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 675b546f8..ff7812339 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -44,7 +44,7 @@ General & use them. - In reader.get_reader_class (& parser & writer too), should we be - importing 'standalone' or 'docutils.readers.standalone'? (This would + importing "standalone" or "docutils.readers.standalone"? (This would avoid importing top-level modules if the module name is not in docutils/readers. Potential nastiness.) @@ -97,7 +97,7 @@ reStructuredText Parser - Support generic hyperlink references to targets in other documents? Not in an HTML-centric way, though (it's trivial to say - ``http://www.whatever.com/doc#name``, and useless in non-HTML + ``http://www.example.com/doc#name``, and useless in non-HTML contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. @@ -122,7 +122,7 @@ reStructuredText Parser - Implement the header row separator modification to table.el. (Wrote to Takaaki Ota & the table.el mailing list on 2001-08-12, suggesting - support for '=====' header rows. On 2001-08-17 he replied, saying + support for "=====" header rows. On 2001-08-17 he replied, saying he'd put it on his to-do list, but "don't hold your breath".) - Tony says inline markup rule 7 could do with a *little* more @@ -300,9 +300,11 @@ Directives than implicit. Within a "verse" element, should any other constructs be allowed? - Should lists be recognized? The equivalent of block quotes (i.e., - further indented blocks) would be nested verse elements. These - could be "chorus" blocks. + Should lists be recognized? No; verse blocks are variations on + paragraphs, and need not contain arbitrary nested body elements. + However, the equivalent of block quotes (i.e., further indented + blocks) would be nested verse elements. These could be "chorus" + blocks. Perhaps individually indented "continuation lines" should also be recognized (maybe with a "continuation" attribute on the "line" @@ -312,7 +314,7 @@ Directives Ewan McTeagle (for Lassie O'Shea): ;; Lend us a couple of bob till Thursday. - I'm absolutely stint. + I'm absolutely skint. But I'm expecting a postal order and I can pay you back as soon as it comes. Love, Ewan. @@ -394,30 +396,119 @@ HTML Writer to the client? Or up to an explicit distributor/filer? +Project Policies +================ + Coding Conventions -================== +------------------ -This project shall follow the generic coding conventions as specified -in the `Style Guide for Python Code`__ and `Docstring Conventions`__ -PEPs, with the following clarifications: +The Docutils project shall follow the generic coding conventions as +specified in the `Style Guide for Python Code`__ and `Docstring +Conventions`__ PEPs, with the following clarifications: - 4 spaces per indentation level. No tabs. + - No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is O.K.). -- Lines should be no more than 78 or 79 characters long. -- "CamelCase" shall be used for class names (except for element - classes in docutils.nodes). + +- Lines should be no more than 78 characters long. + +- Use "CamelCase" for class names (except for element classes in + docutils.nodes). + - Use "lowercase" or "lowercase_with_underscores" for function, method, and variable names. For short names, maximum two joined - words, use lowercase (e.g. 'tagname'). For long names with three or + words, use lowercase (e.g. "tagname"). For long names with three or more joined words, or where it's hard to parse the split between two - words, use lowercase_with_underscores (e.g., 'note_explicit_target', - 'explicit_target'). If in doubt, use underscores. + words, use lowercase_with_underscores (e.g., "note_explicit_target", + "explicit_target"). If in doubt, use underscores. + +- Use 'single quotes' for string literals, and """triple double + quotes""" for docstrings. __ http://www.python.org/peps/pep-0008.html __ http://www.python.org/peps/pep-0257.html + +CVS Check-ins +------------- + +Instructions for CVS access can be found at +http://sourceforge.net/cvs/?group_id=38414. Anyone can access the CVS +repository anonymously. Only project developers can make changes. + +The `main source tree`_ ("docutils" CVS module) should always be kept +in a stable state (usable and as problem-free as possible). The +Docutils project shall follow the `Python Check-in Policies`_ (as +applicable), with particular emphasis as follows: + +- Before checking in any changes, run the entire Docutils test suite + to be sure that you haven't broken anything. From a shell:: + + cd docutils/test + alltests.py + +- When adding new functionality (or fixing bugs), be sure to add test + cases to the test suite. Practise test-first programming; it's fun, + it's addictive, and it works! + +- The sandbox_ is the place to put new, untried code. See `Additions + to Docutils`_ below. + +Please consider subscribing to the appropriate `mailing lists`_. + +.. _main source tree: + http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/docutils/ +.. _Python Check-in Policies: http://www.python.org/dev/tools.html +.. _sandbox: + http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/sandbox/ +.. _mailing lists: ../index.html#mailing-lists + + +Additions to Docutils +````````````````````` + +Additions to the project, such as new components, should be developed +in in the sandbox_ until they're in good shape, usable, and reasonably +complete. Adding to the `main source tree`_ implies a commitment to +the Docutils user community. + +- Why the sandbox? + + Developers should be able to try out new components while they're + being developed for addition to main source tree. + + The sandbox is a place to play around, to try out and share ideas. + It's a part of the CVS repository but it isn't distributed as part + of Docutils releases. Each developer who wants to play in the + sandbox should create their own subdirectory (suggested name: + SourceForge ID, or given name + family initial). It's OK to make a + mess! But please, play nice. + +- "Good shape" means that the component code is clean, readable, and + free of junk (unused legacy code; by analogy with "junk DNA"). + +- "Usable" means that the code does what it claims to do. An "XYZ + Writer" should produce reasonable XYZ. + +- "Reasonably complete" means that the code must handle all input. + Here "handle" means that no input can cause the code to fail (cause + an exception, or silently and incorrectly produce nothing). + "Reasonably complete" does not mean "finished" (no work left to be + done). For example, a writer must handle every standard element + from the Docutils document model; for unimplemented elements, it + must *at the very least* warn that "Output for element X is not yet + implemented in writer Y". + +If you really want to check code into the main source tree, you can, +but you'll have to be prepared to work on it intensively and complete +it quickly. People will start to use it and they will expect it to +work! If there are any issues with your code, or if you only have +time for gradual development, you should put it in the sandbox first. +It's easy to move code over to the main source tree once it's closer +to completion. + .. Local Variables: diff --git a/test/test_parsers/test_rst/test_definition_lists.py b/test/test_parsers/test_rst/test_definition_lists.py index 81f71a3c5..0142420fe 100755 --- a/test/test_parsers/test_rst/test_definition_lists.py +++ b/test/test_parsers/test_rst/test_definition_lists.py @@ -90,6 +90,23 @@ A paragraph:: A literal block without a blank line first? """], ["""\ +this is not a term; +a term may only be one line long + this is not a definition +""", +"""\ +<document> + <paragraph> + this is not a term; + a term may only be one line long + <system_message level="3" type="ERROR"> + <paragraph> + Unexpected indentation at line 3. + <block_quote> + <paragraph> + this is not a definition +"""], +["""\ term 1 definition 1 -- cgit v1.2.1 From 77568921276db01c972cb1ee4dd8b42d7bf1b7a6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 May 2002 03:50:05 +0000 Subject: - Clarified purpose of directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@116 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 66 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 37b53f784..07c16ccd5 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1581,6 +1581,26 @@ Directives DTD elements: depend on the directive. +Directives are an extension mechanism for reStructuredText, a way of +adding support for new constructs without adding new syntax. +Directives which have been implemented and registered in the reference +reStructuredText parser are described in the `reStructuredText +Directives`_ document. For example, here's how an image may be +placed:: + + .. image:: mylogo.png + +A figure (a graphic with a caption) may placed like this:: + + .. figure:: larch.png + The larch. + +An admonition (note, caution, etc.) contains other body elements:: + + .. note:: This is a paragraph + + - Here is a bullet list. + Directives are indicated by an explicit markup start (".. ") followed by the directive type, two colons, and whitespace. Directive types are case-insensitive single words (alphanumerics plus internal @@ -1609,42 +1629,20 @@ interpreted as a directive block. Simple directives may not require any text beyond the directive data (if that), and will not process any following indented text. -Directives which have been implemented and registered in the reference -reStructuredText parser are described in the `reStructuredText -Directives`_ document. Below are examples of implemented directives. - Directives are meant for the arbitrary processing of their contents (the directive data & text block), which can be transformed into -something possibly unrelated to the original text. Directives are -used as an extension mechanism for reStructuredText, a way of adding -support for new constructs without adding new syntax. For example, -here's how an image may be placed:: - - .. image:: mylogo.png - -A figure (a graphic with a caption) may placed like this:: - - .. figure:: larch.png - The larch. - -An admonition (note, caution, etc.) contains other body elements:: - - .. note:: This is a paragraph - - - Here is a bullet list. - -It may also be possible for directives to be used as pragmas, to -modify the behavior of the parser, such as to experiment with -alternate syntax. There is no parser support for this functionality -at present; if a reasonable need for pragma directives is found, they -may be supported. - -Directives normally do not survive as "directive" elements past the -parsing stage; they are a *parser construct* only, and have no -intrinsic meaning outside of reStructuredText. Instead, the parser -will transform recognized directives into (possibly specialized) -document elements. Unknown directives will trigger level-3 (error) -system messages. +something possibly unrelated to the original text. It may also be +possible for directives to be used as pragmas, to modify the behavior +of the parser, such as to experiment with alternate syntax. There is +no parser support for this functionality at present; if a reasonable +need for pragma directives is found, they may be supported. + +Directives do not survive as "directive" elements past the parsing +stage; they are a *parser construct* only, and have no intrinsic +meaning outside of reStructuredText. Instead, the parser will +transform recognized directives into (possibly specialized) document +elements. Unknown directives will trigger level-3 (error) system +messages. Syntax diagram:: -- cgit v1.2.1 From 0933cae075aafd615c9a0519aa07cdee667d8d38 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 May 2002 03:51:13 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@117 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/dev/todo.txt | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ffbbcb264..3f7dfd821 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -133,6 +133,7 @@ Specific: - Clarified field list usage. - Updated enumerated list description. + - Clarified purpose of directives. * spec/rst/alternatives.txt: Expanded auto-enumerated list idea; thanks to Fred Bremmer. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index ff7812339..bbab8bddb 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -136,6 +136,10 @@ reStructuredText Parser - issue a warning when processing documents with no default role which contain interpreted text with no explicitly specified role +- Perhaps the "default default" role for interpreted text could be + "title", as in, "title of a book". It'd be a text-only reference, + no hyperlink. Idea from Aahz' 2002-05-09 Doc-SIG post. + - @@ Fix the parser's indentation handling to conform with the stricter definition in the spec. (Explicit markup blocks should be strict or forgiving?) @@ -402,11 +406,20 @@ Project Policies Coding Conventions ------------------ +These are the conventions I use in my own code. Contributed code will +not be refused merely because it does not strictly adhere to these +conditions; as long as it's internally consistent, clean, and correct, +it probably will be accepted. But don't be surprised if the +"offending" code gets fiddled over time to conform to these +conventions. + The Docutils project shall follow the generic coding conventions as specified in the `Style Guide for Python Code`__ and `Docstring -Conventions`__ PEPs, with the following clarifications: +Conventions`__ PEPs, with the following clarifications (from most to +least important): -- 4 spaces per indentation level. No tabs. +- 4 spaces per indentation level. No tabs. Indent continuation lines + according to the Emacs' python-mode standard. - No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method @@ -418,11 +431,12 @@ Conventions`__ PEPs, with the following clarifications: docutils.nodes). - Use "lowercase" or "lowercase_with_underscores" for function, - method, and variable names. For short names, maximum two joined - words, use lowercase (e.g. "tagname"). For long names with three or - more joined words, or where it's hard to parse the split between two - words, use lowercase_with_underscores (e.g., "note_explicit_target", - "explicit_target"). If in doubt, use underscores. + method, and variable names. For short names, maximum two words, + joined lowercase may be used (e.g. "tagname"). For long names with + three or more words, or where it's hard to parse the split between + two words, use lowercase_with_underscores (e.g., + "note_explicit_target", "explicit_target"). If in doubt, use + underscores. - Use 'single quotes' for string literals, and """triple double quotes""" for docstrings. -- cgit v1.2.1 From 8f2153983e79ea721ea895853f12746eb824b58f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 May 2002 16:45:40 +0000 Subject: more directive clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@121 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 07c16ccd5..32d03f7ea 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1582,11 +1582,14 @@ Directives DTD elements: depend on the directive. Directives are an extension mechanism for reStructuredText, a way of -adding support for new constructs without adding new syntax. -Directives which have been implemented and registered in the reference -reStructuredText parser are described in the `reStructuredText -Directives`_ document. For example, here's how an image may be -placed:: +adding support for new constructs without adding new syntax. All +standard directives (those implemented and registered in the reference +reStructuredText parser) are described in the `reStructuredText +Directives`_ document, and are always available. Any other directives +are domain-specific, and may require special action to make them +available when processing the document. + +For example, here's how an image may be placed:: .. image:: mylogo.png -- cgit v1.2.1 From 393114781fc407dd29fc736f05372e83552f0b5c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 May 2002 16:46:17 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@122 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index bbab8bddb..a629ea411 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -323,6 +323,10 @@ Directives as soon as it comes. Love, Ewan. + Directive name alternatives: verse, addressblock, address, + lineblock, lines, multiline, freeform, keeplines, nowrap, haiku, + keepbreaks, linebreaks. + - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need some kind of "alternate" mechanism? Perhaps use a "pending" @@ -399,6 +403,28 @@ HTML Writer - @@ Return a string instead of writing to a file? Leave all I/O up to the client? Or up to an explicit distributor/filer? +- @@ Add an option to generate "source text" links (i.e., click to see + the source text). + +- @@ Add an option to generate "generated by Docutils from + reStructuredText source" messages, with links. + + +Front-End +--------- + +- Combine the common code from the existing front-ends into a single + library. + + - Use Optik to do modular command-line option processing. + + - The core would support all common options (--reader, --writer, + etc.). + + - Each front-end would add their own specific options (HTML: + --stylesheet, etc.), and perhaps disable common options that don't + apply. + Project Policies ================ -- cgit v1.2.1 From c9957ebcea78d02fcc2c316e4c902fdf83031c09 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 May 2002 18:38:10 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@123 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 32d03f7ea..31c22a184 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1596,6 +1596,7 @@ For example, here's how an image may be placed:: A figure (a graphic with a caption) may placed like this:: .. figure:: larch.png + The larch. An admonition (note, caution, etc.) contains other body elements:: -- cgit v1.2.1 From 0d70f08e9e19d34bfe082d13170ca4e525f92425 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:51:30 +0000 Subject: - Minor edits. - Reworked Q&A as an enumerated list. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@128 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 549 +++++++++++++++++++++++++------------------------ 1 file changed, 277 insertions(+), 272 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index a3d4216d1..ecfa3186c 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -48,7 +48,7 @@ Benefits and software systems; readers are only meant to see the processed form, either on paper or via browser software. ReStructuredText is different: it is intended to be easily readable in source form, - without prior knowledge of the markup. ReStructuredText) is + without prior knowledge of the markup. ReStructuredText is entirely readable in plaintext format, and many of the markup forms match common usage (e.g., ``*emphasis*``), so it reads quite naturally. Yet it is rich enough to produce complex documents, @@ -67,7 +67,7 @@ Benefits Tools will become available in the near future, which will allow programmers to generate HTML for online help, XML for multiple - purposes, and perhaps eventually PDF/DocBook/LaTeX for printed + purposes, and eventually PDF/DocBook/LaTeX for printed documentation, essentially "for free" from the existing docstrings. The adoption of a standard will, at the very least, benefit docstring processing tools by preventing further @@ -98,7 +98,8 @@ Goals docstrings, without feeling hampered by the markup language. reStructuredText meets and exceeds all of these goals, and sets - its own goals as well, even more stringent. See "Features" below. + its own goals as well, even more stringent. See + "Docstring-Significant Features" below. The goals of this PEP are as follows: @@ -132,9 +133,9 @@ Goals be applied: a) Keep the existing PEP section structure constructs (one-line - section headers, indented body text). Subsections can - either be forbidden or supported with underlined headers in - the indented body text. + section headers, indented body text). Subsections can either + be forbidden, or supported with reStructuredText-style + underlined headers in the indented body text. b) Replace the PEP section structure constructs with the reStructuredText syntax. Section headers will require @@ -142,11 +143,11 @@ Goals and body text need not be indented (except for block quotes). - Support for RFC 2822 headers will be added to the reStructuredText - parser for PEPs (unambiguous given a specific context: the first - contiguous block of the document). It may be desired to - concretely specify what over/underline styles are allowed for PEP - section headers, for uniformity. + Support for RFC 2822 headers has been added to the + reStructuredText parser for PEPs (unambiguous given a specific + context: the first contiguous block of the document). It may be + desired to concretely specify what over/underline styles are + allowed for PEP section headers, for uniformity. Rationale @@ -203,8 +204,8 @@ Rationale - Perl POD [9]_ - Most Perl modules are documented in a format called POD -- Plain - Old Documentation. This is an easy-to-type, very low level + Most Perl modules are documented in a format called POD (Plain + Old Documentation). This is an easy-to-type, very low level format with strong integration with the Perl parser. Many tools exist to turn POD documentation into other formats: info, HTML and man pages, among others. However, the POD syntax takes @@ -250,6 +251,7 @@ Rationale - There has been no mechanism to get around the SText markup rules when a markup character is used in a non-markup context. + In other words, no way to escape markup. Proponents of implicit STexts have vigorously opposed proposals for explicit markup (XML, HTML, TeX, POD, etc.), and the debates @@ -268,8 +270,8 @@ Specification Please first take a look at "A ReStructuredText Primer" [13]_, a short and gentle introduction. The "Quick reStructuredText" user reference [14]_ quickly summarizes all of the markup constructs. - For complete and extensive details, the following documents - contain the full specification itself: + For complete and extensive details, please refer to the following + documents: - An Introduction to reStructuredText [15]_ @@ -458,263 +460,266 @@ Docstring-Significant Features Questions & Answers - Q1: Is reStructuredText rich enough? - - A1: Yes, it is for most people. If it lacks some construct that - is required for a specific application, it can be added via - the directive mechanism. If a common construct has been - overlooked and a suitably readable syntax can be found, it can - be added to the specification and parser. - - Q2: Is reStructuredText *too* rich? - - A2: For specific applications or individuals, perhaps. In - general, no. - - Since the very beginning, whenever a markup syntax has been - proposed on the Doc-SIG, someone has complained about the lack - of support for some construct or other. The reply was often - something like, "These are docstrings we're talking about, and - docstrings shouldn't have complex markup." The problem is - that a construct that seems superfluous to one person may be - absolutely essential to another. - - reStructuredText takes the opposite approach: it provides a - rich set of implicit markup constructs (plus a generic - extension mechanism for explicit markup), allowing for all - kinds of documents. If the set of constructs is too rich for - a particular application, the unused constructs can either be - removed from the parser (via application-specific overrides) - or simply omitted by convention. - - Q3: Why not use indentation for section structure, like - StructuredText does? Isn't it more "Pythonic"? - - A3: Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG - post: - - I still think that using indentation to indicate - sectioning is wrong. If you look at how real books and - other print publications are laid out, you'll notice that - indentation is used frequently, but mostly at the - intra-section level. Indentation can be used to offset - lists, tables, quotations, examples, and the like. (The - argument that docstrings are different because they are - input for a text formatter is wrong: the whole point is - that they are also readable without processing.) - - I reject the argument that using indentation is Pythonic: - text is not code, and different traditions and conventions - hold. People have been presenting text for readability - for over 30 centuries. Let's not innovate needlessly. - - See "Section Structure via Indentation" in "Problems With - StructuredText" [18 ]_ for further elaboration. - - Q4: Why use reStructuredText for PEPs? What's wrong with the - existing standard? - - A4: The existing standard for PEPs is very limited in terms of - general expressibility, and referencing is especially lacking - for such a reference-rich document type. PEPs are currently - converted into HTML, but the results (mostly monospaced text) - are less than attractive, and most of the value-added - potential of HTML is untapped. - - Making reStructuredText a standard markup for PEPs will enable - much richer expression, including support for section - structure, inline markup, graphics, and tables. In several - PEPs there are ASCII graphics diagrams, which are all that - plaintext documents can support. Since PEPs are made - available in HTML form, the ability to include proper diagrams - would be immediately useful. - - Current PEP practices allow for reference markers in the form - "[1]" in the text, and the footnotes/references themselves are - listed in a section toward the end of the document. There is - currently no hyperlinking between the reference marker and the - footnote/reference itself (it would be possible to add this to - pep2html.py, but the "markup" as it stands is ambiguous and - mistakes would be inevitable). A PEP with many references - (such as this one ;-) requires a lot of flipping back and - forth. When revising a PEP, often new references are added or - unused references deleted. It is painful to renumber the - references, since it has to be done in two places and can have - a cascading effect (insert a single new reference 1, and every - other reference has to be renumbered; always adding new - references to the end is suboptimal). It is easy for - references to go out of sync. - - PEPs use references for two purposes: simple URL references - and footnotes. reStructuredText differentiates between the - two. A PEP might contain references like this:: - - Abstract - - This PEP proposes adding frungible doodads [1] to the - core. It extends PEP 9876 [2] via the BCA [3] - mechanism. - - References and Footnotes - - [1] http://www.example.org/ - - [2] PEP 9876, Let's Hope We Never Get Here - http://www.python.org/peps/pep-9876.html - - [3] "Bogus Complexity Addition" - - Reference 1 is a simple URL reference. Reference 2 is a - footnote containing text and a URL. Reference 3 is a footnote - containing text only. Rewritten using reStructuredText, this - PEP could look like this:: - - Abstract - ======== - - This PEP proposes adding `frungible doodads`_ to the - core. It extends PEP 9876 [#pep9876]_ via the BCA [#]_ - mechanism. - - .. _frungible doodads: http://www.example.org/ - - .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here - - __ http://www.python.org/peps/pep-9876.html - - .. [#] "Bogus Complexity Addition" - - URLs and footnotes can be defined close to their references if - desired, making them easier to read in the source text, and - making the PEPs easier to revise. The "References and - Footnotes" section can be auto-generated with a document tree - transform. Footnotes from throughout the PEP would be - gathered and displayed under a standard header. If URL - references should likewise be written out explicitly (in - citation form), another tree transform could be used. - - URL references can be named ("frungible doodads"), and can be - referenced from multiple places in the document without - additional definitions. When converted to HTML, references - will be replaced with inline hyperlinks (HTML <A> tags). The - two footnotes are automatically numbered, so they will always - stay in sync. The first footnote also contains an internal - reference name, "pep9876", so it's easier to see the - connection between reference and footnote in the source text. - Named footnotes can be referenced multiple times, maintaining - consistent numbering. - - The "#pep9876" footnote could also be written in the form of a - citation:: - - It extends PEP 9876 [PEP9876]_ ... - - .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here - - Footnotes are numbered, whereas citations use text for their - references. - - Q5: Wouldn't it be better to keep the docstring and PEP proposals - separate? - - A5: The PEP markup proposal may be removed if it is deemed that - there is no need for PEP markup, or it could be made into a - separate PEP. If accepted, PEP 1, PEP Purpose and Guidelines - [20]_, and PEP 9, Sample PEP Template [21]_ will be updated. - - It seems natural to adopt a single consistent markup standard - for all uses of structured plaintext in Python, and to propose - it all in one place. - - Q6: The existing pep2html.py script converts the existing PEP - format to HTML. How will the new-format PEPs be converted to - HTML? - - A6: One of the deliverables of the Docutils project [22]_ will be - a new version of pep2html.py with integrated reStructuredText - parsing. The Docutils project will support PEPs with a "PEP - Reader" component, including all functionality currently in - pep2html.py (auto-recognition of PEP & RFC references). - - Q7: Who's going to convert the existing PEPs to reStructuredText? - - A7: PEP authors or volunteers may convert existing PEPs if they - like, but there is no requirement to do so. The - reStructuredText-based PEPs will coexist with the old PEP - standard. The pep2html.py mentioned in A6 will process both - old and new standards. - - Q8: Why use reStructuredText for README and other ancillary files? - - A8: The reasoning given for PEPs in A4 above also applies to - README and other ancillary files. By adopting a standard - markup, these files can be converted to attractive - cross-referenced HTML and put up on python.org. Developers of - Python projects can also take advantage of this facility for - their own documentation. - - Q9: Won't the superficial similarity to existing markup - conventions cause problems, and result in people writing - invalid markup (and not noticing, because the plaintext looks - natural)? How forgiving is reStructuredText of "not quite - right" markup? - - A9: There will be some mis-steps, as there would be when moving - from one programming language to another. As with any - language, proficiency grows with experience. Luckily, - reStructuredText is a very little language indeed. - - As with any syntax, there is the possibility of syntax errors. - It is expected that a user will run the processing system over - their input and check the output for correctness. - - In a strict sense, the reStructuredText parser is very - unforgiving (as it should be; "In the face of ambiguity, - refuse the temptation to guess" [23]_ applies to parsing - markup as well as computer languages). Here's a design goal - from "An Introduction to reStructuredText" [15 ]_: - - 3. Unambiguous. The rules for markup must not be open for - interpretation. For any given input, there should be - one and only one possible output (including error - output). - - While unforgiving, at the same time the parser does try to be - helpful by producing useful diagnostic output ("system - messages"). The parser reports problems, indicating their - level of severity (from least to most: debug, info, warning, - error, severe). The user or the client software can decide on - reporting thresholds; they can ignore low-level problems or - cause high-level problems to bring processing to an immediate - halt. Problems are reported during the parse as well as - included in the output, often with two-way links between the - source of the problem and the system message explaining it. - - Q10: Will the docstrings in the Python standard library modules be - converted to reStructuredText? - - A10: No. Python's library reference documentation is maintained - separately from the source. Docstrings in the Python - standard library should not try to duplicate the library - reference documentation. The current policy for docstrings - in the Python standard library is that they should be no more - than concise hints. - - Q11: I want to write all my strings in Unicode. Will anything - break? - - A11: The parser will fully support Unicode. It may not yet, but - only because nobody's gotten around to implementing or - testing Unicode support. Contributions are always welcome! - - Q12: Why does the community need a new structured text design? - What is wrong with existing markup methodologies? - - A12: The existing structured text designs are deficient. - @@@ - - For Python docstrings, there is no official standard. - @@@ + 1. Is reStructuredText rich enough? + + Yes, it is for most people. If it lacks some construct that is + required for a specific application, it can be added via the + directive mechanism. If a useful and common construct has been + overlooked and a suitably readable syntax can be found, it can + be added to the specification and parser. + + 2. Is reStructuredText *too* rich? + + For specific applications or individuals, perhaps. In general, + no. + + Since the very beginning, whenever a docstring markup syntax + has been proposed on the Doc-SIG, someone has complained about + the lack of support for some construct or other. The reply was + often something like, "These are docstrings we're talking + about, and docstrings shouldn't have complex markup." The + problem is that a construct that seems superfluous to one + person may be absolutely essential to another. + + reStructuredText takes the opposite approach: it provides a + rich set of implicit markup constructs (plus a generic + extension mechanism for explicit markup), allowing for all + kinds of documents. If the set of constructs is too rich for a + particular application, the unused constructs can either be + removed from the parser (via application-specific overrides) or + simply omitted by convention. + + 3. Why not use indentation for section structure, like + StructuredText does? Isn't it more "Pythonic"? + + Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG + post: + + I still think that using indentation to indicate sectioning + is wrong. If you look at how real books and other print + publications are laid out, you'll notice that indentation + is used frequently, but mostly at the intra-section level. + Indentation can be used to offset lists, tables, + quotations, examples, and the like. (The argument that + docstrings are different because they are input for a text + formatter is wrong: the whole point is that they are also + readable without processing.) + + I reject the argument that using indentation is Pythonic: + text is not code, and different traditions and conventions + hold. People have been presenting text for readability for + over 30 centuries. Let's not innovate needlessly. + + See "Section Structure via Indentation" in "Problems With + StructuredText" [18 ]_ for further elaboration. + + 4. Why use reStructuredText for PEPs? What's wrong with the + existing standard? + + The existing standard for PEPs is very limited in terms of + general expressibility, and referencing is especially lacking + for such a reference-rich document type. PEPs are currently + converted into HTML, but the results (mostly monospaced text) + are less than attractive, and most of the value-added potential + of HTML (especially inline hyperlinks) is untapped. + + Making reStructuredText a standard markup for PEPs will enable + much richer expression, including support for section + structure, inline markup, graphics, and tables. In several + PEPs there are ASCII graphics diagrams, which are all that + plaintext documents can support. Since PEPs are made available + in HTML form, the ability to include proper diagrams would be + immediately useful. + + Current PEP practices allow for reference markers in the form + "[1]" in the text, and the footnotes/references themselves are + listed in a section toward the end of the document. There is + currently no hyperlinking between the reference marker and the + footnote/reference itself (it would be possible to add this to + pep2html.py, but the "markup" as it stands is ambiguous and + mistakes would be inevitable). A PEP with many references + (such as this one ;-) requires a lot of flipping back and + forth. When revising a PEP, often new references are added or + unused references deleted. It is painful to renumber the + references, since it has to be done in two places and can have + a cascading effect (insert a single new reference 1, and every + other reference has to be renumbered; always adding new + references to the end is suboptimal). It is easy for + references to go out of sync. + + PEPs use references for two purposes: simple URL references and + footnotes. reStructuredText differentiates between the two. A + PEP might contain references like this:: + + Abstract + + This PEP proposes adding frungible doodads [1] to the + core. It extends PEP 9876 [2] via the BCA [3] + mechanism. + + References and Footnotes + + [1] http://www.example.org/ + + [2] PEP 9876, Let's Hope We Never Get Here + http://www.python.org/peps/pep-9876.html + + [3] "Bogus Complexity Addition" + + Reference 1 is a simple URL reference. Reference 2 is a + footnote containing text and a URL. Reference 3 is a footnote + containing text only. Rewritten using reStructuredText, this + PEP could look like this:: + + Abstract + ======== + + This PEP proposes adding `frungible doodads`_ to the core. + It extends PEP 9876 [#pep9876]_ via the BCA [#]_ mechanism. + + .. _frungible doodads: http://www.example.org/ + + .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here + + __ http://www.python.org/peps/pep-9876.html + + .. [#] "Bogus Complexity Addition" + + URLs and footnotes can be defined close to their references if + desired, making them easier to read in the source text, and + making the PEPs easier to revise. The "References and + Footnotes" section can be auto-generated with a document tree + transform. Footnotes from throughout the PEP would be gathered + and displayed under a standard header. If URL references + should likewise be written out explicitly (in citation form), + another tree transform could be used. + + URL references can be named ("frungible doodads"), and can be + referenced from multiple places in the document without + additional definitions. When converted to HTML, references + will be replaced with inline hyperlinks (HTML <A> tags). The + two footnotes are automatically numbered, so they will always + stay in sync. The first footnote also contains an internal + reference name, "pep9876", so it's easier to see the connection + between reference and footnote in the source text. Named + footnotes can be referenced multiple times, maintaining + consistent numbering. + + The "#pep9876" footnote could also be written in the form of a + citation:: + + It extends PEP 9876 [PEP9876]_ ... + + .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here + + Footnotes are numbered, whereas citations use text for their + references. + + 5. Wouldn't it be better to keep the docstring and PEP proposals + separate? + + The PEP markup proposal may be removed if it is deemed that + there is no need for PEP markup, or it could be made into a + separate PEP. If accepted, PEP 1, PEP Purpose and Guidelines + [20]_, and PEP 9, Sample PEP Template [21]_ will be updated. + + It seems natural to adopt a single consistent markup standard + for all uses of structured plaintext in Python, and to propose + it all in one place. + + 6. The existing pep2html.py script converts the existing PEP + format to HTML. How will the new-format PEPs be converted to + HTML? + + One of the deliverables of the Docutils project [22]_ will be a + new version of pep2html.py with integrated reStructuredText + parsing. The Docutils project will support PEPs with a "PEP + Reader" component, including all functionality currently in + pep2html.py (auto-recognition of PEP & RFC references). + + 7. Who's going to convert the existing PEPs to reStructuredText? + + PEP authors or volunteers may convert existing PEPs if they + like, but there is no requirement to do so. The + reStructuredText-based PEPs will coexist with the old PEP + standard. The pep2html.py mentioned in answer 6 will process + both old and new standards. + + 8. Why use reStructuredText for README and other ancillary files? + + The reasoning given for PEPs in answer 4 above also applies to + README and other ancillary files. By adopting a standard + markup, these files can be converted to attractive + cross-referenced HTML and put up on python.org. Developers of + Python projects can also take advantage of this facility for + their own documentation. + + 9. Won't the superficial similarity to existing markup conventions + cause problems, and result in people writing invalid markup + (and not noticing, because the plaintext looks natural)? How + forgiving is reStructuredText of "not quite right" markup? + + There will be some mis-steps, as there would be when moving + from one programming language to another. As with any + language, proficiency grows with experience. Luckily, + reStructuredText is a very little language indeed. + + As with any syntax, there is the possibility of syntax errors. + It is expected that a user will run the processing system over + their input and check the output for correctness. + + In a strict sense, the reStructuredText parser is very + unforgiving (as it should be; "In the face of ambiguity, refuse + the temptation to guess" [23]_ applies to parsing markup as + well as computer languages). Here's design goal 3 from "An + Introduction to reStructuredText" [15 ]_: + + Unambiguous. The rules for markup must not be open for + interpretation. For any given input, there should be one + and only one possible output (including error output). + + While unforgiving, at the same time the parser does try to be + helpful by producing useful diagnostic output ("system + messages"). The parser reports problems, indicating their + level of severity (from least to most: debug, info, warning, + error, severe). The user or the client software can decide on + reporting thresholds; they can ignore low-level problems or + cause high-level problems to bring processing to an immediate + halt. Problems are reported during the parse as well as + included in the output, often with two-way links between the + source of the problem and the system message explaining it. + + 10. Will the docstrings in the Python standard library modules be + converted to reStructuredText? + + No. Python's library reference documentation is maintained + separately from the source. Docstrings in the Python standard + library should not try to duplicate the library reference + documentation. The current policy for docstrings in the + Python standard library is that they should be no more than + concise hints, simple and markup-free (although many *do* + contain ad-hoc implicit markup). + + 11. I want to write all my strings in Unicode. Will anything + break? + + The parser will fully support Unicode. It may not yet, but + only because nobody's gotten around to implementing or testing + Unicode support. Contributions are always welcome! + + 12. Why does the community need a new structured text design? + + The existing structured text designs are deficient, for the + reasons given in "Rationale" above. + + 13. What is wrong with existing documentation methodologies? + + What existing methodologies? For Python docstrings, there is + **no** official standard markup format, let alone a + documentation methodology. The question of methodology is at + a much higher level than syntax (what this PEP addresses), + potentially much more controversial and difficult to resolve, + and is intentionally left out of this discussion. References & Footnotes -- cgit v1.2.1 From b55a024c56277e5f9afea839679eaec5893b5f86 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:52:35 +0000 Subject: Added "The Sandbox" section. Updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@129 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 184 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 146 insertions(+), 38 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a629ea411..11b55da83 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -62,6 +62,12 @@ General lists & PEP headers. (The same could apply to "language".) - Need a Unicode -> HTML entities codec for HTML writer? +- Distributor/filer object passed to Writer, equivalent passed to + Reader, to provide I/O access with a uniform API? (Names for input + object: inputter, sourcer, scanner.) Simple vs. complex I/O + structure: single file or string, vs. directory/package or tree of + strings. Simple string I/O is default? + Specification ------------- @@ -101,7 +107,7 @@ reStructuredText Parser contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. -- Add character processing? For example: +- Add _`character processing`? For example: - ``--`` -> em-dash (or ``--`` -> en-dash, and ``---`` -> em-dash). (Look for pre-existing conventions.) @@ -212,7 +218,7 @@ reStructuredText Parser Directives `````````` -- Allow directives to be added at run-time. +- Allow directives to be added at run-time? - Use the language module for directive attribute names? @@ -224,11 +230,11 @@ Directives image only in non-HTML writers?) - _`parts.endnotes` - + - _`parts.citations` - + - _`parts.topic` - + - _`parts.sectnum` (section numbering; add support to .contents; could be cmdline option also) @@ -253,21 +259,42 @@ Directives time or at substitution time? Dangerous? Perhaps limit to canned macros; see text.date_ below. - - @@@ _`body.qa` (directive a.k.a. "faq", "questions"): Questions & + - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a - standalone (non-directive) construct? (Is the markup ambiguous?) + standalone (non-directive) construct? (Is the markup ambiguous?) Add support to parts.Contents (optional attribute "qa" done). New elements would be required. Perhaps:: <!ELEMENT question_list (question_list_item+)> <!ATTLIST question_list - numbered (no | local | global) #IMPLIED + numbering (none | local | global) + #IMPLIED start NUMBER #IMPLIED> <!ELEMENT question_list_item (question, answer*)> <!ELEMENT question %text.model;> <!ELEMENT answer (%body.elements;)+> + Originally I thought of implementing a Q&A list with special + syntax:: + + Q: What am I? + + A: You are a question-and-answer + list. + + Q: What are you? + + A: I am the omniscient "we". + + Where each "Q" and "A" could also be numbered (e.g., "Q1"). + However, a simple enumerated or bulleted list will do just fine + for syntax. A directive could treat the list specially; e.g. the + first paragraph could be treated as a question, the remainder as + the answer (multiple answers could be represented by nested + lists). Without special syntax, this directive becomes low + priority. + - _`body.columns`: Multi-column table/list, with number of columns as argument. @@ -305,7 +332,7 @@ Directives Within a "verse" element, should any other constructs be allowed? Should lists be recognized? No; verse blocks are variations on - paragraphs, and need not contain arbitrary nested body elements. + paragraphs, and need not contain arbitrary nested body elements. However, the equivalent of block quotes (i.e., further indented blocks) would be nested verse elements. These could be "chorus" blocks. @@ -323,9 +350,22 @@ Directives as soon as it comes. Love, Ewan. - Directive name alternatives: verse, addressblock, address, - lineblock, lines, multiline, freeform, keeplines, nowrap, haiku, - keepbreaks, linebreaks. + Another idea for syntax: in an ordinary paragraph, if the first + line ends with a backslash (escaping the newline), interpret the + entire paragraph as a verse block? This ties in to the `character + processing`_ idea, above. For example:: + + Adding a backslash\ + And this paragraph becomes + An awful haiku + + (And arguably invalid, since in Japanese the word "haiku" contains + three syllables.) + + Directive/construct name alternatives: verse, addressblock, + address, lineblock, lines, multiline, freeform, keeplines, nowrap, + haiku, keepbreaks, linebreaks, obeylines, linewise, textblock, + textart, text, linetext. - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we @@ -391,39 +431,74 @@ Unimplemented Transforms HTML Writer ----------- -- @@ Allow for style sheet info to be passed in, either as a <LINK>, +- @@@ Allow for style sheet info to be passed in, either as a <LINK>, or as embedded style info. -- @ Construct a templating system, as in ht2html/yaptu, using +- @@@ Construct a templating system, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. - @@ Improve the granularity of document parts in the HTML writer, so that one could just grab the parts needed. -- @@ Return a string instead of writing to a file? Leave all I/O up +- @@@ Return a string instead of writing to a file? Leave all I/O up to the client? Or up to an explicit distributor/filer? -- @@ Add an option to generate "source text" links (i.e., click to see - the source text). +- @@ Add an option to generate a "View source text" link. -- @@ Add an option to generate "generated by Docutils from - reStructuredText source" messages, with links. +- @@ Add an option to generate a "Generated by Docutils [from + reStructuredText source?]" message, with links. +- If a list's items contain single paragraphs only, omit the <P> tags? + Recursively? (if item == list whose items are single paragraphs + only...) -Front-End ---------- -- Combine the common code from the existing front-ends into a single - library. +Front-Ends +---------- + +@@ Rather than a single all-purpose program, it is probably preferable +to have a bunch of small front-ends, each specialized for a specific +reader (and possibly writer as well). Each of the front-ends would +depend on a common code library described below. + +- Combine the common code from the existing front-ends into a + single library (docutils.frontend? docutils.core.xyz?). - Use Optik to do modular command-line option processing. + - Pass around an Optik 'options' object? Attach it to the + document? What to do when *not* using a front-end (i.e., when + docutils is imported by an unrelated client)? + - The core would support all common options (--reader, --writer, etc.). - Each front-end would add their own specific options (HTML: --stylesheet, etc.), and perhaps disable common options that don't - apply. + apply. (Added/removed dynamically? Is this possible with Optik? + Is it desirable?) + +- Command-line option ideas. Common options: + + --credit Include a "Generated by Docutils" credit with a + link. + --source-link Include a "(View document source)" link. + --verbose Report all system messages, info-level and higher. + (Same as "--report=info".) + --debug Report debug-level system messages. + --report=level Set verbosity; report system messages at or higher + than level (by name or number: "info" or "1", + warning/2, error/3, severe/4, none/5+). + --halt=level Set the level at or above which system messages are + converted to exceptions, halting execution + immediately. Levels as in --report. + --strict Same as "--halt=info": halt processing at the + slightest problem. + + Options specific to HTML writer: + + --stylesheet=file + Specify a stylesheet (default: "default.css"). Project Policies @@ -493,8 +568,8 @@ applicable), with particular emphasis as follows: cases to the test suite. Practise test-first programming; it's fun, it's addictive, and it works! -- The sandbox_ is the place to put new, untried code. See `Additions - to Docutils`_ below. +- The sandbox_ directory is the place to put new, untried code. See + `Additions to Docutils`_ and `The Sandbox`_ below. Please consider subscribing to the appropriate `mailing lists`_. @@ -510,21 +585,15 @@ Additions to Docutils ````````````````````` Additions to the project, such as new components, should be developed -in in the sandbox_ until they're in good shape, usable, and reasonably -complete. Adding to the `main source tree`_ implies a commitment to -the Docutils user community. +in the sandbox_ directory until they're in good shape, usable, and +reasonably complete. Adding to the `main source tree`_ implies a +commitment to the Docutils user community. - Why the sandbox? Developers should be able to try out new components while they're - being developed for addition to main source tree. - - The sandbox is a place to play around, to try out and share ideas. - It's a part of the CVS repository but it isn't distributed as part - of Docutils releases. Each developer who wants to play in the - sandbox should create their own subdirectory (suggested name: - SourceForge ID, or given name + family initial). It's OK to make a - mess! But please, play nice. + being developed for addition to main source tree. See `The + Sandbox`_ below. - "Good shape" means that the component code is clean, readable, and free of junk (unused legacy code; by analogy with "junk DNA"). @@ -534,7 +603,7 @@ the Docutils user community. - "Reasonably complete" means that the code must handle all input. Here "handle" means that no input can cause the code to fail (cause - an exception, or silently and incorrectly produce nothing). + an exception, or silently and incorrectly produce nothing). "Reasonably complete" does not mean "finished" (no work left to be done). For example, a writer must handle every standard element from the Docutils document model; for unimplemented elements, it @@ -549,6 +618,45 @@ time for gradual development, you should put it in the sandbox first. It's easy to move code over to the main source tree once it's closer to completion. + +The Sandbox +----------- + +The sandbox_ directory is a place to play around, to try out and share +ideas. It's a part of the CVS repository but it isn't distributed as +part of Docutils releases. Feel free to check in code to the CVS +sandbox; that way people can try it out but you won't have to worry +about it working 100% error-free, as is the goal of the `main source +tree`_. Each developer who wants to play in the sandbox should create +their own subdirectory (suggested name: SourceForge ID, or given name ++ family initial). It's OK to make a mess! But please, play nice. + +In order to minimize the work necessary for others to install and try +out new, experimental components, the following sandbox directory +structure is recommended:: + + sandbox/ + userid/ + component_name/ # A verbose name is best. + README.txt # Please explain requirements, + # purpose/goals, and usage. + docs/ + ... + component.py # The component is a single module. + # *OR* (but *not* both) + component/ # The component is a package. + __init__.py # Contains the Reader/Writer class. + other1.py # Other modules and data files used + data.txt # by this component. + ... + test/ # Test suite. + ... + tools/ # For front-ends etc. + ... + setup.py # Use Distutils to install the component + # code and tools/ files into the right + # places in Docutils. + .. Local Variables: -- cgit v1.2.1 From 3510bd954117ba2d0179a2419887fd61cb3a2c7c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:53:47 +0000 Subject: - Added a "generator" meta tag to <head>. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@130 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index c1e3246b5..71a416ed4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -47,8 +47,10 @@ class HTMLTranslator(nodes.NodeVisitor): ' SYSTEM "http://www.w3.org/TR/xhtml1/DTD/' \ 'xhtml1-transitional.dtd">\n' html_head = '<html lang="%s">\n<head>\n' - content_type = '<meta http-equiv=Content-Type content="text/html; ' \ + content_type = '<meta http-equiv="Content-Type" content="text/html; ' \ 'charset=UTF-8">\n' + generator = '<meta name="generator" content="Docutils: ' \ + 'http://docutils.sourceforge.net/">\n' stylesheet_link = '<link rel="stylesheet" href="default.css"' \ ' type="text/css" />\n' @@ -60,6 +62,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.doctype, self.html_head % document.language_code, self.content_type, # @@@ % output encoding + self.generator, self.stylesheet_link] # @@@ % stylesheet self.head = [] self.body_prefix = ['</head>\n<body>\n'] -- cgit v1.2.1 From 9e311d21148b1320c59bc46990f073939bec7826 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:55:04 +0000 Subject: - Filled in some descriptions. - Added "shttp" scheme. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@131 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/urischemes.py | 57 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/docutils/urischemes.py b/docutils/urischemes.py index 367217ad4..6eb45820a 100644 --- a/docutils/urischemes.py +++ b/docutils/urischemes.py @@ -1,13 +1,14 @@ """ `schemes` is a dictionary with lowercase URI addressing schemes as keys and descriptions as values. It was compiled from the index at -http://www.w3.org/Addressing/schemes.html, revised 2001-08-20. Many -values are blank and should be filled in with useful descriptions. +http://www.w3.org/Addressing/schemes.html (revised 2001-08-20). """ +# Many values are blank and should be filled in with useful descriptions. + schemes = { 'about': 'provides information on Navigator', - 'acap': 'application configuration access protocol', + 'acap': 'Application Configuration Access Protocol', 'addbook': "To add vCard entries to Communicator's Address Book", 'afp': 'Apple Filing Protocol', 'afs': 'Andrew File System global file names', @@ -16,33 +17,38 @@ schemes = { 'castanet': 'Castanet Tuner URLs for Netcaster', 'chttp': 'cached HTTP supported by RealPlayer', 'cid': 'content identifier', - 'data': 'allows inclusion of small data items as "immediate" data; RFC-2397', + 'data': ('allows inclusion of small data items as "immediate" data; ' + 'RFC 2397'), 'dav': 'Distributed Authoring and Versioning Protocol; RFC 2518', 'dns': 'Domain Name System resources', 'eid': ('External ID; non-URL data; general escape mechanism to allow ' 'access to information for applications that are too ' 'specialized to justify their own schemes'), - 'fax': '', + 'fax': ('a connection to a terminal that can handle telefaxes ' + '(facsimiles); RFC 2806'), 'file': 'Host-specific file names', 'finger': '', 'freenet': '', 'ftp': 'File Transfer Protocol', 'gopher': 'The Gopher Protocol', - 'gsm-sms': '', - 'h323': '', - 'h324': '', - 'hdl': '', - 'hnews': '', + 'gsm-sms': ('Global System for Mobile Communications Short Message ' + 'Service'), + 'h323': 'video (audiovisual) communication on local area networks', + 'h324': ('video and audio communications over low bitrate connections ' + 'such as POTS modem connections'), + 'hdl': 'CNRI handle system', + 'hnews': 'an HTTP-tunneling variant of the NNTP news protocol', 'http': 'Hypertext Transfer Protocol', - 'https': '', - 'iioploc': '', - 'ilu': '', - 'imap': 'internet message access protocol', - 'ior': '', - 'ipp': '', + 'https': 'HTTP over SSL', + 'iioploc': 'Internet Inter-ORB Protocol Location?', + 'ilu': 'Inter-Language Unification', + 'imap': 'Internet Message Access Protocol', + 'ior': 'CORBA interoperable object reference', + 'ipp': 'Internet Printing Protocol', 'irc': 'Internet Relay Chat', - 'jar': '', - 'javascript': 'JavaScript code; evaluates the expression after the colon', + 'jar': 'Java archive', + 'javascript': ('JavaScript code; evaluates the expression after the ' + 'colon'), 'jdbc': '', 'ldap': 'Lightweight Directory Access Protocol', 'lifn': '', @@ -54,9 +60,10 @@ schemes = { 'md5': '', 'mid': 'message identifier', 'mocha': '', - 'modem': '', + 'modem': ('a connection to a terminal that can handle incoming data ' + 'calls; RFC 2806'), 'news': 'USENET news', - 'nfs': 'network file system protocol', + 'nfs': 'Network File System protocol', 'nntp': 'USENET news using NNTP access', 'opaquelocktoken': '', 'phone': '', @@ -71,12 +78,16 @@ schemes = { 'rx': 'Remote Execution', 'sdp': '', 'service': 'service location', - 'sip': 'session initiation protocol', + 'shttp': 'secure hypertext transfer protocol', + 'sip': 'Session Initiation Protocol', 'smb': '', 'snews': 'For NNTP postings via SSL', - 't120': '', + 't120': 'real time data conferencing (audiographics)', 'tcp': '', - 'tel': 'telephone', + 'tel': ('a connection to a terminal that handles normal voice ' + 'telephone calls, a voice mailbox or another voice messaging ' + 'system or a service that can be operated using DTMF tones; ' + 'RFC 2806.'), 'telephone': 'telephone', 'telnet': 'Reference to interactive sessions', 'tip': 'Transaction Internet Protocol', -- cgit v1.2.1 From da1419a26009c34ea88c885bca2ef99f455c0708 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:57:27 +0000 Subject: docstring fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@132 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 7 +++---- docutils/statemachine.py | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index a578fef5f..ffb86303c 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -10,7 +10,7 @@ Calling the `publish` convenience function (or instantiating a `Publisher` object) with component names will result in default behavior. For custom behavior (setting component options), create -custom component objects first, and pass *them* to +custom component objects first, and pass *them* to `publish`/`Publisher`. """ @@ -33,8 +33,8 @@ class Publisher: warning_stream=None, debug=0): """ Initial setup. If any of `reader`, `parser`, or `writer` are - not specified, the corresponding 'set*' method should be - called. + not specified, the corresponding ``set_...`` method should be + called with a component name. """ self.reader = reader self.parser = parser @@ -85,4 +85,3 @@ def publish(source=None, destination=None, if writer is None: pub.set_writer(writer_name) pub.publish(source, destination) - diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 8c4cddb81..2a772c206 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -94,11 +94,11 @@ How To Use This Module input_string = open('inputfile').read() input_lines = statemachine.string2lines(input_string) -6. Run the state machine on the input text and collect the results, a list:: +5. Run the state machine on the input text and collect the results, a list:: results = sm.run(input_lines) -7. Remove any lingering circular references:: +6. Remove any lingering circular references:: sm.unlink() """ -- cgit v1.2.1 From 8fcc258c1ca5eb0f84fa197ec491f410c0030a97 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 May 2002 02:58:10 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@133 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 3f7dfd821..a0b0c274a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,13 +17,13 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - David Ascher, Fred Drake, Jim Fulton, Peter Funk, Doug Hellmann, - Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, Garth - Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward - Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, - Tim Peters, Mark Pilgrim, Tavis Rudd, Ueli Schlaepfer, Bob - Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward - Welbourne, Ka-Ping Yee, Moshe Zadka + David Ascher, Fred Drake, Jim Fulton, Peter Funk, Engelbert + Gruber, Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, + Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, + Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel + Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ueli + Schlaepfer, Bob Tolbert, Laurence Tratt, Guido van Rossum, Barry + Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -68,6 +68,11 @@ Specific: - Added ``runtime_init`` method to ``StateMachine`` and ``State``. - Added underscores to improve many awkward names. +* docutils/urischemes.py: + + - Filled in some descriptions. + - Added "shttp" scheme. + * docutils/utils.py: - Added ``clean_rcs_keywords`` function (moved from @@ -122,6 +127,7 @@ Specific: names; empty tag format). - Escape double-dashes in comment text. - Improved boilerplate & modularity of output. + - Added a "generator" meta tag to <head>. * docutils/writers/pseudoxml.py: Renamed from pprint.py. @@ -129,6 +135,11 @@ Specific: * spec/pep-0257.txt: Clarified prohibition of signature repetition. +* spec/pep-0287.txt: + + - Minor edits. + - Reworked Q&A as an enumerated list. + * spec/rst/reStructuredText.txt: - Clarified field list usage. -- cgit v1.2.1 From 9931e557165e396bc1891a13197fa59db3571aae Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 19 May 2002 16:44:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@134 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 11b55da83..15a631d29 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1,16 +1,20 @@ -================ - Docutils Notes -================ +================= + Docutils_ Notes +================= :Date: $Date$ :Revision: $Revision$ +.. _Docutils: http://docutils.sourceforge.net/ + .. contents:: To Do ===== Priority items are marked with "@" symbols. The more @s, the higher -the priority. +the priority. Items in question form (containing "?") are ideas which +require more thought and debate; they are potential to-do's. + General ------- @@ -94,6 +98,10 @@ Specification reStructuredText Parser ----------------------- +Also see the `... Or Not To Do?`__ list. + +__ http://docutils.sf.net/spec/rst/alternatives.html#or-not-to-do + - Add motivation sections for constructs in spec. - Allow very long titles (on two or more lines)? @@ -355,7 +363,7 @@ Directives entire paragraph as a verse block? This ties in to the `character processing`_ idea, above. For example:: - Adding a backslash\ + Add just one backslash\ And this paragraph becomes An awful haiku @@ -568,15 +576,15 @@ applicable), with particular emphasis as follows: cases to the test suite. Practise test-first programming; it's fun, it's addictive, and it works! -- The sandbox_ directory is the place to put new, untried code. See - `Additions to Docutils`_ and `The Sandbox`_ below. +- The `sandbox CVS directory`_ is the place to put new, untried code. + See `Additions to Docutils`_ and `The Sandbox`_ below. Please consider subscribing to the appropriate `mailing lists`_. .. _main source tree: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/docutils/ .. _Python Check-in Policies: http://www.python.org/dev/tools.html -.. _sandbox: +.. sandbox CVS directory: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/sandbox/ .. _mailing lists: ../index.html#mailing-lists @@ -585,9 +593,9 @@ Additions to Docutils ````````````````````` Additions to the project, such as new components, should be developed -in the sandbox_ directory until they're in good shape, usable, and -reasonably complete. Adding to the `main source tree`_ implies a -commitment to the Docutils user community. +in the `sandbox CVS directory`_ until they're in `good shape`_, +usable_, and `reasonably complete`_. Adding to the `main source +tree`_ implies a commitment to the Docutils user community. - Why the sandbox? @@ -595,13 +603,13 @@ commitment to the Docutils user community. being developed for addition to main source tree. See `The Sandbox`_ below. -- "Good shape" means that the component code is clean, readable, and - free of junk (unused legacy code; by analogy with "junk DNA"). +- _`Good shape` means that the component code is clean, readable, and + free of junk code (unused legacy code; by analogy with "junk DNA"). -- "Usable" means that the code does what it claims to do. An "XYZ +- _`Usable` means that the code does what it claims to do. An "XYZ Writer" should produce reasonable XYZ. -- "Reasonably complete" means that the code must handle all input. +- _`Reasonably complete` means that the code must handle all input. Here "handle" means that no input can cause the code to fail (cause an exception, or silently and incorrectly produce nothing). "Reasonably complete" does not mean "finished" (no work left to be -- cgit v1.2.1 From f500944f4fbc72dd11c3a334a2b87b37cebd3fd3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 19 May 2002 16:55:10 +0000 Subject: fixed targets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@135 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 15a631d29..145316371 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -584,7 +584,7 @@ Please consider subscribing to the appropriate `mailing lists`_. .. _main source tree: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/docutils/ .. _Python Check-in Policies: http://www.python.org/dev/tools.html -.. sandbox CVS directory: +.. _sandbox CVS directory: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/sandbox/ .. _mailing lists: ../index.html#mailing-lists @@ -630,14 +630,15 @@ to completion. The Sandbox ----------- -The sandbox_ directory is a place to play around, to try out and share -ideas. It's a part of the CVS repository but it isn't distributed as -part of Docutils releases. Feel free to check in code to the CVS -sandbox; that way people can try it out but you won't have to worry -about it working 100% error-free, as is the goal of the `main source -tree`_. Each developer who wants to play in the sandbox should create -their own subdirectory (suggested name: SourceForge ID, or given name -+ family initial). It's OK to make a mess! But please, play nice. +The `sandbox CVS directory`_ is a place to play around, to try out and +share ideas. It's a part of the CVS repository but it isn't +distributed as part of Docutils releases. Feel free to check in code +to the CVS sandbox; that way people can try it out but you won't have +to worry about it working 100% error-free, as is the goal of the `main +source tree`_. Each developer who wants to play in the sandbox should +create their own subdirectory (suggested name: SourceForge ID, or +given name + family initial). It's OK to make a mess! But please, +play nice. In order to minimize the work necessary for others to install and try out new, experimental components, the following sandbox directory -- cgit v1.2.1 From 05e4910c4b36bdcc1534594160644f2bb2fec9c4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 22 May 2002 04:19:32 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@136 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 9 ++++++++- docutils/transforms/components.py | 14 ++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index e70a33167..db9d384cb 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -61,8 +61,15 @@ class Component: Base class for Docutils components. """ - names = () + 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 component (Reader or Writer) + controlling the transform if that component supports a certain input + context or output format. + """ return format in self.supported diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index b0d1ae48f..71473bea9 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -27,18 +27,20 @@ class Filter(Transform): attribute is 'last writer'). The value is the name of a specific format or context of that component (e.g. ``details['writer'] = 'html'``). If the Docutils component which called this transform supports that format or - context, the "pending" element is replaced by the nodes in - ``details['nodes']``; otherwise, the "pending" element is removed. + 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. Only writers supporting the "html" - format will include the "meta" element; it will be deleted from the output - of all other writers. + element containing a "meta" element (in ``pending.details['nodes']``). + Only writers supporting the "html" format will include the "meta" element; + it will be deleted from the output of all other writers. """ def transform(self): pending = self.startnode - component_name = pending.details[pending.stage.split()[-1]] + component_type = pending.stage.split()[-1] # 'reader' or 'writer' + component_name = pending.details[component_type] if self.component.supports(component_name): pending.parent.replace(pending, pending.details['nodes']) else: -- cgit v1.2.1 From 8e5307cf701ccd24de772d2dd3cb1ae11b726318 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 22 May 2002 04:21:21 +0000 Subject: - Improved docstrings. - Added SparseNodeVisitor, refined NodeVisitor. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@137 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 52 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 275469f6e..ee05a638c 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -128,6 +128,12 @@ class Node: class Text(Node, MutableString): + """ + Instances are terminal nodes (leaves) containing text only; no child + nodes or attributes. Initialize by passing a string to the constructor. + Access the text itself with the `astext` method. + """ + tagname = '#text' def __repr__(self): @@ -171,26 +177,30 @@ class Element(Node): """ `Element` is the superclass to all specific elements. - Elements contain attributes and child nodes. Elements emulate dictionaries - for attributes, indexing by attribute name (a string). To set the - attribute 'att' to 'value', do:: + Elements contain attributes and child nodes. Elements emulate + dictionaries for attributes, indexing by attribute name (a string). To + set the attribute 'att' to 'value', do:: element['att'] = 'value' Elements also emulate lists for child nodes (element nodes and/or text - nodes), indexing by integer. To get the first child node, use:: + nodes), indexing by integer. To get the first child node, use:: element[0] - Elements may be constructed using the ``+=`` operator. To add one new + Elements may be constructed using the ``+=`` operator. To add one new child node to element, do:: element += node + This is equivalent to ``element.append(node)``. + To add a list of multiple child nodes at once, use the same ``+=`` operator:: element += [node1, node2] + + This is equivalent to ``element.extend([node1, node2])``. """ tagname = None @@ -523,9 +533,6 @@ class Part: pass class Inline: pass class Referential(Resolvable): pass - #refnode = None - #"""Resolved reference to a node.""" - class Targetable(Resolvable): @@ -662,7 +669,8 @@ class document(Root, Structural, Element): if self.explicit_targets.has_key(name) \ or self.implicit_targets.has_key(name): msg = self.reporter.info( - 'Duplicate implicit target name: "%s".' % name, backrefs=[id]) + 'Duplicate implicit target name: "%s".' % name, + backrefs=[id]) msgnode += msg self.clear_target_names(name, self.implicit_targets) del target['name'] @@ -695,7 +703,8 @@ class document(Root, Structural, Element): target['dupname'] = name elif self.implicit_targets.has_key(name): msg = self.reporter.info( - 'Duplicate implicit target name: "%s".' % name, backrefs=[id]) + 'Duplicate implicit target name: "%s".' % name, + backrefs=[id]) msgnode += msg self.clear_target_names(name, self.implicit_targets) self.explicit_targets[name] = target @@ -1072,11 +1081,20 @@ class NodeVisitor: tree traversals. Each node class has corresponding methods, doing nothing by default; - override individual methods for specific and useful behaviour. The + override individual methods for specific and useful behaviour. The "``visit_`` + node class name" method is called by `Node.walk()` upon - entering a node. `Node.walkabout()` also calls the "``depart_`` + node + entering a node. `Node.walkabout()` also calls the "``depart_`` + node class name" method before exiting a node. + This is a base class for visitors whose ``visit_...`` & ``depart_...`` + methods should be implemented for *all* node types encountered (such as + for `docutils.writers.Writer` subclasses). Unimplemented methods will + raise exceptions. + + For sparse traversals, where only certain node types are of interest, + subclass `SparseNodeVisitor` instead. When (mostly or entirely) uniform + processing is desired, subclass `GenericNodeVisitor`. + .. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA, 1995. @@ -1103,6 +1121,16 @@ class NodeVisitor: raise NotImplementedError('departing unknown node type: %s' % node.__class__.__name__) + +class SparseNodeVisitor(NodeVisitor): + + """ + Base class for sparse traversals, where only certain node types are of + interest. When ``visit_...`` & ``depart_...`` methods should be + implemented for *all* node types (such as for `docutils.writers.Writer` + subclasses), subclass `NodeVisitor` instead. + """ + # Save typing with dynamic definitions. for name in node_class_names: exec """def visit_%s(self, node): pass\n""" % name -- cgit v1.2.1 From b4c6826884a1c00c4fb928dc3584cf241fdaff40 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 22 May 2002 04:23:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@138 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docs/dev/todo.txt | 25 ++++++++++++++++++++----- docutils/transforms/references.py | 2 +- docutils/transforms/universal.py | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index a0b0c274a..476c70f8c 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -62,6 +62,8 @@ Specific: - Renamed ``TreePruningException`` from ``VisitorException``. - Added docstrings to ``TreePruningException``, subclasses, and ``Nodes.walk()``. + - Improved docstrings. + - Added ``SparseNodeVisitor``, refined ``NodeVisitor``. * docutils/statemachine.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 145316371..e2476a2a2 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -469,14 +469,19 @@ to have a bunch of small front-ends, each specialized for a specific reader (and possibly writer as well). Each of the front-ends would depend on a common code library described below. -- Combine the common code from the existing front-ends into a - single library (docutils.frontend? docutils.core.xyz?). +- Combine the common code from the existing front-ends into a single + library. + + - docutils.frontend? docutils.core.xyz? docutils.utils.options? + Part of docutils.core.Publisher/publish()? (Add a ``cmdline`` + parameter? To publish() only?) - Use Optik to do modular command-line option processing. - - Pass around an Optik 'options' object? Attach it to the + - Pass around an Optik 'option Values' object? Attach it to the document? What to do when *not* using a front-end (i.e., when - docutils is imported by an unrelated client)? + docutils is imported by an unrelated client)? I.e., + warning_level etc. - The core would support all common options (--reader, --writer, etc.). @@ -486,6 +491,16 @@ depend on a common code library described below. apply. (Added/removed dynamically? Is this possible with Optik? Is it desirable?) + - Build an OptionParser based on the known Reader & Writer? I.e., + first instantiate the common OptionParser subclass, which can be + passed to a standard function in the Reader module which adds its + specific options, then on to the Writer module. Or, store a data + structure in each component containing its specific options. + + - What about if we don't know which Reader and/or Writer we are + going to use? If the Reader/Writer is specified on the + command-line? (Will this ever happen?) + - Command-line option ideas. Common options: --credit Include a "Generated by Docutils" credit with a @@ -528,7 +543,7 @@ Conventions`__ PEPs, with the following clarifications (from most to least important): - 4 spaces per indentation level. No tabs. Indent continuation lines - according to the Emacs' python-mode standard. + according to the Emacs python-mode standard. - No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 15ca5db89..ccd43c749 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -330,7 +330,7 @@ class Hyperlinks(Transform): target.referenced = 1 -class ChainedTargetResolver(nodes.NodeVisitor): +class ChainedTargetResolver(nodes.SparseNodeVisitor): """ Copy reference attributes up the length of a hyperlink target chain. diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 36c83f003..fb422270b 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -70,7 +70,7 @@ class FinalChecks(Transform): self.document.walk(visitor) -class FinalCheckVisitor(nodes.NodeVisitor): +class FinalCheckVisitor(nodes.SparseNodeVisitor): def unknown_visit(self, node): pass -- cgit v1.2.1 From d5a3bb20bbf9c70b3ac3caa79bc3dbd5a7b23225 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 23 May 2002 04:18:12 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@139 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_nodes.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test_nodes.py b/test/test_nodes.py index ddec58b95..5f0a2b1a8 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -11,6 +11,7 @@ Test module for nodes.py. """ import unittest +from types import ClassType from DocutilsTestSupport import nodes, utils debug = 0 @@ -79,6 +80,18 @@ class ElementTests(unittest.TestCase): """) +class MiscTests(unittest.TestCase): + + def test_node_class_names(self): + node_class_names = [] + for x in dir(nodes): + c = getattr(nodes, x) + if type(c) is ClassType and issubclass(c, nodes.Node) \ + and len(c.__bases__) > 1: + node_class_names.append(x) + self.assertEquals(node_class_names, nodes.node_class_names) + + class TreeCopyVisitorTests(unittest.TestCase): def setUp(self): -- cgit v1.2.1 From b9a42c808f2d269e277d5c937e78ca1401563aff Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 23 May 2002 04:19:54 +0000 Subject: expanded docstrings; workings of a Writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@140 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 49eba12da..35e5254c6 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -14,6 +14,7 @@ __docformat__ = 'reStructuredText' import sys +import docutils from docutils import languages, Component from docutils.transforms import universal @@ -24,6 +25,8 @@ class Writer(Component): Abstract base class for docutils Writers. Each writer module or package must export a subclass also called 'Writer'. + Each writer must support all standard node types listed in + `docutils.nodes.node_class_names`. Call `write()` to process a document. """ @@ -63,7 +66,16 @@ class Writer(Component): xclass(self.document, self).transform() def translate(self): - """Override to do final document tree translation.""" + """ + Override to do final document tree translation. + + This is usually done with a `docutils.nodes.NodeVisitor` subclass, in + combination with a call to `docutils.nodes.Node.walk()` or + `docutils.nodes.Node.walkabout()`. The ``NodeVisitor`` subclass must + support all standard elements (listed in + `docutils.nodes.node_class_names`) and possibly non-standard elements + used by the current Reader as well. + """ raise NotImplementedError('subclass must override this method') def record(self): -- cgit v1.2.1 From a9230c020146ecfdc0488d9b49524f306a9e166e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 23 May 2002 04:21:31 +0000 Subject: - Added "Copyrights and Licensing" section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@141 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e2476a2a2..33b5efe4a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -56,7 +56,11 @@ General permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) -- @@@ Implement a PEP reader. +- @@@ Implement a PEP reader. (Reader for RST-PEP format done. + Writer support needed.) + + - Implement a specialized PEP/HTML writer? Or implement a generic + `templating system`_, with PEP/HTML as one application? - @@ Add support for character set encodings on input & output, Unicode internally. @@ -442,7 +446,7 @@ HTML Writer - @@@ Allow for style sheet info to be passed in, either as a <LINK>, or as embedded style info. -- @@@ Construct a templating system, as in ht2html/yaptu, using +- @@@ Construct a _`templating system`, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. - @@ Improve the granularity of document parts in the HTML writer, so @@ -569,6 +573,33 @@ __ http://www.python.org/peps/pep-0008.html __ http://www.python.org/peps/pep-0257.html +Copyrights and Licensing +------------------------ + +The majority of the Docutils project code and documentation has been +written by me (David Goodger), and has been placed in the public +domain. Unless clearly and explicitly indicated otherwise, any +patches (modifications to existing files) submitted to the project for +inclusion (via SourceForge trackers, mailing lists, or private email) +are assumed to have been placed in the public domain as well. + +Any new files contributed to the project should clearly state their +intentions regarding copyright, in one of the following ways: + +- Public domain (preferred): state "This module has been placed in the + public domain." + +- Copyright & open source license: include a copyright notice, along + with an embedded license statement, a reference to an accompanying + license file, or a license URL. + +One of the goals of the Docutils project, once complete, is to be +incorporated into the Python standard library. At that time copyright +of the Docutils code will be assumed by or transferred to the Python +Software Foundation (PSF), and will be released under Python's +license. + + CVS Check-ins ------------- -- cgit v1.2.1 From b21ee64ccb2daeb368843a84972bfdece858b6c3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 24 May 2002 03:03:19 +0000 Subject: Removed <dt> space reduction; didn't work. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@142 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 2db991782..17bc06900 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -69,9 +69,6 @@ div.system-message p.system-message-title { div.topic { margin: 2em } -dt { - margin-bottom: -1em } - h1.title { text-align: center } -- cgit v1.2.1 From 060ae1cc18c6362cbfc28c6ee525ff32616ad1fb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 24 May 2002 03:08:09 +0000 Subject: - Changed names of Reporter's thresholds: warning_level -> report_level; error_level -> halt_level. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@143 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 8 ++--- docutils/transforms/universal.py | 2 +- docutils/utils.py | 71 ++++++++++++++++++++-------------------- docutils/writers/html4css1.py | 3 +- test/DocutilsTestSupport.py | 6 ++-- 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index ffb86303c..3cab9a5c1 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -29,7 +29,7 @@ class Publisher: """A `utils.Reporter` instance used for all document processing.""" def __init__(self, reader=None, parser=None, writer=None, reporter=None, - language_code='en', warning_level=2, error_level=4, + language_code='en', report_level=2, halt_level=4, warning_stream=None, debug=0): """ Initial setup. If any of `reader`, `parser`, or `writer` are @@ -40,7 +40,7 @@ class Publisher: self.parser = parser self.writer = writer if not reporter: - reporter = utils.Reporter(warning_level, error_level, + reporter = utils.Reporter(report_level, halt_level, warning_stream, debug) self.reporter = reporter self.language_code = language_code @@ -76,10 +76,10 @@ def publish(source=None, destination=None, parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', reporter=None, language_code='en', - warning_level=2, error_level=4, warning_stream=None, debug=0): + report_level=2, halt_level=4, warning_stream=None, debug=0): """A convenience function; set up & run a `Publisher`.""" pub = Publisher(reader, parser, writer, reporter, language_code, - warning_level, error_level, warning_stream, debug) + report_level, halt_level, warning_stream, debug) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index fb422270b..c17341bb9 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -33,7 +33,7 @@ class Messages(Transform): def transform(self): unfiltered = self.document.messages.get_children() - threshold = self.document.reporter['writer'].warning_level + threshold = self.document.reporter['writer'].report_level messages = [] for msg in unfiltered: if msg['level'] >= threshold: diff --git a/docutils/utils.py b/docutils/utils.py index 0602b8d64..9f9130b5e 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -29,27 +29,28 @@ class Reporter: Five levels of system messages are defined, along with corresponding methods: `debug()`, `info()`, `warning()`, `error()`, and `severe()`. - There is typically one Reporter object per process. A Reporter object is - instantiated with thresholds for generating warnings and errors (raising - exceptions), a switch to turn debug output on or off, and an I/O stream - for warnings. These are stored in the default reporting category, '' - (zero-length string). - - Multiple reporting categories [#]_ may be set, each with its own warning - and error thresholds, debugging switch, and warning stream (collectively a - `ConditionSet`). Categories are hierarchically-named strings that look - like attribute references: 'spam', 'spam.eggs', 'neeeow.wum.ping'. The - 'spam' category is the ancestor of 'spam.bacon.eggs'. Unset categories - inherit stored conditions from their closest ancestor category that has - been set. + There is typically one Reporter object per process. A Reporter object is + instantiated with thresholds for reporting (generating warnings) and + halting processing (raising exceptions), a switch to turn debug output on + or off, and an I/O stream for warnings. These are stored in the default + reporting category, '' (zero-length string). + + Multiple reporting categories [#]_ may be set, each with its own reporting + and halting thresholds, debugging switch, and warning stream + (collectively a `ConditionSet`). Categories are hierarchical dotted-name + strings that look like attribute references: 'spam', 'spam.eggs', + 'neeeow.wum.ping'. The 'spam' category is the ancestor of + 'spam.bacon.eggs'. Unset categories inherit stored conditions from their + closest ancestor category that has been set. When a system message is generated, the stored conditions from its - category (or ancestor if unset) are retrieved. The system message level is - compared to the thresholds stored in the category, and a warning or error - is generated as appropriate. Debug messages are produced iff the stored - debug switch is on. Message output is sent to the stored warning stream. + category (or ancestor if unset) are retrieved. The system message level + is compared to the thresholds stored in the category, and a warning or + error is generated as appropriate. Debug messages are produced iff the + stored debug switch is on. Message output is sent to the stored warning + stream. - The default category is '' (empty string). By convention, Writers should + The default category is '' (empty string). By convention, Writers should retrieve reporting conditions from the 'writer' category (which, unless explicitly set, defaults to the conditions of the default category). @@ -60,16 +61,16 @@ class Reporter: levels = 'DEBUG INFO WARNING ERROR SEVERE'.split() """List of names for system message levels, indexed by level.""" - def __init__(self, warning_level, error_level, stream=None, debug=0): + def __init__(self, report_level, halt_level, stream=None, debug=0): """ Initialize the `ConditionSet` forthe `Reporter`'s default category. :Parameters: - - `warning_level`: The level at or above which warning output will + - `report_level`: The level at or above which warning output will be sent to `stream`. - - `error_level`: The level at or above which `SystemMessage` - exceptions will be raised. + - `halt_level`: The level at or above which `SystemMessage` + exceptions will be raised, halting execution. - `debug`: Show debug (level=0) system messages? - `stream`: Where warning output is sent (`None` implies `sys.stderr`). @@ -78,16 +79,16 @@ class Reporter: if stream is None: stream = sys.stderr - self.categories = {'': ConditionSet(debug, warning_level, error_level, + self.categories = {'': ConditionSet(debug, report_level, halt_level, stream)} """Mapping of category names to conditions. Default category is ''.""" - def set_conditions(self, category, warning_level, error_level, + def set_conditions(self, category, report_level, halt_level, stream=None, debug=0): if stream is None: stream = sys.stderr - self.categories[category] = ConditionSet(debug, warning_level, - error_level, stream) + self.categories[category] = ConditionSet(debug, report_level, + halt_level, stream) def unset_conditions(self, category): if category and self.categories.has_key(category): @@ -112,13 +113,13 @@ class Reporter: msg = nodes.system_message(comment, level=level, type=self.levels[level], *children, **attributes) - debug, warning_level, error_level, stream = self[category].astuple() - if level >= warning_level or debug and level == 0: + debug, report_level, halt_level, stream = self[category].astuple() + if level >= report_level or debug and level == 0: if category: print >>stream, 'Reporter "%s":' % category, msg.astext() else: print >>stream, 'Reporter:', msg.astext() - if level >= error_level: + if level >= halt_level: raise SystemMessage(msg) return msg @@ -172,14 +173,14 @@ class ConditionSet: category. """ - def __init__(self, debug, warning_level, error_level, stream): + def __init__(self, debug, report_level, halt_level, stream): self.debug = debug - self.warning_level = warning_level - self.error_level = error_level + self.report_level = report_level + self.halt_level = halt_level self.stream = stream def astuple(self): - return (self.debug, self.warning_level, self.error_level, + return (self.debug, self.report_level, self.halt_level, self.stream) @@ -367,9 +368,9 @@ def id(string): non_id_chars = re.compile('[^a-z0-9]+') non_id_at_ends = re.compile('^[-0-9]+|-+$') -def new_document(language_code='en', warning_level=2, error_level=4, +def new_document(language_code='en', report_level=2, halt_level=4, stream=None, debug=0): - reporter = Reporter(warning_level, error_level, stream, debug) + reporter = Reporter(report_level, halt_level, stream, debug) document = nodes.document(language_code=language_code, reporter=reporter) return document diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 71a416ed4..2a32a88a1 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -78,6 +78,7 @@ class HTMLTranslator(nodes.NodeVisitor): def encode(self, text): """Encode special characters in `text` & return.""" + # @@@ A codec to do these and all other HTML entities would be nice. text = text.replace("&", "&") text = text.replace("<", "<") text = text.replace('"', """) @@ -663,7 +664,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</h2>\n') def visit_system_message(self, node): - if node['level'] < self.document.reporter['writer'].warning_level: + if node['level'] < self.document.reporter['writer'].report_level: raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) self.body.append('<p class="system-message-title">') diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 3b883d49b..43e5cc4af 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -236,7 +236,7 @@ class TransformTestCase(CustomTestCase): def test_transforms(self): if self.runInDebugger: pdb.set_trace() - document = utils.new_document(warning_level=1, error_level=5, + document = utils.new_document(report_level=1, halt_level=5, debug=package_unittest.debug, stream=DevNull()) self.parser.parse(self.input, document) @@ -251,7 +251,7 @@ class TransformTestCase(CustomTestCase): print '\n', self.id print '-' * 70 print self.input - document = utils.new_document(warning_level=1, error_level=5, + document = utils.new_document(report_level=1, halt_level=5, debug=package_unittest.debug, stream=DevNull()) self.parser.parse(self.input, document) @@ -281,7 +281,7 @@ class ParserTestCase(CustomTestCase): def test_parser(self): if self.runInDebugger: pdb.set_trace() - document = utils.new_document(warning_level=5, error_level=5, + document = utils.new_document(report_level=5, halt_level=5, debug=package_unittest.debug) self.parser.parse(self.input, document) output = document.pformat() -- cgit v1.2.1 From 50bdc5897f3d5d533625ee82b2d1b8ecc1270106 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 24 May 2002 03:13:01 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@145 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 + docs/dev/todo.txt | 120 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 89 insertions(+), 33 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 476c70f8c..e1642ca40 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -81,6 +81,8 @@ Specific: 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. * docutils/parsers/rst/states.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 33b5efe4a..5da55712e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -377,7 +377,8 @@ Directives Directive/construct name alternatives: verse, addressblock, address, lineblock, lines, multiline, freeform, keeplines, nowrap, haiku, keepbreaks, linebreaks, obeylines, linewise, textblock, - textart, text, linetext. + textart, text, linetext. Current favorites: "line_block" for + element name, "lines" for directive name. - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we @@ -396,6 +397,9 @@ Directives Where "macros" contains ``.. |date| date::``, among others. + - _`pysource.usage`: Extract a usage message from the program, + either by running it at the command line with a ``--help`` option + or through an exposed API. [Suggestion for Optik.] Unimplemented Transforms ------------------------ @@ -468,13 +472,14 @@ HTML Writer Front-Ends ---------- -@@ Rather than a single all-purpose program, it is probably preferable -to have a bunch of small front-ends, each specialized for a specific -reader (and possibly writer as well). Each of the front-ends would -depend on a common code library described below. +@@@ Rather than a single all-purpose program, it is probably +preferable to have a bunch of small front-ends, each specialized for a +specific reader (and possibly writer as well; each could have a name +of the form "context2format"). Each of the front-ends would depend on +a common option-processing module, as described below. - Combine the common code from the existing front-ends into a single - library. + module, and add option processing. - docutils.frontend? docutils.core.xyz? docutils.utils.options? Part of docutils.core.Publisher/publish()? (Add a ``cmdline`` @@ -483,49 +488,95 @@ depend on a common code library described below. - Use Optik to do modular command-line option processing. - Pass around an Optik 'option Values' object? Attach it to the - document? What to do when *not* using a front-end (i.e., when - docutils is imported by an unrelated client)? I.e., - warning_level etc. + document? + + - What to do when *not* using a front-end (i.e., when docutils is + imported by an unrelated client)? I.e., report_level etc. Use + the default values of the OptionParser? Perhaps:: + + options = optik.option_parser.Values(option_parser.defaults) + options.an_option = "my default value" - The core would support all common options (--reader, --writer, etc.). - - Each front-end would add their own specific options (HTML: + - Each component would add its own specific options (HTML: --stylesheet, etc.), and perhaps disable common options that don't - apply. (Added/removed dynamically? Is this possible with Optik? - Is it desirable?) + apply. + + - Added/removed dynamically (during option processing)? Is this + possible with Optik? Is it desirable? + + - Parsers too? + + - Common and component-specific options may not conflict. + + - Build an OptionParser dynamically based on the known Reader & + Writer? Alternatives: + + a) First instantiate the common OptionParser subclass, which can + be passed to a standard function in the Reader module which + adds its specific options, then on to the Writer module. + + b) Or, store a data structure in each component containing its + specific options, merge with the common option data, and + instantiate an OptionParser. + + - What about if we don't know which Reader and/or Writer we are + going to use? If the Reader/Writer is specified on the + command-line? (Will this ever happen?) + + Perhaps have different types of front ends: + + a) _`Fully qualified`: Reader and Writer are hard-coded into the + front-end (e.g. ``pep2html [options]``, ``pysource2pdf + [options]``). + + b) _`Partially qualified`: Reader is hard-coded, and the Writer is + specified a sub-command (e.g. ``pep2 html [options]``, + ``pysource2 pdf [options]``). The Writer is known before + option processing happens, allowing the OptionParser to be + built dynamically. - - Build an OptionParser based on the known Reader & Writer? I.e., - first instantiate the common OptionParser subclass, which can be - passed to a standard function in the Reader module which adds its - specific options, then on to the Writer module. Or, store a data - structure in each component containing its specific options. + c) _`Unqualified`: Reader and Writer are specified as subcommands + (e.g. ``publish pep html [options]``, ``publish pysource pdf + [options]``). A single front-end would be sufficient, but + probably only useful for testing purposes. - - What about if we don't know which Reader and/or Writer we are - going to use? If the Reader/Writer is specified on the - command-line? (Will this ever happen?) + Allow common options before subcommands, as in CVS? Or group all + options together? In the case of the `fully qualified`_ + front-ends, options will have to be grouped together anyway, so + there's no advantage to splitting common and component-specific + options apart. - Command-line option ideas. Common options: - --credit Include a "Generated by Docutils" credit with a - link. + --generator Include a "Generated by Docutils" credit with a + link, at the end of the document. + --date Include a datestamp at the end of the document. --source-link Include a "(View document source)" link. --verbose Report all system messages, info-level and higher. (Same as "--report=info".) --debug Report debug-level system messages. --report=level Set verbosity; report system messages at or higher - than level (by name or number: "info" or "1", - warning/2, error/3, severe/4, none/5+). - --halt=level Set the level at or above which system messages are - converted to exceptions, halting execution - immediately. Levels as in --report. + than ``level`` (by name or number: "info" or "1", + warning/2, error/3, severe/4; also, "none" or 5+). + Default is 2 (warning). + --halt=level Set the ``level`` at or above which system messages + are converted to exceptions, halting execution + immediately. Levels as in --report. Default is 4 + (severe). --strict Same as "--halt=info": halt processing at the slightest problem. + --encoding=name Specify the encoding of input text. Default is + "utf-8". + --language=name Specify the language of input text. Default is + "en" (English). Options specific to HTML writer: --stylesheet=file - Specify a stylesheet (default: "default.css"). + Specify a stylesheet. Default is "default.css". Project Policies @@ -586,18 +637,21 @@ are assumed to have been placed in the public domain as well. Any new files contributed to the project should clearly state their intentions regarding copyright, in one of the following ways: -- Public domain (preferred): state "This module has been placed in the - public domain." +- Public domain (preferred): include the statement "This + module/document has been placed in the public domain." - Copyright & open source license: include a copyright notice, along - with an embedded license statement, a reference to an accompanying - license file, or a license URL. + with either an embedded license statement, a reference to an + accompanying license file, or a license URL. One of the goals of the Docutils project, once complete, is to be incorporated into the Python standard library. At that time copyright of the Docutils code will be assumed by or transferred to the Python Software Foundation (PSF), and will be released under Python's -license. +license. If the copyright/license option is chosen for new files, the +license should be compatible with Python's current license, and the +author(s) of the files should be willing to assign copyright to the +PSF. CVS Check-ins -- cgit v1.2.1 From c95927c8ddb04d0b89e84311ff5f0eb9f953f9f7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:07:32 +0000 Subject: - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@147 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 31c22a184..3d90489d4 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1948,8 +1948,9 @@ follows. If any of the conditions are not met, the start-string or end-string will not be recognized or processed. 1. Inline markup start-strings must start a text block or be - immediately preceded by whitespace, single or double quotes, "(", - "[", "{", or "<". + immediately preceded by whitespace or one of:: + + ' " ( [ { < - / : 2. Inline markup start-strings must be immediately followed by non-whitespace. @@ -1960,7 +1961,7 @@ end-string will not be recognized or processed. 4. Inline markup end-strings must end a text block or be immediately followed by whitespace or one of:: - ' " . , : ; ! ? - ) ] } > + ' " ) ] } > - / : . , ; ! ? 5. If an inline markup start-string is immediately preceded by a single or double quote, "(", "[", "{", or "<", it must not be -- cgit v1.2.1 From 6f467ee322d74ec5c68592a4c9b97a96488d79b8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:09:19 +0000 Subject: - Added support for an option values object which carries default settings and overrides (from command-line options and library use). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@148 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 8 +++++++- docutils/readers/__init__.py | 19 ++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index db9d384cb..fe63168b7 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -19,7 +19,9 @@ Modules: - core.py: Contains the ``Publisher`` class and ``publish()`` convenience function. -- nodes.py: DPS document tree (doctree) node class library. +- frontend.py: Command-line and common processing for Docutils front-ends. + +- nodes.py: Docutils document tree (doctree) node class library. - roman.py: Conversion to and from Roman numerals. Courtesy of Mark Pilgrim (http://diveintopython.org/). @@ -64,6 +66,10 @@ class Component: supported = () """Names for this component. Override in subclasses.""" + cmdline_options = () + """Command-line option specification. A list/tuple of tuples: + ``('help text', [list of option strings], {keyword arguments})``.""" + def supports(self, format): """ Is `format` supported by this component? diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 0ade6dbe3..47c5b2fab 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -14,7 +14,7 @@ __docformat__ = 'reStructuredText' import sys -from docutils import nodes, utils, parsers, Component +from docutils import utils, parsers, Component from docutils.transforms import universal @@ -33,7 +33,7 @@ class Reader(Component): """Ordered tuple of transform classes (each with a ``transform()`` method). Populated by subclasses. `Reader.transform()` instantiates & runs them.""" - def __init__(self, reporter, parser, parser_name, language_code): + def __init__(self, parser, parser_name): """ Initialize the Reader instance. @@ -41,12 +41,6 @@ class Reader(Component): Subclasses may use these attributes as they wish. """ - self.language_code = language_code - """Default language for new documents.""" - - self.reporter = reporter - """A `utils.Reporter` instance shared by all doctrees.""" - self.parser = parser """A `parsers.Parser` instance shared by all doctrees. May be left unspecified if the document source determines the parser.""" @@ -66,10 +60,11 @@ class Reader(Component): parser_class = parsers.get_parser_class(parser_name) self.parser = parser_class() - def read(self, source, parser): + def read(self, source, parser, options): self.source = source if not self.parser: self.parser = parser + self.options = options self.scan() # may modify self.parser, depending on input self.parse() self.transform() @@ -107,11 +102,9 @@ class Reader(Component): + universal.last_reader_transforms): xclass(self.document, self).transform() - def new_document(self, language_code=None): + def new_document(self): """Create and return a new empty document tree (root node).""" - document = nodes.document( - language_code=(language_code or self.language_code), - reporter=self.reporter) + document = utils.new_document(self.options) document['source'] = self.source return document -- cgit v1.2.1 From 94bef8e11867100fe10a5daf83bde3db0019edd9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:10:56 +0000 Subject: - Removed many keyword parameters to ``Publisher.__init__()`` and ``publish()``; bundled into an option values object. Added ``argv`` and ``usage`` parameters for command-line support. - Added ``Publisher.process_command_line()`` and ``.set_options()`` methods. - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@149 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 109 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 37 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 3cab9a5c1..7c28d800a 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -16,7 +16,10 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' -import readers, parsers, writers, utils +import sys +from docutils import Component +from docutils import readers, parsers, writers +from docutils.frontend import OptionParser class Publisher: @@ -25,63 +28,95 @@ class Publisher: A facade encapsulating the high-level logic of a Docutils system. """ - reporter = None - """A `utils.Reporter` instance used for all document processing.""" - - def __init__(self, reader=None, parser=None, writer=None, reporter=None, - language_code='en', report_level=2, halt_level=4, - warning_stream=None, debug=0): + def __init__(self, reader=None, parser=None, writer=None): """ - Initial setup. If any of `reader`, `parser`, or `writer` are - not specified, the corresponding ``set_...`` method should be - called with a component name. + Initial setup. If any of `reader`, `parser`, or `writer` are not + specified, the corresponding ``set_...`` method should be called with + a component name (`set_reader` sets the parser as well). """ + self.reader = reader + """A `readers.Reader` instance.""" + self.parser = parser + """A `parsers.Parser` instance.""" + self.writer = writer - if not reporter: - reporter = utils.Reporter(report_level, halt_level, - warning_stream, debug) - self.reporter = reporter - self.language_code = language_code - - def set_reader(self, reader_name, parser, parser_name, - language_code=None): + """A `writers.Writer` instance.""" + + self.options = None + """An object containing Docutils settings as instance attributes. + Set by `self.process_command_line()` or `self.set_options()`.""" + + self.source = None + """The source of input data.""" + + self.destination = None + """The destination for docutils output.""" + + def set_reader(self, reader_name, parser, parser_name): """Set `self.reader` by name.""" reader_class = readers.get_reader_class(reader_name) - self.reader = reader_class(self.reporter, parser, parser_name, - language_code or self.language_code) - - def set_parser(self, parser_name): - """Set `self.parser` by name.""" - parser_class = parsers.get_parser_class(parser_name) - self.parser = parser_class() + self.reader = reader_class(parser, parser_name) def set_writer(self, writer_name): """Set `self.writer` by name.""" writer_class = writers.get_writer_class(writer_name) self.writer = writer_class() - def publish(self, source, destination): + def set_options(self, **defaults): + """ + Set default option values (keyword arguments). + + Set components first (`self.set_reader` & `self.set_writer`). + Overrides the command line. + """ + option_parser = OptionParser( + components=(self.reader, self.parser, self.writer), + defaults=defaults) + self.options = option_parser.get_default_values() + + def process_command_line(self, argv=None, usage=None): + """ + Pass an empty list to `argv` to avoid reading `sys.argv` (the + default). + + Set components first (`self.set_reader` & `self.set_writer`). + """ + option_parser = OptionParser( + components=(self.reader, self.parser, self.writer), usage=usage) + if argv is None: + argv = sys.argv[1:] + self.options, self.source, self.destination \ + = option_parser.parse_args(argv) + """ + # For testing purposes: + from pprint import pformat + print 'options:' + print pformat(options.__dict__) + print 'source=%r, destination=%r' % (source, destination) + sys.exit(0) + """ + + def publish(self, argv=None, usage=None): """ - Run `source` through `self.reader`, then through `self.writer` to - `destination`. + Process command line options and arguments, run `self.reader` + and then `self.writer`. """ - document = self.reader.read(source, self.parser) - self.writer.write(document, destination) + if self.options is None: + self.process_command_line(argv, usage) + document = self.reader.read(self.source, self.parser, self.options) + self.writer.write(document, self.destination) -def publish(source=None, destination=None, - reader=None, reader_name='standalone', +def publish(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', - reporter=None, language_code='en', - report_level=2, halt_level=4, warning_stream=None, debug=0): + argv=None, usage=None): """A convenience function; set up & run a `Publisher`.""" - pub = Publisher(reader, parser, writer, reporter, language_code, - report_level, halt_level, warning_stream, debug) + pub = Publisher(reader, parser, writer) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: pub.set_writer(writer_name) - pub.publish(source, destination) + pub.publish(argv, usage) -- cgit v1.2.1 From 3f909add8d4943b2334a2943d8c7817fed3692cc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:12:05 +0000 Subject: Support for front-end scripts. Option specifications may be augmented by components. Requires Optik (http://optik.sf.net/) for option processing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@150 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 docutils/frontend.py diff --git a/docutils/frontend.py b/docutils/frontend.py new file mode 100644 index 000000000..727db95d0 --- /dev/null +++ b/docutils/frontend.py @@ -0,0 +1,122 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Command-line and common processing for Docutils front-ends. +""" + +__docformat__ = 'reStructuredText' + +import optik + + +class OptionParser(optik.OptionParser): + + """ + Parser for command-line and library use. The `cmdline_options` specification here and in other Docutils components are merged + """ + + standard_option_list = [] + """We supply our own help option.""" + + cmdline_options = ( + # Unimplemented or unused options are commented out. + #('Include a "Generated by Docutils" credit with a link, at the end ' + # 'of the document.', + # ['--generator', '-g'], {'action': 'store_true', 'default': 0}), + #('Include the date at the end of the document (UTC).', + # ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d', + # 'dest': 'datestamp', 'default': ''}), + #('Include the time & date at the end of the document (UTC).', + # ['--time', '-t'], {'action': 'store_const', + # 'const': '%Y-%m-%d %H:%M:%S UTC', + # 'dest': 'datestamp', 'default': ''}), + #('Include a "(View document source)" link.', + # ['--source-link', '-s'], {'action': 'store_true', 'default': 0}), + ('Set verbosity threshold; report system messages at or higher than ' + '<level> (by name or number: "info" or "1", warning/2, error/3, ' + 'severe/4; also, "none" or 5+). Default is 2 (warning).', + ['--report', '-r'], {'dest': 'report_level', 'default': 2, + 'metavar': '<level>'}), + ('Report all system messages, info-level and higher. (Same as ' + '"--report=info".)', + ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', + 'dest': 'report_level'}), + ('Set the threshold (<level>) at or above which system messages are ' + 'converted to exceptions, halting execution immediately. Levels as ' + 'in --report. Default is 4 (severe).', + ['--halt'], {'dest': 'halt_level', 'default': 4, + 'metavar': '<level>'}), + ('Same as "--halt=info": halt processing at the slightest problem.', + ['--strict'], {'action': 'store_const', 'const': 'info', + 'dest': 'halt_level'}), + ('Report debug-level system messages.', + ['--debug'], {'action': 'store_true', 'default': 0}), + ('Send the output of system messages (warnings) to <file>.', + ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), + # @@@ Take default encoding & language from locale? + #('Specify the encoding of input text. Default is "utf-8".', + # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': '<name>'}), + ('Specify the language of input text (ISO 639 2-letter identifier. ' + 'Default is "en" (English).', + ['--language', '-l'], {'dest': 'language_code', 'default': 'en', + 'metavar': '<name>'}), + ('Show this help message and exit.', + ['--help', '-h'], {'action': 'help'}),) + """Command-line option specifications, common to all Docutils front-ends. + A list/tuple of tuples: ``('help text', [list of option strings], {keyword + arguments})``. Option specs from Docutils components are also used (see + `build_option_parser()`).""" + + thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} + """Lookup table for --report and --halt threshold values.""" + + def __init__(self, components=(), defaults={}, *args, **kwargs): + """ + `components` is a list of Docutils components each containing a + ``.cmdline_options`` attribute. `defaults` is a + """ + optik.OptionParser.__init__(self, *args, **kwargs) + self.populate_from_components((self,) + tuple(components)) + self.set_defaults(**defaults) + + def populate_from_components(self, components): + for component in components: + if component is not None: + for (help_text, option_strings, kwargs) \ + in component.cmdline_options: + self.add_option(help=help_text, *option_strings, + **kwargs) + + def check_values(self, values, args): + values.report_level = self.check_threshold(values.report_level) + values.halt_level = self.check_threshold(values.halt_level) + source, destination = self.check_args(args) + return values, source, destination + + def check_threshold(self, level): + try: + return int(level) + except ValueError: + try: + return self.thresholds[level.lower()] + except (KeyError, AttributeError): + self.error('Unknown threshold: %r.' % level) + + def check_args(self, args): + source = destination = None + if args: + source = args.pop(0) + if args: + destination = args.pop(0) + if args: + self.error('Maximum 2 arguments allowed.') + return source, destination + + def get_default_values(self): + return optik.option_parser.Values(self.defaults) -- cgit v1.2.1 From 71a20e7a69cab41243bfb71ae0bab6fe91cbd2d3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:13:34 +0000 Subject: - Moved ``utils.id()`` to ``nodes.make_id()`` to avoid circular imports. - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@151 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index ee05a638c..6784416b2 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -19,12 +19,14 @@ element generic identifiers in the DTD_. .. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd """ -import sys, os +__docformat__ = 'reStructuredText' + +import sys +import os +import re import xml.dom.minidom from types import IntType, SliceType, StringType, TupleType, ListType from UserString import MutableString -import utils -import docutils # ============================== @@ -545,15 +547,15 @@ class Targetable(Resolvable): class document(Root, Structural, Element): - def __init__(self, reporter, language_code, *args, **kwargs): + def __init__(self, options, reporter, *args, **kwargs): Element.__init__(self, *args, **kwargs) + self.options = options + """Command-line or internal option data record.""" + self.reporter = reporter """System message generator.""" - self.language_code = language_code - """ISO 639 2-letter language identifier.""" - self.explicit_targets = {} """Mapping of target names to explicit target nodes.""" @@ -649,7 +651,7 @@ class document(Root, Structural, Element): msgnode += msg else: if node.has_key('name'): - id = utils.id(node['name']) + id = make_id(node['name']) else: id = '' while not id or self.ids.has_key(id): @@ -798,7 +800,7 @@ class document(Root, Structural, Element): self.pending.append(pending) def copy(self): - return self.__class__(self.reporter, self.language_code, + return self.__class__(self.options, self.reporter, **self.attributes) @@ -832,6 +834,7 @@ class copyright(Bibliographic, TextElement): pass class section(Structural, Element): pass + class topic(Structural, Element): """ @@ -1250,3 +1253,46 @@ class SkipDeparture(TreePruningException): """ pass + + +def make_id(string): + """ + Convert `string` into an identifier and return it. + + Docutils identifiers will conform to the regular expression + ``[a-z][-a-z0-9]*``. For CSS compatibility, identifiers (the "class" and + "id" attributes) should have no underscores, colons, or periods. Hyphens + may be used. + + - The `HTML 4.01 spec`_ defines identifiers based on SGML tokens: + + ID and NAME tokens must begin with a letter ([A-Za-z]) and may be + followed by any number of letters, digits ([0-9]), hyphens ("-"), + underscores ("_"), colons (":"), and periods ("."). + + - However the `CSS1 spec`_ defines identifiers based on the "name" token, + a tighter interpretation ("flex" tokenizer notation; "latin1" and + "escape" 8-bit characters have been replaced with entities):: + + unicode \\[0-9a-f]{1,4} + latin1 [¡-ÿ] + escape {unicode}|\\[ -~¡-ÿ] + nmchar [-a-z0-9]|{latin1}|{escape} + name {nmchar}+ + + The CSS1 "nmchar" rule does not include underscores ("_"), colons (":"), + or periods ("."), therefore "class" and "id" attributes should not contain + these characters. They should be replaced with hyphens ("-"). Combined + with HTML's requirements (the first character must be a letter; no + "unicode", "latin1", or "escape" characters), this results in the + ``[a-z][-a-z0-9]*`` pattern. + + .. _HTML 4.01 spec: http://www.w3.org/TR/html401 + .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 + """ + id = _non_id_chars.sub('-', ' '.join(string.lower().split())) + id = _non_id_at_ends.sub('', id) + return str(id) + +_non_id_chars = re.compile('[^a-z0-9]+') +_non_id_at_ends = re.compile('^[-0-9]+|-+$') -- cgit v1.2.1 From 677a4213e1d8a8c3ccfa01bfbcb67a5264adb129 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:14:23 +0000 Subject: - Moved ``utils.id()`` to ``nodes.make_id()``. - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@152 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 68 +++++++++++++------------------------------------------ 1 file changed, 16 insertions(+), 52 deletions(-) diff --git a/docutils/utils.py b/docutils/utils.py index 9f9130b5e..d276b671f 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -10,9 +10,12 @@ Miscellaneous utilities for the documentation utilities. """ -import sys, re -import nodes +__docformat__ = 'reStructuredText' + +import sys +from types import StringTypes from docutils import ApplicationError, DataError +from docutils import frontend, nodes class SystemMessage(ApplicationError): @@ -72,12 +75,14 @@ class Reporter: - `halt_level`: The level at or above which `SystemMessage` exceptions will be raised, halting execution. - `debug`: Show debug (level=0) system messages? - - `stream`: Where warning output is sent (`None` implies - `sys.stderr`). + - `stream`: Where warning output is sent. Can be file-like (has a + ``.write`` method), a string (file name, opened for writing), or + `None` (implies `sys.stderr`; default). """ - if stream is None: stream = sys.stderr + elif type(stream) in StringTypes: + raise NotImplementedError('This should open a file for writing.') self.categories = {'': ConditionSet(debug, report_level, halt_level, stream)} @@ -321,57 +326,16 @@ def extract_name_value(line): attlist.append((attname.lower(), data)) return attlist - def normalize_name(name): """Return a case- and whitespace-normalized name.""" return ' '.join(name.lower().split()) -def id(string): - """ - Convert `string` into an identifier and return it. - - Docutils identifiers will conform to the regular expression - ``[a-z][-a-z0-9]*``. For CSS compatibility, identifiers (the "class" and - "id" attributes) should have no underscores, colons, or periods. Hyphens - may be used. - - - The `HTML 4.01 spec`_ defines identifiers based on SGML tokens: - - ID and NAME tokens must begin with a letter ([A-Za-z]) and may be - followed by any number of letters, digits ([0-9]), hyphens ("-"), - underscores ("_"), colons (":"), and periods ("."). - - - However the `CSS1 spec`_ defines identifiers based on the "name" token, - a tighter interpretation ("flex" tokenizer notation; "latin1" and - "escape" 8-bit characters have been replaced with entities):: - - unicode \\[0-9a-f]{1,4} - latin1 [¡-ÿ] - escape {unicode}|\\[ -~¡-ÿ] - nmchar [-a-z0-9]|{latin1}|{escape} - name {nmchar}+ - - The CSS1 "nmchar" rule does not include underscores ("_"), colons (":"), - or periods ("."), therefore "class" and "id" attributes should not contain - these characters. They should be replaced with hyphens ("-"). Combined - with HTML's requirements (the first character must be a letter; no - "unicode", "latin1", or "escape" characters), this results in the - ``[a-z][-a-z0-9]*`` pattern. - - .. _HTML 4.01 spec: http://www.w3.org/TR/html401 - .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 - """ - id = non_id_chars.sub('-', normalize_name(string)) - id = non_id_at_ends.sub('', id) - return str(id) - -non_id_chars = re.compile('[^a-z0-9]+') -non_id_at_ends = re.compile('^[-0-9]+|-+$') - -def new_document(language_code='en', report_level=2, halt_level=4, - stream=None, debug=0): - reporter = Reporter(report_level, halt_level, stream, debug) - document = nodes.document(language_code=language_code, reporter=reporter) +def new_document(options=None): + if options is None: + options = frontend.OptionParser().get_default_values() + reporter = Reporter(options.report_level, options.halt_level, + options.warning_stream, options.debug) + document = nodes.document(options=options, reporter=reporter) return document def clean_rcs_keywords(paragraph, keyword_substitutions): -- cgit v1.2.1 From 9c4cc2885cf24d4bf4c5edb3d968ecb3dae2ef0d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:15:20 +0000 Subject: - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@153 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 434888417..3ee0e0534 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -12,6 +12,7 @@ the reStructuredText parser. It defines the following: - `RSTStateMachine`: reStructuredText parser's entry point. - `NestedStateMachine`: recursive StateMachine. - `RSTState`: reStructuredText State superclass. + - `Inliner`: For parsing inline markup. - `Body`: Generic classifier of the first line of a block. - `SpecializedBody`: Superclass for compound element members. - `BulletList`: Second and subsequent bullet_list list_items @@ -102,13 +103,15 @@ Parsing proceeds as follows: __docformat__ = 'reStructuredText' -import sys, re, string -from docutils import nodes, statemachine, utils, roman, urischemes, \ - ApplicationError, DataError +import sys +import re +import string +from docutils import nodes, statemachine, utils, roman, urischemes +from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.utils import normalize_name -import directives, languages -from tableparser import TableParser, TableMarkupError +from docutils.parsers.rst import directives, languages +from docutils.parsers.rst.tableparser import TableParser, TableMarkupError class MarkupError(DataError): pass @@ -141,7 +144,7 @@ class RSTStateMachine(StateMachineWS): StateMachine, and return the resulting document. """ - self.language = languages.get_language(document.language_code) + self.language = languages.get_language(document.options.language_code) self.match_titles = match_titles if inliner is None: inliner = Inliner() @@ -431,9 +434,9 @@ class Inliner: openers = '\'"([{<' closers = '\'")]}>' - start_string_prefix = (r'(?:(?<=^)|(?<=[ \n%s]))' + start_string_prefix = (r'(?:(?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) - end_string_suffix = (r'(?:(?=$)|(?=[- \n.,:;!?%s]))' + end_string_suffix = (r'(?:(?=$)|(?=[-/:.,;!? \n%s]))' % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' -- cgit v1.2.1 From 1bdab0e631f8ebc174d56c4c6b7a23d788ab09cf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:17:28 +0000 Subject: - Added support for the ``--stylesheet`` option. - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@154 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2a32a88a1..931718706 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -17,7 +17,10 @@ contains a minimum of formatting information. A cascading style sheet __docformat__ = 'reStructuredText' -import sys, time, string, re +import sys +import time +import string +import re from types import ListType from docutils import writers, nodes, languages @@ -27,6 +30,10 @@ class Writer(writers.Writer): supported = ('html', 'html4css1', 'xhtml') """Formats this writer supports.""" + cmdline_options = ( + ('Specify a stylesheet file. Default is "default.css".', + ['--stylesheet'], {'default': 'default.css', 'metavar': '<file>'}),) + output = None """Final translated form of `document`.""" @@ -51,19 +58,18 @@ class HTMLTranslator(nodes.NodeVisitor): 'charset=UTF-8">\n' generator = '<meta name="generator" content="Docutils: ' \ 'http://docutils.sourceforge.net/">\n' - stylesheet_link = '<link rel="stylesheet" href="default.css"' \ - ' type="text/css" />\n' + stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - self.language = languages.get_language(document.language_code) + self.language = languages.get_language(document.options.language_code) self.head_prefix = [ self.xml_declaration, # @@@ % output_encoding self.doctype, - self.html_head % document.language_code, + self.html_head % document.options.language_code, self.content_type, # @@@ % output encoding self.generator, - self.stylesheet_link] # @@@ % stylesheet + self.stylesheet_link % document.options.stylesheet] self.head = [] self.body_prefix = ['</head>\n<body>\n'] self.body = [] -- cgit v1.2.1 From 67b87f5d516ec079f2465fbbc7301d83f42d7683 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:18:16 +0000 Subject: - Added support for an option values object which carries default settings and overrides (from command-line options and library use). - Cleaned up imports: no more relative package imports or comma-separated lists of top-level modules. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@155 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 48 +++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 43e5cc4af..76e3a36e0 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -28,11 +28,15 @@ Exports the following: """ __docformat__ = 'reStructuredText' -import package_unittest -import sys, os, unittest, difflib, inspect, os, sys +import sys +import os +import unittest +import difflib +import inspect from pprint import pformat +import package_unittest import docutils -from docutils import statemachine, nodes, urischemes, utils, transforms +from docutils import frontend, nodes, statemachine, urischemes, utils from docutils.transforms import universal from docutils.parsers import rst from docutils.parsers.rst import states, tableparser, directives, languages @@ -45,6 +49,14 @@ except: import pdb +class DevNull: + + """Output sink.""" + + def write(self, string): + pass + + class CustomTestSuite(unittest.TestSuite): """ @@ -220,6 +232,12 @@ class TransformTestCase(CustomTestCase): cases that have nothing to do with the input and output of the transform. """ + options = frontend.OptionParser().get_default_values() + options.report_level = 1 + options.halt_level = 5 + options.debug = package_unittest.debug + options.warning_stream = DevNull() + def __init__(self, *args, **kwargs): self.transforms = kwargs['transforms'] """List of transforms to perform for this test case.""" @@ -236,9 +254,7 @@ class TransformTestCase(CustomTestCase): def test_transforms(self): if self.runInDebugger: pdb.set_trace() - document = utils.new_document(report_level=1, halt_level=5, - debug=package_unittest.debug, - stream=DevNull()) + document = utils.new_document(self.options) self.parser.parse(self.input, document) for transformClass in (self.transforms + universal.test_transforms): transformClass(document, self).transform() @@ -251,9 +267,7 @@ class TransformTestCase(CustomTestCase): print '\n', self.id print '-' * 70 print self.input - document = utils.new_document(report_level=1, halt_level=5, - debug=package_unittest.debug, - stream=DevNull()) + document = utils.new_document(self.options) self.parser.parse(self.input, document) print '-' * 70 print document.pformat() @@ -278,11 +292,15 @@ class ParserTestCase(CustomTestCase): parser = rst.Parser() """Parser shared by all ParserTestCases.""" + options = frontend.OptionParser().get_default_values() + options.report_level = 5 + options.halt_level = 5 + options.debug = package_unittest.debug + def test_parser(self): if self.runInDebugger: pdb.set_trace() - document = utils.new_document(report_level=5, halt_level=5, - debug=package_unittest.debug) + document = utils.new_document(self.options) self.parser.parse(self.input, document) output = document.pformat() self.compareOutput(self.input, output, self.expected) @@ -403,11 +421,3 @@ class TableParserTestCase(CustomTestCase): output = '%s: %s' % (details.__class__.__name__, details) self.compareOutput(self.input, pformat(output) + '\n', pformat(self.expected) + '\n') - - -class DevNull: - - """Output sink.""" - - def write(self, string): - pass -- cgit v1.2.1 From 00a4065f9d8c7bd420ab5e7662b06cb5e43639ab Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:19:18 +0000 Subject: Updated front-ends 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. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@156 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/html.py | 24 +++--------------------- tools/publish.py | 22 +++------------------- 2 files changed, 6 insertions(+), 40 deletions(-) diff --git a/tools/html.py b/tools/html.py index 2b9d727ea..e93abe3ca 100755 --- a/tools/html.py +++ b/tools/html.py @@ -7,30 +7,12 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher. - -This module takes advantage of the default values defined in `publish()`. +A minimal front-end to the Docutils Publisher, producing HTML. """ -import sys from docutils.core import publish -from docutils import utils -reporter = utils.Reporter(1, 4) -#reporter.setconditions('nodes.Node.walkabout', 2, 4, debug=1) +usage = 'usage:\n %prog [options] [source [destination]]' -if len(sys.argv) == 2: - source = sys.argv[1] - destination = None -elif len(sys.argv) == 3: - source = sys.argv[1] - destination = sys.argv[2] -elif len(sys.argv) > 3: - print >>sys.stderr, 'Maximum 2 arguments allowed.' - sys.exit(1) -else: - source = None - destination = None -publish(source=source, destination=destination, reporter=reporter, - writer_name='html') +publish(writer_name='html', usage=usage) diff --git a/tools/publish.py b/tools/publish.py index 33655d6b6..606cb7645 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -7,28 +7,12 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher. - -This module takes advantage of the default values defined in `publish()`. +A minimal front-end to the Docutils Publisher, producing pseudo-XML. """ -import sys from docutils.core import publish -from docutils import utils -reporter = utils.Reporter(1, 4) +usage = 'usage:\n %prog [options] [source [destination]]' -if len(sys.argv) == 2: - source = sys.argv[1] - destination = None -elif len(sys.argv) == 3: - source = sys.argv[1] - destination = sys.argv[2] -elif len(sys.argv) > 3: - print >>sys.stderr, 'Maximum 2 arguments allowed.' - sys.exit(1) -else: - source = None - destination = None -publish(source=source, destination=destination, reporter=reporter) +publish(usage=usage) -- cgit v1.2.1 From 1be17ead1d6e210c5a8d76cd44a283879f932d69 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:29:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@158 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 2 +- docutils/writers/__init__.py | 2 +- test/alltests.py | 3 ++- test/test_nodes.py | 10 +++++++++ test/test_parsers/test_rst/__init__.py | 4 +++- .../test_rst/test_directives/__init__.py | 4 +++- test/test_parsers/test_rst/test_inline_markup.py | 24 +++++++++++++++++----- test/test_readers/test_pep/__init__.py | 4 +++- test/test_statemachine.py | 4 +++- test/test_transforms/__init__.py | 5 ++++- test/test_utils.py | 14 +++---------- tools/quicktest.py | 4 +++- 12 files changed, 55 insertions(+), 25 deletions(-) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 55e656bff..b2b9337d5 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -59,7 +59,7 @@ class Transform(Component): apply to the document as a whole, `startnode` is not set (i.e. its value is `None`).""" - self.language = languages.get_language(document.language_code) + self.language = languages.get_language(document.options.language_code) """Language module local to this document.""" def transform(self): diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 35e5254c6..3c20068d4 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -52,7 +52,7 @@ class Writer(Component): def write(self, document, destination): self.document = document - self.language = languages.get_language(document.language_code) + self.language = languages.get_language(document.options.language_code) self.destination = destination self.transform() self.translate() diff --git a/test/alltests.py b/test/alltests.py index a01a60ee5..35cbe8dfa 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -17,7 +17,8 @@ import time # and setup outside of unittest. start = time.time() -import sys, os +import sys +import os class Tee: diff --git a/test/test_nodes.py b/test/test_nodes.py index 5f0a2b1a8..d14851740 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -91,6 +91,16 @@ class MiscTests(unittest.TestCase): node_class_names.append(x) self.assertEquals(node_class_names, nodes.node_class_names) + ids = [('a', 'a'), ('A', 'a'), ('', ''), ('a b \n c', 'a-b-c'), + ('a.b.c', 'a-b-c'), (' - a - b - c - ', 'a-b-c'), (' - ', ''), + (u'\u2020\u2066', ''), (u'a \xa7 b \u2020 c', 'a-b-c'), + ('1', ''), ('1abc', 'abc')] + + def test_make_id(self): + for input, output in self.ids: + normed = nodes.make_id(input) + self.assertEquals(normed, output) + class TreeCopyVisitorTests(unittest.TestCase): diff --git a/test/test_parsers/test_rst/__init__.py b/test/test_parsers/test_rst/__init__.py index 8df5d4778..2fe79c55c 100644 --- a/test/test_parsers/test_rst/__init__.py +++ b/test/test_parsers/test_rst/__init__.py @@ -1,4 +1,6 @@ -import os, os.path, sys +import os +import os.path +import sys sys.path.insert(0, os.path.abspath(os.curdir)) prev = '' diff --git a/test/test_parsers/test_rst/test_directives/__init__.py b/test/test_parsers/test_rst/test_directives/__init__.py index 8df5d4778..2fe79c55c 100644 --- a/test/test_parsers/test_rst/test_directives/__init__.py +++ b/test/test_parsers/test_rst/test_directives/__init__.py @@ -1,4 +1,6 @@ -import os, os.path, sys +import os +import os.path +import sys sys.path.insert(0, os.path.abspath(os.curdir)) prev = '' diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index 4a1c3e4c6..2212935a5 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -54,7 +54,8 @@ across lines* Inline emphasis start-string without end-string at line 1. """], ["""\ -'*emphasis*' but not '*' or '"*"' or x*2* or 2*x* or \\*args or * +'*emphasis*' and 1/*emphasis*/2 and 3-*emphasis*-4 and 5:*emphasis*:6 +but not '*' or '"*"' or x*2* or 2*x* or \\*args or * or *the\\* *stars\\\\\\* *inside* (however, '*args' will trigger a warning and may be problematic) @@ -67,7 +68,17 @@ what about *this**? ' <emphasis> emphasis - ' but not '*' or '"*"' or x*2* or 2*x* or *args or * + ' and 1/ + <emphasis> + emphasis + /2 and 3- + <emphasis> + emphasis + -4 and 5: + <emphasis> + emphasis + :6 + but not '*' or '"*"' or x*2* or 2*x* or *args or * or \n\ <emphasis> the* *stars\* *inside @@ -78,7 +89,7 @@ what about *this**? args' will trigger a warning and may be problematic) <system_message backrefs="id2" id="id1" level="2" type="WARNING"> <paragraph> - Inline emphasis start-string without end-string at line 4. + Inline emphasis start-string without end-string at line 5. <paragraph> what about \n\ <emphasis> @@ -360,7 +371,7 @@ ref__ ref """], ["""\ -ref_, r_, r_e-f_, and anonymousref__, but not _ref_ or -ref_ +ref_, r_, r_e-f_, -ref_, and anonymousref__, but not _ref_ """, """\ <document> @@ -373,10 +384,13 @@ ref_, r_, r_e-f_, and anonymousref__, but not _ref_ or -ref_ , \n\ <reference refname="r_e-f"> r_e-f + , - + <reference refname="ref"> + ref , and \n\ <reference anonymous="1"> anonymousref - , but not _ref_ or -ref_ + , but not _ref_ """], ] diff --git a/test/test_readers/test_pep/__init__.py b/test/test_readers/test_pep/__init__.py index 8df5d4778..2fe79c55c 100644 --- a/test/test_readers/test_pep/__init__.py +++ b/test/test_readers/test_pep/__init__.py @@ -1,4 +1,6 @@ -import os, os.path, sys +import os +import os.path +import sys sys.path.insert(0, os.path.abspath(os.curdir)) prev = '' diff --git a/test/test_statemachine.py b/test/test_statemachine.py index 02dd1e69b..8c336ca78 100755 --- a/test/test_statemachine.py +++ b/test/test_statemachine.py @@ -10,7 +10,9 @@ Test module for statemachine.py. """ -import unittest, sys, re +import unittest +import sys +import re from DocutilsTestSupport import statemachine diff --git a/test/test_transforms/__init__.py b/test/test_transforms/__init__.py index 027d2f3bc..2fe79c55c 100644 --- a/test/test_transforms/__init__.py +++ b/test/test_transforms/__init__.py @@ -1,4 +1,6 @@ -import os, os.path, sys +import os +import os.path +import sys sys.path.insert(0, os.path.abspath(os.curdir)) prev = '' @@ -9,3 +11,4 @@ while sys.path[0] != prev: except ImportError: prev = sys.path[0] sys.path[0] = os.path.dirname(prev) +sys.path.pop(0) diff --git a/test/test_utils.py b/test/test_utils.py index 3f3b53db8..8383d49a1 100755 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -10,7 +10,9 @@ Test module for utils.py. """ -import unittest, StringIO, sys +import unittest +import StringIO +import sys from DocutilsTestSupport import utils, nodes @@ -304,16 +306,6 @@ class MiscFunctionTests(unittest.TestCase): normed = utils.normalize_name(input) self.assertEquals(normed, output) - ids = [('a', 'a'), ('A', 'a'), ('', ''), ('a b \n c', 'a-b-c'), - ('a.b.c', 'a-b-c'), (' - a - b - c - ', 'a-b-c'), (' - ', ''), - (u'\u2020\u2066', ''), (u'a \xa7 b \u2020 c', 'a-b-c'), - ('1', ''), ('1abc', 'abc')] - - def test_id(self): - for input, output in self.ids: - normed = utils.id(input) - self.assertEquals(normed, output) - if __name__ == '__main__': unittest.main() diff --git a/tools/quicktest.py b/tools/quicktest.py index fab25adce..d76845023 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -10,7 +10,9 @@ :Copyright: This module has been placed in the public domain. """ -import sys, os, getopt +import sys +import os +import getopt import docutils.utils from docutils.parsers.rst import Parser -- cgit v1.2.1 From 1934c6cf5d19f763d01e03aa4babd681eea3b399 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:29:30 +0000 Subject: Cleaned up imports; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@159 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 113b2705e..b7fabebb9 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -13,7 +13,9 @@ Python Enhancement Proposal (PEP) Reader. __docformat__ = 'reStructuredText' -import sys, os, re +import sys +import os +import re from docutils import nodes from docutils.readers import standalone from docutils.transforms import peps, references @@ -30,12 +32,11 @@ class Reader(standalone.Reader): references.Footnotes, references.Hyperlinks,) - def __init__(self, reporter, parser, parser_name, language_code): + def __init__(self, parser, parser_name): """`parser` should be ``None``.""" if parser is None: parser = rst.Parser(rfc2822=1, inliner=Inliner()) - standalone.Reader.__init__( - self, reporter, parser, '', language_code) + standalone.Reader.__init__(self, parser, '') class Inliner(rst.states.Inliner): -- cgit v1.2.1 From 6e398dc95eb60a5b81047b899954503ce780f1db Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:30:40 +0000 Subject: Cleaned up imports git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@160 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/__init__.py | 2 +- docutils/statemachine.py | 4 +++- docutils/transforms/components.py | 8 ++++++-- docutils/transforms/parts.py | 3 ++- docutils/transforms/peps.py | 8 ++++++-- docutils/transforms/universal.py | 3 ++- test/package_unittest.py | 7 ++++++- 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 506a9e9fb..66b594841 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -48,7 +48,7 @@ __docformat__ = 'reStructuredText' import docutils.parsers import docutils.statemachine -import states +from docutils.parsers.rst import states class Parser(docutils.parsers.Parser): diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 2a772c206..e6502d3cd 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -105,7 +105,9 @@ How To Use This Module __docformat__ = 'restructuredtext' -import sys, re, string +import sys +import re +import string class StateMachine: diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index 71473bea9..dee54a215 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -11,8 +11,12 @@ Docutils component-related transforms. __docformat__ = 'reStructuredText' -import sys, os, re, time -from docutils import nodes, utils, ApplicationError, DataError +import sys +import os +import re +import time +from docutils import nodes, utils +from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index ac9ad0466..7a6d97219 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -14,7 +14,8 @@ Transforms related to document parts. __docformat__ = 'reStructuredText' -import re, sys +import re +import sys from docutils import nodes, utils from docutils.transforms import TransformError, Transform diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index ba311d488..2c51fa861 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -14,8 +14,12 @@ Transforms for PEP processing. __docformat__ = 'reStructuredText' -import sys, os, re, time -from docutils import nodes, utils, ApplicationError, DataError +import sys +import os +import re +import time +from docutils import nodes, utils +from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index c17341bb9..175faf637 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -19,7 +19,8 @@ Transforms needed by most or all documents: __docformat__ = 'reStructuredText' -import re, sys +import re +import sys from docutils import nodes, utils from docutils.transforms import TransformError, Transform diff --git a/test/package_unittest.py b/test/package_unittest.py index 32ced69c2..73b850331 100644 --- a/test/package_unittest.py +++ b/test/package_unittest.py @@ -12,7 +12,12 @@ test modules from a directory. Optionally, test packages are also loaded, recursively. """ -import sys, os, getopt, types, unittest, re +import sys +import os +import getopt +import types +import unittest +import re # So that individual test modules can share a bit of state, -- cgit v1.2.1 From a36ccb8dddee6b4f75ec62644a566d6d5cfaca3f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 02:48:15 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@161 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 30 +++++++++++++++- README.txt | 9 ++++- docs/dev/todo.txt | 106 ++++++++++++++++++++++-------------------------------- 3 files changed, 80 insertions(+), 65 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e1642ca40..b5261bd16 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -41,9 +41,12 @@ General: "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). Specific: @@ -54,6 +57,18 @@ Specific: - Added ``Component`` base class for Docutils components; implements the ``supports`` method. +* docutils/core.py: + + - Removed many keyword parameters to ``Publisher.__init__()`` and + ``publish()``; bundled into an option values object. Added + ``argv`` and ``usage`` parameters for command-line support. + - Added ``Publisher.process_command_line()`` and ``.set_options()`` + methods. + +* docutils/frontend.py: Added to project; support for front-end + scripts. Option specifications may be augmented by components. + Requires Optik (http://optik.sf.net/) for option processing. + * docutils/nodes.py: - Added ``TreeCopyVisitor`` class. @@ -64,6 +79,8 @@ Specific: ``Nodes.walk()``. - Improved docstrings. - Added ``SparseNodeVisitor``, refined ``NodeVisitor``. + - Moved ``utils.id()`` to ``nodes.make_id()`` to avoid circular + imports. * docutils/statemachine.py: @@ -83,6 +100,7 @@ Specific: - 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()``. * docutils/parsers/rst/states.py: @@ -94,6 +112,8 @@ Specific: (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. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -132,6 +152,7 @@ Specific: - Escape double-dashes in comment text. - Improved boilerplate & modularity of output. - Added a "generator" meta tag to <head>. + - Added support for the ``--stylesheet`` option. * docutils/writers/pseudoxml.py: Renamed from pprint.py. @@ -149,6 +170,8 @@ Specific: - 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. * spec/rst/alternatives.txt: Expanded auto-enumerated list idea; thanks to Fred Bremmer. @@ -168,6 +191,11 @@ Specific: * test/test_pep/: Subpackage added to project; PEP testing. +* tools: Updated html.py and publish.py front-ends 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. + Release 0.1 (2002-04-20) ======================== diff --git a/README.txt b/README.txt index fe979db32..f3972bd8a 100644 --- a/README.txt +++ b/README.txt @@ -12,10 +12,17 @@ this is a work in progress, please check the project website for updated working files. This project should be considered highly experimental; APIs are subject to change at any time. + +Requirements +============ + To run the code, Python 2.0 or later must already be installed. Python 2.1 or later is required to run the test suite. You can get Python from http://www.python.org/. +Greg Ward's Optik option processing package is required. You can get +Optik from http://optik.sourceforge.net/. + Project Files & Directories =========================== @@ -30,7 +37,7 @@ Project Files & Directories * setup.py: Installation script. See "Installation" below. -* install.py: Quick & dirty installation script. +* install.py: Quick & dirty installation script. Just run it. * docutils: The project source directory, installed as a Python package. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5da55712e..f0ab9880c 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -447,14 +447,14 @@ Unimplemented Transforms HTML Writer ----------- -- @@@ Allow for style sheet info to be passed in, either as a <LINK>, - or as embedded style info. +- Allow for style sheet info to be passed in. (Done, with the + ``--stylesheet`` command-line option.) - @@@ Construct a _`templating system`, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. -- @@ Improve the granularity of document parts in the HTML writer, so - that one could just grab the parts needed. +- Improve the granularity of document parts in the HTML writer, so + that one could just grab the parts needed. (Done.) - @@@ Return a string instead of writing to a file? Leave all I/O up to the client? Or up to an explicit distributor/filer? @@ -481,46 +481,43 @@ a common option-processing module, as described below. - Combine the common code from the existing front-ends into a single module, and add option processing. - - docutils.frontend? docutils.core.xyz? docutils.utils.options? - Part of docutils.core.Publisher/publish()? (Add a ``cmdline`` - parameter? To publish() only?) + - Named docutils.frontend.OptionParser. Supporting parameters have + been added to docutils.core.Publisher/publish(): ``argv`` & + ``usage``. - Use Optik to do modular command-line option processing. - - Pass around an Optik 'option Values' object? Attach it to the - document? + - An Optik 'option Values' object is attached to the document. - - What to do when *not* using a front-end (i.e., when docutils is - imported by an unrelated client)? I.e., report_level etc. Use - the default values of the OptionParser? Perhaps:: + - The Optik 'option Values' object is used even when *not* using a + front-end (i.e., when docutils is imported by an unrelated + client). An artificial argv list can be constructed & passed to + publish(), or a default Values object can be created and + modified manually:: - options = optik.option_parser.Values(option_parser.defaults) - options.an_option = "my default value" + pub = Publisher(...) + pub.process_command_line(argv=[]) + pub.options.an_option = "my default value" + pub.publish() - - The core would support all common options (--reader, --writer, + - The core supports all common options (--verbose, --date, etc.). + + - Each component adds its own specific options (HTML: --stylesheet, etc.). - - Each component would add its own specific options (HTML: - --stylesheet, etc.), and perhaps disable common options that don't - apply. + - Disables common options that don't apply? - Added/removed dynamically (during option processing)? Is this - possible with Optik? Is it desirable? - - - Parsers too? + possible with Optik? Is it desirable? (See dynamic_ below.) - - Common and component-specific options may not conflict. + - Common and component-specific options must not conflict. Reserve + short options for the core, and restrict components to long + options? - Build an OptionParser dynamically based on the known Reader & - Writer? Alternatives: - - a) First instantiate the common OptionParser subclass, which can - be passed to a standard function in the Reader module which - adds its specific options, then on to the Writer module. - - b) Or, store a data structure in each component containing its - specific options, merge with the common option data, and - instantiate an OptionParser. + Writer. Store a data structure in each component containing its + specific options, merge with the common option data, and + instantiate an OptionParser. - What about if we don't know which Reader and/or Writer we are going to use? If the Reader/Writer is specified on the @@ -543,40 +540,23 @@ a common option-processing module, as described below. [options]``). A single front-end would be sufficient, but probably only useful for testing purposes. + d) _`Dynamic`: Reader and/or Writer are specified by options, with + defaults if unspecified (e.g. ``publish --writer pdf + [options]``). Is this possible? The option parser would have + to be told about new options it needs to handle, on the fly. + Component-specific options would have to be specified *after* + the component-specifying option. + Allow common options before subcommands, as in CVS? Or group all options together? In the case of the `fully qualified`_ - front-ends, options will have to be grouped together anyway, so - there's no advantage to splitting common and component-specific - options apart. - -- Command-line option ideas. Common options: - - --generator Include a "Generated by Docutils" credit with a - link, at the end of the document. - --date Include a datestamp at the end of the document. - --source-link Include a "(View document source)" link. - --verbose Report all system messages, info-level and higher. - (Same as "--report=info".) - --debug Report debug-level system messages. - --report=level Set verbosity; report system messages at or higher - than ``level`` (by name or number: "info" or "1", - warning/2, error/3, severe/4; also, "none" or 5+). - Default is 2 (warning). - --halt=level Set the ``level`` at or above which system messages - are converted to exceptions, halting execution - immediately. Levels as in --report. Default is 4 - (severe). - --strict Same as "--halt=info": halt processing at the - slightest problem. - --encoding=name Specify the encoding of input text. Default is - "utf-8". - --language=name Specify the language of input text. Default is - "en" (English). - - Options specific to HTML writer: - - --stylesheet=file - Specify a stylesheet. Default is "default.css". + front-ends, all the options will have to be grouped together + anyway, so there's no advantage (we can't use it to avoid + conflicts) to splitting common and component-specific options + apart. + +- Implement command-line options. Common options: --generator, + --date, --time, --source-link, --warnings, --encoding=name, + --language=name. Project Policies -- cgit v1.2.1 From f58fb865a3aea6a7b87ca716fd16a0ba2cdd9ac6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 May 2002 03:14:26 +0000 Subject: removed 2.2ism git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@162 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/utils.py b/docutils/utils.py index d276b671f..da9c49512 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -13,7 +13,7 @@ Miscellaneous utilities for the documentation utilities. __docformat__ = 'reStructuredText' import sys -from types import StringTypes +from types import StringType, UnicodeType from docutils import ApplicationError, DataError from docutils import frontend, nodes @@ -81,7 +81,7 @@ class Reporter: """ if stream is None: stream = sys.stderr - elif type(stream) in StringTypes: + elif type(stream) in (StringType, UnicodeType): raise NotImplementedError('This should open a file for writing.') self.categories = {'': ConditionSet(debug, report_level, halt_level, -- cgit v1.2.1 From 0e41749d3da1e831a98aefb848c6a168894db738 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 31 May 2002 00:50:04 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@163 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/core.py b/docutils/core.py index 7c28d800a..f64e00b8c 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -69,7 +69,8 @@ class Publisher: Set default option values (keyword arguments). Set components first (`self.set_reader` & `self.set_writer`). - Overrides the command line. + Explicitly setting options disables command line option processing + from `self.publish()`. """ option_parser = OptionParser( components=(self.reader, self.parser, self.writer), -- cgit v1.2.1 From fa47be81f29db06976116a9202f9150b06b0c9ef Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 31 May 2002 00:51:44 +0000 Subject: Reworked based on ideas stolen from Tony Ibbs; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@164 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/pysource.dtd | 55 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/docs/dev/pysource.dtd b/docs/dev/pysource.dtd index 1a1aa6e8b..7fa920363 100644 --- a/docs/dev/pysource.dtd +++ b/docs/dev/pysource.dtd @@ -61,37 +61,50 @@ http://docutils.sourceforge.net/spec/docutils.dtd. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> -<!ELEMENT package_section (package, %structure.model;)> +<!ELEMENT package_section (package, fullname?, %structure.model;)> <!ATTLIST package_section %basic.atts;> -<!ELEMENT module_section (module, %structure.model;)> +<!ELEMENT module_section (module, fullname?, %structure.model;)> <!ATTLIST module_section %basic.atts;> <!ELEMENT class_section - (class, inheritance_list?, parameter_list?, %structure.model;)> + (class, inheritance_list?, fullname?, subclasses?, %structure.model;)> <!ATTLIST class_section %basic.atts;> -<!ELEMENT method_section (method, parameter_list?, %structure.model;)> +<!ELEMENT method_section + (method, parameter_list?, fullname?, overrides?, %structure.model;)> <!ATTLIST method_section %basic.atts;> -<!ELEMENT function_section (function, parameter_list?, %structure.model;)> +<!ELEMENT function_section + (function, parameter_list?, fullname?, %structure.model;)> <!ATTLIST function_section %basic.atts;> <!ELEMENT module_attribute_section - (module_attribute, initial_value?, %structure.model;)> + (module_attribute, initial_value?, fullname?, %structure.model;)> <!ATTLIST module_attribute_section %basic.atts;> <!ELEMENT class_attribute_section - (class_attribute, initial_value?, %structure.model;)> + (class_attribute, initial_value?, fullname?, overrides?, + %structure.model;)> <!ATTLIST class_attribute_section %basic.atts;> <!ELEMENT instance_attribute_section - (instance_attribute, initial_value?, %structure.model;)> + (instance_attribute, initial_value?, fullname?, overrides?, + %structure.model;)> <!ATTLIST instance_attribute_section %basic.atts;> +<!ELEMENT fullname (package | module | class | method | function)+> +<!ATTLIST fullname %basic.atts;> + +<!ELEMENT overrides (fullname+)> +<!ATTLIST overrides %basic.atts;> + <!ELEMENT inheritance_list (class+)> <!ATTLIST inheritance_list %basic.atts;> +<!ELEMENT subclasses (class+)> +<!ATTLIST subclasses %basic.atts;> + <!ELEMENT parameter_list ((parameter_item+, optional_parameters*) | optional_parameters+)> <!ATTLIST parameter_list %basic.atts;> @@ -122,13 +135,13 @@ http://docutils.sourceforge.net/spec/docutils.dtd. <!ELEMENT package (#PCDATA)> <!ATTLIST package %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `module_section` identifier/title. --> <!ELEMENT module (#PCDATA)> <!ATTLIST module %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `class_section` identifier/title, and in the @@ -137,19 +150,19 @@ Also used as the `class_section` identifier/title, and in the <!ELEMENT class (#PCDATA)> <!ATTLIST class %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `method_section` identifier/title. --> <!ELEMENT method (#PCDATA)> <!ATTLIST method %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `function_section` identifier/title. --> <!ELEMENT function (#PCDATA)> <!ATTLIST function %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `module_attribute_section` identifier/title. A module @@ -158,13 +171,13 @@ attribute is an exported module-level global variable. <!ELEMENT module_attribute (#PCDATA)> <!ATTLIST module_attribute %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `class_attribute_section` identifier/title. --> <!ELEMENT class_attribute (#PCDATA)> <!ATTLIST class_attribute %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used as the `instance_attribute_section` identifier/title. @@ -172,35 +185,35 @@ Also used as the `instance_attribute_section` identifier/title. <!ELEMENT instance_attribute (#PCDATA)> <!ATTLIST instance_attribute %basic.atts; - %link.atts;> + %reference.atts;> <!ELEMENT variable (#PCDATA)> <!ATTLIST variable %basic.atts; - %link.atts;> + %reference.atts;> <!-- Also used in `parameter_list`. --> <!ELEMENT parameter (#PCDATA)> <!ATTLIST parameter %basic.atts; - %link.atts; + %reference.atts; excess_positional %yesorno; #IMPLIED excess_keyword %yesorno; #IMPLIED> <!ELEMENT type (#PCDATA)> <!ATTLIST type %basic.atts; - %link.atts;> + %reference.atts;> <!ELEMENT exception_class (#PCDATA)> <!ATTLIST exception_class %basic.atts; - %link.atts;> + %reference.atts;> <!ELEMENT warning_class (#PCDATA)> <!ATTLIST warning_class %basic.atts; - %link.atts;> + %reference.atts;> <!-- -- cgit v1.2.1 From 34973b112ed65c6fc0285a71104f2b6e94b82224 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 31 May 2002 00:52:19 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@165 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 9 ++++--- docs/dev/todo.txt | 71 +++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/README.txt b/README.txt index f3972bd8a..2b4dc1d3a 100644 --- a/README.txt +++ b/README.txt @@ -12,6 +12,8 @@ this is a work in progress, please check the project website for updated working files. This project should be considered highly experimental; APIs are subject to change at any time. +.. contents:: + Requirements ============ @@ -59,7 +61,8 @@ Project Files & Directories the "standalone" reader and "pformat" writer. - html.py: Read standalone reStructuredText documents and write - HTML4/CSS1. Uses the default.css stylesheet. + HTML4/CSS1. Uses the default.css stylesheet (but can be + overridden). * test: Unit tests; ``test/alltests.py`` runs all the tests. Not required to use the software, but very useful if you're planning to @@ -73,8 +76,8 @@ The first step is to expand the .tar.gz archive. It contains a distutils setup file "setup.py". OS-specific installation instructions follow. -Linux, Unix, MacOS X --------------------- +GNU/Linux, Unix, MacOS X, etc. +------------------------------ 1. Open a shell. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f0ab9880c..0faeb4552 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -76,6 +76,13 @@ General structure: single file or string, vs. directory/package or tree of strings. Simple string I/O is default? +- Fix tests to run standalone. I.e., allow:: + + cd test/test_rst + test_inline_markup.py + + Raises an exception with path processing on GNU/Linux. + Specification ------------- @@ -404,44 +411,53 @@ Directives Unimplemented Transforms ------------------------ -- Footnote Gathering +Footnote Gathering +`````````````````` - Collect and move footnotes to the end of a document. +Collect and move footnotes to the end of a document. -- Hyperlink Target Gathering +Hyperlink Target Gathering +`````````````````````````` - It probably comes in two phases, because in a Python context we need - to *resolve* them on a per-docstring basis [do we? --DG], but if the - user is trying to do the callout form of presentation, they would - then want to group them all at the end of the document. +It probably comes in two phases, because in a Python context we need +to *resolve* them on a per-docstring basis [do we? --DG], but if the +user is trying to do the callout form of presentation, they would +then want to group them all at the end of the document. -- Reference Merging +Reference Merging +````````````````` - When merging two or more subdocuments (such as docstrings), - conflicting references may need to be resolved. There may be: +When merging two or more subdocuments (such as docstrings), +conflicting references may need to be resolved. There may be: - - duplicate reference and/or substitution names that need to be made - unique; and/or - - duplicate footnote numbers that need to be renumbered. +- duplicate reference and/or substitution names that need to be made + unique; and/or +- duplicate footnote numbers that need to be renumbered. - Should this be done before or after reference-resolving transforms - are applied? What about references from within one subdocument to - inside another? +Should this be done before or after reference-resolving transforms +are applied? What about references from within one subdocument to +inside another? -- Document Splitting +Document Splitting +`````````````````` - If the processed document is written to multiple files (possibly in - a directory tree), it will need to be split up. References will - have to be adjusted. +If the processed document is written to multiple files (possibly in +a directory tree), it will need to be split up. References will +have to be adjusted. - (HTML only?) +(HTML only? For now, yes.) -- Navigation +Navigation +`````````` + +If a document is split up, each segment will need navigation links: +parent, children (small TOC), previous (preorder), next (preorder). +Part of `Document Splitting`_? - If a document is split up, each segment will need navigation links: - parent, children (small TOC), previous (preorder), next (preorder). +Others +`````` -- Index +Index HTML Writer @@ -510,6 +526,9 @@ a common option-processing module, as described below. - Added/removed dynamically (during option processing)? Is this possible with Optik? Is it desirable? (See dynamic_ below.) + - Perhaps each component could have an ``init_options`` method, + which can do surgery on the option list? + - Common and component-specific options must not conflict. Reserve short options for the core, and restrict components to long options? @@ -586,7 +605,7 @@ least important): - Lines should be no more than 78 characters long. -- Use "CamelCase" for class names (except for element classes in +- Use "StudlyCaps" for class names (except for element classes in docutils.nodes). - Use "lowercase" or "lowercase_with_underscores" for function, -- cgit v1.2.1 From 0e8a50000a0064dd14910bfe641b459e86f7013c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:35:06 +0000 Subject: fiddling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@166 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/pysource.dtd | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/dev/pysource.dtd b/docs/dev/pysource.dtd index 7fa920363..f81de795d 100644 --- a/docs/dev/pysource.dtd +++ b/docs/dev/pysource.dtd @@ -68,11 +68,13 @@ http://docutils.sourceforge.net/spec/docutils.dtd. <!ATTLIST module_section %basic.atts;> <!ELEMENT class_section - (class, inheritance_list?, fullname?, subclasses?, %structure.model;)> + (class, inheritance_list?, fullname?, subclasses?, + %structure.model;)> <!ATTLIST class_section %basic.atts;> <!ELEMENT method_section - (method, parameter_list?, fullname?, overrides?, %structure.model;)> + (method, parameter_list?, fullname?, overrides?, + %structure.model;)> <!ATTLIST method_section %basic.atts;> <!ELEMENT function_section @@ -109,7 +111,8 @@ http://docutils.sourceforge.net/spec/docutils.dtd. ((parameter_item+, optional_parameters*) | optional_parameters+)> <!ATTLIST parameter_list %basic.atts;> -<!ELEMENT parameter_item ((parameter | parameter_tuple), parameter_default?)> +<!ELEMENT parameter_item + ((parameter | parameter_tuple), parameter_default?)> <!ATTLIST parameter_item %basic.atts;> <!ELEMENT optional_parameters (parameter_item+, optional_parameters*)> -- cgit v1.2.1 From 7608caed8e3ec8e027810d7509121697a5e981b0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:35:59 +0000 Subject: - Added ``decoration``, ``header``, and ``footer`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@167 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/docutils.dtd | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 9f3d1836a..856f3c13e 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -174,7 +174,7 @@ http://www.oasis-open.org/html/tm9901.htm). <!-- Optional elements may be generated by internal processing. --> <!ELEMENT document - ((title, subtitle?)?, docinfo?, %structure.model;)> + ((title, subtitle?)?, docinfo?, decoration?, %structure.model;)> <!ATTLIST document %basic.atts;> @@ -231,6 +231,22 @@ http://www.oasis-open.org/html/tm9901.htm). <!ATTLIST copyright %basic.atts;> +<!-- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Decoration Elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--> + +<!ELEMENT decoration (header?, footer?)> +<!ATTLIST decoration %basic.atts;> + +<!ELEMENT header (%body.elements;)+> +<!ATTLIST header %basic.atts;> + +<!ELEMENT footer (%body.elements;)+> +<!ATTLIST footer %basic.atts;> + + <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Structural Elements -- cgit v1.2.1 From 8610e9c1dfa7383679ef821aac3e95185feadae4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:37:29 +0000 Subject: - Added ``decoration``, ``header``, and ``footer`` node classes, and ``PreDecorative`` mixin. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@168 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 6784416b2..45d5ef726 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -446,6 +446,7 @@ class Element(Node): for c in childclass: if isinstance(self.children[index], c): match = 1 + break if not match: return index return None @@ -506,13 +507,15 @@ class Root: pass class Titular: pass -class Bibliographic: pass +class PreDecorative: + """Category of Node which may occur before Decorative Nodes.""" - -class PreBibliographic: +class PreBibliographic(PreDecorative): """Category of Node which may occur before Bibliographic Nodes.""" - pass +class Bibliographic(PreDecorative): pass + +class Decorative: pass class Structural: pass @@ -524,11 +527,8 @@ class Sequential(Body): pass class Admonition(Body): pass - class Special(Body): """Special internal body elements.""" - pass - class Part: pass @@ -828,6 +828,15 @@ class date(Bibliographic, TextElement): pass class copyright(Bibliographic, TextElement): pass +# ===================== +# Decorative Elements +# ===================== + +class decoration(Decorative, Element): pass +class header(Decorative, Element): pass +class footer(Decorative, Element): pass + + # ===================== # Structural Elements # ===================== @@ -848,8 +857,6 @@ class topic(Structural, Element): list, block quote, etc. """ - pass - class transition(Structural, Element): pass @@ -1054,14 +1061,14 @@ node_class_names = """ Text attention author authors block_quote bullet_list - caption caution citation citation_reference classifier colspec - comment contact copyright - danger date definition definition_list definition_list_item + caption caution citation citation_reference classifier colspec comment + contact copyright + danger date decoration definition definition_list definition_list_item description docinfo doctest_block document emphasis entry enumerated_list error - field field_argument field_body field_list field_name figure + field field_argument field_body field_list field_name figure footer footnote footnote_reference - hint + header hint image important interpreted label legend list_item literal literal_block note @@ -1069,8 +1076,8 @@ node_class_names = """ option_string organization paragraph pending problematic raw reference revision row - section status strong substitution_definition - substitution_reference subtitle system_message + section status strong substitution_definition substitution_reference + subtitle system_message table target tbody term tgroup thead tip title topic transition version warning""".split() -- cgit v1.2.1 From 8f2f1d9958c71eecc024167722971ada5158f99d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:40:18 +0000 Subject: - Added ``Decorations`` transform (support for "--generator", "--date", "--time", "--source-link" options). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@169 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 58 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 175faf637..782d930c5 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -8,6 +8,7 @@ Transforms needed by most or all documents: +- `Decorations`: Generate a document's header & footer. - `Messages`: Placement of system messages stored in `nodes.document.messages`. - `TestMessages`: Like `Messages`, used on test runs. @@ -21,10 +22,65 @@ __docformat__ = 'reStructuredText' import re import sys +import time from docutils import nodes, utils from docutils.transforms import TransformError, Transform +class Decorations(Transform): + + """ + Populate a document's decoration element (header, footer). + """ + + def transform(self): + header = self.generate_header() + footer = self.generate_footer() + if header or footer: + decoration = nodes.decoration() + decoration += header + decoration += footer + document = self.document + index = document.first_child_not_matching_class( + nodes.PreDecorative) + if index is None: + document += decoration + else: + document[index:index] = [decoration] + + def generate_header(self): + return None + + def generate_footer(self): + # @@@ Text is hard-coded for now. + # Should be made dynamic (language-dependent). + options = self.document.options + if options.generator or options.datestamp or options.source_link: + text = [] + if options.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. ')]) + if options.source_link: + text.extend([ + nodes.reference('', 'View document source', + refuri=self.document['source']), + nodes.Text('. ')]) + if options.datestamp: + datestamp = time.strftime(options.datestamp, time.gmtime()) + text.append(nodes.Text('Date: ' + datestamp + '. ')) + footer = nodes.footer() + footer += nodes.paragraph('', '', *text) + return footer + else: + return None + + class Messages(Transform): """ @@ -149,7 +205,7 @@ test_transforms = (TestMessages,) first_reader_transforms = (FirstReaderPending,) """Universal transforms to apply before any other Reader transforms.""" -last_reader_transforms = (LastReaderPending,) +last_reader_transforms = (LastReaderPending, Decorations) """Universal transforms to apply after all other Reader transforms.""" first_writer_transforms = (FirstWriterPending,) -- cgit v1.2.1 From 83de8a45d6e3ca1567ee955f9d557c8f0c75e2c2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:41:33 +0000 Subject: Enabled a bunch of command-line options relating to the document footer. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@170 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 727db95d0..6f158e862 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -26,18 +26,26 @@ class OptionParser(optik.OptionParser): cmdline_options = ( # Unimplemented or unused options are commented out. - #('Include a "Generated by Docutils" credit with a link, at the end ' - # 'of the document.', - # ['--generator', '-g'], {'action': 'store_true', 'default': 0}), - #('Include the date at the end of the document (UTC).', - # ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d', - # 'dest': 'datestamp', 'default': ''}), - #('Include the time & date at the end of the document (UTC).', - # ['--time', '-t'], {'action': 'store_const', - # 'const': '%Y-%m-%d %H:%M:%S UTC', - # 'dest': 'datestamp', 'default': ''}), - #('Include a "(View document source)" link.', - # ['--source-link', '-s'], {'action': 'store_true', 'default': 0}), + ('Include a "Generated by Docutils" credit with a link, at the end ' + 'of the document.', + ['--generator', '-g'], {'action': 'store_true'}), + ('Do not include a generator credit.', + ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}), + ('Include the date at the end of the document (UTC).', + ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d', + 'dest': 'datestamp'}), + ('Include the time & date at the end of the document (UTC).', + ['--time', '-t'], {'action': 'store_const', + 'const': '%Y-%m-%d %H:%M UTC', + 'dest': 'datestamp'}), + ('Do not include a datestamp of any kind.', + ['--no-datestamp'], {'action': 'store_const', 'const': None, + 'dest': 'datestamp'}), + ('Include a "View document source." link.', + ['--source-link', '-s'], {'action': 'store_true'}), + ('Do not include a "(View document source)" link.', + ['--no-source-link'], {'action': 'store_false', + 'dest': 'source_link'}), ('Set verbosity threshold; report system messages at or higher than ' '<level> (by name or number: "info" or "1", warning/2, error/3, ' 'severe/4; also, "none" or 5+). Default is 2 (warning).', @@ -56,7 +64,9 @@ class OptionParser(optik.OptionParser): ['--strict'], {'action': 'store_const', 'const': 'info', 'dest': 'halt_level'}), ('Report debug-level system messages.', - ['--debug'], {'action': 'store_true', 'default': 0}), + ['--debug'], {'action': 'store_true'}), + ('Do not report debug-level system messages.', + ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), ('Send the output of system messages (warnings) to <file>.', ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), # @@@ Take default encoding & language from locale? -- cgit v1.2.1 From 4c89d002f8f9017caa9ff690e0a82d1ec7556f5d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:42:51 +0000 Subject: Removed temporary testing code. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@171 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index f64e00b8c..f46527a9f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -90,14 +90,6 @@ class Publisher: argv = sys.argv[1:] self.options, self.source, self.destination \ = option_parser.parse_args(argv) - """ - # For testing purposes: - from pprint import pformat - print 'options:' - print pformat(options.__dict__) - print 'source=%r, destination=%r' % (source, destination) - sys.exit(0) - """ def publish(self, argv=None, usage=None): """ -- cgit v1.2.1 From 52f3b32ff8b86bfee7f2415e0d1e6db5dc5a1acc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:43:35 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@172 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index da9c49512..161526fa0 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -174,7 +174,8 @@ class Reporter: class ConditionSet: """ - A set of thresholds, switches, and streams corresponding to one `Reporter` + A set of two thresholds (`report_level` & `halt_level`), a switch + (`debug`), and an I/O stream (`stream`), corresponding to one `Reporter` category. """ -- cgit v1.2.1 From dfaa9f0a48d38d190eb44a83cef3a0cff6257805 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:44:33 +0000 Subject: - Added support for ``decoration``, ``header``, and ``footer`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@173 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 931718706..60570a914 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -265,6 +265,12 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_date(self, node): self.depart_docinfo_item() + def visit_decoration(self, node): + pass + + def depart_decoration(self, node): + pass + def visit_definition(self, node): self.body.append('</dt>\n') self.body.append(self.starttag(node, 'dd')) @@ -425,6 +431,16 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_figure(self, node): self.body.append('</div>\n') + def visit_footer(self, node): + self.context.append(len(self.body)) + + def depart_footer(self, node): + start = self.context.pop() + footer = ([self.starttag(node, 'div', CLASS='footer'), '<hr />\n'] + + self.body[start:] + ['</div>\n']) + self.body_suffix[:0] = footer + del self.body[start:] + def visit_footnote(self, node): self.body.append(self.starttag(node, 'table', CLASS='footnote', frame="void", rules="none")) @@ -449,6 +465,16 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footnote_reference(self, node): self.body.append('</a>') + def visit_header(self, node): + self.context.append(len(self.body)) + + def depart_header(self, node): + start = self.context.pop() + self.body_prefix.append(self.starttag(node, 'div', CLASS='header')) + self.body_prefix.extend(self.body[start:]) + self.body_prefix.append('<hr />\n</div>\n') + del self.body[start:] + def visit_hint(self, node): self.visit_admonition(node, 'hint') -- cgit v1.2.1 From 14a0689d77ea855ef7f983a3cad114bb7ae4df5f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 01:45:11 +0000 Subject: - Added support for ``header`` and ``footer`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@174 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 17bc06900..802c83c76 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -52,6 +52,11 @@ div.field-list { div.figure { margin-left: 2em } +div.footer, div.header { + font-size: smaller ; + font-style: italic ; + text-align: center } + div.system-messages { margin: 5em } -- cgit v1.2.1 From 545bb4ccc830105d91375a47eb953ee239e81a53 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 02:04:24 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@175 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 33 +++++++++++++++++++++++++++------ docs/dev/todo.txt | 27 ++++++++++++++++----------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index b5261bd16..60ef842ea 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -22,8 +22,8 @@ and related projects: Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ueli - Schlaepfer, Bob Tolbert, Laurence Tratt, Guido van Rossum, Barry - Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, + Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -66,8 +66,9 @@ Specific: methods. * docutils/frontend.py: Added to project; support for front-end - scripts. Option specifications may be augmented by components. - Requires Optik (http://optik.sf.net/) for option processing. + (command-line) scripts. Option specifications may be augmented by + components. Requires Optik (http://optik.sf.net/) for option + processing. * docutils/nodes.py: @@ -81,6 +82,8 @@ Specific: - 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. * docutils/statemachine.py: @@ -139,8 +142,12 @@ Specific: * docutils/transforms/components.py: Added to project; transforms related to Docutils components. -* docutils/transforms/universal.py: Changed ``Messages`` transform to - properly filter out system messages below the warning threshold. +* 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. @@ -153,9 +160,15 @@ Specific: - Improved boilerplate & modularity of output. - Added a "generator" meta tag to <head>. - Added support for the ``--stylesheet`` option. + - Added support for ``decoration``, ``header``, and ``footer`` + elements. * docutils/writers/pseudoxml.py: Renamed from pprint.py. +* spec/docutils.dtd: + + - Added ``decoration``, ``header``, and ``footer`` elements. + * spec/notes.txt: Continual updates. Added "Project Policies". * spec/pep-0257.txt: Clarified prohibition of signature repetition. @@ -165,6 +178,10 @@ Specific: - Minor edits. - Reworked Q&A as an enumerated list. +* spec/pysource.dtd: + + - Reworked structural elements, incorporating ideas from Tony Ibbs. + * spec/rst/reStructuredText.txt: - Clarified field list usage. @@ -196,6 +213,10 @@ Specific: in ``docutils.core.Publisher``), reducing each to just a few lines of code. +* tools/default.css: + + - Added support for ``header`` and ``footer`` elements. + Release 0.1 (2002-04-20) ======================== diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 0faeb4552..19a9622b9 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -100,7 +100,7 @@ Specification - Rework PEP 257, separating style from spec from tools, wrt Docutils? See Doc-SIG from 2001-06-19/20. -- Add layout component to framework? Or part of the formatter? +- Add layout component to framework? Or part of the writer? - Once doctree.txt is fleshed out, how about breaking (most of) it up and putting it into nodes.py as docstrings? @@ -408,6 +408,7 @@ Directives either by running it at the command line with a ``--help`` option or through an exposed API. [Suggestion for Optik.] + Unimplemented Transforms ------------------------ @@ -416,6 +417,7 @@ Footnote Gathering Collect and move footnotes to the end of a document. + Hyperlink Target Gathering `````````````````````````` @@ -424,6 +426,7 @@ to *resolve* them on a per-docstring basis [do we? --DG], but if the user is trying to do the callout form of presentation, they would then want to group them all at the end of the document. + Reference Merging ````````````````` @@ -438,6 +441,7 @@ Should this be done before or after reference-resolving transforms are applied? What about references from within one subdocument to inside another? + Document Splitting `````````````````` @@ -447,6 +451,7 @@ have to be adjusted. (HTML only? For now, yes.) + Navigation `````````` @@ -454,6 +459,7 @@ If a document is split up, each segment will need navigation links: parent, children (small TOC), previous (preorder), next (preorder). Part of `Document Splitting`_? + Others `````` @@ -475,10 +481,10 @@ HTML Writer - @@@ Return a string instead of writing to a file? Leave all I/O up to the client? Or up to an explicit distributor/filer? -- @@ Add an option to generate a "View source text" link. +- Add an option to generate a "View source text" link. (Done.) -- @@ Add an option to generate a "Generated by Docutils [from - reStructuredText source?]" message, with links. +- Add an option to generate a "Generated by Docutils [from + reStructuredText source?]" message, with links. (Done.) - If a list's items contain single paragraphs only, omit the <P> tags? Recursively? (if item == list whose items are single paragraphs @@ -499,9 +505,9 @@ a common option-processing module, as described below. - Named docutils.frontend.OptionParser. Supporting parameters have been added to docutils.core.Publisher/publish(): ``argv`` & - ``usage``. + ``usage``. (Done.) - - Use Optik to do modular command-line option processing. + - Use Optik to do modular command-line option processing. (Done.) - An Optik 'option Values' object is attached to the document. @@ -517,9 +523,10 @@ a common option-processing module, as described below. pub.publish() - The core supports all common options (--verbose, --date, etc.). + (Done.) - Each component adds its own specific options (HTML: --stylesheet, - etc.). + etc.). (Done.) - Disables common options that don't apply? @@ -536,7 +543,7 @@ a common option-processing module, as described below. - Build an OptionParser dynamically based on the known Reader & Writer. Store a data structure in each component containing its specific options, merge with the common option data, and - instantiate an OptionParser. + instantiate an OptionParser. (Done.) - What about if we don't know which Reader and/or Writer we are going to use? If the Reader/Writer is specified on the @@ -573,9 +580,7 @@ a common option-processing module, as described below. conflicts) to splitting common and component-specific options apart. -- Implement command-line options. Common options: --generator, - --date, --time, --source-link, --warnings, --encoding=name, - --language=name. +- Implement command-line options. Common options: --encoding=name. Project Policies -- cgit v1.2.1 From 147e98fd9a033cc75331cf9fe3417258e5ab761a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 1 Jun 2002 02:38:12 +0000 Subject: Removed italics & centering from footer; hard to read. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@176 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 802c83c76..690caf82b 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -53,9 +53,7 @@ div.figure { margin-left: 2em } div.footer, div.header { - font-size: smaller ; - font-style: italic ; - text-align: center } + font-size: smaller } div.system-messages { margin: 5em } -- cgit v1.2.1 From 7ce7476c958ae579fbd64bbbb00ebcee127d88ac Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:23:39 +0000 Subject: Added __version__ git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@179 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/__init__.py b/docutils/__init__.py index fe63168b7..0ea2f1803 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,6 +51,7 @@ Subpackages: """ __docformat__ = 'reStructuredText' +__version__ = '0.1+' class ApplicationError(StandardError): pass -- cgit v1.2.1 From 361fcaa4671d334ee92294de947ad99546469bd5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:25:41 +0000 Subject: Updated for new Optik option group functionality. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@180 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 13 ++--- docutils/frontend.py | 146 +++++++++++++++++++++++++++------------------------ 2 files changed, 83 insertions(+), 76 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index f46527a9f..1fe6af418 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -77,7 +77,7 @@ class Publisher: defaults=defaults) self.options = option_parser.get_default_values() - def process_command_line(self, argv=None, usage=None): + def process_command_line(self, argv=None, usage=None, description=None): """ Pass an empty list to `argv` to avoid reading `sys.argv` (the default). @@ -85,19 +85,20 @@ class Publisher: Set components first (`self.set_reader` & `self.set_writer`). """ option_parser = OptionParser( - components=(self.reader, self.parser, self.writer), usage=usage) + components=(self.reader, self.parser, self.writer), + usage=usage, description=description) if argv is None: argv = sys.argv[1:] self.options, self.source, self.destination \ = option_parser.parse_args(argv) - def publish(self, argv=None, usage=None): + def publish(self, argv=None, usage=None, description=None): """ Process command line options and arguments, run `self.reader` and then `self.writer`. """ if self.options is None: - self.process_command_line(argv, usage) + self.process_command_line(argv, usage, description) document = self.reader.read(self.source, self.parser, self.options) self.writer.write(document, self.destination) @@ -105,11 +106,11 @@ class Publisher: def publish(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', - argv=None, usage=None): + argv=None, usage=None, description=None): """A convenience function; set up & run a `Publisher`.""" pub = Publisher(reader, parser, writer) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: pub.set_writer(writer_name) - pub.publish(argv, usage) + pub.publish(argv, usage, description) diff --git a/docutils/frontend.py b/docutils/frontend.py index 6f158e862..01b0ed489 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -12,7 +12,8 @@ Command-line and common processing for Docutils front-ends. __docformat__ = 'reStructuredText' -import optik +import docutils +from docutils import optik class OptionParser(optik.OptionParser): @@ -21,87 +22,95 @@ class OptionParser(optik.OptionParser): Parser for command-line and library use. The `cmdline_options` specification here and in other Docutils components are merged """ - standard_option_list = [] - """We supply our own help option.""" - cmdline_options = ( - # Unimplemented or unused options are commented out. - ('Include a "Generated by Docutils" credit with a link, at the end ' - 'of the document.', - ['--generator', '-g'], {'action': 'store_true'}), - ('Do not include a generator credit.', - ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}), - ('Include the date at the end of the document (UTC).', - ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d', - 'dest': 'datestamp'}), - ('Include the time & date at the end of the document (UTC).', - ['--time', '-t'], {'action': 'store_const', - 'const': '%Y-%m-%d %H:%M UTC', - 'dest': 'datestamp'}), - ('Do not include a datestamp of any kind.', - ['--no-datestamp'], {'action': 'store_const', 'const': None, - 'dest': 'datestamp'}), - ('Include a "View document source." link.', - ['--source-link', '-s'], {'action': 'store_true'}), - ('Do not include a "(View document source)" link.', - ['--no-source-link'], {'action': 'store_false', - 'dest': 'source_link'}), - ('Set verbosity threshold; report system messages at or higher than ' - '<level> (by name or number: "info" or "1", warning/2, error/3, ' - 'severe/4; also, "none" or 5+). Default is 2 (warning).', - ['--report', '-r'], {'dest': 'report_level', 'default': 2, - 'metavar': '<level>'}), - ('Report all system messages, info-level and higher. (Same as ' - '"--report=info".)', - ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', - 'dest': 'report_level'}), - ('Set the threshold (<level>) at or above which system messages are ' - 'converted to exceptions, halting execution immediately. Levels as ' - 'in --report. Default is 4 (severe).', - ['--halt'], {'dest': 'halt_level', 'default': 4, - 'metavar': '<level>'}), - ('Same as "--halt=info": halt processing at the slightest problem.', - ['--strict'], {'action': 'store_const', 'const': 'info', - 'dest': 'halt_level'}), - ('Report debug-level system messages.', - ['--debug'], {'action': 'store_true'}), - ('Do not report debug-level system messages.', - ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), - ('Send the output of system messages (warnings) to <file>.', - ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), - # @@@ Take default encoding & language from locale? - #('Specify the encoding of input text. Default is "utf-8".', - # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': '<name>'}), - ('Specify the language of input text (ISO 639 2-letter identifier. ' - 'Default is "en" (English).', - ['--language', '-l'], {'dest': 'language_code', 'default': 'en', - 'metavar': '<name>'}), - ('Show this help message and exit.', - ['--help', '-h'], {'action': 'help'}),) + 'General Options', + None, + (('Include a "Generated by Docutils" credit with a link, at the end ' + 'of the document.', + ['--generator', '-g'], {'action': 'store_true'}), + ('Do not include a generator credit.', + ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}), + ('Include the date at the end of the document (UTC).', + ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d', + 'dest': 'datestamp'}), + ('Include the time & date at the end of the document (UTC).', + ['--time', '-t'], {'action': 'store_const', + 'const': '%Y-%m-%d %H:%M UTC', + 'dest': 'datestamp'}), + ('Do not include a datestamp of any kind.', + ['--no-datestamp'], {'action': 'store_const', 'const': None, + 'dest': 'datestamp'}), + ('Include a "View document source." link.', + ['--source-link', '-s'], {'action': 'store_true'}), + ('Do not include a "(View document source)" link.', + ['--no-source-link'], {'action': 'store_false', + 'dest': 'source_link'}), + ('Set verbosity threshold; report system messages at or higher than ' + '<level> (by name or number: "info" or "1", warning/2, error/3, ' + 'severe/4; also, "none" or 5+). Default is 2 (warning).', + ['--report', '-r'], {'dest': 'report_level', 'default': 2, + 'metavar': '<level>'}), + ('Report all system messages, info-level and higher. (Same as ' + '"--report=info".)', + ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', + 'dest': 'report_level'}), + ('Set the threshold (<level>) at or above which system messages are ' + 'converted to exceptions, halting execution immediately. Levels ' + 'as in --report. Default is 4 (severe).', + ['--halt'], {'dest': 'halt_level', 'default': 4, + 'metavar': '<level>'}), + ('Same as "--halt=info": halt processing at the slightest problem.', + ['--strict'], {'action': 'store_const', 'const': 'info', + 'dest': 'halt_level'}), + ('Report debug-level system messages.', + ['--debug'], {'action': 'store_true'}), + ('Do not report debug-level system messages.', + ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), + ('Send the output of system messages (warnings) to <file>.', + ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), + # @@@ Take default encoding & language from locale? + #('Specify the encoding of input text. Default is "utf-8".', + # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': '<name>'}), + ('Specify the language of input text (ISO 639 2-letter identifier. ' + 'Default is "en" (English).', + ['--language', '-l'], {'dest': 'language_code', 'default': 'en', + 'metavar': '<name>'}), + ("Show this program's version number and exit.", + ['--version'], {'action': 'version'}), + ('Show this help message and exit.', + ['--help', '-h'], {'action': 'help'}),)) """Command-line option specifications, common to all Docutils front-ends. - A list/tuple of tuples: ``('help text', [list of option strings], {keyword - arguments})``. Option specs from Docutils components are also used (see - `build_option_parser()`).""" + Option group title, description, and a list/tuple of tuples: ``('help + text', [list of option strings], {keyword arguments})``. Option specs + from Docutils components are also used (see + `populate_from_components()`).""" thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} """Lookup table for --report and --halt threshold values.""" + version_template = '%%prog (Docutils %s)' % docutils.__version__ + def __init__(self, components=(), defaults={}, *args, **kwargs): """ `components` is a list of Docutils components each containing a ``.cmdline_options`` attribute. `defaults` is a """ - optik.OptionParser.__init__(self, *args, **kwargs) - self.populate_from_components((self,) + tuple(components)) + optik.OptionParser.__init__(self, help=None, format=optik.Titled(), + *args, **kwargs) + if not self.version: + self.version = self.version_template + self.populate_from_components(tuple(components) + (self,)) self.set_defaults(**defaults) def populate_from_components(self, components): for component in components: - if component is not None: - for (help_text, option_strings, kwargs) \ - in component.cmdline_options: - self.add_option(help=help_text, *option_strings, - **kwargs) + if component is not None and component.cmdline_options: + title, description, option_spec = component.cmdline_options + group = optik.OptionGroup(self, title, description) + self.add_option_group(group) + for (help_text, option_strings, kwargs) in option_spec: + group.add_option(help=help_text, *option_strings, + **kwargs) def check_values(self, values, args): values.report_level = self.check_threshold(values.report_level) @@ -127,6 +136,3 @@ class OptionParser(optik.OptionParser): if args: self.error('Maximum 2 arguments allowed.') return source, destination - - def get_default_values(self): - return optik.option_parser.Values(self.defaults) -- cgit v1.2.1 From aff483bd932352ce97700fb7666c2cfc8190f5c5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:29:13 +0000 Subject: Combined from Optik package, with added option groups and other modifications. The use of this module is probably only temporary. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@181 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 1282 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1282 insertions(+) create mode 100644 docutils/optik.py diff --git a/docutils/optik.py b/docutils/optik.py new file mode 100644 index 000000000..6feebabb4 --- /dev/null +++ b/docutils/optik.py @@ -0,0 +1,1282 @@ +# This is *not* the official distribution of Optik. See +# http://optik.sourceforge.net/ for the official distro. +# +# This combined module was converted from the "optik" package for Docutils use +# by David Goodger (2002-06-12). Optik is slated for inclusion in the Python +# standard library as OptionParser.py. Once Optik itself becomes a single +# module, Docutils will include the official module and kill off this +# temporary fork. + +"""optik + +A powerful, extensible, and easy-to-use command-line parser for Python. + +By Greg Ward <gward@python.net> + +See http://optik.sourceforge.net/ +""" + +# Copyright (c) 2001 Gregory P. Ward. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the author nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +__revision__ = "$Id$" + +__version__ = "1.3+" + + +import sys +import os +import types +from types import TupleType, DictType +from distutils.fancy_getopt import wrap_text + + +SUPPRESS_HELP = "SUPPRESS"+"HELP" +SUPPRESS_USAGE = "SUPPRESS"+"USAGE" +# Not supplying a default is different from a default of None, +# so we need an explicit "not supplied" value. +NO_DEFAULT = "NO"+"DEFAULT" + + +class OptikError (Exception): + def __init__ (self, msg): + self.msg = msg + + def __str__ (self): + return self.msg + + +class OptionError (OptikError): + """ + Raised if an Option instance is created with invalid or + inconsistent arguments. + """ + + def __init__ (self, msg, option): + self.msg = msg + self.option_id = str(option) + + def __str__ (self): + if self.option_id: + return "option %s: %s" % (self.option_id, self.msg) + else: + return self.msg + +class OptionConflictError (OptionError): + """ + Raised if conflicting options are added to an OptionParser. + """ + +class OptionValueError (OptikError): + """ + Raised if an invalid option value is encountered on the command + line. + """ + +class BadOptionError (OptikError): + """ + Raised if an invalid or ambiguous option is seen on the command-line. + """ + + +_builtin_cvt = { "int" : (int, "integer"), + "long" : (long, "long integer"), + "float" : (float, "floating-point"), + "complex" : (complex, "complex") } + +def check_builtin (option, opt, value): + (cvt, what) = _builtin_cvt[option.type] + try: + return cvt(value) + except ValueError: + raise OptionValueError( + #"%s: invalid %s argument %r" % (opt, what, value)) + "option %s: invalid %s value: %r" % (opt, what, value)) + + +class Option: + """ + Instance attributes: + _short_opts : [string] + _long_opts : [string] + + action : string + type : string + dest : string + default : any + nargs : int + const : any + callback : function + callback_args : (any*) + callback_kwargs : { string : any } + help : string + metavar : string + """ + + # The list of instance attributes that may be set through + # keyword args to the constructor. + ATTRS = ['action', + 'type', + 'dest', + 'default', + 'nargs', + 'const', + 'callback', + 'callback_args', + 'callback_kwargs', + 'help', + 'metavar'] + + # The set of actions allowed by option parsers. Explicitly listed + # here so the constructor can validate its arguments. + ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "count", + "callback", + "help", + "version") + + # The set of actions that involve storing a value somewhere; + # also listed just for constructor argument validation. (If + # the action is one of these, there must be a destination.) + STORE_ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "count") + + # The set of actions for which it makes sense to supply a value + # type, ie. where we expect an argument to this option. + TYPED_ACTIONS = ("store", + "append", + "callback") + + # The set of known types for option parsers. Again, listed here for + # constructor argument validation. + TYPES = ("string", "int", "long", "float", "complex") + + # Dictionary of argument checking functions, which convert and + # validate option arguments according to the option type. + # + # Signature of checking functions is: + # check(option : Option, opt : string, value : string) -> any + # where + # option is the Option instance calling the checker + # opt is the actual option seen on the command-line + # (eg. "-a", "--file") + # value is the option argument seen on the command-line + # + # The return value should be in the appropriate Python type + # for option.type -- eg. an integer if option.type == "int". + # + # If no checker is defined for a type, arguments will be + # unchecked and remain strings. + TYPE_CHECKER = { "int" : check_builtin, + "long" : check_builtin, + "float" : check_builtin, + "complex" : check_builtin, + } + + + # CHECK_METHODS is a list of unbound method objects; they are called + # by the constructor, in order, after all attributes are + # initialized. The list is created and filled in later, after all + # the methods are actually defined. (I just put it here because I + # like to define and document all class attributes in the same + # place.) Subclasses that add another _check_*() method should + # define their own CHECK_METHODS list that adds their check method + # to those from this class. + CHECK_METHODS = None + + + # -- Constructor/initialization methods ---------------------------- + + def __init__ (self, *opts, **attrs): + # Set _short_opts, _long_opts attrs from 'opts' tuple + opts = self._check_opt_strings(opts) + self._set_opt_strings(opts) + + # Set all other attrs (action, type, etc.) from 'attrs' dict + self._set_attrs(attrs) + + # Check all the attributes we just set. There are lots of + # complicated interdependencies, but luckily they can be farmed + # out to the _check_*() methods listed in CHECK_METHODS -- which + # could be handy for subclasses! The one thing these all share + # is that they raise OptionError if they discover a problem. + for checker in self.CHECK_METHODS: + checker(self) + + def _check_opt_strings (self, opts): + # Filter out None because early versions of Optik had exactly + # one short option and one long option, either of which + # could be None. + opts = filter(None, opts) + if not opts: + raise OptionError("at least one option string must be supplied", + self) + return opts + + def _set_opt_strings (self, opts): + self._short_opts = [] + self._long_opts = [] + for opt in opts: + if len(opt) < 2: + raise OptionError( + "invalid option string %r: " + "must be at least two characters long" % opt, self) + elif len(opt) == 2: + if not (opt[0] == "-" and opt[1] != "-"): + raise OptionError( + "invalid short option string %r: " + "must be of the form -x, (x any non-dash char)" % opt, + self) + self._short_opts.append(opt) + else: + if not (opt[0:2] == "--" and opt[2] != "-"): + raise OptionError( + "invalid long option string %r: " + "must start with --, followed by non-dash" % opt, + self) + self._long_opts.append(opt) + + def _set_attrs (self, attrs): + for attr in self.ATTRS: + if attrs.has_key(attr): + setattr(self, attr, attrs[attr]) + del attrs[attr] + else: + if attr == 'default': + setattr(self, attr, NO_DEFAULT) + else: + setattr(self, attr, None) + if attrs: + raise OptionError( + "invalid keyword arguments: %s" % ", ".join(attrs.keys()), + self) + + + # -- Constructor validation methods -------------------------------- + + def _check_action (self): + if self.action is None: + self.action = "store" + elif self.action not in self.ACTIONS: + raise OptionError("invalid action: %r" % self.action, self) + + def _check_type (self): + if self.type is None: + # XXX should factor out another class attr here: list of + # actions that *require* a type + if self.action in ("store", "append"): + # No type given? "string" is the most sensible default. + self.type = "string" + else: + if self.type not in self.TYPES: + raise OptionError("invalid option type: %r" % self.type, self) + if self.action not in self.TYPED_ACTIONS: + raise OptionError( + "must not supply a type for action %r" % self.action, self) + + def _check_dest (self): + if self.action in self.STORE_ACTIONS and self.dest is None: + # No destination given, and we need one for this action. + # Glean a destination from the first long option string, + # or from the first short option string if no long options. + if self._long_opts: + # eg. "--foo-bar" -> "foo_bar" + self.dest = self._long_opts[0][2:].replace('-', '_') + else: + self.dest = self._short_opts[0][1] + + def _check_const (self): + if self.action != "store_const" and self.const is not None: + raise OptionError( + "'const' must not be supplied for action %r" % self.action, + self) + + def _check_nargs (self): + if self.action in self.TYPED_ACTIONS: + if self.nargs is None: + self.nargs = 1 + elif self.nargs is not None: + raise OptionError( + "'nargs' must not be supplied for action %r" % self.action, + self) + + def _check_callback (self): + if self.action == "callback": + if not callable(self.callback): + raise OptionError( + "callback not callable: %r" % self.callback, self) + if (self.callback_args is not None and + type(self.callback_args) is not TupleType): + raise OptionError( + "callback_args, if supplied, must be a tuple: not %r" + % self.callback_args, self) + if (self.callback_kwargs is not None and + type(self.callback_kwargs) is not DictType): + raise OptionError( + "callback_kwargs, if supplied, must be a dict: not %r" + % self.callback_kwargs, self) + else: + if self.callback is not None: + raise OptionError( + "callback supplied (%r) for non-callback option" + % self.callback, self) + if self.callback_args is not None: + raise OptionError( + "callback_args supplied for non-callback option", self) + if self.callback_kwargs is not None: + raise OptionError( + "callback_kwargs supplied for non-callback option", self) + + + CHECK_METHODS = [_check_action, + _check_type, + _check_dest, + _check_const, + _check_nargs, + _check_callback] + + + # -- Miscellaneous methods ----------------------------------------- + + def __str__ (self): + if self._short_opts or self._long_opts: + return "/".join(self._short_opts + self._long_opts) + else: + raise RuntimeError, "short_opts and long_opts both empty!" + + def takes_value (self): + return self.type is not None + + + # -- Processing methods -------------------------------------------- + + def check_value (self, opt, value): + checker = self.TYPE_CHECKER.get(self.type) + if checker is None: + return value + else: + return checker(self, opt, value) + + def process (self, opt, value, values, parser): + + # First, convert the value(s) to the right type. Howl if any + # value(s) are bogus. + if value is not None: + if self.nargs == 1: + value = self.check_value(opt, value) + else: + value = tuple([self.check_value(opt, v) for v in value]) + + # And then take whatever action is expected of us. + # This is a separate method to make life easier for + # subclasses to add new actions. + return self.take_action( + self.action, self.dest, opt, value, values, parser) + + def take_action (self, action, dest, opt, value, values, parser): + if action == "store": + setattr(values, dest, value) + elif action == "store_const": + setattr(values, dest, self.const) + elif action == "store_true": + setattr(values, dest, 1) + elif action == "store_false": + setattr(values, dest, 0) + elif action == "append": + values.ensure_value(dest, []).append(value) + elif action == "count": + setattr(values, dest, values.ensure_value(dest, 0) + 1) + elif action == "callback": + args = self.callback_args or () + kwargs = self.callback_kwargs or {} + self.callback(self, opt, value, parser, *args, **kwargs) + elif action == "help": + parser.print_help() + sys.exit(0) + elif action == "version": + parser.print_version() + sys.exit(0) + else: + raise RuntimeError, "unknown action %r" % self.action + + return 1 + +# class Option + + +# Some day, there might be many Option classes. As of Optik 1.3, the +# preferred way to instantiate Options is indirectly, via make_option(), +# which will become a factory function when there are many Option +# classes. +make_option = Option + + +STD_HELP_OPTION = Option("-h", "--help", + action="help", + help="show this help message and exit") +STD_VERSION_OPTION = Option("--version", + action="version", + help="show program's version number and exit") + + +class OptionContainer: + + """ + Abstract base class. + + Class attributes: + standard_option_list : [Option] + List of standard options that will be accepted by all instances + of this parser class (intended to be overridden by subclasses). + + Instance attributes: + option_list : [Option] + The list of Option objects contained by this OptionContainer. + _short_opt : { string : Option } + Dictionary mapping short option strings, eg. "-f" or "-X", + to the Option instances that implement them. If an Option + has multiple short option strings, it will appears in this + dictionary multiple times. [1] + _long_opt : { string : Option } + Dictionary mapping long option strings, eg. "--file" or + "--exclude", to the Option instances that implement them. + Again, a given Option can occur multiple times in this + dictionary. [1] + defaults : { string : any } + Dictionary mapping option destination names to default + values for each destination. [1] + + [1] These mappings are common to (shared by) all components of the + controlling OptionParser, where they are initially created. + + """ + + standard_option_list = [] + + def __init__(self, parser, description=None, option_list=None): + # List of Options is local to this OptionContainer. + self.option_list = [] + # The shared mappings are stored in the parser. + self._short_opt = parser._short_opt + self._long_opt = parser._long_opt + self.defaults = parser.defaults + # + self.format = parser.format + self.option_class = parser.option_class + self.conflict_handler = parser.conflict_handler + self.set_description(description) + self._populate_option_list(option_list) + + def set_description(self, description): + self.description = description + + def _populate_option_list(self, option_list, version=None, help=None): + if self.standard_option_list: + self.add_options(self.standard_option_list) + if option_list: + self.add_options(option_list) + if version: + self.add_option(STD_VERSION_OPTION) + if help: + self.add_option(STD_HELP_OPTION) + + + # -- Option-adding methods ----------------------------------------- + + def _check_conflict (self, option): + conflict_opts = [] + for opt in option._short_opts: + if self._short_opt.has_key(opt): + conflict_opts.append((opt, self._short_opt[opt])) + for opt in option._long_opts: + if self._long_opt.has_key(opt): + conflict_opts.append((opt, self._long_opt[opt])) + + if conflict_opts: + handler = self.conflict_handler + if handler == "ignore": # behaviour for Optik 1.0, 1.1 + pass + elif handler == "error": # new in 1.2 + raise OptionConflictError( + "conflicting option string(s): %s" + % ", ".join([co[0] for co in conflict_opts]), + option) + elif handler == "resolve": # new in 1.2 + for (opt, c_option) in conflict_opts: + if opt.startswith("--"): + c_option._long_opts.remove(opt) + del self._long_opt[opt] + else: + c_option._short_opts.remove(opt) + del self._short_opt[opt] + if not (c_option._short_opts or c_option._long_opts): + c_option.container.option_list.remove(c_option) + + def add_option (self, *args, **kwargs): + """add_option(Option) + add_option(opt_str, ..., kwarg=val, ...) + """ + if type(args[0]) is types.StringType: + option = self.option_class(*args, **kwargs) + elif len(args) == 1 and not kwargs: + option = args[0] + if not isinstance(option, Option): + raise TypeError, "not an Option instance: %r" % option + else: + raise TypeError, "invalid arguments" + + self._check_conflict(option) + + self.option_list.append(option) + option.container = self + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + if option.dest is not None: # option has a dest, we need a default + if option.default is not NO_DEFAULT: + self.defaults[option.dest] = option.default + elif not self.defaults.has_key(option.dest): + self.defaults[option.dest] = None + + def add_options (self, option_list): + for option in option_list: + self.add_option(option) + + # -- Option query/removal methods ---------------------------------- + + def get_option (self, opt_str): + return (self._short_opt.get(opt_str) or + self._long_opt.get(opt_str)) + + def has_option (self, opt_str): + return (self._short_opt.has_key(opt_str) or + self._long_opt.has_key(opt_str)) + + def remove_option (self, opt_str): + option = self._short_opt.get(opt_str) + if option is None: + option = self._long_opt.get(opt_str) + if option is None: + raise ValueError("no such option %r" % opt_str) + + for opt in option._short_opts: + del self._short_opt[opt] + for opt in option._long_opts: + del self._long_opt[opt] + option.container.option_list.remove(option) + + + # -- Feedback methods ---------------------------------------------- + + def get_options(self): + if not self.option_list: + return "" + # The help for each option consists of two parts: + # * the opt strings and metavars + # eg. ("-x", or "-fFILENAME, --file=FILENAME") + # * the user-supplied help string + # eg. ("turn on expert mode", "read data from FILENAME") + # + # If possible, we write both of these on the same line: + # -x turn on expert mode + # + # But if the opt string list is too long, we put the help + # string on a second line, indented to the same column it would + # start in if it fit on the first line. + # -fFILENAME, --file=FILENAME + # read data from FILENAME + result = [] # list of strings to "".join() later + for option in self.option_list: + if not option.help is SUPPRESS_HELP: + result.append(self.format.format_option(option)) + return "".join(result) + + def get_description(self): + if self.description: + return self.format.format_description(self.description) + else: + return "" + + def get_help(self): + result = "" + if self.description: + result = self.get_description() + "\n" + return result + self.get_options() + + +class OptionGroup(OptionContainer): + + def __init__(self, parser, title, description=None): + OptionContainer.__init__(self, parser, description) + self.parser = parser + self.title = title + self.description = description + + def set_title(self, title): + self.title = title + + def get_help(self): + result = self.format.format_heading(self.title) + self.format.increase_nesting() + result += OptionContainer.get_help(self) + self.format.decrease_nesting() + return result + + +class Values: + + def __init__ (self, defaults=None): + if defaults: + for (attr, val) in defaults.items(): + setattr(self, attr, val) + + + def _update_careful (self, dict): + """ + Update the option values from an arbitrary dictionary, but only + use keys from dict that already have a corresponding attribute + in self. Any keys in dict without a corresponding attribute + are silently ignored. + """ + for attr in dir(self): + if dict.has_key(attr): + dval = dict[attr] + if dval is not None: + setattr(self, attr, dval) + + def _update_loose (self, dict): + """ + Update the option values from an arbitrary dictionary, + using all keys from the dictionary regardless of whether + they have a corresponding attribute in self or not. + """ + self.__dict__.update(dict) + + def _update (self, dict, mode): + if mode == "careful": + self._update_careful(dict) + elif mode == "loose": + self._update_loose(dict) + else: + raise ValueError, "invalid update mode: %r" % mode + + def read_module (self, modname, mode="careful"): + __import__(modname) + mod = sys.modules[modname] + self._update(vars(mod), mode) + + def read_file (self, filename, mode="careful"): + vars = {} + execfile(filename, vars) + self._update(vars, mode) + + def ensure_value (self, attr, value): + if not hasattr(self, attr) or getattr(self, attr) is None: + setattr(self, attr, value) + return getattr(self, attr) + + +class OptionParser(OptionContainer): + + """ + Instance attributes: + usage : string + a usage string for your program. Before it is displayed + to the user, "%prog" will be expanded to the name of + your program (os.path.basename(sys.argv[0])). + + allow_interspersed_args : boolean = true + If true, positional arguments may be interspersed with options. + Assuming -a and -b each take a single argument, the command-line + -ablah foo bar -bboo baz + will be interpreted the same as + -ablah -bboo -- foo bar baz + If this flag were false, that command line would be interpreted as + -ablah -- foo bar -bboo baz + -- ie. we stop processing options as soon as we see the first + non-option argument. (This is the tradition followed by + Python's getopt module, Perl's Getopt::Std, and other argument- + parsing libraries, but it is generally annoying to users.) + + rargs : [string] + the argument list currently being parsed. Only set when + parse_args() is active, and continually trimmed down as + we consume arguments. Mainly there for the benefit of + callback options. + largs : [string] + the list of leftover arguments that we have skipped while + parsing options. If allow_interspersed_args is false, this + list is always empty. + values : Values + the set of option values currently being accumulated. Only + set when parse_args() is active. Also mainly for callbacks. + + Because of the 'rargs', 'largs', and 'values' attributes, + OptionParser is not thread-safe. If, for some perverse reason, you + need to parse command-line arguments simultaneously in different + threads, use different OptionParser instances. + + """ + + def __init__ (self, + usage=None, + description=None, + option_list=None, + option_class=Option, + version=None, + help=1, + conflict_handler="error", + format=None): + """Override OptionContainer.__init__.""" + self.set_usage(usage) + self.set_description(description) + self.option_class = option_class + self.version = version + self.set_conflict_handler(conflict_handler) + self.allow_interspersed_args = 1 + if not format: + format = Indented() + self.format = format + + # Create the various lists and dicts that constitute the + # "option list". See class docstring for details about + # each attribute. + self._create_option_list() + + # Populate the option list; initial sources are the + # standard_option_list class attribute, the 'option_list' argument, + # and the STD_VERSION_OPTION and STD_HELP_OPTION globals (if 'version' + # and/or 'help' supplied). + self._populate_option_list(option_list, version=version, help=help) + + self._init_parsing_state() + + # -- Private methods ----------------------------------------------- + # (used by the constructor) + + def _create_option_list (self): + self.option_list = [] + self.option_groups = [] + self._short_opt = {} # single letter -> Option instance + self._long_opt = {} # long option -> Option instance + self.defaults = {} # maps option dest -> default value + + def _init_parsing_state (self): + # These are set in parse_args() for the convenience of callbacks. + self.rargs = None + self.largs = None + self.values = None + + + # -- Simple modifier methods --------------------------------------- + + def set_usage (self, usage): + if usage is None: + self.usage = "%prog [options]" + elif usage is SUPPRESS_USAGE: + self.usage = None + else: + self.usage = usage + + def enable_interspersed_args (self): + self.allow_interspersed_args = 1 + + def disable_interspersed_args (self): + self.allow_interspersed_args = 0 + + def set_conflict_handler (self, handler): + if handler not in ("ignore", "error", "resolve"): + raise ValueError, "invalid conflict_resolution value %r" % handler + self.conflict_handler = handler + + def set_default (self, dest, value): + self.defaults[dest] = value + + def set_defaults (self, **kwargs): + self.defaults.update(kwargs) + + def get_default_values(self): + return Values(self.defaults) + + + # -- OptionGroup methods ------------------------------------------- + + def add_option_group(self, group): + self.option_groups.append(group) + + def get_option_group(self, opt_str): + option = (self._short_opt.get(opt_str) or + self._long_opt.get(opt_str)) + if option and option.container is not self: + return option.container + return None + + + # -- Option-parsing methods ---------------------------------------- + + def _get_args (self, args): + if args is None: + return sys.argv[1:] + else: + return args[:] # don't modify caller's list + + def parse_args (self, args=None, values=None): + """ + parse_args(args : [string] = sys.argv[1:], + values : Values = None) + -> (values : Values, args : [string]) + + Parse the command-line options found in 'args' (default: + sys.argv[1:]). Any errors result in a call to 'error()', which + by default prints the usage message to stderr and calls + sys.exit() with an error message. On success returns a pair + (values, args) where 'values' is an Values instance (with all + your option values) and 'args' is the list of arguments left + over after parsing options. + """ + rargs = self._get_args(args) + if values is None: + values = self.get_default_values() + + # Store the halves of the argument list as attributes for the + # convenience of callbacks: + # rargs + # the rest of the command-line (the "r" stands for + # "remaining" or "right-hand") + # largs + # the leftover arguments -- ie. what's left after removing + # options and their arguments (the "l" stands for "leftover" + # or "left-hand") + self.rargs = rargs + self.largs = largs = [] + self.values = values + + try: + stop = self._process_args(largs, rargs, values) + except (BadOptionError, OptionValueError), err: + self.error(err.msg) + + args = largs + rargs + return self.check_values(values, args) + + def check_values (self, values, args): + """ + check_values(values : Values, args : [string]) + -> (values : Values, args : [string]) + + Check that the supplied option values and leftover arguments are + valid. Returns the option values and leftover arguments + (possibly adjusted, possibly completely new -- whatever you + like). Default implementation just returns the passed-in + values; subclasses may override as desired. + """ + return (values, args) + + def _process_args (self, largs, rargs, values): + """_process_args(largs : [string], + rargs : [string], + values : Values) + + Process command-line arguments and populate 'values', consuming + options and arguments from 'rargs'. If 'allow_interspersed_args' is + false, stop at the first non-option argument. If true, accumulate any + interspersed non-option arguments in 'largs'. + """ + while rargs: + arg = rargs[0] + # We handle bare "--" explicitly, and bare "-" is handled by the + # standard arg handler since the short arg case ensures that the + # len of the opt string is greater than 1. + if arg == "--": + del rargs[0] + return + elif arg[0:2] == "--": + # process a single long option (possibly with value(s)) + self._process_long_opt(rargs, values) + elif arg[:1] == "-" and len(arg) > 1: + # process a cluster of short options (possibly with + # value(s) for the last one only) + self._process_short_opts(rargs, values) + elif self.allow_interspersed_args: + largs.append(arg) + del rargs[0] + else: + return # stop now, leave this arg in rargs + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # _process_arg() will usually consume 1 or more arguments. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt (self, opt): + """_match_long_opt(opt : string) -> string + + Determine which long option string 'opt' matches, ie. which one + it is an unambiguous abbrevation for. Raises BadOptionError if + 'opt' doesn't unambiguously match any long option string. + """ + return _match_abbrev(opt, self._long_opt) + + def _process_long_opt (self, rargs, values): + arg = rargs.pop(0) + + # Value explicitly attached to arg? Pretend it's the next + # argument. + if "=" in arg: + (opt, next_arg) = arg.split("=", 1) + rargs.insert(0, next_arg) + had_explicit_value = 1 + else: + opt = arg + had_explicit_value = 0 + + opt = self._match_long_opt(opt) + option = self._long_opt[opt] + if option.takes_value(): + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error("%s option requires a value" % opt) + else: + self.error("%s option requires %d values" + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + elif had_explicit_value: + self.error("%s option does not take a value" % opt) + + else: + value = None + + option.process(opt, value, values, self) + + def _process_short_opts (self, rargs, values): + arg = rargs.pop(0) + stop = 0 + i = 1 + for ch in arg[1:]: + opt = "-" + ch + option = self._short_opt.get(opt) + i += 1 # we have consumed a character + + if not option: + self.error("no such option: %s" % opt) + if option.takes_value(): + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + rargs.insert(0, arg[i:]) + stop = 1 + + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error("%s option requires a value" % opt) + else: + self.error("%s option requires %s values" + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + else: # option doesn't take a value + value = None + + option.process(opt, value, values, self) + + if stop: + break + + + # -- Feedback methods ---------------------------------------------- + + def error (self, msg): + """error(msg : string) + + Print a usage message incorporating 'msg' to stderr and exit. + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(sys.stderr) + sys.exit("%s: error: %s" % (get_prog_name(), msg)) + + def get_usage(self): + if self.usage: + return self.format.format_usage( + self.usage.replace("%prog", get_prog_name())) + else: + return "" + + def print_usage (self, file=None): + """print_usage(file : file = stdout) + + Print the usage message for the current program (self.usage) to + 'file' (default stdout). Any occurence of the string "%prog" in + self.usage is replaced with the name of the current program + (basename of sys.argv[0]). Does nothing if self.usage is empty + or not defined. + """ + if self.usage: + print >>file, self.get_usage() + + def get_version(self): + if self.version: + return self.version.replace("%prog", get_prog_name()) + else: + return "" + + def print_version (self, file=None): + """print_version(file : file = stdout) + + Print the version message for this program (self.version) to + 'file' (default stdout). As with print_usage(), any occurence + of "%prog" in self.version is replaced by the current program's + name. Does nothing if self.version is empty or undefined. + """ + if self.version: + print >>file, self.get_version() + + def get_options(self): + result = [] + result.append(self.format.format_heading("Options")) + self.format.increase_nesting() + if self.option_list: + result.append(OptionContainer.get_options(self)) + result.append("\n") + for group in self.option_groups: + result.append(group.get_help()) + result.append("\n") + self.format.decrease_nesting() + # Drop the last "\n", or the header if no options or option groups: + return "".join(result[:-1]) + + def get_help(self): + result = [] + if self.usage: + result.append(self.get_usage() + "\n") + if self.description: + result.append(self.get_description() + "\n") + #if self.option_list or self.option_groups: + result.append(self.get_options()) + return "".join(result) + + def print_help (self, file=None): + """print_help(file : file = stdout) + + Print an extended help message, listing all options and any + help text provided with them, to 'file' (default stdout). + """ + if file is None: + file = sys.stdout + file.write(self.get_help()) + +# class OptionParser + + +class HelpFormat: + + """ + "--help" output format; abstract base class (Strategy). + """ + + def __init__(self, indent_increment, help_indent, width, short_first): + self.current_indent = 0 + self.level = 0 + self.indent_increment = indent_increment + self.help_indent = help_indent + self.width = width + self.help_width = self.width - self.help_indent + if short_first: + self.format_option_list = self.format_option_list_short_first + else: + self.format_option_list = self.format_option_list_long_first + + def increase_nesting(self): + self.current_indent += self.indent_increment + self.level += 1 + + def decrease_nesting(self): + self.current_indent -= self.indent_increment + assert self.current_indent >= 0, "Indent decreased below 0." + self.level -= 1 + + def format_usage(self, usage): + raise NotImplementedError + + def format_heading(self, heading): + raise NotImplementedError + + def format_description(self, description): + desc_width = self.width - self.current_indent + desc_lines = wrap_text(description, desc_width) + result = ["%*s%s\n" % (self.current_indent, "", line) + for line in desc_lines] + return "".join(result) + + def format_option(self, option): + result = [] + opts = self.format_option_list(option) + opt_width = self.help_indent - self.current_indent - 2 + if len(opts) > opt_width: + opts = "%*s%s\n" % (self.current_indent, "", opts) + indent_first = self.help_indent + else: # start help on same line as opts + opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) + indent_first = 0 + result.append(opts) + if option.help: + help_lines = wrap_text(option.help, self.help_width) + result.append("%*s%s\n" % (indent_first, "", help_lines[0])) + result.extend(["%*s%s\n" % (self.help_indent, "", line) + for line in help_lines[1:]]) + elif opts[-1] != "\n": + result.append("\n") + return "".join(result) + + def format_option_list(self, option): + """Return a comma-separated list of option strigs & metavariables.""" + raise NotImplementedError( + "Virtual method; use format_option_list_short_first or " + "format_option_list_long_first instead.") + + def format_option_list_short_first(self, option): + opts = [] # list of "-a" or "--foo=FILE" strings + takes_value = option.takes_value() + if takes_value: + metavar = option.metavar or option.dest.upper() + for sopt in option._short_opts: + opts.append(sopt + metavar) + for lopt in option._long_opts: + opts.append(lopt + "=" + metavar) + else: + for opt in option._short_opts + option._long_opts: + opts.append(opt) + return ", ".join(opts) + + def format_option_list_long_first(self, option): + opts = [] # list of "-a" or "--foo=FILE" strings + takes_value = option.takes_value() + if takes_value: + metavar = option.metavar or option.dest.upper() + for lopt in option._long_opts: + opts.append(lopt + "=" + metavar) + for sopt in option._short_opts: + opts.append(sopt + metavar) + else: + for opt in option._long_opts + option._short_opts: + opts.append(opt) + return ", ".join(opts) + + +class Indented(HelpFormat): + + def __init__(self, indent_increment=2, help_indent=24, width=78, + short_first=1): + HelpFormat.__init__(self, indent_increment, help_indent, width, + short_first) + + def format_usage(self, usage): + return "Usage: %s\n" % usage + + def format_heading(self, heading): + return "%*s%s:\n" % (self.current_indent, "", heading) + + +class Titled(HelpFormat): + + def __init__(self, indent_increment=0, help_indent=24, width=78, + short_first=None): + HelpFormat.__init__(self, indent_increment, help_indent, width, + short_first) + + def format_usage(self, usage): + return "%s %s\n" % (self.format_heading("Usage"), usage) + + def format_heading(self, heading): + return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading)) + + +def _match_abbrev (s, wordmap): + """_match_abbrev(s : string, wordmap : {string : Option}) -> string + + Returns the string key in 'wordmap' for which 's' is an unambiguous + abbreviation. If 's' is found to be ambiguous or doesn't match any of + 'words', raises BadOptionError. + """ + # Is there an exact match? + if wordmap.has_key(s): + return s + else: + # Isolate all words with s as a prefix. + possibilities = [word for word in wordmap.keys() + if word.startswith(s)] + # No exact match, so there had better be just one possibility. + if len(possibilities) == 1: + return possibilities[0] + elif not possibilities: + raise BadOptionError("no such option: %s" % s) + else: + # More than one possible completion: ambiguous prefix. + raise BadOptionError("ambiguous option: %s (%s?)" + % (s, ", ".join(possibilities))) + +def get_prog_name (): + return os.path.basename(sys.argv[0]) -- cgit v1.2.1 From 6453bd44f1c452379e81c537adfca225fb6ce65d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:30:45 +0000 Subject: Combined from the Optik package, with no modifications. This module will probably eventually take over from optik.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@182 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/OptionParser.py | 1087 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1087 insertions(+) create mode 100644 docutils/OptionParser.py diff --git a/docutils/OptionParser.py b/docutils/OptionParser.py new file mode 100644 index 000000000..d0e4ab899 --- /dev/null +++ b/docutils/OptionParser.py @@ -0,0 +1,1087 @@ +"""optik + +A powerful, extensible, and easy-to-use command-line parser for Python. + +By Greg Ward <gward@python.net> + +See http://optik.sourceforge.net/ +""" + +# Copyright (c) 2001 Gregory P. Ward. All rights reserved. +# See the README.txt distributed with Optik for licensing terms. + +# This combined module created 2002-06-12 by David Goodger, +# from the optik package. + +__revision__ = "$Id$" + +__version__ = "1.3" + + +import sys +import os +import types +from types import TupleType, DictType +from distutils.fancy_getopt import wrap_text + + +SUPPRESS_HELP = "SUPPRESS"+"HELP" +SUPPRESS_USAGE = "SUPPRESS"+"USAGE" +# Not supplying a default is different from a default of None, +# so we need an explicit "not supplied" value. +NO_DEFAULT = "NO"+"DEFAULT" + + +class OptikError (Exception): + def __init__ (self, msg): + self.msg = msg + + def __str__ (self): + return self.msg + + +class OptionError (OptikError): + """ + Raised if an Option instance is created with invalid or + inconsistent arguments. + """ + + def __init__ (self, msg, option): + self.msg = msg + self.option_id = str(option) + + def __str__ (self): + if self.option_id: + return "option %s: %s" % (self.option_id, self.msg) + else: + return self.msg + +class OptionConflictError (OptionError): + """ + Raised if conflicting options are added to an OptionParser. + """ + +class OptionValueError (OptikError): + """ + Raised if an invalid option value is encountered on the command + line. + """ + +class BadOptionError (OptikError): + """ + Raised if an invalid or ambiguous option is seen on the command-line. + """ + + +_builtin_cvt = { "int" : (int, "integer"), + "long" : (long, "long integer"), + "float" : (float, "floating-point"), + "complex" : (complex, "complex") } + +def check_builtin (option, opt, value): + (cvt, what) = _builtin_cvt[option.type] + try: + return cvt(value) + except ValueError: + raise OptionValueError( + #"%s: invalid %s argument %r" % (opt, what, value)) + "option %s: invalid %s value: %r" % (opt, what, value)) + + +class Option: + """ + Instance attributes: + _short_opts : [string] + _long_opts : [string] + + action : string + type : string + dest : string + default : any + nargs : int + const : any + callback : function + callback_args : (any*) + callback_kwargs : { string : any } + help : string + metavar : string + """ + + # The list of instance attributes that may be set through + # keyword args to the constructor. + ATTRS = ['action', + 'type', + 'dest', + 'default', + 'nargs', + 'const', + 'callback', + 'callback_args', + 'callback_kwargs', + 'help', + 'metavar'] + + # The set of actions allowed by option parsers. Explicitly listed + # here so the constructor can validate its arguments. + ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "count", + "callback", + "help", + "version") + + # The set of actions that involve storing a value somewhere; + # also listed just for constructor argument validation. (If + # the action is one of these, there must be a destination.) + STORE_ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "count") + + # The set of actions for which it makes sense to supply a value + # type, ie. where we expect an argument to this option. + TYPED_ACTIONS = ("store", + "append", + "callback") + + # The set of known types for option parsers. Again, listed here for + # constructor argument validation. + TYPES = ("string", "int", "long", "float", "complex") + + # Dictionary of argument checking functions, which convert and + # validate option arguments according to the option type. + # + # Signature of checking functions is: + # check(option : Option, opt : string, value : string) -> any + # where + # option is the Option instance calling the checker + # opt is the actual option seen on the command-line + # (eg. "-a", "--file") + # value is the option argument seen on the command-line + # + # The return value should be in the appropriate Python type + # for option.type -- eg. an integer if option.type == "int". + # + # If no checker is defined for a type, arguments will be + # unchecked and remain strings. + TYPE_CHECKER = { "int" : check_builtin, + "long" : check_builtin, + "float" : check_builtin, + "complex" : check_builtin, + } + + + # CHECK_METHODS is a list of unbound method objects; they are called + # by the constructor, in order, after all attributes are + # initialized. The list is created and filled in later, after all + # the methods are actually defined. (I just put it here because I + # like to define and document all class attributes in the same + # place.) Subclasses that add another _check_*() method should + # define their own CHECK_METHODS list that adds their check method + # to those from this class. + CHECK_METHODS = None + + + # -- Constructor/initialization methods ---------------------------- + + def __init__ (self, *opts, **attrs): + # Set _short_opts, _long_opts attrs from 'opts' tuple + opts = self._check_opt_strings(opts) + self._set_opt_strings(opts) + + # Set all other attrs (action, type, etc.) from 'attrs' dict + self._set_attrs(attrs) + + # Check all the attributes we just set. There are lots of + # complicated interdependencies, but luckily they can be farmed + # out to the _check_*() methods listed in CHECK_METHODS -- which + # could be handy for subclasses! The one thing these all share + # is that they raise OptionError if they discover a problem. + for checker in self.CHECK_METHODS: + checker(self) + + def _check_opt_strings (self, opts): + # Filter out None because early versions of Optik had exactly + # one short option and one long option, either of which + # could be None. + opts = filter(None, opts) + if not opts: + raise OptionError("at least one option string must be supplied", + self) + return opts + + def _set_opt_strings (self, opts): + self._short_opts = [] + self._long_opts = [] + for opt in opts: + if len(opt) < 2: + raise OptionError( + "invalid option string %r: " + "must be at least two characters long" % opt, self) + elif len(opt) == 2: + if not (opt[0] == "-" and opt[1] != "-"): + raise OptionError( + "invalid short option string %r: " + "must be of the form -x, (x any non-dash char)" % opt, + self) + self._short_opts.append(opt) + else: + if not (opt[0:2] == "--" and opt[2] != "-"): + raise OptionError( + "invalid long option string %r: " + "must start with --, followed by non-dash" % opt, + self) + self._long_opts.append(opt) + + def _set_attrs (self, attrs): + for attr in self.ATTRS: + if attrs.has_key(attr): + setattr(self, attr, attrs[attr]) + del attrs[attr] + else: + if attr == 'default': + setattr(self, attr, NO_DEFAULT) + else: + setattr(self, attr, None) + if attrs: + raise OptionError( + "invalid keyword arguments: %s" % ", ".join(attrs.keys()), + self) + + + # -- Constructor validation methods -------------------------------- + + def _check_action (self): + if self.action is None: + self.action = "store" + elif self.action not in self.ACTIONS: + raise OptionError("invalid action: %r" % self.action, self) + + def _check_type (self): + if self.type is None: + # XXX should factor out another class attr here: list of + # actions that *require* a type + if self.action in ("store", "append"): + # No type given? "string" is the most sensible default. + self.type = "string" + else: + if self.type not in self.TYPES: + raise OptionError("invalid option type: %r" % self.type, self) + if self.action not in self.TYPED_ACTIONS: + raise OptionError( + "must not supply a type for action %r" % self.action, self) + + def _check_dest (self): + if self.action in self.STORE_ACTIONS and self.dest is None: + # No destination given, and we need one for this action. + # Glean a destination from the first long option string, + # or from the first short option string if no long options. + if self._long_opts: + # eg. "--foo-bar" -> "foo_bar" + self.dest = self._long_opts[0][2:].replace('-', '_') + else: + self.dest = self._short_opts[0][1] + + def _check_const (self): + if self.action != "store_const" and self.const is not None: + raise OptionError( + "'const' must not be supplied for action %r" % self.action, + self) + + def _check_nargs (self): + if self.action in self.TYPED_ACTIONS: + if self.nargs is None: + self.nargs = 1 + elif self.nargs is not None: + raise OptionError( + "'nargs' must not be supplied for action %r" % self.action, + self) + + def _check_callback (self): + if self.action == "callback": + if not callable(self.callback): + raise OptionError( + "callback not callable: %r" % self.callback, self) + if (self.callback_args is not None and + type(self.callback_args) is not TupleType): + raise OptionError( + "callback_args, if supplied, must be a tuple: not %r" + % self.callback_args, self) + if (self.callback_kwargs is not None and + type(self.callback_kwargs) is not DictType): + raise OptionError( + "callback_kwargs, if supplied, must be a dict: not %r" + % self.callback_kwargs, self) + else: + if self.callback is not None: + raise OptionError( + "callback supplied (%r) for non-callback option" + % self.callback, self) + if self.callback_args is not None: + raise OptionError( + "callback_args supplied for non-callback option", self) + if self.callback_kwargs is not None: + raise OptionError( + "callback_kwargs supplied for non-callback option", self) + + + CHECK_METHODS = [_check_action, + _check_type, + _check_dest, + _check_const, + _check_nargs, + _check_callback] + + + # -- Miscellaneous methods ----------------------------------------- + + def __str__ (self): + if self._short_opts or self._long_opts: + return "/".join(self._short_opts + self._long_opts) + else: + raise RuntimeError, "short_opts and long_opts both empty!" + + def takes_value (self): + return self.type is not None + + + # -- Processing methods -------------------------------------------- + + def check_value (self, opt, value): + checker = self.TYPE_CHECKER.get(self.type) + if checker is None: + return value + else: + return checker(self, opt, value) + + def process (self, opt, value, values, parser): + + # First, convert the value(s) to the right type. Howl if any + # value(s) are bogus. + if value is not None: + if self.nargs == 1: + value = self.check_value(opt, value) + else: + value = tuple([self.check_value(opt, v) for v in value]) + + # And then take whatever action is expected of us. + # This is a separate method to make life easier for + # subclasses to add new actions. + return self.take_action( + self.action, self.dest, opt, value, values, parser) + + def take_action (self, action, dest, opt, value, values, parser): + if action == "store": + setattr(values, dest, value) + elif action == "store_const": + setattr(values, dest, self.const) + elif action == "store_true": + setattr(values, dest, 1) + elif action == "store_false": + setattr(values, dest, 0) + elif action == "append": + values.ensure_value(dest, []).append(value) + elif action == "count": + setattr(values, dest, values.ensure_value(dest, 0) + 1) + elif action == "callback": + args = self.callback_args or () + kwargs = self.callback_kwargs or {} + self.callback(self, opt, value, parser, *args, **kwargs) + elif action == "help": + parser.print_help() + sys.exit(0) + elif action == "version": + parser.print_version() + sys.exit(0) + else: + raise RuntimeError, "unknown action %r" % self.action + + return 1 + +# class Option + + +# Some day, there might be many Option classes. As of Optik 1.3, the +# preferred way to instantiate Options is indirectly, via make_option(), +# which will become a factory function when there are many Option +# classes. +make_option = Option + + +STD_HELP_OPTION = Option("-h", "--help", + action="help", + help="show this help message and exit") +STD_VERSION_OPTION = Option("--version", + action="version", + help="show program's version number and exit") + + +class Values: + + def __init__ (self, defaults=None): + if defaults: + for (attr, val) in defaults.items(): + setattr(self, attr, val) + + + def _update_careful (self, dict): + """ + Update the option values from an arbitrary dictionary, but only + use keys from dict that already have a corresponding attribute + in self. Any keys in dict without a corresponding attribute + are silently ignored. + """ + for attr in dir(self): + if dict.has_key(attr): + dval = dict[attr] + if dval is not None: + setattr(self, attr, dval) + + def _update_loose (self, dict): + """ + Update the option values from an arbitrary dictionary, + using all keys from the dictionary regardless of whether + they have a corresponding attribute in self or not. + """ + self.__dict__.update(dict) + + def _update (self, dict, mode): + if mode == "careful": + self._update_careful(dict) + elif mode == "loose": + self._update_loose(dict) + else: + raise ValueError, "invalid update mode: %r" % mode + + def read_module (self, modname, mode="careful"): + __import__(modname) + mod = sys.modules[modname] + self._update(vars(mod), mode) + + def read_file (self, filename, mode="careful"): + vars = {} + execfile(filename, vars) + self._update(vars, mode) + + def ensure_value (self, attr, value): + if not hasattr(self, attr) or getattr(self, attr) is None: + setattr(self, attr, value) + return getattr(self, attr) + + +class OptionParser: + """ + Class attributes: + standard_option_list : [Option] + list of standard options that will be accepted by all instances + of this parser class (intended to be overridden by subclasses). + + Instance attributes: + usage : string + a usage string for your program. Before it is displayed + to the user, "%prog" will be expanded to the name of + your program (os.path.basename(sys.argv[0])). + option_list : [Option] + the list of all options accepted on the command-line of + this program + _short_opt : { string : Option } + dictionary mapping short option strings, eg. "-f" or "-X", + to the Option instances that implement them. If an Option + has multiple short option strings, it will appears in this + dictionary multiple times. + _long_opt : { string : Option } + dictionary mapping long option strings, eg. "--file" or + "--exclude", to the Option instances that implement them. + Again, a given Option can occur multiple times in this + dictionary. + _long_opts : [string] + list of long option strings recognized by this option + parser. Should be equal to _long_opt.keys(). + defaults : { string : any } + dictionary mapping option destination names to default + values for each destination. + + allow_interspersed_args : boolean = true + if true, positional arguments may be interspersed with options. + Assuming -a and -b each take a single argument, the command-line + -ablah foo bar -bboo baz + will be interpreted the same as + -ablah -bboo -- foo bar baz + If this flag were false, that command line would be interpreted as + -ablah -- foo bar -bboo baz + -- ie. we stop processing options as soon as we see the first + non-option argument. (This is the tradition followed by + Python's getopt module, Perl's Getopt::Std, and other argument- + parsing libraries, but it is generally annoying to users.) + + rargs : [string] + the argument list currently being parsed. Only set when + parse_args() is active, and continually trimmed down as + we consume arguments. Mainly there for the benefit of + callback options. + largs : [string] + the list of leftover arguments that we have skipped while + parsing options. If allow_interspersed_args is false, this + list is always empty. + values : Values + the set of option values currently being accumulated. Only + set when parse_args() is active. Also mainly for callbacks. + + Because of the 'rargs', 'largs', and 'values' attributes, + OptionParser is not thread-safe. If, for some perverse reason, you + need to parse command-line arguments simultaneously in different + threads, use different OptionParser instances. + + """ + + standard_option_list = [STD_HELP_OPTION] + + + def __init__ (self, + usage=None, + option_list=None, + option_class=Option, + version=None, + conflict_handler="error"): + self.set_usage(usage) + self.option_class = option_class + self.version = version + self.set_conflict_handler(conflict_handler) + self.allow_interspersed_args = 1 + + # Create the various lists and dicts that constitute the + # "option list". See class docstring for details about + # each attribute. + self._create_option_list() + + # Populate the option list; initial sources are the + # standard_option_list class attribute, the 'option_list' + # argument, and the STD_VERSION_OPTION global (if 'version' + # supplied). + self._populate_option_list(option_list) + + self._init_parsing_state() + + # -- Private methods ----------------------------------------------- + # (used by the constructor) + + def _create_option_list (self): + self.option_list = [] + self._short_opt = {} # single letter -> Option instance + self._long_opt = {} # long option -> Option instance + self._long_opts = [] # list of long options + self.defaults = {} # maps option dest -> default value + + def _populate_option_list (self, option_list): + if self.standard_option_list: + self.add_options(self.standard_option_list) + if self.version: + self.add_option(STD_VERSION_OPTION) + if option_list: + self.add_options(option_list) + + def _init_parsing_state (self): + # These are set in parse_args() for the convenience of callbacks. + self.rargs = None + self.largs = None + self.values = None + + + # -- Simple modifier methods --------------------------------------- + + def set_usage (self, usage): + if usage is None: + self.usage = "usage: %prog [options]" + elif usage is SUPPRESS_USAGE: + self.usage = None + else: + self.usage = usage + + def enable_interspersed_args (self): + self.allow_interspersed_args = 1 + + def disable_interspersed_args (self): + self.allow_interspersed_args = 0 + + def set_conflict_handler (self, handler): + if handler not in ("ignore", "error", "resolve"): + raise ValueError, "invalid conflict_resolution value %r" % handler + self.conflict_handler = handler + + def set_default (self, dest, value): + self.defaults[dest] = value + + def set_defaults (self, **kwargs): + self.defaults.update(kwargs) + + def get_default_values(self): + return Values(self.defaults) + + + # -- Option-adding methods ----------------------------------------- + + def _check_conflict (self, option): + conflict_opts = [] + for opt in option._short_opts: + if self._short_opt.has_key(opt): + conflict_opts.append((opt, self._short_opt[opt])) + for opt in option._long_opts: + if self._long_opt.has_key(opt): + conflict_opts.append((opt, self._long_opt[opt])) + + if conflict_opts: + handler = self.conflict_handler + if handler == "ignore": # behaviour for Optik 1.0, 1.1 + pass + elif handler == "error": # new in 1.2 + raise OptionConflictError( + "conflicting option string(s): %s" + % ", ".join([co[0] for co in conflict_opts]), + option) + elif handler == "resolve": # new in 1.2 + for (opt, c_option) in conflict_opts: + if opt.startswith("--"): + c_option._long_opts.remove(opt) + del self._long_opt[opt] + else: + c_option._short_opts.remove(opt) + del self._short_opt[opt] + if not (c_option._short_opts or c_option._long_opts): + self.option_list.remove(c_option) + + + def add_option (self, *args, **kwargs): + """add_option(Option) + add_option(opt_str, ..., kwarg=val, ...) + """ + if type(args[0]) is types.StringType: + option = self.option_class(*args, **kwargs) + elif len(args) == 1 and not kwargs: + option = args[0] + if not isinstance(option, Option): + raise TypeError, "not an Option instance: %r" % option + else: + raise TypeError, "invalid arguments" + + self._check_conflict(option) + + self.option_list.append(option) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + self._long_opts.append(opt) + + if option.dest is not None: # option has a dest, we need a default + if option.default is not NO_DEFAULT: + self.defaults[option.dest] = option.default + elif not self.defaults.has_key(option.dest): + self.defaults[option.dest] = None + + def add_options (self, option_list): + for option in option_list: + self.add_option(option) + + + # -- Option query/removal methods ---------------------------------- + + def get_option (self, opt_str): + return (self._short_opt.get(opt_str) or + self._long_opt.get(opt_str)) + + def has_option (self, opt_str): + return (self._short_opt.has_key(opt_str) or + self._long_opt.has_key(opt_str)) + + + def remove_option (self, opt_str): + option = self._short_opt.get(opt_str) + if option is None: + option = self._long_opt.get(opt_str) + if option is None: + raise ValueError("no such option %r" % opt_str) + + for opt in option._short_opts: + del self._short_opt[opt] + for opt in option._long_opts: + del self._long_opt[opt] + self._long_opts.remove(opt) + self.option_list.remove(option) + + + # -- Option-parsing methods ---------------------------------------- + + def _get_args (self, args): + if args is None: + return sys.argv[1:] + else: + return args[:] # don't modify caller's list + + def parse_args (self, args=None, values=None): + """ + parse_args(args : [string] = sys.argv[1:], + values : Values = None) + -> (values : Values, args : [string]) + + Parse the command-line options found in 'args' (default: + sys.argv[1:]). Any errors result in a call to 'error()', which + by default prints the usage message to stderr and calls + sys.exit() with an error message. On success returns a pair + (values, args) where 'values' is an Values instance (with all + your option values) and 'args' is the list of arguments left + over after parsing options. + """ + rargs = self._get_args(args) + if values is None: + values = self.get_default_values() + + # Store the halves of the argument list as attributes for the + # convenience of callbacks: + # rargs + # the rest of the command-line (the "r" stands for + # "remaining" or "right-hand") + # largs + # the leftover arguments -- ie. what's left after removing + # options and their arguments (the "l" stands for "leftover" + # or "left-hand") + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] + # and largs is a *subset* of [arg0, ..., arg(i-1)] + # (any options and their arguments will have been removed + # from largs). + # + # _process_arg() will always consume 1 or more arguments. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + self.rargs = rargs + self.largs = largs = [] + self.values = values + + stop = 0 + while rargs and not stop: + try: + stop = self._process_arg(largs, rargs, values) + except (BadOptionError, OptionValueError), err: + self.error(err.msg) + + args = largs + rargs + return self.check_values(values, args) + + def check_values (self, values, args): + """ + check_values(values : Values, args : [string]) + -> (values : Values, args : [string]) + + Check that the supplied option values and leftover arguments are + valid. Returns the option values and leftover arguments + (possibly adjusted, possibly completely new -- whatever you + like). Default implementation just returns the passed-in + values; subclasses may override as desired. + """ + return (values, args) + + def _process_arg (self, largs, rargs, values): + """_process_args(largs : [string], + rargs : [string], + values : Values) + -> stop : boolean + + Process a single command-line argument, consuming zero or more + arguments. The next argument to process is rargs[0], which will + almost certainly be consumed from rargs. (It might wind up in + largs, or it might affect a value in values, or -- if a callback + is involved -- almost anything might happen. It will not be + consumed if it is a non-option argument and + allow_interspersed_args is false.) More arguments from rargs + may also be consumed, depending on circumstances. + + Returns true if option processing should stop after this + argument is processed. + """ + + # We handle bare "--" explicitly, and bare "-" is handled by the + # standard arg handler since the short arg case ensures that the len + # of the opt string is greater than 1. + + arg = rargs[0] + if arg == "--": + del rargs[0] + return 1 + elif arg[0:2] == "--": + # process a single long option (possibly with value(s)) + self._process_long_opt(rargs, values) + elif arg[:1] == "-" and len(arg) > 1: + # process a cluster of short options (possibly with + # value(s) for the last one only) + self._process_short_opts(rargs, values) + else: + if self.allow_interspersed_args: + largs.append(arg) + del rargs[0] + else: + return 1 # stop now, leave this arg in rargs + + return 0 # keep processing args + + def _match_long_opt (self, opt): + """_match_long_opt(opt : string) -> string + + Determine which long option string 'opt' matches, ie. which one + it is an unambiguous abbrevation for. Raises BadOptionError if + 'opt' doesn't unambiguously match any long option string. + """ + return _match_abbrev(opt, self._long_opts) + + def _process_long_opt (self, rargs, values): + arg = rargs.pop(0) + + # Value explicitly attached to arg? Pretend it's the next + # argument. + if "=" in arg: + (opt, next_arg) = arg.split("=", 1) + rargs.insert(0, next_arg) + had_explicit_value = 1 + else: + opt = arg + had_explicit_value = 0 + + opt = self._match_long_opt(opt) + option = self._long_opt[opt] + if option.takes_value(): + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error("%s option requires a value" % opt) + else: + self.error("%s option requires %d values" + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + elif had_explicit_value: + self.error("%s option does not take a value" % opt) + + else: + value = None + + option.process(opt, value, values, self) + + def _process_short_opts (self, rargs, values): + arg = rargs.pop(0) + stop = 0 + i = 1 + for ch in arg[1:]: + opt = "-" + ch + option = self._short_opt.get(opt) + i += 1 # we have consumed a character + + if not option: + self.error("no such option: %s" % opt) + if option.takes_value(): + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + rargs.insert(0, arg[i:]) + stop = 1 + + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error("%s option requires a value" % opt) + else: + self.error("%s option requires %s values" + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + else: # option doesn't take a value + value = None + + option.process(opt, value, values, self) + + if stop: + break + + + # -- Output/error methods ------------------------------------------ + + def error (self, msg): + """error(msg : string) + + Print a usage message incorporating 'msg' to stderr and exit. + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(sys.stderr) + sys.exit("%s: error: %s" % (get_prog_name(), msg)) + + def print_usage (self, file=None): + """print_usage(file : file = stdout) + + Print the usage message for the current program (self.usage) to + 'file' (default stdout). Any occurence of the string "%prog" in + self.usage is replaced with the name of the current program + (basename of sys.argv[0]). Does nothing if self.usage is empty + or not defined. + """ + if self.usage: + usage = self.usage.replace("%prog", get_prog_name()) + print >>file, usage + print >>file + + def print_version (self, file=None): + """print_version(file : file = stdout) + + Print the version message for this program (self.version) to + 'file' (default stdout). As with print_usage(), any occurence + of "%prog" in self.version is replaced by the current program's + name. Does nothing if self.version is empty or undefined. + """ + if self.version: + version = self.version.replace("%prog", get_prog_name()) + print >>file, version + + def print_help (self, file=None): + """print_help(file : file = stdout) + + Print an extended help message, listing all options and any + help text provided with them, to 'file' (default stdout). + """ + from distutils.fancy_getopt import wrap_text + + if file is None: + file = sys.stdout + + self.print_usage(file) + + # The help for each option consists of two parts: + # * the opt strings and metavars + # eg. ("-x", or "-fFILENAME, --file=FILENAME") + # * the user-supplied help string + # eg. ("turn on expert mode", "read data from FILENAME") + # + # If possible, we write both of these on the same line: + # -x turn on expert mode + # + # But if the opt string list is too long, we put the help + # string on a second line, indented to the same column it would + # start in if it fit on the first line. + # -fFILENAME, --file=FILENAME + # read data from FILENAME + + print >>file, "options:" + width = 78 # assume 80 cols for now + + option_help = [] # list of (string, string) tuples + lengths = [] + + for option in self.option_list: + takes_value = option.takes_value() + if takes_value: + metavar = option.metavar or option.dest.upper() + + opts = [] # list of "-a" or "--foo=FILE" strings + if option.help is SUPPRESS_HELP: + continue + + if takes_value: + for sopt in option._short_opts: + opts.append(sopt + metavar) + for lopt in option._long_opts: + opts.append(lopt + "=" + metavar) + else: + for opt in option._short_opts + option._long_opts: + opts.append(opt) + + opts = ", ".join(opts) + option_help.append((opts, option.help)) + lengths.append(len(opts)) + + max_opts = min(max(lengths), 20) + + for (opts, help) in option_help: + # how much to indent lines 2 .. N of help text + indent_rest = 2 + max_opts + 2 + help_width = width - indent_rest + + if len(opts) > max_opts: + opts = " " + opts + "\n" + indent_first = indent_rest + + else: # start help on same line as opts + opts = " %-*s " % (max_opts, opts) + indent_first = 0 + + file.write(opts) + + if help: + help_lines = wrap_text(help, help_width) + print >>file, "%*s%s" % (indent_first, "", help_lines[0]) + for line in help_lines[1:]: + print >>file, "%*s%s" % (indent_rest, "", line) + elif opts[-1] != "\n": + file.write("\n") + +# class OptionParser + + +def _match_abbrev (s, words): + """_match_abbrev(s : string, words : [string]) -> string + + Returns the string in 'words' for which 's' is an unambiguous + abbreviation. If 's' is found to be ambiguous or doesn't match any + of 'words', raises BadOptionError. + """ + match = None + for word in words: + # If s isn't even a prefix for this word, don't waste any + # more time on it: skip to the next word and try again. + if not word.startswith(s): + continue + + # Exact match? Great, return now. + if s == word: + return word + + # Now comes the tricky business of disambiguation. At this + # point, we know s is a proper prefix of word, eg. s='--foo' and + # word=='--foobar'. If we have already seen another word where + # this was the case, eg. '--foobaz', fail: s is ambiguous. + # Otherwise record this match and keep looping; we will return + # if we see an exact match, or when we fall out of the loop and + # it turns out that the current word is the match. + if match: + raise BadOptionError("ambiguous option: %s (%s, %s, ...?)" + % (s, match, word)) + match = word + + if match: + return match + else: + raise BadOptionError("no such option: %s" % s) + +def get_prog_name (): + return os.path.basename(sys.argv[0]) -- cgit v1.2.1 From 8950f53d00b5c27c494af1207b6e5ecf859bef78 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:33:06 +0000 Subject: Updated for new Optik option group functionality. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@183 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 60570a914..bebc0a369 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -31,8 +31,11 @@ class Writer(writers.Writer): """Formats this writer supports.""" cmdline_options = ( - ('Specify a stylesheet file. Default is "default.css".', - ['--stylesheet'], {'default': 'default.css', 'metavar': '<file>'}),) + 'HTML-Specific Options', + None, + (('Specify a stylesheet file. Default is "default.css".', + ['--stylesheet'], + {'default': 'default.css', 'metavar': '<file>'}),),) output = None """Final translated form of `document`.""" -- cgit v1.2.1 From 87a136ed0c7a0e107cd58bb96e587daacd265eeb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:34:19 +0000 Subject: Updated for new Optik functionality. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@184 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/html.py | 6 ++++-- tools/publish.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/html.py b/tools/html.py index e93abe3ca..faee09f9c 100755 --- a/tools/html.py +++ b/tools/html.py @@ -13,6 +13,8 @@ A minimal front-end to the Docutils Publisher, producing HTML. from docutils.core import publish -usage = 'usage:\n %prog [options] [source [destination]]' +usage = '%prog [options] [source [destination]]' +description = ('Generate HTML documents from standalone reStructuredText ' + 'sources.') -publish(writer_name='html', usage=usage) +publish(writer_name='html', usage=usage, description=description) diff --git a/tools/publish.py b/tools/publish.py index 606cb7645..14c0ea09a 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -13,6 +13,8 @@ A minimal front-end to the Docutils Publisher, producing pseudo-XML. from docutils.core import publish -usage = 'usage:\n %prog [options] [source [destination]]' +usage = '%prog [options] [source [destination]]' +description = ('Generate pseudo-XML from standalone reStructuredText sources ' + '(for testing purposes).') -publish(usage=usage) +publish(usage=usage, description=description) -- cgit v1.2.1 From 682398e24b9262bb39c4e3aaefe6903f1031e51c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 03:35:39 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@185 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 9 +++++++++ docs/dev/todo.txt | 30 +++++++++++++++++++++++------- setup.py | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 60ef842ea..5e36845df 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -56,6 +56,7 @@ Specific: the package. - Added ``Component`` base class for Docutils components; implements the ``supports`` method. + - Added ``__version__`` (thus, ``docutils.__version__``). * docutils/core.py: @@ -85,6 +86,14 @@ Specific: - Added ``decoration``, ``header``, and ``footer`` node classes, and ``PreDecorative`` mixin. +* 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/OptionParser.py: Added to project. Combined from the Optik + package, with no modifications. This module will probably + eventually take over from optik.py. Not used at present. + * docutils/statemachine.py: - Added ``runtime_init`` method to ``StateMachine`` and ``State``. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 19a9622b9..b7a974d19 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -76,6 +76,11 @@ General structure: single file or string, vs. directory/package or tree of strings. Simple string I/O is default? +- Name ideas: importer/exporter. Perhaps reader/writer should be + applied to lower-level tasks? "PySource Reader" or "PySource + Importer"? "HTML Writer" or "HTML Exporter"? If we stick with the + status quo, what to call the components that do low-level I/O? + - Fix tests to run standalone. I.e., allow:: cd test/test_rst @@ -314,8 +319,20 @@ Directives lists). Without special syntax, this directive becomes low priority. - - _`body.columns`: Multi-column table/list, with number of columns - as argument. + - _`body.columns`: Multi-column table/list. Number of columns as + argument? Perhaps a variation on `table syntax alternative 2`__:: + + col 1 col 2 + ===== ===== + - 1 Second column of row 1. + - 2 Second column of row 2. + Second line of paragraph. + - 3 Second column of row 3. + + Second paragraph of row 3, + column 2 + + __ problems.html#tables - @@ _`body.verse`: Paragraphs with linebreaks preserved, *and* inline markup support too. Use cases: verse (poetry, song lyrics, @@ -632,11 +649,10 @@ Copyrights and Licensing ------------------------ The majority of the Docutils project code and documentation has been -written by me (David Goodger), and has been placed in the public -domain. Unless clearly and explicitly indicated otherwise, any -patches (modifications to existing files) submitted to the project for -inclusion (via SourceForge trackers, mailing lists, or private email) -are assumed to have been placed in the public domain as well. +placed in the public domain. Unless clearly and explicitly indicated +otherwise, any patches (modifications to existing files) submitted to +the project for inclusion (via SourceForge trackers, mailing lists, or +private email) are assumed to be in the public domain as well. Any new files contributed to the project should clearly state their intentions regarding copyright, in one of the following ways: diff --git a/setup.py b/setup.py index ca4fb45f2..ef42fdfd2 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ def do_setup(): description = 'Python Documentation Utilities', #long_description = '', url = 'http://docutils.sourceforge.net/', - version = '0.1', + version = '0.1+', author = 'David Goodger', author_email = 'goodger@users.sourceforge.net', license = 'public domain, Python (see COPYING.txt)', -- cgit v1.2.1 From 13da103589ae4085005670489808aaff76d54145 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 22:31:33 +0000 Subject: Docstrings, comments, minor edits, whitespace. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@186 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 69 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/docutils/optik.py b/docutils/optik.py index 6feebabb4..9faedd699 100644 --- a/docutils/optik.py +++ b/docutils/optik.py @@ -17,22 +17,22 @@ See http://optik.sourceforge.net/ """ # Copyright (c) 2001 Gregory P. Ward. All rights reserved. -# +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. -# +# # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# +# # * Neither the name of the author nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A @@ -608,20 +608,6 @@ class OptionContainer: def get_options(self): if not self.option_list: return "" - # The help for each option consists of two parts: - # * the opt strings and metavars - # eg. ("-x", or "-fFILENAME, --file=FILENAME") - # * the user-supplied help string - # eg. ("turn on expert mode", "read data from FILENAME") - # - # If possible, we write both of these on the same line: - # -x turn on expert mode - # - # But if the opt string list is too long, we put the help - # string on a second line, indented to the same column it would - # start in if it fit on the first line. - # -fFILENAME, --file=FILENAME - # read data from FILENAME result = [] # list of strings to "".join() later for option in self.option_list: if not option.help is SUPPRESS_HELP: @@ -1114,7 +1100,6 @@ class OptionParser(OptionContainer): result.append(self.get_usage() + "\n") if self.description: result.append(self.get_description() + "\n") - #if self.option_list or self.option_groups: result.append(self.get_options()) return "".join(result) @@ -1134,15 +1119,29 @@ class OptionParser(OptionContainer): class HelpFormat: """ - "--help" output format; abstract base class (Strategy). + "--help" output format; abstract base class (Strategy design pattern). + + Instance attributes: + indent_increment : int + number of columns to indent per nesting level + help_indent : int + the starting column for option help text + width : int + the overall width (in columns) for output + current_indent : int + in columns, calculated + level : int + increased for each additional nesting level + help_width : int + number of columns available for option help text """ def __init__(self, indent_increment, help_indent, width, short_first): - self.current_indent = 0 - self.level = 0 self.indent_increment = indent_increment self.help_indent = help_indent self.width = width + self.current_indent = 0 + self.level = 0 self.help_width = self.width - self.help_indent if short_first: self.format_option_list = self.format_option_list_short_first @@ -1152,7 +1151,7 @@ class HelpFormat: def increase_nesting(self): self.current_indent += self.indent_increment self.level += 1 - + def decrease_nesting(self): self.current_indent -= self.indent_increment assert self.current_indent >= 0, "Indent decreased below 0." @@ -1172,6 +1171,20 @@ class HelpFormat: return "".join(result) def format_option(self, option): + # The help for each option consists of two parts: + # * the opt strings and metavars + # eg. ("-x", or "-fFILENAME, --file=FILENAME") + # * the user-supplied help string + # eg. ("turn on expert mode", "read data from FILENAME") + # + # If possible, we write both of these on the same line: + # -x turn on expert mode + # + # But if the opt string list is too long, we put the help + # string on a second line, indented to the same column it would + # start in if it fit on the first line. + # -fFILENAME, --file=FILENAME + # read data from FILENAME result = [] opts = self.format_option_list(option) opt_width = self.help_indent - self.current_indent - 2 @@ -1228,6 +1241,8 @@ class HelpFormat: class Indented(HelpFormat): + """Formats help with indented section bodies.""" + def __init__(self, indent_increment=2, help_indent=24, width=78, short_first=1): HelpFormat.__init__(self, indent_increment, help_indent, width, @@ -1242,6 +1257,8 @@ class Indented(HelpFormat): class Titled(HelpFormat): + """Formats help with underlined section headers.""" + def __init__(self, indent_increment=0, help_indent=24, width=78, short_first=None): HelpFormat.__init__(self, indent_increment, help_indent, width, @@ -1257,9 +1274,9 @@ class Titled(HelpFormat): def _match_abbrev (s, wordmap): """_match_abbrev(s : string, wordmap : {string : Option}) -> string - Returns the string key in 'wordmap' for which 's' is an unambiguous + Return the string key in 'wordmap' for which 's' is an unambiguous abbreviation. If 's' is found to be ambiguous or doesn't match any of - 'words', raises BadOptionError. + 'words', raise BadOptionError. """ # Is there an exact match? if wordmap.has_key(s): -- cgit v1.2.1 From c68e44ec4f2b29042e1ea2ae425ed982c00162c6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 22:32:07 +0000 Subject: minor git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@187 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 01b0ed489..275137a9c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -23,7 +23,7 @@ class OptionParser(optik.OptionParser): """ cmdline_options = ( - 'General Options', + 'General Docutils Options', None, (('Include a "Generated by Docutils" credit with a link, at the end ' 'of the document.', @@ -93,7 +93,8 @@ class OptionParser(optik.OptionParser): def __init__(self, components=(), defaults={}, *args, **kwargs): """ `components` is a list of Docutils components each containing a - ``.cmdline_options`` attribute. `defaults` is a + ``.cmdline_options`` attribute. `defaults` is a mapping of option + default overrides. """ optik.OptionParser.__init__(self, help=None, format=optik.Titled(), *args, **kwargs) -- cgit v1.2.1 From adaac3281b2d8453669df76025e2f6b2491768d0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 13 Jun 2002 22:33:18 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@188 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b7a974d19..890b7cc1e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -257,7 +257,7 @@ Directives - _`parts.citations` - - _`parts.topic` + - _`parts.topic` (maybe "body.topic") - _`parts.sectnum` (section numbering; add support to .contents; could be cmdline option also) @@ -286,7 +286,7 @@ Directives - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) - Add support to parts.Contents (optional attribute "qa" done). + Add support to parts.contents (optional attribute "qa" done). New elements would be required. Perhaps:: @@ -320,7 +320,8 @@ Directives priority. - _`body.columns`: Multi-column table/list. Number of columns as - argument? Perhaps a variation on `table syntax alternative 2`__:: + argument? Perhaps a variation on `table syntax alternative 2`__, + combined with bullet list syntax to indicate rows:: col 1 col 2 ===== ===== @@ -404,6 +405,10 @@ Directives textart, text, linetext. Current favorites: "line_block" for element name, "lines" for directive name. + - _`body.example`: Examples; suggested by Simon Hefti. Semantics as + per Docbook's "example"; admonition-style, numbered, reference, + with a caption/title. (Maybe "admonitions.example"?) + - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need some kind of "alternate" mechanism? Perhaps use a "pending" -- cgit v1.2.1 From ae57b4ceca35d1f06037284f4089684604a48e26 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 14 Jun 2002 23:09:10 +0000 Subject: comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@191 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/optik.py b/docutils/optik.py index 9faedd699..16a927aec 100644 --- a/docutils/optik.py +++ b/docutils/optik.py @@ -935,7 +935,7 @@ class OptionParser(OptionContainer): # [arg0, ..., arg(i-1)] (any options and their arguments will have # been removed from largs). # - # _process_arg() will usually consume 1 or more arguments. + # The while loop will usually consume 1 or more arguments per pass. # If it consumes 1 (eg. arg is an option that takes no arguments), # then after _process_arg() is done the situation is: # -- cgit v1.2.1 From c004505fe4f0fe0afda4e39cf488a4204e01e343 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 14 Jun 2002 23:14:14 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@192 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- COPYING.txt | 17 +++++++++++------ README.txt | 12 +++++------- docs/dev/todo.txt | 29 +++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/COPYING.txt b/COPYING.txt index fb2c3f5ae..e74ff96ee 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -11,7 +11,11 @@ Most of the files included in this project are in the public domain, and therefore have no license requirement and no restrictions on copying or usage. The two exceptions are: -- docutils/roman.py, copyright 2001 by Mark Pilgrim, licensed under the +- docutils/optik.py & OptionParser.py, copyright Gregory P. Ward, + licensed under the BSD license (which can be found in the source + code of optik.py). + +- docutils/roman.py, copyright by Mark Pilgrim, licensed under the `Python 2.1.1 license`_. - test/difflib.py, copyright by the Python Software Foundation, @@ -22,11 +26,12 @@ copying or usage. The two exceptions are: anywhere. The included file is a pre-generator version of the difflib.py module included in Python 2.2.) -(Disclaimer: I am not a lawyer.) The Python license is OSI-approved_ -and GPL-compatible_. Although complicated by multiple owners and lots -of legalese, it basically lets you copy, use, modify, and redistribute -files as long as you keep the copyright attribution intact, note any -changes you make, and don't use the owner's name in vain. +(Disclaimer: I am not a lawyer.) Both the BSD license and the Python +license are OSI-approved_ and GPL-compatible_. Although complicated +by multiple owners and lots of legalese, the Python license basically +lets you copy, use, modify, and redistribute files as long as you keep +the copyright attribution intact, note any changes you make, and don't +use the owner's name in vain. .. _Python 2.1.1 license: http://www.python.org/2.1.1/license.html .. _Python 2.2 license: http://www.python.org/2.2/license.html diff --git a/README.txt b/README.txt index 2b4dc1d3a..911595512 100644 --- a/README.txt +++ b/README.txt @@ -22,9 +22,6 @@ To run the code, Python 2.0 or later must already be installed. Python 2.1 or later is required to run the test suite. You can get Python from http://www.python.org/. -Greg Ward's Optik option processing package is required. You can get -Optik from http://optik.sourceforge.net/. - Project Files & Directories =========================== @@ -72,8 +69,8 @@ Project Files & Directories Installation ============ -The first step is to expand the .tar.gz archive. It contains a -distutils setup file "setup.py". OS-specific installation +The first step is to expand the .tar.gz or .tgz archive. It contains +a distutils setup file "setup.py". OS-specific installation instructions follow. GNU/Linux, Unix, MacOS X, etc. @@ -141,13 +138,14 @@ Usage Start with the html.py and publish.py front-ends from the unpacked "tools" subdirectory. Both 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-ends for details on options and +arguments. The package modules are continually growing and evolving. The ``docutils.statemachine`` module is usable independently. It contains extensive inline documentation (in reStructuredText format). -The specs, the package structure, and the skeleton modules may also be -of interest to you. Contributions are welcome! +Contributions are welcome! .. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 890b7cc1e..c2f6e94f1 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -15,6 +15,9 @@ Priority items are marked with "@" symbols. The more @s, the higher the priority. Items in question form (containing "?") are ideas which require more thought and debate; they are potential to-do's. +Many of these items are awaiting champions. If you see something +you'd like to tackle, please do! + General ------- @@ -238,6 +241,32 @@ __ http://docutils.sf.net/spec/rst/alternatives.html#or-not-to-do - Continue to report (info, level 1) enumerated lists whose start value is not ordinal-1? +- Generalize the "doctest block" construct (which is overly + Python-centric) to other interactive sessions? "Doctest block" + could be renamed to "I/O block" or "interactive block", and each of + these could also be recognized as such by the parser: + + - Shell sessions:: + + $ cat example1.txt + A block beginning with a "$ " prompt is interpreted as a shell + session interactive block. As with Doctest blocks, the + interactive block ends with the first blank line, and wouldn't + have to be indented. + + - Root shell sessions:: + + # cat example2.txt + A block beginning with a "# " prompt is interpreted as a root + shell session (the user is or has to be logged in as root) + interactive block. Again, the block ends with a blank line. + + Other standard (and unambiguous) interactive session prompts could + easily be added (such as "> " for WinDOS). + + Tony Ibbs spoke out against this idea (2002-06-14 Doc-SIG thread + "docutils feedback"). + Directives `````````` -- cgit v1.2.1 From 9a910be6f560da3ecf986662a61b27b20eee579d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 18 Jun 2002 22:24:35 +0000 Subject: fixed link; thanks to Greg Ward git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@196 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index 7208b8b9f..0ae99bfcd 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -24,7 +24,7 @@ <p>The full details may be found on the - <a href="http://docutils.sourceforge.net/rest.html">reStructuredText</a> + <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> page. This document is just intended as a reminder. <p>Links that look like "(<a href="#details">details?</a>)" point -- cgit v1.2.1 From 7f675ec43766d8805ba70f87064e330912f90ec3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 19 Jun 2002 02:54:38 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@197 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 53 +++++++++++++++++++++++++++++++++++++++---- docutils/writers/html4css1.py | 7 +++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c2f6e94f1..c22c65e08 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -68,10 +68,47 @@ General - @@ Add support for character set encodings on input & output, Unicode internally. - - Default UTF-8 on both input & output, overrideable. - - Use an "encoding" directive, and/or an "encoding" field in field - lists & PEP headers. (The same could apply to "language".) - - Need a Unicode -> HTML entities codec for HTML writer? + To determine the encoding, use these heuristics in order: + + - Try the encoding specified by a command-line option, if any. + + - Try the encoding specified by an "encoding" directive, and/or an + "encoding" field in field lists & PEP headers, if any. (The same + could apply to "language".) + + - Try ASCII. + + - Try the locale default encoding. + + - Try UTF-8. + + - Try Latin-1. + + From Skip Montanaro's "Using Unicode in Python":: + + def encode_heuristically(s, enc=None): + "try interpreting s using several possible encodings" + try: + x = unicode(s, "ascii") + # if it's ascii, just return the plain string + return s + # you might want to return a Unicode object instead + # return x + except UnicodeError: + encodings = ["cp1252", "utf-8", "iso-8859-15", "iso-8859-1"] + # try any caller-provided encoding first + if enc: encodings.insert(0, enc) + for enc in encodings: + try: + x = unicode(s , enc) + except UnicodeError: + pass + else: + return x + # punt + return s + +- Need a Unicode -> HTML entities codec for HTML writer? - Distributor/filer object passed to Writer, equivalent passed to Reader, to provide I/O access with a uniform API? (Names for input @@ -84,6 +121,14 @@ General Importer"? "HTML Writer" or "HTML Exporter"? If we stick with the status quo, what to call the components that do low-level I/O? + - IOReader, IOWriter + - StreamReader, StreamWriter + - DataReader, DataWriter + - Inputter, Outputter + - Scanner, Recorder? + - Lector?, Scribe + - Loader, Storer/Recorder (maybe subclasses of Storage) + - Fix tests to run standalone. I.e., allow:: cd test/test_rst diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index bebc0a369..380179651 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -502,6 +502,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_interpreted(self, node): + # @@@ Incomplete, pending a proper implementation on the + # Parser/Reader end. self.body.append('<span class="interpreted">') def depart_interpreted(self, node): @@ -684,10 +686,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</strong>') def visit_substitution_definition(self, node): - raise nodes.SkipChildren - - def depart_substitution_definition(self, node): - pass + raise nodes.SkipNode def visit_substitution_reference(self, node): self.unimplemented_visit(node) -- cgit v1.2.1 From ab7c4bbb0085e8cdc6fc716a3294294308de21a1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 20 Jun 2002 03:52:42 +0000 Subject: not happening, not yet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@198 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/OptionParser.py | 1087 ---------------------------------------------- 1 file changed, 1087 deletions(-) delete mode 100644 docutils/OptionParser.py diff --git a/docutils/OptionParser.py b/docutils/OptionParser.py deleted file mode 100644 index d0e4ab899..000000000 --- a/docutils/OptionParser.py +++ /dev/null @@ -1,1087 +0,0 @@ -"""optik - -A powerful, extensible, and easy-to-use command-line parser for Python. - -By Greg Ward <gward@python.net> - -See http://optik.sourceforge.net/ -""" - -# Copyright (c) 2001 Gregory P. Ward. All rights reserved. -# See the README.txt distributed with Optik for licensing terms. - -# This combined module created 2002-06-12 by David Goodger, -# from the optik package. - -__revision__ = "$Id$" - -__version__ = "1.3" - - -import sys -import os -import types -from types import TupleType, DictType -from distutils.fancy_getopt import wrap_text - - -SUPPRESS_HELP = "SUPPRESS"+"HELP" -SUPPRESS_USAGE = "SUPPRESS"+"USAGE" -# Not supplying a default is different from a default of None, -# so we need an explicit "not supplied" value. -NO_DEFAULT = "NO"+"DEFAULT" - - -class OptikError (Exception): - def __init__ (self, msg): - self.msg = msg - - def __str__ (self): - return self.msg - - -class OptionError (OptikError): - """ - Raised if an Option instance is created with invalid or - inconsistent arguments. - """ - - def __init__ (self, msg, option): - self.msg = msg - self.option_id = str(option) - - def __str__ (self): - if self.option_id: - return "option %s: %s" % (self.option_id, self.msg) - else: - return self.msg - -class OptionConflictError (OptionError): - """ - Raised if conflicting options are added to an OptionParser. - """ - -class OptionValueError (OptikError): - """ - Raised if an invalid option value is encountered on the command - line. - """ - -class BadOptionError (OptikError): - """ - Raised if an invalid or ambiguous option is seen on the command-line. - """ - - -_builtin_cvt = { "int" : (int, "integer"), - "long" : (long, "long integer"), - "float" : (float, "floating-point"), - "complex" : (complex, "complex") } - -def check_builtin (option, opt, value): - (cvt, what) = _builtin_cvt[option.type] - try: - return cvt(value) - except ValueError: - raise OptionValueError( - #"%s: invalid %s argument %r" % (opt, what, value)) - "option %s: invalid %s value: %r" % (opt, what, value)) - - -class Option: - """ - Instance attributes: - _short_opts : [string] - _long_opts : [string] - - action : string - type : string - dest : string - default : any - nargs : int - const : any - callback : function - callback_args : (any*) - callback_kwargs : { string : any } - help : string - metavar : string - """ - - # The list of instance attributes that may be set through - # keyword args to the constructor. - ATTRS = ['action', - 'type', - 'dest', - 'default', - 'nargs', - 'const', - 'callback', - 'callback_args', - 'callback_kwargs', - 'help', - 'metavar'] - - # The set of actions allowed by option parsers. Explicitly listed - # here so the constructor can validate its arguments. - ACTIONS = ("store", - "store_const", - "store_true", - "store_false", - "append", - "count", - "callback", - "help", - "version") - - # The set of actions that involve storing a value somewhere; - # also listed just for constructor argument validation. (If - # the action is one of these, there must be a destination.) - STORE_ACTIONS = ("store", - "store_const", - "store_true", - "store_false", - "append", - "count") - - # The set of actions for which it makes sense to supply a value - # type, ie. where we expect an argument to this option. - TYPED_ACTIONS = ("store", - "append", - "callback") - - # The set of known types for option parsers. Again, listed here for - # constructor argument validation. - TYPES = ("string", "int", "long", "float", "complex") - - # Dictionary of argument checking functions, which convert and - # validate option arguments according to the option type. - # - # Signature of checking functions is: - # check(option : Option, opt : string, value : string) -> any - # where - # option is the Option instance calling the checker - # opt is the actual option seen on the command-line - # (eg. "-a", "--file") - # value is the option argument seen on the command-line - # - # The return value should be in the appropriate Python type - # for option.type -- eg. an integer if option.type == "int". - # - # If no checker is defined for a type, arguments will be - # unchecked and remain strings. - TYPE_CHECKER = { "int" : check_builtin, - "long" : check_builtin, - "float" : check_builtin, - "complex" : check_builtin, - } - - - # CHECK_METHODS is a list of unbound method objects; they are called - # by the constructor, in order, after all attributes are - # initialized. The list is created and filled in later, after all - # the methods are actually defined. (I just put it here because I - # like to define and document all class attributes in the same - # place.) Subclasses that add another _check_*() method should - # define their own CHECK_METHODS list that adds their check method - # to those from this class. - CHECK_METHODS = None - - - # -- Constructor/initialization methods ---------------------------- - - def __init__ (self, *opts, **attrs): - # Set _short_opts, _long_opts attrs from 'opts' tuple - opts = self._check_opt_strings(opts) - self._set_opt_strings(opts) - - # Set all other attrs (action, type, etc.) from 'attrs' dict - self._set_attrs(attrs) - - # Check all the attributes we just set. There are lots of - # complicated interdependencies, but luckily they can be farmed - # out to the _check_*() methods listed in CHECK_METHODS -- which - # could be handy for subclasses! The one thing these all share - # is that they raise OptionError if they discover a problem. - for checker in self.CHECK_METHODS: - checker(self) - - def _check_opt_strings (self, opts): - # Filter out None because early versions of Optik had exactly - # one short option and one long option, either of which - # could be None. - opts = filter(None, opts) - if not opts: - raise OptionError("at least one option string must be supplied", - self) - return opts - - def _set_opt_strings (self, opts): - self._short_opts = [] - self._long_opts = [] - for opt in opts: - if len(opt) < 2: - raise OptionError( - "invalid option string %r: " - "must be at least two characters long" % opt, self) - elif len(opt) == 2: - if not (opt[0] == "-" and opt[1] != "-"): - raise OptionError( - "invalid short option string %r: " - "must be of the form -x, (x any non-dash char)" % opt, - self) - self._short_opts.append(opt) - else: - if not (opt[0:2] == "--" and opt[2] != "-"): - raise OptionError( - "invalid long option string %r: " - "must start with --, followed by non-dash" % opt, - self) - self._long_opts.append(opt) - - def _set_attrs (self, attrs): - for attr in self.ATTRS: - if attrs.has_key(attr): - setattr(self, attr, attrs[attr]) - del attrs[attr] - else: - if attr == 'default': - setattr(self, attr, NO_DEFAULT) - else: - setattr(self, attr, None) - if attrs: - raise OptionError( - "invalid keyword arguments: %s" % ", ".join(attrs.keys()), - self) - - - # -- Constructor validation methods -------------------------------- - - def _check_action (self): - if self.action is None: - self.action = "store" - elif self.action not in self.ACTIONS: - raise OptionError("invalid action: %r" % self.action, self) - - def _check_type (self): - if self.type is None: - # XXX should factor out another class attr here: list of - # actions that *require* a type - if self.action in ("store", "append"): - # No type given? "string" is the most sensible default. - self.type = "string" - else: - if self.type not in self.TYPES: - raise OptionError("invalid option type: %r" % self.type, self) - if self.action not in self.TYPED_ACTIONS: - raise OptionError( - "must not supply a type for action %r" % self.action, self) - - def _check_dest (self): - if self.action in self.STORE_ACTIONS and self.dest is None: - # No destination given, and we need one for this action. - # Glean a destination from the first long option string, - # or from the first short option string if no long options. - if self._long_opts: - # eg. "--foo-bar" -> "foo_bar" - self.dest = self._long_opts[0][2:].replace('-', '_') - else: - self.dest = self._short_opts[0][1] - - def _check_const (self): - if self.action != "store_const" and self.const is not None: - raise OptionError( - "'const' must not be supplied for action %r" % self.action, - self) - - def _check_nargs (self): - if self.action in self.TYPED_ACTIONS: - if self.nargs is None: - self.nargs = 1 - elif self.nargs is not None: - raise OptionError( - "'nargs' must not be supplied for action %r" % self.action, - self) - - def _check_callback (self): - if self.action == "callback": - if not callable(self.callback): - raise OptionError( - "callback not callable: %r" % self.callback, self) - if (self.callback_args is not None and - type(self.callback_args) is not TupleType): - raise OptionError( - "callback_args, if supplied, must be a tuple: not %r" - % self.callback_args, self) - if (self.callback_kwargs is not None and - type(self.callback_kwargs) is not DictType): - raise OptionError( - "callback_kwargs, if supplied, must be a dict: not %r" - % self.callback_kwargs, self) - else: - if self.callback is not None: - raise OptionError( - "callback supplied (%r) for non-callback option" - % self.callback, self) - if self.callback_args is not None: - raise OptionError( - "callback_args supplied for non-callback option", self) - if self.callback_kwargs is not None: - raise OptionError( - "callback_kwargs supplied for non-callback option", self) - - - CHECK_METHODS = [_check_action, - _check_type, - _check_dest, - _check_const, - _check_nargs, - _check_callback] - - - # -- Miscellaneous methods ----------------------------------------- - - def __str__ (self): - if self._short_opts or self._long_opts: - return "/".join(self._short_opts + self._long_opts) - else: - raise RuntimeError, "short_opts and long_opts both empty!" - - def takes_value (self): - return self.type is not None - - - # -- Processing methods -------------------------------------------- - - def check_value (self, opt, value): - checker = self.TYPE_CHECKER.get(self.type) - if checker is None: - return value - else: - return checker(self, opt, value) - - def process (self, opt, value, values, parser): - - # First, convert the value(s) to the right type. Howl if any - # value(s) are bogus. - if value is not None: - if self.nargs == 1: - value = self.check_value(opt, value) - else: - value = tuple([self.check_value(opt, v) for v in value]) - - # And then take whatever action is expected of us. - # This is a separate method to make life easier for - # subclasses to add new actions. - return self.take_action( - self.action, self.dest, opt, value, values, parser) - - def take_action (self, action, dest, opt, value, values, parser): - if action == "store": - setattr(values, dest, value) - elif action == "store_const": - setattr(values, dest, self.const) - elif action == "store_true": - setattr(values, dest, 1) - elif action == "store_false": - setattr(values, dest, 0) - elif action == "append": - values.ensure_value(dest, []).append(value) - elif action == "count": - setattr(values, dest, values.ensure_value(dest, 0) + 1) - elif action == "callback": - args = self.callback_args or () - kwargs = self.callback_kwargs or {} - self.callback(self, opt, value, parser, *args, **kwargs) - elif action == "help": - parser.print_help() - sys.exit(0) - elif action == "version": - parser.print_version() - sys.exit(0) - else: - raise RuntimeError, "unknown action %r" % self.action - - return 1 - -# class Option - - -# Some day, there might be many Option classes. As of Optik 1.3, the -# preferred way to instantiate Options is indirectly, via make_option(), -# which will become a factory function when there are many Option -# classes. -make_option = Option - - -STD_HELP_OPTION = Option("-h", "--help", - action="help", - help="show this help message and exit") -STD_VERSION_OPTION = Option("--version", - action="version", - help="show program's version number and exit") - - -class Values: - - def __init__ (self, defaults=None): - if defaults: - for (attr, val) in defaults.items(): - setattr(self, attr, val) - - - def _update_careful (self, dict): - """ - Update the option values from an arbitrary dictionary, but only - use keys from dict that already have a corresponding attribute - in self. Any keys in dict without a corresponding attribute - are silently ignored. - """ - for attr in dir(self): - if dict.has_key(attr): - dval = dict[attr] - if dval is not None: - setattr(self, attr, dval) - - def _update_loose (self, dict): - """ - Update the option values from an arbitrary dictionary, - using all keys from the dictionary regardless of whether - they have a corresponding attribute in self or not. - """ - self.__dict__.update(dict) - - def _update (self, dict, mode): - if mode == "careful": - self._update_careful(dict) - elif mode == "loose": - self._update_loose(dict) - else: - raise ValueError, "invalid update mode: %r" % mode - - def read_module (self, modname, mode="careful"): - __import__(modname) - mod = sys.modules[modname] - self._update(vars(mod), mode) - - def read_file (self, filename, mode="careful"): - vars = {} - execfile(filename, vars) - self._update(vars, mode) - - def ensure_value (self, attr, value): - if not hasattr(self, attr) or getattr(self, attr) is None: - setattr(self, attr, value) - return getattr(self, attr) - - -class OptionParser: - """ - Class attributes: - standard_option_list : [Option] - list of standard options that will be accepted by all instances - of this parser class (intended to be overridden by subclasses). - - Instance attributes: - usage : string - a usage string for your program. Before it is displayed - to the user, "%prog" will be expanded to the name of - your program (os.path.basename(sys.argv[0])). - option_list : [Option] - the list of all options accepted on the command-line of - this program - _short_opt : { string : Option } - dictionary mapping short option strings, eg. "-f" or "-X", - to the Option instances that implement them. If an Option - has multiple short option strings, it will appears in this - dictionary multiple times. - _long_opt : { string : Option } - dictionary mapping long option strings, eg. "--file" or - "--exclude", to the Option instances that implement them. - Again, a given Option can occur multiple times in this - dictionary. - _long_opts : [string] - list of long option strings recognized by this option - parser. Should be equal to _long_opt.keys(). - defaults : { string : any } - dictionary mapping option destination names to default - values for each destination. - - allow_interspersed_args : boolean = true - if true, positional arguments may be interspersed with options. - Assuming -a and -b each take a single argument, the command-line - -ablah foo bar -bboo baz - will be interpreted the same as - -ablah -bboo -- foo bar baz - If this flag were false, that command line would be interpreted as - -ablah -- foo bar -bboo baz - -- ie. we stop processing options as soon as we see the first - non-option argument. (This is the tradition followed by - Python's getopt module, Perl's Getopt::Std, and other argument- - parsing libraries, but it is generally annoying to users.) - - rargs : [string] - the argument list currently being parsed. Only set when - parse_args() is active, and continually trimmed down as - we consume arguments. Mainly there for the benefit of - callback options. - largs : [string] - the list of leftover arguments that we have skipped while - parsing options. If allow_interspersed_args is false, this - list is always empty. - values : Values - the set of option values currently being accumulated. Only - set when parse_args() is active. Also mainly for callbacks. - - Because of the 'rargs', 'largs', and 'values' attributes, - OptionParser is not thread-safe. If, for some perverse reason, you - need to parse command-line arguments simultaneously in different - threads, use different OptionParser instances. - - """ - - standard_option_list = [STD_HELP_OPTION] - - - def __init__ (self, - usage=None, - option_list=None, - option_class=Option, - version=None, - conflict_handler="error"): - self.set_usage(usage) - self.option_class = option_class - self.version = version - self.set_conflict_handler(conflict_handler) - self.allow_interspersed_args = 1 - - # Create the various lists and dicts that constitute the - # "option list". See class docstring for details about - # each attribute. - self._create_option_list() - - # Populate the option list; initial sources are the - # standard_option_list class attribute, the 'option_list' - # argument, and the STD_VERSION_OPTION global (if 'version' - # supplied). - self._populate_option_list(option_list) - - self._init_parsing_state() - - # -- Private methods ----------------------------------------------- - # (used by the constructor) - - def _create_option_list (self): - self.option_list = [] - self._short_opt = {} # single letter -> Option instance - self._long_opt = {} # long option -> Option instance - self._long_opts = [] # list of long options - self.defaults = {} # maps option dest -> default value - - def _populate_option_list (self, option_list): - if self.standard_option_list: - self.add_options(self.standard_option_list) - if self.version: - self.add_option(STD_VERSION_OPTION) - if option_list: - self.add_options(option_list) - - def _init_parsing_state (self): - # These are set in parse_args() for the convenience of callbacks. - self.rargs = None - self.largs = None - self.values = None - - - # -- Simple modifier methods --------------------------------------- - - def set_usage (self, usage): - if usage is None: - self.usage = "usage: %prog [options]" - elif usage is SUPPRESS_USAGE: - self.usage = None - else: - self.usage = usage - - def enable_interspersed_args (self): - self.allow_interspersed_args = 1 - - def disable_interspersed_args (self): - self.allow_interspersed_args = 0 - - def set_conflict_handler (self, handler): - if handler not in ("ignore", "error", "resolve"): - raise ValueError, "invalid conflict_resolution value %r" % handler - self.conflict_handler = handler - - def set_default (self, dest, value): - self.defaults[dest] = value - - def set_defaults (self, **kwargs): - self.defaults.update(kwargs) - - def get_default_values(self): - return Values(self.defaults) - - - # -- Option-adding methods ----------------------------------------- - - def _check_conflict (self, option): - conflict_opts = [] - for opt in option._short_opts: - if self._short_opt.has_key(opt): - conflict_opts.append((opt, self._short_opt[opt])) - for opt in option._long_opts: - if self._long_opt.has_key(opt): - conflict_opts.append((opt, self._long_opt[opt])) - - if conflict_opts: - handler = self.conflict_handler - if handler == "ignore": # behaviour for Optik 1.0, 1.1 - pass - elif handler == "error": # new in 1.2 - raise OptionConflictError( - "conflicting option string(s): %s" - % ", ".join([co[0] for co in conflict_opts]), - option) - elif handler == "resolve": # new in 1.2 - for (opt, c_option) in conflict_opts: - if opt.startswith("--"): - c_option._long_opts.remove(opt) - del self._long_opt[opt] - else: - c_option._short_opts.remove(opt) - del self._short_opt[opt] - if not (c_option._short_opts or c_option._long_opts): - self.option_list.remove(c_option) - - - def add_option (self, *args, **kwargs): - """add_option(Option) - add_option(opt_str, ..., kwarg=val, ...) - """ - if type(args[0]) is types.StringType: - option = self.option_class(*args, **kwargs) - elif len(args) == 1 and not kwargs: - option = args[0] - if not isinstance(option, Option): - raise TypeError, "not an Option instance: %r" % option - else: - raise TypeError, "invalid arguments" - - self._check_conflict(option) - - self.option_list.append(option) - for opt in option._short_opts: - self._short_opt[opt] = option - for opt in option._long_opts: - self._long_opt[opt] = option - self._long_opts.append(opt) - - if option.dest is not None: # option has a dest, we need a default - if option.default is not NO_DEFAULT: - self.defaults[option.dest] = option.default - elif not self.defaults.has_key(option.dest): - self.defaults[option.dest] = None - - def add_options (self, option_list): - for option in option_list: - self.add_option(option) - - - # -- Option query/removal methods ---------------------------------- - - def get_option (self, opt_str): - return (self._short_opt.get(opt_str) or - self._long_opt.get(opt_str)) - - def has_option (self, opt_str): - return (self._short_opt.has_key(opt_str) or - self._long_opt.has_key(opt_str)) - - - def remove_option (self, opt_str): - option = self._short_opt.get(opt_str) - if option is None: - option = self._long_opt.get(opt_str) - if option is None: - raise ValueError("no such option %r" % opt_str) - - for opt in option._short_opts: - del self._short_opt[opt] - for opt in option._long_opts: - del self._long_opt[opt] - self._long_opts.remove(opt) - self.option_list.remove(option) - - - # -- Option-parsing methods ---------------------------------------- - - def _get_args (self, args): - if args is None: - return sys.argv[1:] - else: - return args[:] # don't modify caller's list - - def parse_args (self, args=None, values=None): - """ - parse_args(args : [string] = sys.argv[1:], - values : Values = None) - -> (values : Values, args : [string]) - - Parse the command-line options found in 'args' (default: - sys.argv[1:]). Any errors result in a call to 'error()', which - by default prints the usage message to stderr and calls - sys.exit() with an error message. On success returns a pair - (values, args) where 'values' is an Values instance (with all - your option values) and 'args' is the list of arguments left - over after parsing options. - """ - rargs = self._get_args(args) - if values is None: - values = self.get_default_values() - - # Store the halves of the argument list as attributes for the - # convenience of callbacks: - # rargs - # the rest of the command-line (the "r" stands for - # "remaining" or "right-hand") - # largs - # the leftover arguments -- ie. what's left after removing - # options and their arguments (the "l" stands for "leftover" - # or "left-hand") - - # Say this is the original argument list: - # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] - # ^ - # (we are about to process arg(i)). - # - # Then rargs is [arg(i), ..., arg(N-1)] - # and largs is a *subset* of [arg0, ..., arg(i-1)] - # (any options and their arguments will have been removed - # from largs). - # - # _process_arg() will always consume 1 or more arguments. - # If it consumes 1 (eg. arg is an option that takes no arguments), - # then after _process_arg() is done the situation is: - # largs = subset of [arg0, ..., arg(i)] - # rargs = [arg(i+1), ..., arg(N-1)] - # - # If allow_interspersed_args is false, largs will always be - # *empty* -- still a subset of [arg0, ..., arg(i-1)], but - # not a very interesting subset! - - self.rargs = rargs - self.largs = largs = [] - self.values = values - - stop = 0 - while rargs and not stop: - try: - stop = self._process_arg(largs, rargs, values) - except (BadOptionError, OptionValueError), err: - self.error(err.msg) - - args = largs + rargs - return self.check_values(values, args) - - def check_values (self, values, args): - """ - check_values(values : Values, args : [string]) - -> (values : Values, args : [string]) - - Check that the supplied option values and leftover arguments are - valid. Returns the option values and leftover arguments - (possibly adjusted, possibly completely new -- whatever you - like). Default implementation just returns the passed-in - values; subclasses may override as desired. - """ - return (values, args) - - def _process_arg (self, largs, rargs, values): - """_process_args(largs : [string], - rargs : [string], - values : Values) - -> stop : boolean - - Process a single command-line argument, consuming zero or more - arguments. The next argument to process is rargs[0], which will - almost certainly be consumed from rargs. (It might wind up in - largs, or it might affect a value in values, or -- if a callback - is involved -- almost anything might happen. It will not be - consumed if it is a non-option argument and - allow_interspersed_args is false.) More arguments from rargs - may also be consumed, depending on circumstances. - - Returns true if option processing should stop after this - argument is processed. - """ - - # We handle bare "--" explicitly, and bare "-" is handled by the - # standard arg handler since the short arg case ensures that the len - # of the opt string is greater than 1. - - arg = rargs[0] - if arg == "--": - del rargs[0] - return 1 - elif arg[0:2] == "--": - # process a single long option (possibly with value(s)) - self._process_long_opt(rargs, values) - elif arg[:1] == "-" and len(arg) > 1: - # process a cluster of short options (possibly with - # value(s) for the last one only) - self._process_short_opts(rargs, values) - else: - if self.allow_interspersed_args: - largs.append(arg) - del rargs[0] - else: - return 1 # stop now, leave this arg in rargs - - return 0 # keep processing args - - def _match_long_opt (self, opt): - """_match_long_opt(opt : string) -> string - - Determine which long option string 'opt' matches, ie. which one - it is an unambiguous abbrevation for. Raises BadOptionError if - 'opt' doesn't unambiguously match any long option string. - """ - return _match_abbrev(opt, self._long_opts) - - def _process_long_opt (self, rargs, values): - arg = rargs.pop(0) - - # Value explicitly attached to arg? Pretend it's the next - # argument. - if "=" in arg: - (opt, next_arg) = arg.split("=", 1) - rargs.insert(0, next_arg) - had_explicit_value = 1 - else: - opt = arg - had_explicit_value = 0 - - opt = self._match_long_opt(opt) - option = self._long_opt[opt] - if option.takes_value(): - nargs = option.nargs - if len(rargs) < nargs: - if nargs == 1: - self.error("%s option requires a value" % opt) - else: - self.error("%s option requires %d values" - % (opt, nargs)) - elif nargs == 1: - value = rargs.pop(0) - else: - value = tuple(rargs[0:nargs]) - del rargs[0:nargs] - - elif had_explicit_value: - self.error("%s option does not take a value" % opt) - - else: - value = None - - option.process(opt, value, values, self) - - def _process_short_opts (self, rargs, values): - arg = rargs.pop(0) - stop = 0 - i = 1 - for ch in arg[1:]: - opt = "-" + ch - option = self._short_opt.get(opt) - i += 1 # we have consumed a character - - if not option: - self.error("no such option: %s" % opt) - if option.takes_value(): - # Any characters left in arg? Pretend they're the - # next arg, and stop consuming characters of arg. - if i < len(arg): - rargs.insert(0, arg[i:]) - stop = 1 - - nargs = option.nargs - if len(rargs) < nargs: - if nargs == 1: - self.error("%s option requires a value" % opt) - else: - self.error("%s option requires %s values" - % (opt, nargs)) - elif nargs == 1: - value = rargs.pop(0) - else: - value = tuple(rargs[0:nargs]) - del rargs[0:nargs] - - else: # option doesn't take a value - value = None - - option.process(opt, value, values, self) - - if stop: - break - - - # -- Output/error methods ------------------------------------------ - - def error (self, msg): - """error(msg : string) - - Print a usage message incorporating 'msg' to stderr and exit. - If you override this in a subclass, it should not return -- it - should either exit or raise an exception. - """ - self.print_usage(sys.stderr) - sys.exit("%s: error: %s" % (get_prog_name(), msg)) - - def print_usage (self, file=None): - """print_usage(file : file = stdout) - - Print the usage message for the current program (self.usage) to - 'file' (default stdout). Any occurence of the string "%prog" in - self.usage is replaced with the name of the current program - (basename of sys.argv[0]). Does nothing if self.usage is empty - or not defined. - """ - if self.usage: - usage = self.usage.replace("%prog", get_prog_name()) - print >>file, usage - print >>file - - def print_version (self, file=None): - """print_version(file : file = stdout) - - Print the version message for this program (self.version) to - 'file' (default stdout). As with print_usage(), any occurence - of "%prog" in self.version is replaced by the current program's - name. Does nothing if self.version is empty or undefined. - """ - if self.version: - version = self.version.replace("%prog", get_prog_name()) - print >>file, version - - def print_help (self, file=None): - """print_help(file : file = stdout) - - Print an extended help message, listing all options and any - help text provided with them, to 'file' (default stdout). - """ - from distutils.fancy_getopt import wrap_text - - if file is None: - file = sys.stdout - - self.print_usage(file) - - # The help for each option consists of two parts: - # * the opt strings and metavars - # eg. ("-x", or "-fFILENAME, --file=FILENAME") - # * the user-supplied help string - # eg. ("turn on expert mode", "read data from FILENAME") - # - # If possible, we write both of these on the same line: - # -x turn on expert mode - # - # But if the opt string list is too long, we put the help - # string on a second line, indented to the same column it would - # start in if it fit on the first line. - # -fFILENAME, --file=FILENAME - # read data from FILENAME - - print >>file, "options:" - width = 78 # assume 80 cols for now - - option_help = [] # list of (string, string) tuples - lengths = [] - - for option in self.option_list: - takes_value = option.takes_value() - if takes_value: - metavar = option.metavar or option.dest.upper() - - opts = [] # list of "-a" or "--foo=FILE" strings - if option.help is SUPPRESS_HELP: - continue - - if takes_value: - for sopt in option._short_opts: - opts.append(sopt + metavar) - for lopt in option._long_opts: - opts.append(lopt + "=" + metavar) - else: - for opt in option._short_opts + option._long_opts: - opts.append(opt) - - opts = ", ".join(opts) - option_help.append((opts, option.help)) - lengths.append(len(opts)) - - max_opts = min(max(lengths), 20) - - for (opts, help) in option_help: - # how much to indent lines 2 .. N of help text - indent_rest = 2 + max_opts + 2 - help_width = width - indent_rest - - if len(opts) > max_opts: - opts = " " + opts + "\n" - indent_first = indent_rest - - else: # start help on same line as opts - opts = " %-*s " % (max_opts, opts) - indent_first = 0 - - file.write(opts) - - if help: - help_lines = wrap_text(help, help_width) - print >>file, "%*s%s" % (indent_first, "", help_lines[0]) - for line in help_lines[1:]: - print >>file, "%*s%s" % (indent_rest, "", line) - elif opts[-1] != "\n": - file.write("\n") - -# class OptionParser - - -def _match_abbrev (s, words): - """_match_abbrev(s : string, words : [string]) -> string - - Returns the string in 'words' for which 's' is an unambiguous - abbreviation. If 's' is found to be ambiguous or doesn't match any - of 'words', raises BadOptionError. - """ - match = None - for word in words: - # If s isn't even a prefix for this word, don't waste any - # more time on it: skip to the next word and try again. - if not word.startswith(s): - continue - - # Exact match? Great, return now. - if s == word: - return word - - # Now comes the tricky business of disambiguation. At this - # point, we know s is a proper prefix of word, eg. s='--foo' and - # word=='--foobar'. If we have already seen another word where - # this was the case, eg. '--foobaz', fail: s is ambiguous. - # Otherwise record this match and keep looping; we will return - # if we see an exact match, or when we fall out of the loop and - # it turns out that the current word is the match. - if match: - raise BadOptionError("ambiguous option: %s (%s, %s, ...?)" - % (s, match, word)) - match = word - - if match: - return match - else: - raise BadOptionError("no such option: %s" % s) - -def get_prog_name (): - return os.path.basename(sys.argv[0]) -- cgit v1.2.1 From f44268b3aa6ee4f03a83bd857cc7efd6b5d73dc7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 20 Jun 2002 03:56:59 +0000 Subject: - Added new "choice" option type. - Re-enabled optimized help text positioning. - Renamed some methods related to help output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@199 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 136 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 41 deletions(-) diff --git a/docutils/optik.py b/docutils/optik.py index 16a927aec..fda0967a9 100644 --- a/docutils/optik.py +++ b/docutils/optik.py @@ -120,6 +120,14 @@ def check_builtin (option, opt, value): #"%s: invalid %s argument %r" % (opt, what, value)) "option %s: invalid %s value: %r" % (opt, what, value)) +def check_choice(option, opt, value): + if value in option.choices: + return value + else: + raise OptionValueError( + "option %s: invalid choice: %r (choose one of %r)" + % (opt, value, option.choices)) + class Option: """ @@ -127,12 +135,16 @@ class Option: _short_opts : [string] _long_opts : [string] + option_string : string + Set when help output is formatted. + action : string type : string dest : string default : any nargs : int const : any + choices : [string] callback : function callback_args : (any*) callback_kwargs : { string : any } @@ -148,6 +160,7 @@ class Option: 'default', 'nargs', 'const', + 'choices', 'callback', 'callback_args', 'callback_kwargs', @@ -184,7 +197,7 @@ class Option: # The set of known types for option parsers. Again, listed here for # constructor argument validation. - TYPES = ("string", "int", "long", "float", "complex") + TYPES = ("string", "int", "long", "float", "complex", "choice") # Dictionary of argument checking functions, which convert and # validate option arguments according to the option type. @@ -206,6 +219,7 @@ class Option: "long" : check_builtin, "float" : check_builtin, "complex" : check_builtin, + "choice" : check_choice, } @@ -300,8 +314,12 @@ class Option: # XXX should factor out another class attr here: list of # actions that *require* a type if self.action in ("store", "append"): - # No type given? "string" is the most sensible default. - self.type = "string" + if self.choices is not None: + # The "choices" attribute implies "choice" type. + self.type = "choice" + else: + # No type given? "string" is the most sensible default. + self.type = "string" else: if self.type not in self.TYPES: raise OptionError("invalid option type: %r" % self.type, self) @@ -309,6 +327,19 @@ class Option: raise OptionError( "must not supply a type for action %r" % self.action, self) + def _check_choice(self): + if self.type == "choice": + if self.choices is None: + raise OptionError( + "must supply a list of choices for type 'choice'", self) + elif type(self.choices) not in (TupleType, ListType): + raise OptionError( + "choices must be a list of strings ('%s' supplied)" + % str(type(self.choices)).split("'")[1], self) + elif self.choices is not None: + raise OptionError( + "must not supply choices for type %r" % self.type, self) + def _check_dest (self): if self.action in self.STORE_ACTIONS and self.dest is None: # No destination given, and we need one for this action. @@ -365,6 +396,7 @@ class Option: CHECK_METHODS = [_check_action, _check_type, + _check_choice, _check_dest, _check_const, _check_nargs, @@ -605,7 +637,7 @@ class OptionContainer: # -- Feedback methods ---------------------------------------------- - def get_options(self): + def get_option_help(self): if not self.option_list: return "" result = [] # list of strings to "".join() later @@ -614,7 +646,7 @@ class OptionContainer: result.append(self.format.format_option(option)) return "".join(result) - def get_description(self): + def get_description_help(self): if self.description: return self.format.format_description(self.description) else: @@ -623,8 +655,8 @@ class OptionContainer: def get_help(self): result = "" if self.description: - result = self.get_description() + "\n" - return result + self.get_options() + result = self.get_description_help() + "\n" + return result + self.get_option_help() class OptionGroup(OptionContainer): @@ -1044,7 +1076,7 @@ class OptionParser(OptionContainer): self.print_usage(sys.stderr) sys.exit("%s: error: %s" % (get_prog_name(), msg)) - def get_usage(self): + def get_usage_help(self): if self.usage: return self.format.format_usage( self.usage.replace("%prog", get_prog_name())) @@ -1061,9 +1093,9 @@ class OptionParser(OptionContainer): or not defined. """ if self.usage: - print >>file, self.get_usage() + print >>file, self.get_usage_help() - def get_version(self): + def get_version_help(self): if self.version: return self.version.replace("%prog", get_prog_name()) else: @@ -1078,14 +1110,15 @@ class OptionParser(OptionContainer): name. Does nothing if self.version is empty or undefined. """ if self.version: - print >>file, self.get_version() + print >>file, self.get_version_help() - def get_options(self): + def get_option_help(self): + self.format.store_option_strings(self) result = [] result.append(self.format.format_heading("Options")) self.format.increase_nesting() if self.option_list: - result.append(OptionContainer.get_options(self)) + result.append(OptionContainer.get_option_help(self)) result.append("\n") for group in self.option_groups: result.append(group.get_help()) @@ -1097,10 +1130,10 @@ class OptionParser(OptionContainer): def get_help(self): result = [] if self.usage: - result.append(self.get_usage() + "\n") + result.append(self.get_usage_help() + "\n") if self.description: - result.append(self.get_description() + "\n") - result.append(self.get_options()) + result.append(self.get_description_help() + "\n") + result.append(self.get_option_help()) return "".join(result) def print_help (self, file=None): @@ -1123,30 +1156,34 @@ class HelpFormat: Instance attributes: indent_increment : int - number of columns to indent per nesting level - help_indent : int - the starting column for option help text + The number of columns to indent per nesting level. + max_help_position : int + The maximum starting column for option help text. + help_position : int + The calculated starting column for option help text; + initially the same as the maximum. width : int - the overall width (in columns) for output + The overall width (in columns) for output. current_indent : int - in columns, calculated + In columns, calculated. level : int - increased for each additional nesting level + Increased for each additional nesting level. help_width : int - number of columns available for option help text + Number of columns available for option help text, calculated. """ - def __init__(self, indent_increment, help_indent, width, short_first): + def __init__(self, indent_increment, max_help_position, width, + short_first): self.indent_increment = indent_increment - self.help_indent = help_indent + self.help_position = self.max_help_position = max_help_position self.width = width self.current_indent = 0 self.level = 0 - self.help_width = self.width - self.help_indent + self.help_width = width - max_help_position if short_first: - self.format_option_list = self.format_option_list_short_first + self.format_option_strings = self.format_option_strings_short_first else: - self.format_option_list = self.format_option_list_long_first + self.format_option_strings = self.format_option_strings_long_first def increase_nesting(self): self.current_indent += self.indent_increment @@ -1186,11 +1223,11 @@ class HelpFormat: # -fFILENAME, --file=FILENAME # read data from FILENAME result = [] - opts = self.format_option_list(option) - opt_width = self.help_indent - self.current_indent - 2 + opts = option.option_strings + opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: opts = "%*s%s\n" % (self.current_indent, "", opts) - indent_first = self.help_indent + indent_first = self.help_position else: # start help on same line as opts opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) indent_first = 0 @@ -1198,19 +1235,36 @@ class HelpFormat: if option.help: help_lines = wrap_text(option.help, self.help_width) result.append("%*s%s\n" % (indent_first, "", help_lines[0])) - result.extend(["%*s%s\n" % (self.help_indent, "", line) + result.extend(["%*s%s\n" % (self.help_position, "", line) for line in help_lines[1:]]) elif opts[-1] != "\n": result.append("\n") return "".join(result) - def format_option_list(self, option): + def store_option_strings(self, parser): + self.increase_nesting() + max_len = 0 + for opt in parser.option_list: + strings = self.format_option_strings(opt) + opt.option_strings = strings + max_len = max(max_len, len(strings) + self.current_indent) + self.increase_nesting() + for group in parser.option_groups: + for opt in group.option_list: + strings = self.format_option_strings(opt) + opt.option_strings = strings + max_len = max(max_len, len(strings) + self.current_indent) + self.decrease_nesting() + self.decrease_nesting() + self.help_position = min(max_len + 2, self.max_help_position) + + def format_option_strings(self, option): """Return a comma-separated list of option strigs & metavariables.""" raise NotImplementedError( - "Virtual method; use format_option_list_short_first or " - "format_option_list_long_first instead.") + "Virtual method; use format_option_strings_short_first or " + "format_option_strings_long_first instead.") - def format_option_list_short_first(self, option): + def format_option_strings_short_first(self, option): opts = [] # list of "-a" or "--foo=FILE" strings takes_value = option.takes_value() if takes_value: @@ -1224,7 +1278,7 @@ class HelpFormat: opts.append(opt) return ", ".join(opts) - def format_option_list_long_first(self, option): + def format_option_strings_long_first(self, option): opts = [] # list of "-a" or "--foo=FILE" strings takes_value = option.takes_value() if takes_value: @@ -1243,9 +1297,9 @@ class Indented(HelpFormat): """Formats help with indented section bodies.""" - def __init__(self, indent_increment=2, help_indent=24, width=78, + def __init__(self, indent_increment=2, max_help_position=24, width=78, short_first=1): - HelpFormat.__init__(self, indent_increment, help_indent, width, + HelpFormat.__init__(self, indent_increment, max_help_position, width, short_first) def format_usage(self, usage): @@ -1259,9 +1313,9 @@ class Titled(HelpFormat): """Formats help with underlined section headers.""" - def __init__(self, indent_increment=0, help_indent=24, width=78, + def __init__(self, indent_increment=0, max_help_position=24, width=78, short_first=None): - HelpFormat.__init__(self, indent_increment, help_indent, width, + HelpFormat.__init__(self, indent_increment, max_help_position, width, short_first) def format_usage(self, usage): -- cgit v1.2.1 From e423e67e9ed18cdb153baa37a936482e85efb79a Mon Sep 17 00:00:00 2001 From: orutherfurd <orutherfurd@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 24 Jun 2002 03:30:31 +0000 Subject: - added missing ListType import which is used for validating "choice" options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@200 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/optik.py b/docutils/optik.py index fda0967a9..d717f6864 100644 --- a/docutils/optik.py +++ b/docutils/optik.py @@ -54,7 +54,7 @@ __version__ = "1.3+" import sys import os import types -from types import TupleType, DictType +from types import TupleType, DictType, ListType from distutils.fancy_getopt import wrap_text -- cgit v1.2.1 From 12566a28180aa8448773ffd892fe841fa3f2314c Mon Sep 17 00:00:00 2001 From: richard <richard@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 24 Jun 2002 04:32:42 +0000 Subject: Remove the extra whitespace from the top of the first paragraph of a <dd> or <li>. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@201 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 690caf82b..ffeec0d69 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -96,6 +96,14 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } +dd p:first-child { + margin-top: 0px; +} + +li p:first-child { + margin-top: 0px; +} + p.caption { font-style: italic } -- cgit v1.2.1 From 373cca31645a6460611519ee0ae27e02076d2495 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:16:03 +0000 Subject: - Added ``option_spec`` parameter to ``publish()`` etc. - Added "--dump-internal-document-attributes" support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@204 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 1fe6af418..4a75a9508 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -37,7 +37,7 @@ class Publisher: self.reader = reader """A `readers.Reader` instance.""" - + self.parser = parser """A `parsers.Parser` instance.""" @@ -77,40 +77,45 @@ class Publisher: defaults=defaults) self.options = option_parser.get_default_values() - def process_command_line(self, argv=None, usage=None, description=None): + def process_command_line(self, argv=None, usage=None, description=None, + option_spec=None): """ Pass an empty list to `argv` to avoid reading `sys.argv` (the default). - + Set components first (`self.set_reader` & `self.set_writer`). """ option_parser = OptionParser( - components=(self.reader, self.parser, self.writer), + components=(option_spec, self.reader, self.parser, self.writer), usage=usage, description=description) if argv is None: argv = sys.argv[1:] self.options, self.source, self.destination \ = option_parser.parse_args(argv) - def publish(self, argv=None, usage=None, description=None): + def publish(self, argv=None, usage=None, description=None, + option_spec=None): """ Process command line options and arguments, run `self.reader` and then `self.writer`. """ if self.options is None: - self.process_command_line(argv, usage, description) + self.process_command_line(argv, usage, description, option_spec) document = self.reader.read(self.source, self.parser, self.options) self.writer.write(document, self.destination) + if self.options.dump_internal_document_attributes: + from pprint import pformat + print >>sys.stderr, pformat(document.__dict__) def publish(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', - argv=None, usage=None, description=None): + argv=None, usage=None, description=None, option_spec=None): """A convenience function; set up & run a `Publisher`.""" pub = Publisher(reader, parser, writer) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: pub.set_writer(writer_name) - pub.publish(argv, usage, description) + pub.publish(argv, usage, description, option_spec) -- cgit v1.2.1 From f7261b75de49dbcd0da320ac34cd549425e9dac2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:17:24 +0000 Subject: - Enabled "--encoding" option (but not implemented yet). - Added "--dump-internal-document-attributes". - Support for non-grouped options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@205 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 275137a9c..c833940b4 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -68,9 +68,8 @@ class OptionParser(optik.OptionParser): ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}), ('Send the output of system messages (warnings) to <file>.', ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), - # @@@ Take default encoding & language from locale? - #('Specify the encoding of input text. Default is "utf-8".', - # ['--encoding', '-e'], {'default': 'utf-8', 'metavar': '<name>'}), + ('Specify the encoding of input text. Default is locale-dependent.', + ['--encoding', '-e'], {'metavar': '<name>'}), ('Specify the language of input text (ISO 639 2-letter identifier. ' 'Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', @@ -78,12 +77,17 @@ class OptionParser(optik.OptionParser): ("Show this program's version number and exit.", ['--version'], {'action': 'version'}), ('Show this help message and exit.', - ['--help', '-h'], {'action': 'help'}),)) + ['--help', '-h'], {'action': 'help'}), + # Hidden options, for development use only: + (optik.SUPPRESS_HELP, ['--dump-internal-document-attributes'], + {'action': 'store_true'}),)) + """Command-line option specifications, common to all Docutils front-ends. Option group title, description, and a list/tuple of tuples: ``('help - text', [list of option strings], {keyword arguments})``. Option specs - from Docutils components are also used (see - `populate_from_components()`).""" + text', [list of option strings], {keyword arguments})``. Group title + and/or description may be `None`; no group title implies no group, just a + list of single options. Option specs from Docutils components are also + used (see `populate_from_components()`).""" thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} """Lookup table for --report and --halt threshold values.""" @@ -107,8 +111,11 @@ class OptionParser(optik.OptionParser): for component in components: if component is not None and component.cmdline_options: title, description, option_spec = component.cmdline_options - group = optik.OptionGroup(self, title, description) - self.add_option_group(group) + if title: + group = optik.OptionGroup(self, title, description) + self.add_option_group(group) + else: + group = self # single options for (help_text, option_strings, kwargs) in option_spec: group.add_option(help=help_text, *option_strings, **kwargs) -- cgit v1.2.1 From 5e35a98b286b3a7a3107818e01bdcc13dd2f2a79 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:18:21 +0000 Subject: - Reworked the name/id bookkeeping; to ``document``, removed ``explicit_targets`` and ``implicit_targets`` attributes, added ``nametypes`` attribute and ``set_name_id_map`` method. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@206 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 127 +++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 64 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 45d5ef726..6f6367cdd 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -556,13 +556,6 @@ class document(Root, Structural, Element): self.reporter = reporter """System message generator.""" - self.explicit_targets = {} - """Mapping of target names to explicit target nodes.""" - - self.implicit_targets = {} - """Mapping of target names to implicit (internal) target - nodes.""" - self.external_targets = [] """List of external target nodes.""" @@ -584,6 +577,10 @@ class document(Root, Structural, Element): self.nameids = {} """Mapping of names to unique id's.""" + self.nametypes = {} + """Mapping of names to hyperlink type (boolean: True => explicit, + False => implicit.""" + self.ids = {} """Mapping of ids to nodes.""" @@ -622,7 +619,7 @@ class document(Root, Structural, Element): """List of citation nodes.""" self.pending = [] - """List of pending elements @@@.""" + """List of pending elements.""" self.autofootnote_start = 1 """Initial auto-numbered footnote number.""" @@ -642,12 +639,12 @@ class document(Root, Structural, Element): return domroot def set_id(self, node, msgnode=None): - if msgnode == None: - msgnode = self.messages if node.has_key('id'): id = node['id'] if self.ids.has_key(id) and self.ids[id] is not node: msg = self.reporter.severe('Duplicate ID: "%s".' % id) + if msgnode == None: + msgnode = self.messages msgnode += msg else: if node.has_key('name'): @@ -659,66 +656,66 @@ class document(Root, Structural, Element): self.id_start += 1 node['id'] = id self.ids[id] = node - if node.has_key('name'): - self.nameids[node['name']] = id return id - def note_implicit_target(self, target, msgnode=None): + def set_name_id_map(self, node, id, msgnode=None, explicit=None): + if node.has_key('name'): + name = node['name'] + if self.nameids.has_key(name): + self.set_duplicate_name_id(node, id, name, msgnode, explicit) + else: + self.nameids[name] = id + self.nametypes[name] = explicit + + def set_duplicate_name_id(self, node, id, name, msgnode, explicit): if msgnode == None: msgnode = self.messages - id = self.set_id(target, msgnode) - name = target['name'] - if self.explicit_targets.has_key(name) \ - or self.implicit_targets.has_key(name): + old_id = self.nameids[name] + old_explicit = self.nametypes[name] + self.nametypes[name] = old_explicit or explicit + if explicit: + if old_explicit: + level = 2 + if old_id is not None: + old_node = self.ids[old_id] + if node.has_key('refuri'): + refuri = node['refuri'] + if old_node.has_key('name') \ + and old_node.has_key('refuri') \ + and old_node['refuri'] == refuri: + level = 1 # just inform if refuri's identical + if level > 1: + dupname(old_node) + self.nameids[name] = None + msg = self.reporter.system_message( + level, 'Duplicate explicit target name: "%s".' % name, + backrefs=[id]) + msgnode += msg + dupname(node) + else: + self.nameids[name] = id + if old_id is not None: + old_node = self.ids[old_id] + dupname(old_node) + else: + if old_id is not None and not old_explicit: + self.nameids[name] = None + old_node = self.ids[old_id] + dupname(old_node) + dupname(node) + if not explicit or (not old_explicit and old_id is not None): msg = self.reporter.info( - 'Duplicate implicit target name: "%s".' % name, - backrefs=[id]) + 'Duplicate implicit target name: "%s".' % name, + backrefs=[id]) msgnode += msg - self.clear_target_names(name, self.implicit_targets) - del target['name'] - target['dupname'] = name - self.implicit_targets[name] = None - else: - self.implicit_targets[name] = target + + def note_implicit_target(self, target, msgnode=None): + id = self.set_id(target, msgnode) + self.set_name_id_map(target, id, msgnode, explicit=None) def note_explicit_target(self, target, msgnode=None): - if msgnode == None: - msgnode = self.messages id = self.set_id(target, msgnode) - name = target['name'] - if self.explicit_targets.has_key(name): - level = 2 - if target.has_key('refuri'): # external target, dups OK - refuri = target['refuri'] - t = self.explicit_targets[name] - if t.has_key('name') and t.has_key('refuri') \ - and t['refuri'] == refuri: - level = 1 # just inform if refuri's identical - msg = self.reporter.system_message( - level, 'Duplicate explicit target name: "%s".' % name, - backrefs=[id]) - msgnode += msg - self.clear_target_names(name, self.explicit_targets, - self.implicit_targets) - if level > 1: - del target['name'] - target['dupname'] = name - elif self.implicit_targets.has_key(name): - msg = self.reporter.info( - 'Duplicate implicit target name: "%s".' % name, - backrefs=[id]) - msgnode += msg - self.clear_target_names(name, self.implicit_targets) - self.explicit_targets[name] = target - - def clear_target_names(self, name, *targetdicts): - for targetdict in targetdicts: - if not targetdict.has_key(name): - continue - node = targetdict[name] - if node.has_key('name'): - node['dupname'] = node['name'] - del node['name'] + self.set_name_id_map(target, id, msgnode, explicit=1) def note_refname(self, node): self.refnames.setdefault(node['refname'], []).append(node) @@ -770,7 +767,6 @@ class document(Root, Structural, Element): self.note_refname(ref) def note_citation(self, citation): - self.set_id(citation) self.citations.append(citation) def note_citation_ref(self, ref): @@ -787,8 +783,7 @@ class document(Root, Structural, Element): msgnode = self.messages msgnode += msg oldnode = self.substitution_defs[name] - oldnode['dupname'] = oldnode['name'] - del oldnode['name'] + dupname(oldnode) # keep only the last definition self.substitution_defs[name] = subdef @@ -1303,3 +1298,7 @@ def make_id(string): _non_id_chars = re.compile('[^a-z0-9]+') _non_id_at_ends = re.compile('^[-0-9]+|-+$') + +def dupname(node): + node['dupname'] = node['name'] + del node['name'] -- cgit v1.2.1 From b0f8ccca541e0f8adc95209845d205feb163f229 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:19:28 +0000 Subject: - Some ``types`` cleanup. - Added ``Values.__repr__`` method. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@207 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/optik.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docutils/optik.py b/docutils/optik.py index d717f6864..a8652860c 100644 --- a/docutils/optik.py +++ b/docutils/optik.py @@ -53,8 +53,7 @@ __version__ = "1.3+" import sys import os -import types -from types import TupleType, DictType, ListType +from types import TupleType, ListType, DictType, StringType from distutils.fancy_getopt import wrap_text @@ -583,7 +582,7 @@ class OptionContainer: """add_option(Option) add_option(opt_str, ..., kwarg=val, ...) """ - if type(args[0]) is types.StringType: + if type(args[0]) is StringType: option = self.option_class(*args, **kwargs) elif len(args) == 1 and not kwargs: option = args[0] @@ -685,6 +684,8 @@ class Values: for (attr, val) in defaults.items(): setattr(self, attr, val) + def __repr__(self): + return "%s(%r)" % (self.__class__, self.__dict__) def _update_careful (self, dict): """ -- cgit v1.2.1 From 279a5cfc2c066bba8de6a9035c077f43710d849d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:20:25 +0000 Subject: Updated & cleaned up (a bit). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@208 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 3ee0e0534..543bc1108 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1361,8 +1361,9 @@ class Body(RSTState): footnote['name'] = name self.document.note_footnote(footnote) if name: - self.document.note_explicit_target(footnote, - footnote) + self.document.note_explicit_target(footnote, footnote) + else: + self.document.set_id(footnote) if indented: self.nested_parse(indented, input_offset=offset, node=footnote) return [footnote], blank_finish @@ -1444,8 +1445,7 @@ class Body(RSTState): self.document.note_external_target(target) else: self.document.note_internal_target(target) - self.document.note_explicit_target( - target, self.parent) + self.document.note_explicit_target(target, self.parent) else: # anonymous target if refuri: target['refuri'] = refuri -- cgit v1.2.1 From b42175f802cb1f8bce74017430c5135e3fff5c55 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:21:24 +0000 Subject: Fixed indirect target resolution in ``Hyperlinks`` transform; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@209 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index ccd43c749..20cdcd525 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -1,6 +1,6 @@ #! /usr/bin/env python """ -:Authors: David Goodger +:Author: David Goodger :Contact: goodger@users.sourceforge.net :Revision: $Revision$ :Date: $Date$ @@ -146,14 +146,11 @@ class Hyperlinks(Transform): def resolve_indirect_target(self, target): refname = target['refname'] - reftarget = None - if self.document.explicit_targets.has_key(refname): - reftarget = self.document.explicit_targets[refname] - elif self.document.implicit_targets.has_key(refname): - reftarget = self.document.implicit_targets[refname] - if not reftarget: + reftarget_id = self.document.nameids.get(refname) + if not reftarget_id: self.nonexistent_indirect_target(target) return + reftarget = self.document.ids[reftarget_id] if isinstance(reftarget, nodes.target) \ and not reftarget.resolved and reftarget.hasattr('refname'): self.one_indirect_target(reftarget) # multiply indirect @@ -179,9 +176,9 @@ class Hyperlinks(Transform): naming = '' if target.hasattr('name'): naming = '"%s" ' % target['name'] - reflist = self.document.refnames[target['name']] + reflist = self.document.refnames.get(target['name'], []) else: - reflist = self.document.refnames[target['id']] + reflist = self.document.refids.get(target['id'], []) naming += '(id="%s")' % target['id'] msg = self.document.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' @@ -495,7 +492,7 @@ class Footnotes(Transform): while 1: label = str(startnum) startnum += 1 - if not self.document.explicit_targets.has_key(label): + if not self.document.nameids.has_key(label): break footnote.insert(0, nodes.label('', label)) if footnote.hasattr('dupname'): @@ -540,8 +537,9 @@ class Footnotes(Transform): ref.parent.replace(ref, prb) break ref += nodes.Text(label) - footnote = self.document.explicit_targets[label] - ref['refid'] = footnote['id'] + id = self.document.nameids[label] + footnote = self.document.ids[id] + ref['refid'] = id self.document.note_refid(ref) footnote.add_backref(ref['id']) ref.resolved = 1 -- cgit v1.2.1 From 4c08c14508ae15f0d45164b54497ecf0105af264 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:22:04 +0000 Subject: fiddling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@210 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 782d930c5..e9553cb13 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -136,9 +136,8 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): if node.resolved or not node.hasattr('refname'): return refname = node['refname'] - try: - id = self.document.nameids[refname] - except KeyError: + id = self.document.nameids.get(refname) + if id is None: msg = self.document.reporter.error( 'Unknown target name: "%s".' % (node['refname'])) self.document.messages += msg @@ -148,11 +147,11 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): prbid = self.document.set_id(prb) msg.add_backref(prbid) node.parent.replace(node, prb) - return - del node['refname'] - node['refid'] = id - self.document.ids[id].referenced = 1 - node.resolved = 1 + else: + del node['refname'] + node['refid'] = id + self.document.ids[id].referenced = 1 + node.resolved = 1 visit_footnote_reference = visit_citation_reference = visit_reference -- cgit v1.2.1 From 8c4fa064a323de3e1d4aba4e853fd004e3e08914 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:23:17 +0000 Subject: - Brought ``interpreted`` element in line with the parser: changed attribute "type" to "role", added "position". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@211 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/docutils.dtd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 856f3c13e..80e54b084 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -112,7 +112,7 @@ resolve to either an internal or external reference. <!ENTITY % additional.body.elements ""> <!ENTITY % body.elements - " paragraph | literal_block | block_quote | doctest_block| table + " paragraph | literal_block | block_quote | doctest_block | table | figure | image | footnote | citation | bullet_list | enumerated_list | definition_list | field_list | option_list @@ -489,7 +489,8 @@ following caveats: <!ELEMENT interpreted (%text.model;)> <!ATTLIST interpreted %basic.atts; - type CDATA #IMPLIED> + role CDATA #IMPLIED + position (prefix | suffix) #IMPLIED> <!ELEMENT literal (#PCDATA)> <!ATTLIST literal %basic.atts;> -- cgit v1.2.1 From 869cd57c4c3dd81cf8934f050fbb7b6217b59653 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:23:55 +0000 Subject: Added new alternative table markup syntaxes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@212 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/problems.txt | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt index e97887a01..677708ce5 100644 --- a/docs/dev/rst/problems.txt +++ b/docs/dev/rst/problems.txt @@ -348,7 +348,7 @@ documentation. Alternatives: allowed; the first line of text in a cell determines its left margin. -2. Below is a minimalist possibility. It may be better suited to +2. Below is a simpler table structure. It may be better suited to manual input than alternative #1, but there is no Emacs editing mode available. One disadvantage is that it resembles section titles; a one-column table would look exactly like section & @@ -374,7 +374,80 @@ documentation. Alternatives: table consists of '=' underlines. A blank line is required following a table. -Alternative #1 is the choice adopted by reStructuredText. +3. A minimalist alternative is as follows:: + + ======== ======== ======== + Header 2 & 3 Span + ------------------ + Header 1 Header 2 Header 3 + ======== ======== ======== + Each line is a new row. + Each row consists of one line only. + Row spans are not possible. + The last column may spill over to the right. + Column spans are possible with an underline joining columns. + ---------------------------- + The span is limited to the row above the underline. + ======== ======== ======== + + The table begins with a top border of equals signs with one or more + spaces at each column boundary (regardless of spans). There must + be at least two columns in the table (to differentiate it from + section headers). Each line starts a new row. The rightmost + column is unbounded; text may continue past the edge of the table. + Each row/line must contain spaces at column boundaries, except for + explicit column spans. Underlines of '-' can be used to indicate + column spans, but should be used sparingly if at all. Lines + containing column span underlines may not contain any other text. + The last of the optional head rows is underlined with '=', again + with spaces at column boundaries. The bottom boundary of the table + consists of '=' underlines. A blank line is required following a + table. + +4. As a variation of alternative 3, bullet list syntax in the first + column could be used to indicate row starts. Multi-line rows are + possible, but row spans are not. For example:: + + ===== ===== + col 1 col 2 + ===== ===== + - 1 Second column of row 1. + - 2 Second column of row 2. + Second line of paragraph. + - 3 Second column of row 3. + + Second paragraph of row 3, + column 2 + ===== ===== + + Column spans would be indicated on the line after the last line of + the row. To indicate a real bullet list within a first-column + cell, simply nest the bullets. + +5. In a further variation, we could simply assume that whitespace in + the first column implies a multi-line row; the text in other + columns is continuation text. For example:: + + ===== ===== + col 1 col 2 + ===== ===== + 1 Second column of row 1. + 2 Second column of row 2. + Second line of paragraph. + 3 Second column of row 3. + + Second paragraph of row 3, + column 2 + ===== ===== + + Limitations of this approach: + + - Cells in the first column are limited to one line of text. + + - Cells in the first column *must* contain some text; blank cells + would lead to a misinterpretation. + +Alternative #1 has been adopted by reStructuredText. Delimitation of Inline Markup -- cgit v1.2.1 From a9913f6dfaab8d568b019f4d700c966c44bb1032 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:24:56 +0000 Subject: Added the "--attributes" option, hacked a bit. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@213 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/quicktest.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/quicktest.py b/tools/quicktest.py index d76845023..cf3884875 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -13,7 +13,8 @@ import sys import os import getopt -import docutils.utils +from docutils.frontend import OptionParser +from docutils.utils import new_document from docutils.parsers.rst import Parser @@ -37,6 +38,7 @@ options = [('pretty', 'p', ('styledxml=', 's', 'output raw XML with XSL style sheet reference ' '(filename supplied in the option argument)'), ('xml', 'x', 'output pretty XML (indented)'), + ('attributes', '', 'dump document attributes after processing'), ('debug', 'd', 'debug mode (lots of output)'), ('help', 'h', 'show help text')] """See distutils.fancy_getopt.FancyGetopt.__init__ for a description of the @@ -127,7 +129,7 @@ def posixGetArgs(argv): except getopt.GetoptError: usage() sys.exit(2) - optargs = {'debug': 0} + optargs = {'debug': 0, 'attributes': 0} for o, a in opts: if o in ['-h', '--help']: usage() @@ -143,6 +145,8 @@ def posixGetArgs(argv): outputFormat = 'pretty' elif o in ['-t', '--test']: outputFormat = 'test' + elif o == '--attributes': + optargs['attributes'] = 1 elif o in ['-d', '--debug']: optargs['debug'] = 1 else: @@ -174,12 +178,17 @@ In the following window, please: def main(): inputFile, outputFormat, optargs = getArgs() # process cmdline arguments + options = OptionParser().get_default_values() + options.debug = optargs['debug'] parser = Parser() input = inputFile.read() - document = docutils.utils.new_document(debug=optargs['debug']) + document = new_document(options) parser.parse(input, document) output = format(outputFormat, input, document, optargs) print output, + if optargs['attributes']: + import pprint + pprint.pprint(document.__dict__) if __name__ == '__main__': -- cgit v1.2.1 From 7169009358ab112b33e8c0fb9d37ff902eb0892c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:26:55 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@214 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 47 ++++--- docs/dev/todo.txt | 189 +++++++++++++++++++++++------ docs/ref/doctree.txt | 13 +- test/test_parsers/test_rst/test_targets.py | 4 +- test/test_transforms/test_hyperlinks.py | 9 +- 5 files changed, 201 insertions(+), 61 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 5e36845df..e917e1af1 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,13 +17,14 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - David Ascher, Fred Drake, Jim Fulton, Peter Funk, Engelbert - Gruber, Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, - Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, - Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel - Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ueli - Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, - Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Aahz, David Ascher, Fred Drake, Dethe Elza, Jim Fulton, Peter + Funk, Engelbert Gruber, Doug Hellmann, Juergen Hermann, Tony Ibbs, + Alan Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, + Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, + Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Mark + Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli Schlaepfer, tav, Bob + Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward + Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -62,7 +63,8 @@ Specific: - Removed many keyword parameters to ``Publisher.__init__()`` and ``publish()``; bundled into an option values object. Added - ``argv`` and ``usage`` parameters for command-line support. + "argv", "usage", "description", and "option_spec" parameters for + command-line support. - Added ``Publisher.process_command_line()`` and ``.set_options()`` methods. @@ -85,6 +87,9 @@ Specific: 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. * docutils/optik.py: Added to project. Combined from the Optik package, with added option groups and other modifications. The use @@ -126,6 +131,7 @@ Specific: - Added ``MarkupMismatch`` exception; for late corrections. - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. + - Fixed a footnote bug. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -141,6 +147,9 @@ Specific: * 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/peps.py: Added to project; PEP-specific. * docutils/transforms/parts.py: Renamed from old components.py. @@ -148,8 +157,8 @@ Specific: - Added filter for `Contents`, to use alt-text for inline images, and to remove inline markup that doesn't make sense in the ToC. -* docutils/transforms/components.py: Added to project; transforms - related to Docutils components. +* docutils/transforms/references.py: Fixed indirect target resolution + in ``Hyperlinks`` transform. * docutils/transforms/universal.py: @@ -177,6 +186,8 @@ Specific: * spec/docutils.dtd: - Added ``decoration``, ``header``, and ``footer`` elements. + - Brought ``interpreted`` element in line with the parser: changed + attribute "type" to "role", added "position". * spec/notes.txt: Continual updates. Added "Project Policies". @@ -191,6 +202,14 @@ Specific: - Reworked structural elements, incorporating ideas from Tony Ibbs. +* spec/rst/alternatives.txt: Expanded auto-enumerated list idea; + thanks to Fred Bremmer. + +* spec/rst/problems.txt: + + - Updated the Enumerated List Markup discussion. + - Added new alternative table markup syntaxes. + * spec/rst/reStructuredText.txt: - Clarified field list usage. @@ -199,12 +218,6 @@ Specific: - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. -* spec/rst/alternatives.txt: Expanded auto-enumerated list idea; - thanks to Fred Bremmer. - -* spec/rst/problems.txt: Updated the Enumerated List Markup - discussion. - * test: Made test modules standalone (subdirectories became packages). * test/DocutilsTestSupport.py: Support for PEP extensions to @@ -226,6 +239,8 @@ Specific: - Added support for ``header`` and ``footer`` elements. +* tools/quicktest.py: Added the "--attributes" option, hacked a bit. + Release 0.1 (2002-04-20) ======================== diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c22c65e08..38f6be2d5 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -19,6 +19,41 @@ Many of these items are awaiting champions. If you see something you'd like to tackle, please do! +Bugs +---- + +- (Fixed, I think.) When there are duplicate implicit target names + (e.g., section headers), a named hyperlink will link to the last of + them. It shouldn't link to any at all, and should report an error. + + - nodes.document.nameids maps names to IDs. When there is a + duplicate, the last one stays. Idea: have a parallel + nodes.document.nametype mapping, name -> boolean (explicit name?). + :: + + ==== ===== ======== ======== ======= ==== ===== ===== + Old State Input Action New State Notes + ----------- -------- ----------------- ----------- + id type new type sys.msg. dupname id type + ==== ===== ======== ======== ======= ==== ===== ===== + -- -- explicit -- -- new True + -- -- implicit -- -- new False + None False explicit -- -- new True + old False explicit implicit old new True + None True explicit explicit new None True + old True explicit explicit new,old None True [1] + None False implicit implicit new None False + old False implicit implicit new,old None False + None True implicit implicit new None True + old True implicit implicit new old True + ==== ===== ======== ======== ======= ==== ===== ===== + + (The above is an example of `table syntax alternative 3`__; not + implemented yet, but I'm thinking about it.) + + __ rst/problems.html#tables + + General ------- @@ -73,8 +108,8 @@ General - Try the encoding specified by a command-line option, if any. - Try the encoding specified by an "encoding" directive, and/or an - "encoding" field in field lists & PEP headers, if any. (The same - could apply to "language".) + "encoding" field in field lists & PEP headers, if any. See the + misc.encoding_ directive below. - Try ASCII. @@ -118,23 +153,36 @@ General - Name ideas: importer/exporter. Perhaps reader/writer should be applied to lower-level tasks? "PySource Reader" or "PySource - Importer"? "HTML Writer" or "HTML Exporter"? If we stick with the - status quo, what to call the components that do low-level I/O? + Importer"? "HTML Writer" or "HTML Exporter"? I like the names + "Reader" & "Writer" for the high-level classes. So if we stick with + the status quo, what to call the components that do low-level I/O? - IOReader, IOWriter - - StreamReader, StreamWriter - DataReader, DataWriter - Inputter, Outputter - Scanner, Recorder? - Lector?, Scribe - - Loader, Storer/Recorder (maybe subclasses of Storage) + - Loader, Storer/Stower/Recorder + - InputStorage, OutputStorage + - Input, Output + - Source, Destination + + Perhaps subclasses of a single class, a abstraction for + file/string/etc. reading & writing. + + - Storage + - IO + + Implement as a single module (``docutils/storage.py``)? Or as a + subpackage (``docutils/storage/*.py``)? - Fix tests to run standalone. I.e., allow:: cd test/test_rst test_inline_markup.py - Raises an exception with path processing on GNU/Linux. + Raises an exception with path processing on GNU/Linux (but only + sometimes?). Specification @@ -164,7 +212,7 @@ reStructuredText Parser Also see the `... Or Not To Do?`__ list. -__ http://docutils.sf.net/spec/rst/alternatives.html#or-not-to-do +__ rst/alternatives.html#or-not-to-do - Add motivation sections for constructs in spec. @@ -214,7 +262,7 @@ __ http://docutils.sf.net/spec/rst/alternatives.html#or-not-to-do - issue a warning when processing documents with no default role which contain interpreted text with no explicitly specified role -- Perhaps the "default default" role for interpreted text could be +- Perhaps the default implicit role for interpreted text could be "title", as in, "title of a book". It'd be a text-only reference, no hyperlink. Idea from Aahz' 2002-05-09 Doc-SIG post. @@ -357,6 +405,20 @@ Directives time or at substitution time? Dangerous? Perhaps limit to canned macros; see text.date_ below. + - _`misc.encoding`: Specify the character encoding of the input + data. But there are problems: + + - When it sees the directive, the parser will already have read + the input data, and encoding determination will already have + been done. + + - If a file with an "encoding" directive is edited and saved with + a different encoding, the directive may cause data corruption. + + - _`misc.language`: Specify the language of a document. There is a + problem similar to the first problem listed for misc.encoding_, + although to a lesser degree. + - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) @@ -394,20 +456,10 @@ Directives priority. - _`body.columns`: Multi-column table/list. Number of columns as - argument? Perhaps a variation on `table syntax alternative 2`__, - combined with bullet list syntax to indicate rows:: - - col 1 col 2 - ===== ===== - - 1 Second column of row 1. - - 2 Second column of row 2. - Second line of paragraph. - - 3 Second column of row 3. + argument? Several `alternative syntaxes`__ are proposed that + might not need a directive.. - Second paragraph of row 3, - column 2 - - __ problems.html#tables + __ rst/problems.html#tables - @@ _`body.verse`: Paragraphs with linebreaks preserved, *and* inline markup support too. Use cases: verse (poetry, song lyrics, @@ -490,7 +542,9 @@ Directives use. Use a factory function "transformFF()" which returns either "HTMLTransform()" instance or "GenericTransform" instance? - - _`text.date`: Datestamp. For substitutions. + - _`text.date`: Datestamp. For substitutions. The directive could + be followed by a formatting string, using strftime codes. Default + is "%Y-%m-%d" (ISO 8601 date), but time fields can also be used. - Combined with misc.include_, implement canned macros? E.g.:: @@ -500,6 +554,9 @@ Directives Where "macros" contains ``.. |date| date::``, among others. + - _`text.time`: Timestamp. For substitutions. Shortcut for + ``.. date:: %H:%M``. Date fields can also be used. + - _`pysource.usage`: Extract a usage message from the program, either by running it at the command line with a ``--help`` option or through an exposed API. [Suggestion for Optik.] @@ -682,6 +739,40 @@ a common option-processing module, as described below. Project Policies ================ +A few quotes sum up the policies of the Docutils project. The IETF's +classic credo (by MIT professor Dave Clark) is an ideal we can aspire +to: + + We reject: kings, presidents, and voting. We believe in: rough + consensus and running code. + +As architect, chief cook and bottle-washer, I currently function as +BDFN (Benevolent Dictator For Now), but I would happily abdicate the +throne given a suitable candidate. Any takers? + +Eric S. Raymond, anthropologist of the hacker subculture, writes in +his essay `The Magic Cauldron`_: + + The number of contributors [to] projects is strongly and inversely + correlated with the number of hoops each project makes a user go + through to contribute. + + .. _The Magic Cauldron: + http://www.tuxedo.org/~esr/writings/magic-cauldron/ + +Therefore, we will endeavour to keep the barrier to entry as low as +possible. The policies below should not be thought of as barriers, +but merely as a codification of experience to date. These are "best +practices", not absolutes; exceptions are expected, tolerated, and +used as a source of improvement. + +As for control issues, Emmett Plant (CEO of the Xiph.org Foundation, +originators of Ogg Vorbis) put it well when he said: + + Open source dictates that you lose a certain amount of control + over your codebase, and that's okay with us. + + Coding Conventions ------------------ @@ -693,8 +784,8 @@ it probably will be accepted. But don't be surprised if the conventions. The Docutils project shall follow the generic coding conventions as -specified in the `Style Guide for Python Code`__ and `Docstring -Conventions`__ PEPs, with the following clarifications (from most to +specified in the `Style Guide for Python Code`_ and `Docstring +Conventions`_ PEPs, with the following clarifications (from most to least important): - 4 spaces per indentation level. No tabs. Indent continuation lines @@ -720,8 +811,9 @@ least important): - Use 'single quotes' for string literals, and """triple double quotes""" for docstrings. -__ http://www.python.org/peps/pep-0008.html -__ http://www.python.org/peps/pep-0257.html +.. _Style Guide for Python Code: + http://www.python.org/peps/pep-0008.html +.. _Docstring Conventions: http://www.python.org/peps/pep-0257.html Copyrights and Licensing @@ -775,17 +867,28 @@ applicable), with particular emphasis as follows: cases to the test suite. Practise test-first programming; it's fun, it's addictive, and it works! -- The `sandbox CVS directory`_ is the place to put new, untried code. - See `Additions to Docutils`_ and `The Sandbox`_ below. +- The `sandbox CVS directory`_ is the place to put new, incomplete or + experimental code. See `Additions to Docutils`_ and `The Sandbox`_ + below. + +- For bugs or omissions that have an obvious fix and can't possibly + mess up anything else, go right ahead and check it in directly. -Please consider subscribing to the appropriate `mailing lists`_. +- For larger changes, use your best judgement. If you're unsure of + the impact, or feel that you require advice or approval, patches or + `the sandbox`_ are the way to go. + +Docutils will pursue an open and trusting policy for as long as +possible, and deal with any abberations if (and hopefully not when) +they happen. I'd rather see a torrent of loose contributions than +just a trickle of perfect-as-they-stand changes. The occasional +mistake is easy to fix. That's what CVS is for. .. _main source tree: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/docutils/ .. _Python Check-in Policies: http://www.python.org/dev/tools.html .. _sandbox CVS directory: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/docutils/sandbox/ -.. _mailing lists: ../index.html#mailing-lists Additions to Docutils @@ -826,6 +929,24 @@ It's easy to move code over to the main source tree once it's closer to completion. +Mailing Lists +------------- + +Developers should subscribe to the mailing lists: + +- The `Python Documentation Special Interest Group (Doc-SIG) mailing + list`__ for high-level discussions on syntax, strategy, and design + (email to Doc-SIG@python.org). +- Docutils-develop__, for implementation discussions + (email to docutils-develop@lists.sourceforge.net). +- Docutils-checkins__, to monitor CVS checkin messages (automatically + generated; normally read-only). + +__ http://mail.python.org/mailman/listinfo/doc-sig +__ http://lists.sourceforge.net/lists/listinfo/docutils-develop +__ http://lists.sourceforge.net/lists/listinfo/docutils-checkins + + The Sandbox ----------- @@ -835,9 +956,9 @@ distributed as part of Docutils releases. Feel free to check in code to the CVS sandbox; that way people can try it out but you won't have to worry about it working 100% error-free, as is the goal of the `main source tree`_. Each developer who wants to play in the sandbox should -create their own subdirectory (suggested name: SourceForge ID, or -given name + family initial). It's OK to make a mess! But please, -play nice. +create their own subdirectory (suggested name: SourceForge ID, +nickname, or given name + family initial). It's OK to make a mess! +But please, play nice. In order to minimize the work necessary for others to install and try out new, experimental components, the following sandbox directory diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 90aea7054..89b222f6f 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -21,7 +21,7 @@ one-to-many relationships; sections may contain (sub)sections, tables contain further body elements, etc. :: +--------------------------------------------------------------------+ - | document [may begin with a title, subtitle, docinfo] | + | document [may begin with a title, subtitle, docinfo, decoration] | | +--------------------------------------+ | | sections [each begins with a title] | +-----------------------------+-------------------------+------------+ @@ -41,11 +41,12 @@ contain further body elements, etc. :: Element Hierarchy ------------------- -A class hierarchy has been implemented in nodes.py where the position -of the element (the level at which it can occur) is significant. -E.G., Root, Structural, Body, Inline classes etc. Certain -transformations will be easier because we can use isinstance() on -them. +A class hierarchy has been implemented in nodes.py. The position of +each node (the level at which it can occur) is significant and is +represented by abstract base classes (Root, Structural, Body, Inline, +etc.). Certain transformations will be easier because we can use +``isinstance(node, base_class)`` to determine the position of the node +in the hierarchy. The elements making up Docutils document trees can be categorized into the following groups: diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index 1379db420..172a0ecd6 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -186,11 +186,11 @@ Duplicate external targets (same URIs): <document> <paragraph> Duplicate external targets (same URIs): - <target dupname="target" id="target" refuri="first"> + <target id="target" name="target" refuri="first"> <system_message backrefs="id1" level="1" type="INFO"> <paragraph> Duplicate explicit target name: "target". - <target id="id1" name="target" refuri="first"> + <target dupname="target" id="id1" refuri="first"> """], ["""\ Duplicate implicit targets. diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 811b2dcfe..b0f930de6 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -217,9 +217,12 @@ __ ztarget_ <paragraph> Second <paragraph> - <reference anonymous="1" refid="id1"> - indirect internal - <target anonymous="1" id="id2" refid="id1"> + <problematic id="id4" refid="id3"> + `indirect internal`__ + <target anonymous="1" id="id2" refname="ztarget"> + <system_message backrefs="id4" id="id3" level="2" type="WARNING"> + <paragraph> + Indirect hyperlink target (id="id2") refers to target "ztarget", which does not exist. """], ]) -- cgit v1.2.1 From 0991966cd6eef900dfbb455ef3a3f643445410f8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:30:38 +0000 Subject: fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@215 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 38f6be2d5..580d9fcdd 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -758,7 +758,7 @@ his essay `The Magic Cauldron`_: through to contribute. .. _The Magic Cauldron: - http://www.tuxedo.org/~esr/writings/magic-cauldron/ + http://www.tuxedo.org/~esr/writings/magic-cauldron/ Therefore, we will endeavour to keep the barrier to entry as low as possible. The policies below should not be thought of as barriers, -- cgit v1.2.1 From 61e25d656ee75dc1924eca96b0ac8fd00cfe1b17 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 27 Jun 2002 01:53:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@216 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 580d9fcdd..69f5770d4 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -51,8 +51,15 @@ Bugs (The above is an example of `table syntax alternative 3`__; not implemented yet, but I'm thinking about it.) + Note 1: Do not clear the name->id map or invalidate the old target + if both old and new targets are external and refer to an identical + URI. The new target is invalidated regardless. + __ rst/problems.html#tables +- The "::" before the table above should be removed completely from + the output. A single ":" is being left behind. + General ------- -- cgit v1.2.1 From 9c38addab1cab5a5e7e5b763984ef67e06881440 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:13:41 +0000 Subject: Added to project; uniform API for a variety of input & output mechanisms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@217 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 docutils/io.py diff --git a/docutils/io.py b/docutils/io.py new file mode 100644 index 000000000..66845e7f7 --- /dev/null +++ b/docutils/io.py @@ -0,0 +1,140 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +""" + +__docformat__ = 'reStructuredText' + +import sys +import locale + + +class IO: + + """ + Base class for abstract input/output wrappers. + """ + + source = None + destination = None + + def __init__(self, options, source=None, destination=None): + """ + :Parameters: + - `options`: a `docutils.optik.Values` object. + - `source`: identifies the source of input data. + - `destination`: identifies the destination for output data. + """ + self.options = options + + def __repr__(self): + return '%s: source=%r, destination=%r' % (self.__class__, self.source, + self.destination) + + def read(self, reader): + raise NotImplementedError + + def write(self, data): + raise NotImplementedError + + def decode(self, data): + """ + Decode a string, `data`, heuristically. + Raise UnicodeError if unsuccessful. + """ + encodings = [self.options.input_encoding, + locale.getlocale()[1], + 'utf-8', + locale.getdefaultlocale()[1],] + # is locale.getdefaultlocale() platform-specific? + for enc in encodings: + if not enc: + continue + try: + decoded = unicode(data, enc) + return decoded + except UnicodeError: + pass + raise UnicodeError( + 'Unable to decode input data. Tried the following encodings: %s.' + % ', '.join([repr(enc) for enc in encodings if enc])) + + +class FileIO(IO): + + """ + IO for single, simple files. + """ + + def __init__(self, options, source=None, destination=None): + """ + :Parameters: + - `source`: one of (a) a file-like object, which is read directly; + (b) a path to a file, which is opened and then read; or (c) + `None`, which implies `sys.stdin`. + - `destination`: one of (a) a file-like object, which is written + directly; (b) a path to a file, which is opened and then + written; or (c) `None`, which implies `sys.stdout`. + """ + IO.__init__(self, options) + if hasattr(source, 'read'): + self.source = source + elif source is None: + self.source = sys.stdin + else: + self.source = open(source) + if hasattr(destination, 'write'): + self.destination = destination + elif destination is None: + self.destination = sys.stdout + else: + self.destination = open(destination, 'w') + + def read(self, reader): + """ + Read and decode a single file and return the data. + """ + data = self.source.read() + return self.decode(data) + + def write(self, data): + """ + Encode and write `data` to a single file. + """ + output = data.encode(self.options.output_encoding) + self.destination.write(output) + + +class StringIO(IO): + + """ + Direct string IO. + """ + + def __init__(self, options, source=None, destination=None): + """ + :Parameters: + - `source`: a string containing input data. + - `destination`: not used. + """ + IO.__init__(self, options) + self.source = source + + def read(self, reader): + """ + Decode and return the source string. + """ + return self.decode(self.source) + + def write(self, data): + """ + Encode and return `data`. + """ + self.destination = data.encode(self.options.output_encoding) + return self.destination -- cgit v1.2.1 From 01e6d2ca28acbc89879acefd8e0baa3e6ca8c457 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:13:57 +0000 Subject: - Added support for the ``docutils.io.IO`` class & subclasses. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@218 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 53 ++++++++++++++++++++++++++++-------------- docutils/frontend.py | 9 ++++--- docutils/readers/__init__.py | 25 +++----------------- docutils/readers/standalone.py | 3 --- docutils/writers/__init__.py | 30 +++--------------------- docutils/writers/pseudoxml.py | 3 --- 6 files changed, 47 insertions(+), 76 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 4a75a9508..c0f9f4375 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -18,7 +18,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import Component -from docutils import readers, parsers, writers +from docutils import readers, parsers, writers, io from docutils.frontend import OptionParser @@ -28,7 +28,10 @@ class Publisher: A facade encapsulating the high-level logic of a Docutils system. """ - def __init__(self, reader=None, parser=None, writer=None): + def __init__(self, reader=None, parser=None, writer=None, + source=None, source_class=io.FileIO, + destination=None, destination_class=io.FileIO, + options=None): """ Initial setup. If any of `reader`, `parser`, or `writer` are not specified, the corresponding ``set_...`` method should be called with @@ -44,27 +47,34 @@ class Publisher: self.writer = writer """A `writers.Writer` instance.""" - self.options = None - """An object containing Docutils settings as instance attributes. - Set by `self.process_command_line()` or `self.set_options()`.""" + self.source = source + """The source of input data, an `io.IO` instance.""" + + self.source_class = source_class + """The class for dynamically created source objects.""" - self.source = None - """The source of input data.""" + self.destination = destination + """The destination for docutils output, an `io.IO` instance.""" - self.destination = None - """The destination for docutils output.""" + self.destination_class = destination_class + """The class for dynamically created destination objects.""" + + self.options = options + """An object containing Docutils settings as instance attributes. + Set by `self.process_command_line()` or `self.set_options()`.""" def set_reader(self, reader_name, parser, parser_name): """Set `self.reader` by name.""" reader_class = readers.get_reader_class(reader_name) self.reader = reader_class(parser, parser_name) + self.parser = self.reader.parser def set_writer(self, writer_name): """Set `self.writer` by name.""" writer_class = writers.get_writer_class(writer_name) self.writer = writer_class() - def set_options(self, **defaults): + def set_options(self, option_spec=None, **defaults): """ Set default option values (keyword arguments). @@ -73,12 +83,12 @@ class Publisher: from `self.publish()`. """ option_parser = OptionParser( - components=(self.reader, self.parser, self.writer), + components=(option_spec, self.reader, self.parser, self.writer), defaults=defaults) self.options = option_parser.get_default_values() def process_command_line(self, argv=None, usage=None, description=None, - option_spec=None): + option_spec=None): """ Pass an empty list to `argv` to avoid reading `sys.argv` (the default). @@ -90,29 +100,36 @@ class Publisher: usage=usage, description=description) if argv is None: argv = sys.argv[1:] - self.options, self.source, self.destination \ - = option_parser.parse_args(argv) + self.options, source, destination = option_parser.parse_args(argv) + self.source = self.source_class(self.options, source=source) + self.destination = self.destination_class(self.options, + destination=destination) def publish(self, argv=None, usage=None, description=None, option_spec=None): """ - Process command line options and arguments, run `self.reader` - and then `self.writer`. + Process command line options and arguments (if `self.options` not + already set), run `self.reader` and then `self.writer`. Return + `self.writer`'s output. """ if self.options is None: self.process_command_line(argv, usage, description, option_spec) document = self.reader.read(self.source, self.parser, self.options) - self.writer.write(document, self.destination) + output = self.writer.write(document, self.destination) if self.options.dump_internal_document_attributes: from pprint import pformat print >>sys.stderr, pformat(document.__dict__) + return output def publish(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', argv=None, usage=None, description=None, option_spec=None): - """A convenience function; set up & run a `Publisher`.""" + """ + A convenience function for file I/O front-ends; set up & run a + `Publisher`. + """ pub = Publisher(reader, parser, writer) if reader is None: pub.set_reader(reader_name, parser, parser_name) diff --git a/docutils/frontend.py b/docutils/frontend.py index c833940b4..cb0a11681 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -69,9 +69,12 @@ class OptionParser(optik.OptionParser): ('Send the output of system messages (warnings) to <file>.', ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}), ('Specify the encoding of input text. Default is locale-dependent.', - ['--encoding', '-e'], {'metavar': '<name>'}), - ('Specify the language of input text (ISO 639 2-letter identifier. ' - 'Default is "en" (English).', + ['--input-encoding', '-i'], {'metavar': '<name>'}), + ('Specify the encoding for output. Default is UTF-8.', + ['--output-encoding', '-o'], + {'metavar': '<name>', 'default': 'utf-8'}), + ('Specify the language of input text (ISO 639 2-letter identifier).' + ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': '<name>'}), ("Show this program's version number and exit.", diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 47c5b2fab..053527faf 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -49,7 +49,7 @@ class Reader(Component): self.set_parser(parser_name) self.source = None - """Path to the source of raw input.""" + """`docutils.io` IO object, source of input data.""" self.input = None """Raw text input; either a single string or, for more complex cases, @@ -65,31 +65,12 @@ class Reader(Component): if not self.parser: self.parser = parser self.options = options - self.scan() # may modify self.parser, depending on input + # May modify self.parser, depending on input: + self.input = self.source.read(self) self.parse() self.transform() return self.document - def scan(self): - """Override to read `self.input` from `self.source`.""" - raise NotImplementedError('subclass must override this method') - - def scan_file(self, source): - """ - Scan a single file and return the raw data. - - Parameter `source` may be: - - (a) a file-like object, which is read directly; - (b) a path to a file, which is opened and then read; or - (c) `None`, which implies `sys.stdin`. - """ - if hasattr(source, 'read'): - return source.read() - if self.source: - return open(source).read() - return sys.stdin.read() - def parse(self): """Parse `self.input` into a document tree.""" self.document = self.new_document() diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index e6108f569..24a8074e7 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -32,6 +32,3 @@ class Reader(readers.Reader): frontmatter.DocInfo, references.Footnotes, references.Hyperlinks,) - - def scan(self): - self.input = self.scan_file(self.source) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 3c20068d4..24d1cf384 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -38,7 +38,7 @@ class Writer(Component): """Language module for the document.""" destination = None - """Where to write the document.""" + """`docutils.io` IO object; where to write the document.""" transforms = () """Ordered list of transform classes (each with a ``transform()`` method). @@ -56,7 +56,8 @@ class Writer(Component): self.destination = destination self.transform() self.translate() - self.record() + output = self.destination.write(self.output) + return output def transform(self): """Run all of the transforms defined for this Writer.""" @@ -78,31 +79,6 @@ class Writer(Component): """ raise NotImplementedError('subclass must override this method') - def record(self): - """Override to record `document` to `destination`.""" - raise NotImplementedError('subclass must override this method') - - def recordfile(self, output, destination): - """ - Write `output` to a single file. - - Parameters: - - - `output`: Data to write. - - `destination`: one of: - - (a) a file-like object, which is written directly; - (b) a path to a file, which is opened and then written; or - (c) `None`, which implies `sys.stdout`. - """ - output = output.encode('utf-8') # @@@ temporary; must not hard-code - if hasattr(self.destination, 'write'): - destination.write(output) - elif self.destination: - open(self.destination, 'w').write(output) - else: - sys.stdout.write(output) - _writer_aliases = { 'html': 'html4css1', diff --git a/docutils/writers/pseudoxml.py b/docutils/writers/pseudoxml.py index a0cf5ea14..c1ba29347 100644 --- a/docutils/writers/pseudoxml.py +++ b/docutils/writers/pseudoxml.py @@ -27,9 +27,6 @@ class Writer(writers.Writer): def translate(self): self.output = self.document.pformat() - def record(self): - self.recordfile(self.output, self.destination) - def supports(self, format): """This writer supports all format-specific elements.""" return 1 -- cgit v1.2.1 From bd73da1949ce273e385463736c868a9d72b32d0d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:16:26 +0000 Subject: - Added support for input and output encodings and for internal Unicode support. - Added support for the ``docutils.io.IO`` class & subclasses. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@219 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 380179651..97cc8b6ea 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -45,20 +45,17 @@ class Writer(writers.Writer): self.document.walkabout(visitor) self.output = visitor.astext() - def record(self): - self.recordfile(self.output, self.destination) - class HTMLTranslator(nodes.NodeVisitor): - xml_declaration = '<?xml version="1.0" encoding="UTF-8"?>\n' + xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' doctype = '<!DOCTYPE html' \ ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' \ ' SYSTEM "http://www.w3.org/TR/xhtml1/DTD/' \ 'xhtml1-transitional.dtd">\n' html_head = '<html lang="%s">\n<head>\n' content_type = '<meta http-equiv="Content-Type" content="text/html; ' \ - 'charset=UTF-8">\n' + 'charset=%s">\n' generator = '<meta name="generator" content="Docutils: ' \ 'http://docutils.sourceforge.net/">\n' stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' @@ -67,10 +64,10 @@ class HTMLTranslator(nodes.NodeVisitor): nodes.NodeVisitor.__init__(self, document) self.language = languages.get_language(document.options.language_code) self.head_prefix = [ - self.xml_declaration, # @@@ % output_encoding + self.xml_declaration % document.options.output_encoding, self.doctype, self.html_head % document.options.language_code, - self.content_type, # @@@ % output encoding + self.content_type % document.options.output_encoding, self.generator, self.stylesheet_link % document.options.stylesheet] self.head = [] @@ -97,7 +94,8 @@ class HTMLTranslator(nodes.NodeVisitor): def attval(self, text, transtable=string.maketrans('\n\r\t\v\f', ' ')): """Cleanse, encode, and return attribute value text.""" - return self.encode(text.translate(transtable)) + return self.encode( + text.encode('utf-8').translate(transtable).decode('utf-8')) def starttag(self, node, tagname, suffix='\n', infix='', **attributes): """ -- cgit v1.2.1 From 8772c081ae9e24fd5ee41211847ed9afc8cf1872 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:18:12 +0000 Subject: - Added support for input and output encodings and for internal Unicode support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@220 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 ++++++----- docutils/statemachine.py | 4 +++- docutils/utils.py | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 6f6367cdd..9324814a3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -25,7 +25,8 @@ import sys import os import re import xml.dom.minidom -from types import IntType, SliceType, StringType, TupleType, ListType +from types import IntType, SliceType, StringType, UnicodeType, \ + TupleType, ListType from UserString import MutableString @@ -298,7 +299,7 @@ class Element(Node): return len(self.children) def __getitem__(self, key): - if isinstance(key, StringType): + if isinstance(key, UnicodeType) or isinstance(key, StringType): return self.attributes[key] elif isinstance(key, IntType): return self.children[key] @@ -310,8 +311,8 @@ class Element(Node): 'an attribute name string') def __setitem__(self, key, item): - if isinstance(key, StringType): - self.attributes[key] = item + if isinstance(key, UnicodeType) or isinstance(key, StringType): + self.attributes[str(key)] = item elif isinstance(key, IntType): item.parent = self self.children[key] = item @@ -325,7 +326,7 @@ class Element(Node): 'an attribute name string') def __delitem__(self, key): - if isinstance(key, StringType): + if isinstance(key, UnicodeType) or isinstance(key, StringType): del self.attributes[key] elif isinstance(key, IntType): del self.children[key] diff --git a/docutils/statemachine.py b/docutils/statemachine.py index e6502d3cd..e985e1f89 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -1028,7 +1028,9 @@ def string2lines(astring, tab_width=8, convert_whitespace=0): - `convert_whitespace`: convert form feeds and vertical tabs to spaces? """ if convert_whitespace: - astring = astring.translate(_whitespace_conversion_table) + encoded = astring.encode('utf-8') + converted = encoded.translate(_whitespace_conversion_table) + astring = converted.decode('utf-8') return [s.expandtabs(tab_width) for s in astring.splitlines()] def extract_indented(lines, until_blank=0, strip_indent=1): diff --git a/docutils/utils.py b/docutils/utils.py index 161526fa0..c2418d91c 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -237,7 +237,7 @@ def extract_attributes(field_list): if len(field) != 2: raise BadAttributeError( 'extension attribute field may not contain field arguments') - name = field[0].astext().lower() + name = str(field[0].astext().lower()) body = field[1] if len(body) == 0: data = None @@ -275,7 +275,7 @@ def assemble_attribute_dict(attlist, attspec): try: attributes[name] = convertor(value) except (ValueError, TypeError), detail: - raise detail.__class__('(attribute "%s", value "%r") %s' + raise detail.__class__('(attribute "%s", value "%s") %s' % (name, value, detail)) return attributes -- cgit v1.2.1 From eca63d0c7af69af08c0acc8e54b1d8e9fc97b88d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:19:02 +0000 Subject: - Fixed bug with literal blocks. - Added support for input and output encodings and for internal Unicode support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@221 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 543bc1108..aff499625 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -353,7 +353,7 @@ class RSTState(StateWS): if data[-2:] == '::': if len(data) == 2: return [], 1 - elif data[-3] == ' ': + elif data[-3] in ' \n': text = data[:-3].rstrip() else: text = data[:-1] @@ -445,8 +445,6 @@ class Inliner: uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" urilast = r"""[_~/\]a-zA-Z0-9]""" emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" - identity = string.maketrans('', '') - null2backslash = string.maketrans('\x00', '\\') patterns = Stuff( initial=re.compile( r""" @@ -970,8 +968,8 @@ class Body(RSTState): if ordinal is None: msg = self.reporter.error( ('Enumerated list start value invalid at line %s: ' - '%r (sequence %r)' % (self.state_machine.abs_line_number(), - text, sequence))) + '"%s" (sequence %r)' + % (self.state_machine.abs_line_number(), text, sequence))) self.parent += msg indented, line_offset, blank_finish = \ self.state_machine.get_known_indented(match.end()) @@ -984,8 +982,8 @@ class Body(RSTState): if ordinal != 1: msg = self.reporter.info( ('Enumerated list start value not ordinal-1 at line %s: ' - '%r (ordinal %s)' % (self.state_machine.abs_line_number(), - text, ordinal))) + '"%s" (ordinal %s)' + % (self.state_machine.abs_line_number(), text, ordinal))) self.parent += msg enumlist = nodes.enumerated_list() self.parent += enumlist @@ -1167,8 +1165,8 @@ class Body(RSTState): optlist.append(option) else: raise MarkupError('wrong numer of option tokens (=%s), ' - 'should be 1 or 2: %r' % (len(tokens), - optionstring)) + 'should be 1 or 2: "%s"' % (len(tokens), + optionstring)) return optlist def doctest(self, match, context, next_state): @@ -2221,6 +2219,6 @@ def escape2null(text): def unescape(text, restore_backslashes=0): """Return a string with nulls removed or restored to backslashes.""" if restore_backslashes: - return text.translate(Inliner.null2backslash) + return text.replace('\x00', '\\') else: - return text.translate(Inliner.identity, '\x00') + return ''.join(text.split('\x00')) -- cgit v1.2.1 From 4118aed4449182d2c89612f83ed0d36e0562ed57 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:21:01 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@222 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 ++ docs/dev/todo.txt | 104 +++++++++++++++++---- .../test_rst/test_directives/test_contents.py | 2 +- .../test_rst/test_directives/test_images.py | 2 +- .../test_parsers/test_rst/test_enumerated_lists.py | 18 ++-- test/test_parsers/test_rst/test_literal_blocks.py | 13 +++ 6 files changed, 116 insertions(+), 31 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e917e1af1..f25ebde7a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -48,6 +48,9 @@ General: 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: @@ -67,12 +70,16 @@ Specific: command-line support. - Added ``Publisher.process_command_line()`` and ``.set_options()`` methods. + - Reworked I/O model for ``docutils.io`` wrappers. * 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. +* docutils/io.py: Added to project; uniform API for a variety of input + output mechanisms. + * docutils/nodes.py: - Added ``TreeCopyVisitor`` class. @@ -132,6 +139,7 @@ Specific: - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. - Fixed a footnote bug. + - Fixed a bug with literal blocks. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 69f5770d4..4ba150157 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -57,9 +57,6 @@ Bugs __ rst/problems.html#tables -- The "::" before the table above should be removed completely from - the output. A single ":" is being left behind. - General ------- @@ -107,26 +104,64 @@ General - Implement a specialized PEP/HTML writer? Or implement a generic `templating system`_, with PEP/HTML as one application? -- @@ Add support for character set encodings on input & output, Unicode - internally. +- @@ Add _`support for character set encodings` on input & output, + Unicode internally. To determine the encoding, use these heuristics in order: - Try the encoding specified by a command-line option, if any. - + - Try the encoding specified by an "encoding" directive, and/or an "encoding" field in field lists & PEP headers, if any. See the misc.encoding_ directive below. - - Try ASCII. - - - Try the locale default encoding. - + - Try the locale's encoding. + - Try UTF-8. - - - Try Latin-1. - - From Skip Montanaro's "Using Unicode in Python":: + + - Try platform-specific encodings: CP-1252 on Windows, Mac-Roman on + MacOS, perhaps Latin-9 (iso-8859-15) otherwise. + + Some questions: + + - Does the application have to call + ``locale.setlocale(locale.LC_ALL, '')``, and if so, where? Is it OK + to call setlocale from within the decoding function, or should it be + left up to the client application? + + - Should I use the result of ``locale.getlocale()``? On + Win2K/Python2.2.1, I get this:: + + >>> import locale + >>> locale.getlocale() + (None, None) + >>> locale.getdefaultlocale() + ('en_US', 'cp1252') + + Looks good so far. + + >>> locale.setlocale(locale.LC_ALL, '') + 'English_United States.1252' + >>> locale.getlocale() + ['English_United States', '1252'] + + "1252"? What happened to the "cp"? + + >>> s='abcd' + >>> s.decode('1252') + Traceback (most recent call last): + File "<stdin>", line 1, in ? + LookupError: unknown encoding + + How can I use ``locale.getlocale()`` when it doesn't return a + known encoding? Or put another way, how can I get a known + encoding out of ``locale.getlocale()``? + + - Does ``locale.getdefaultlocale()[1]`` reliably produce the + platform-specific encoding? + + From Skip Montanaro's `Using Unicode in Python`_ ("Console Input" + section):: def encode_heuristically(s, enc=None): "try interpreting s using several possible encodings" @@ -150,6 +185,28 @@ General # punt return s + .. _Using Unicode in Python: + http://manatee.mojam.com/~skip/unicode/unicode/ + + Windows CP-1252 and MacOS Mac-Roman are full 8-bit encodings, so + there's no point trying anything after them; they'll match any byte + string. UTF-8 is almost a full 8-bit encoding; it only uses up to + 0xFD but 0xFE & 0xFF are likely unused by most texts in other + encodings anyhow (a notable exception is UTF-16, in which 0xFEFF is + used as a "byte order mark"; but we'll ignore UTF-16 as it's + incompatible with ASCII). UTF-8 does have the advantage of a + verifyable encoding scheme, which is unlikely to be achieved by + accident in an 8-bit text. (I assume the UTF-8 codec verifies the + encoding.) So it makes sense to check for UTF-8 before + platform-dependent encodings (like CP-1252). + + ISO-8859-15 is an update of ISO-8859-1, and they share the same code + space (0x00-0x7F, 0xA0-0xFF), so there's no point in checking for + both. If one succeeds, the other one inevitably will too. + + `Introduction to i18n`_ by Tomohiro KUBOTA is a good reference + (http://www.debian.org/doc/manuals/intro-i18n/). + - Need a Unicode -> HTML entities codec for HTML writer? - Distributor/filer object passed to Writer, equivalent passed to @@ -177,11 +234,14 @@ General Perhaps subclasses of a single class, a abstraction for file/string/etc. reading & writing. - - Storage - - IO + - Storage (thus InputStorage/OutputStorage) + - IO (SourceIO/DestIO; InputIO/OutputIO) Implement as a single module (``docutils/storage.py``)? Or as a - subpackage (``docutils/storage/*.py``)? + subpackage (``docutils/storage/*.py``)? Decision: use a single + module for now, possibly switching to a package if it gets too big. + + See `support for character set encodings`_ above. - Fix tests to run standalone. I.e., allow:: @@ -191,6 +251,9 @@ General Raises an exception with path processing on GNU/Linux (but only sometimes?). +- Perhaps the ``Component.supports`` method should deal with + individual features ("meta" etc.) instead of formats ("html" etc.)? + Specification ------------- @@ -648,7 +711,10 @@ HTML Writer - If a list's items contain single paragraphs only, omit the <P> tags? Recursively? (if item == list whose items are single paragraphs - only...) + only...) Optional, with "--compact-lists" and "--no-compact-lists"? + Should only simple lists be compacted, or should the first paragraph + of all list items lack a <p> (perhaps "--compact-all-lists" and + "--compact-simple-lists")? Front-Ends @@ -740,8 +806,6 @@ a common option-processing module, as described below. conflicts) to splitting common and component-specific options apart. -- Implement command-line options. Common options: --encoding=name. - Project Policies ================ diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 452a6d222..43b13c4f7 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -139,7 +139,7 @@ totest['contents'] = [ <paragraph> Error in "contents" directive attributes at line 1: invalid attribute value: - (attribute "depth", value "'two'") invalid literal for int(): two. + (attribute "depth", value "two") invalid literal for int(): two. <literal_block> .. contents:: :depth: two diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index e49a2c3aa..bdaeb08e1 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -204,7 +204,7 @@ totest['images'] = [ <paragraph> Error in "image" directive attributes at line 1: invalid attribute value: - (attribute "scale", value "'fifty'") invalid literal for int(): fifty. + (attribute "scale", value "fifty") invalid literal for int(): fifty. <literal_block> .. image:: picture.png :scale: fifty diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index 75e6e28f8..319589fc1 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -89,7 +89,7 @@ Scrambled: Scrambled: <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 3: '3' (ordinal 3) + Enumerated list start value not ordinal-1 at line 3: "3" (ordinal 3) <enumerated_list enumtype="arabic" prefix="" start="3" suffix="."> <list_item> <paragraph> @@ -99,7 +99,7 @@ Scrambled: Enumerated list ends without a blank line; unexpected unindent at line 4. <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 4: '2' (ordinal 2) + Enumerated list start value not ordinal-1 at line 4: "2" (ordinal 2) <enumerated_list enumtype="arabic" prefix="" start="2" suffix="."> <list_item> <paragraph> @@ -135,7 +135,7 @@ Skipping item 3: Enumerated list ends without a blank line; unexpected unindent at line 5. <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 5: '4' (ordinal 4) + Enumerated list start value not ordinal-1 at line 5: "4" (ordinal 4) <enumerated_list enumtype="arabic" prefix="" start="4" suffix="."> <list_item> <paragraph> @@ -160,7 +160,7 @@ And again: Start with non-ordinal-1: <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 3: '0' (ordinal 0) + Enumerated list start value not ordinal-1 at line 3: "0" (ordinal 0) <enumerated_list enumtype="arabic" prefix="" start="0" suffix="."> <list_item> <paragraph> @@ -178,7 +178,7 @@ And again: And again: <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 10: '2' (ordinal 2) + Enumerated list start value not ordinal-1 at line 10: "2" (ordinal 2) <enumerated_list enumtype="arabic" prefix="" start="2" suffix="."> <list_item> <paragraph> @@ -323,7 +323,7 @@ iiii. iiii Enumerated list ends without a blank line; unexpected unindent at line 6. <system_message level="3" type="ERROR"> <paragraph> - Enumerated list start value invalid at line 6: 'iiii' (sequence 'lowerroman') + Enumerated list start value invalid at line 6: "iiii" (sequence 'lowerroman') <block_quote> <paragraph> iiii @@ -336,7 +336,7 @@ iiii. iiii Enumerated list ends without a blank line; unexpected unindent at line 9. <system_message level="3" type="ERROR"> <paragraph> - Enumerated list start value invalid at line 9: 'IVXLCDM' (sequence 'upperroman') + Enumerated list start value invalid at line 9: "IVXLCDM" (sequence 'upperroman') <block_quote> <paragraph> IVXLCDM @@ -473,7 +473,7 @@ iii. Item iii. Enumerated list ends without a blank line; unexpected unindent at line 12. <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 12: 'II' (ordinal 2) + Enumerated list start value not ordinal-1 at line 12: "II" (ordinal 2) <enumerated_list enumtype="upperroman" prefix="" start="2" suffix="."> <list_item> <paragraph> @@ -514,7 +514,7 @@ iii. Item iii. Enumerated list ends without a blank line; unexpected unindent at line 24. <system_message level="1" type="INFO"> <paragraph> - Enumerated list start value not ordinal-1 at line 24: 'ii' (ordinal 2) + Enumerated list start value not ordinal-1 at line 24: "ii" (ordinal 2) <enumerated_list enumtype="lowerroman" prefix="" start="2" suffix="."> <list_item> <paragraph> diff --git a/test/test_parsers/test_rst/test_literal_blocks.py b/test/test_parsers/test_rst/test_literal_blocks.py index 651733b09..376989b0f 100755 --- a/test/test_parsers/test_rst/test_literal_blocks.py +++ b/test/test_parsers/test_rst/test_literal_blocks.py @@ -128,6 +128,19 @@ A paragraph: :: ["""\ A paragraph: +:: + + A literal block. +""", +"""\ +<document> + <paragraph> + A paragraph: + <literal_block> + A literal block. +"""], +["""\ +A paragraph: :: A literal block. -- cgit v1.2.1 From 90bf36cbb768a40211d0bb87e29e7442f0f240b7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 28 Jun 2002 04:29:03 +0000 Subject: fixed link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@223 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4ba150157..d0fdd2871 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -204,8 +204,10 @@ General space (0x00-0x7F, 0xA0-0xFF), so there's no point in checking for both. If one succeeds, the other one inevitably will too. - `Introduction to i18n`_ by Tomohiro KUBOTA is a good reference - (http://www.debian.org/doc/manuals/intro-i18n/). + `Introduction to i18n`_ by Tomohiro KUBOTA is a good reference. + + .. _Introduction to i18n: + http://www.debian.org/doc/manuals/intro-i18n/ - Need a Unicode -> HTML entities codec for HTML writer? -- cgit v1.2.1 From ce2f906d0b60ee6836aacc32bf2922e338b8a314 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:39:38 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@225 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 5 +++++ docutils/io.py | 2 ++ 2 files changed, 7 insertions(+) diff --git a/docutils/__init__.py b/docutils/__init__.py index 0ea2f1803..52a9e500b 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -21,8 +21,13 @@ Modules: - frontend.py: Command-line and common 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. +- optik.py: Option parsing and command-line help; from Greg Ward's + http://optik.sf.net/ project, included for convenience. + - roman.py: Conversion to and from Roman numerals. Courtesy of Mark Pilgrim (http://diveintopython.org/). diff --git a/docutils/io.py b/docutils/io.py index 66845e7f7..689bf4d80 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -7,6 +7,8 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. +I/O classes provide a uniform API for low-level input and output. Subclasses +will exist for a variety of input/output mechanisms. """ __docformat__ = 'reStructuredText' -- cgit v1.2.1 From b1493cab0b638bf3706cb9968d04fe300d7c3f53 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:42:25 +0000 Subject: - In ``string2lines()``, changed whitespace normalizing translation table to regexp; restores Python 2.0 compatibility with Unicode. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@226 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index e985e1f89..621be35b5 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -1012,9 +1012,8 @@ class TransitionCorrection(Exception): """ -_whitespace_conversion_table = string.maketrans('\v\f', ' ') - -def string2lines(astring, tab_width=8, convert_whitespace=0): +def string2lines(astring, tab_width=8, convert_whitespace=0, + whitespace=re.compile('[\v\f]')): """ Return a list of one-line strings with tabs expanded and no newlines. @@ -1028,9 +1027,7 @@ def string2lines(astring, tab_width=8, convert_whitespace=0): - `convert_whitespace`: convert form feeds and vertical tabs to spaces? """ if convert_whitespace: - encoded = astring.encode('utf-8') - converted = encoded.translate(_whitespace_conversion_table) - astring = converted.decode('utf-8') + astring = whitespace.sub(' ', astring) return [s.expandtabs(tab_width) for s in astring.splitlines()] def extract_indented(lines, until_blank=0, strip_indent=1): -- cgit v1.2.1 From c8ba33f6335505e047a030d9dacf2d3f01521719 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:44:28 +0000 Subject: - In ``HTMLTranslator.attval()``, changed whitespace normalizing translation table to regexp; restores Python 2.0 compatibility with Unicode. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@227 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 97cc8b6ea..4c8a6d9cc 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -92,10 +92,9 @@ class HTMLTranslator(nodes.NodeVisitor): return text def attval(self, text, - transtable=string.maketrans('\n\r\t\v\f', ' ')): - """Cleanse, encode, and return attribute value text.""" - return self.encode( - text.encode('utf-8').translate(transtable).decode('utf-8')) + whitespace=re.compile('[\n\r\t\v\f]')): + """Cleanse, HTML encode, and return attribute value text.""" + return self.encode(whitespace.sub(' ', text)) def starttag(self, node, tagname, suffix='\n', infix='', **attributes): """ -- cgit v1.2.1 From 6adf8d5e25be90964f922d5c9e5ca48aa9e7ac52 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:44:58 +0000 Subject: changed the title git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@228 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 89b222f6f..e58a4f306 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -1,6 +1,6 @@ -================================== - Docutils Document Tree Structure -================================== +============================ + The Docutils Document Tree +============================ :Author: David Goodger :Contact: goodger@users.sourceforge.net :Revision: $Revision$ -- cgit v1.2.1 From 42bbe4f0d9973579b84a38fb425351678d2540ef Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:47:29 +0000 Subject: Updated. Added text from pysource.txt and mailing list discussions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@229 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0258.txt | 878 +++++++++++++++++++++++++++++++------------------ 1 file changed, 563 insertions(+), 315 deletions(-) diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 4acff1039..9360fcf11 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -25,252 +25,49 @@ Abstract Specification - Docstring Extraction Rules - ========================== - - 1. What to examine: - - a) If the "__all__" variable is present in the module being - documented, only identifiers listed in "__all__" are - examined for docstrings. - - b) In the absense of "__all__", all identifiers are examined, - except those whose names are private (names begin with "_" - but don't begin and end with "__"). - - c) 1a and 1b can be overridden by a parameter or command-line - option. - - 2. Where: - - Docstrings are string literal expressions, and are recognized - in the following places within Python modules: - - a) At the beginning of a module, function definition, class - definition, or method definition, after any comments. This - is the standard for Python __doc__ attributes. - - b) Immediately following a simple assignment at the top level - of a module, class definition, or __init__ method - definition, after any comments. See "Attribute Docstrings" - below. - - c) Additional string literals found immediately after the - docstrings in (a) and (b) will be recognized, extracted, and - concatenated. See "Additional Docstrings" below. - - d) @@@ 2.2-style "properties" with attribute docstrings? - - 3. How: - - Whenever possible, Python modules should be parsed by Docutils, - not imported. There are security reasons for not importing - untrusted code. Information from the source is lost when using - introspection to examine an imported module, such as comments - and the order of definitions. Also, docstrings are to be - recognized in places where the bytecode compiler ignores string - literal expressions (2b and 2c above), meaning importing the - module will lose these docstrings. Of course, standard Python - parsing tools such as the "parser" library module may be used. - - When the Python source code for a module is not available - (i.e. only the .pyc file exists) or for C extension modules, to - access docstrings the module can only be imported, and any - limitations must be lived with. - - Since attribute docstrings and additional docstrings are ignored - by the Python bytecode compiler, no namespace pollution or runtime - bloat will result from their use. They are not assigned to - __doc__ or to any other attribute. The initial parsing of a - module may take a slight performance hit. - - - Attribute Docstrings - -------------------- - - (This is a simplified version of PEP 224 [2] by Marc-Andre - Lemberg.) - - A string literal immediately following an assignment statement is - interpreted by the docstring extration machinery as the docstring - of the target of the assignment statement, under the following - conditions: - - 1. The assignment must be in one of the following contexts: - - a) At the top level of a module (i.e., not nested inside a - compound statement such as a loop or conditional): a module - attribute. - - b) At the top level of a class definition: a class attribute. - - c) At the top level of the "__init__" method definition of a - class: an instance attribute. - - Since each of the above contexts are at the top level (i.e., in - the outermost suite of a definition), it may be necessary to - place dummy assignments for attributes assigned conditionally - or in a loop. - - 2. The assignment must be to a single target, not to a list or a - tuple of targets. - - 3. The form of the target: - - a) For contexts 1a and 1b above, the target must be a simple - identifier (not a dotted identifier, a subscripted - expression, or a sliced expression). - - b) For context 1c above, the target must be of the form - "self.attrib", where "self" matches the "__init__" method's - first parameter (the instance parameter) and "attrib" is a - simple indentifier as in 3a. - - Blank lines may be used after attribute docstrings to emphasize - the connection between the assignment and the docstring. - - Examples:: - - g = 'module attribute (module-global variable)' - """This is g's docstring.""" - - class AClass: - - c = 'class attribute' - """This is AClass.c's docstring.""" - - def __init__(self): - self.i = 'instance attribute' - """This is self.i's docstring.""" - - - Additional Docstrings - --------------------- - - (This idea was adapted from PEP 216, Docstring Format [3], by - Moshe Zadka.) - - Many programmers would like to make extensive use of docstrings - for API documentation. However, docstrings do take up space in - the running program, so some of these programmers are reluctant to - "bloat up" their code. Also, not all API documentation is - applicable to interactive environments, where __doc__ would be - displayed. - - The docstring processing system's extraction tools will - concatenate all string literal expressions which appear at the - beginning of a definition or after a simple assignment. Only the - first strings in definitions will be available as __doc__, and can - be used for brief usage text suitable for interactive sessions; - subsequent string literals and all attribute docstrings are - ignored by the Python bytecode compiler and may contain more - extensive API information. - - Example:: - - def function(arg): - """This is __doc__, function's docstring.""" - """ - This is an additional docstring, ignored by the bytecode - compiler, but extracted by the Docutils. - """ - pass - - Issue: This breaks "from __future__ import" statements in Python - 2.1 for multiple module docstrings. The Python Reference Manual - specifies: - - A future statement must appear near the top of the module. - The only lines that can appear before a future statement are: - - * the module docstring (if any), - * comments, - * blank lines, and - * other future statements. - - Resolution? - - 1. Should we search for docstrings after a __future__ statement? - Very ugly. - - 2. Redefine __future__ statements to allow multiple preceeding - string literals? - - 3. Or should we not even worry about this? There shouldn't be - __future__ statements in production code, after all. Will - modules with __future__ statements simply have to put up with - the single-docstring limitation? - - - Choice of Docstring Format - ========================== - - Rather than force everyone to use a single docstring format, - multiple input formats are allowed by the processing system. A - special variable, __docformat__, may appear at the top level of a - module before any function or class definitions. Over time or - through decree, a standard format or set of formats should emerge. - - The __docformat__ variable is a string containing the name of the - format being used, a case-insensitive string matching the input - parser's module or package name (i.e., the same name as required - to "import" the module or package), or a registered alias. If no - __docformat__ is specified, the default format is "plaintext" for - now; this may be changed to the standard format once determined. - - The __docformat__ string may contain an optional second field, - separated from the format name (first field) by a single space: a - case-insensitive language identifier as defined in RFC 1766 [4]. - A typical language identifier consists of a 2-letter language code - from ISO 639 [5] (3-letter codes used only if no 2-letter code - exists; RFC 1766 is currently being revised to allow 3-letter - codes). If no language identifier is specified, the default is - "en" for English. The language identifier is passed to the parser - and can be used for language-dependent markup features. - - Docutils Project Model ====================== :: - +--------------------------+ - | Docutils: | - | docutils.core.Publisher, | - | docutils.core.publish() | - +--------------------------+ - / \ - / \ - 1,3,5 / \ 6,8 - +--------+ +--------+ - | READER | =======================> | WRITER | - +--------+ +--------+ - // \ / \ - // \ / \ - 2 // 4 \ 7 / 9 \ - +--------+ +------------+ +------------+ +--------------+ - | PARSER |...| reader | | writer |...| DISTRIBUTOR? | - +--------+ | transforms | | transforms | | | - | | | | | - one file | - | - docinfo | | - styling | | - many files | - | - titles | | - writer- | | - objects in | - | - linking | | specific | | memory | - | - lookups | | - etc. | +--------------+ - | - reader- | +------------+ - | specific | - | - parser- | - | specific | - | - layout | - | - etc. | - +------------+ - - The numbers indicate the path a document would take through the + +--------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish() | + +--------------------------+ + / \ + / \ + 1,3,5,7 / \ 8,10 + +--------+ +--------+ + | READER | =========================> | WRITER | + +--------+ +--------+ + / || \ / \ + / || \ / \ + 2 / 4 || \ 6 9 / \ 11 + +-----+ +--------+ +-------------+ +------------+ +-----+ + | I/O | | PARSER |...| reader | | writer | | I/O | + +-----+ +--------+ | transforms | | transforms | +-----+ + | | | | + | - docinfo | | - styling | + | - titles | | - writer- | + | - linking | | specific | + | - lookups | | - etc. | + | - reader- | +------------+ + | specific | + | - parser- | + | specific | + | - layout | + | (stylist) | + | - etc. | + +-------------+ + + The numbers indicate the path a document's data takes through the code. Double-width lines between reader & parser and between - reader & writer, indicating that data sent along these paths - should be standard (pure & unextended) Docutils doc trees. - Single-width lines signify that internal tree extensions or - completely unrelated representations are possible, but they must - be supported internally at both ends. + reader & writer indicate that data sent along these paths should + be standard (pure & unextended) Docutils doc trees. Single-width + lines signify that internal tree extensions or completely + unrelated representations are possible, but they must be supported + at both ends. Publisher @@ -279,8 +76,12 @@ Specification The "docutils.core" module contains a "Publisher" facade class and "publish" convenience function. Publisher encapsulates the high-level logic of a Docutils system. The Publisher.publish() - method passes its input to its Reader, then passes the resulting - document tree through its Writer to its destination. + method first calls its Reader, which reads data from its source + I/O, parses and transforms the data, and returns it. + Publisher.publish() then passes the resulting document tree to its + Writer, which further transforms the document before translating + it to the final output format and writing the formatted data to + its destination I/O. Calling the "publish" function (or instantiating a "Publisher" object) with component names will result in default behavior. For @@ -304,24 +105,28 @@ Specification Most Readers will have to be told what parser to use. So far (see the list of examples below), only the Python Source Reader - (PySource) will be able to determine the parser on its own. + (PySource; still incomplete) will be able to determine the parser + on its own. Responsibilities: - - Do raw input on the source ("Reader.scan()"). + - Get input text from the source I/O. - - Pass the raw text to the parser, along with a fresh doctree - root ("Reader.parse()"). + - Pass the input text to the parser, along with a fresh doctree + root. - - Run transforms over the doctree(s) ("Reader.transform()"). + - Run transforms over the doctree(s). Examples: - - Standalone/Raw/Plain: Just read a text file and process it. The - reader needs to be told which parser to use. Parser-specific - readers? + - Standalone (Raw/Plain): Just read a text file and process it. + The reader needs to be told which parser to use. - - Python Source: See `Python Source Reader`_ above. + The "Standalone Reader" has been implemented in + docutils/readers/standalone.py. + + - Python Source: See `Python Source Reader`_ below. This Reader + is currently in development in the Docutils sandbox. - Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. @@ -329,6 +134,9 @@ Specification URIs. Either interpret PEPs' indented sections or convert existing PEPs to reStructuredText (or both?). + The "PEP Reader" is being implemented in + docutils/readers/pep.py. + - Wiki: Global reference lookups of "wiki links" incorporated into transforms. (CamelCase only or unrestricted?) Lazy indentation? @@ -357,7 +165,8 @@ Specification populate the doctree by parsing the input text. Example: The only parser implemented so far is for the - reStructuredText markup. + reStructuredText markup. It is implemented in the + docutils/parsers/rst/ package. Transforms @@ -378,14 +187,29 @@ Specification structure into another, or adding new structures based on the doctree and/or external data. - Examples (in "docutils.transforms"): + Examples (in the docutils/transforms/ package): - - frontmatter.DocInfo: conversion of document metadata + - frontmatter.DocInfo: Conversion of document metadata (bibliographic information). - - references.Hyperlinks: resolution of hyperlinks. + - references.Hyperlinks: Resolution of hyperlinks. + + - parts.Contents: Generates a table of contents for a document. + + - document.Merger: Combining multiple populated doctrees into one + (not yet implemented or fully understood). + + - document.Splitter: Splits a document into a tree-structure of + subdocuments, perhaps by section. It will have to transform + references appropriately. (Neither implemented not remotely + understood.) - - document.Merger: combining multiple populated doctrees into one. + - universal.Pending: Handles transforms that must be executed at + specific stages of processing. + + - components.Filter: Includes or excludes elements which depend on + a specific Docutils component (triggered by the + universal.Pending transform). Writers @@ -393,7 +217,7 @@ Specification Writers produce the final output (HTML, XML, TeX, etc.). Writers translate the internal document tree structure into the final data - format, possibly running output-specific transforms_ first. + format, possibly running Writer-specific transforms_ first. Each writer is a module or package exporting a "Writer" class with a "write" method. The base "Writer" class can be found in the @@ -407,61 +231,78 @@ Specification - Transform references into format-native forms. - - Write output to the destination (possibly via a "Distributor"). + - Write the translated output to the destination I/O. Examples: - - XML: Various forms, such as DocBook. Also, raw doctree XML. + - XML: Various forms, such as: + + - DocBook (being implemented in the Docutils sandbox). + + - Raw doctree XML (accessible via "doctree.asdom().toxml()"; no + Writer component implemented yet). + + - HTML (XHTML implemented as docutils/writers/html4css1.py). - - HTML + - PDF (a ReportLabs interface is being developed in the Docutils + sandbox). - TeX + - Docutils-native pseudo-XML (implemented as + docutils/writers/pseudoxml.py, used for testing). + - Plain text - reStructuredText? - Distributors - ------------ + I/O + --- - Distributors will exist for each method of storing the results of - processing: + I/O classes provide a uniform API for low-level input and output. + Subclasses will exist for a variety of input/output mechanisms. - - In a single file on disk. + I/O classes are currently in the preliminary stages; there's a lot + of work yet to be done. Issues: - - In a tree of directories and files on disk. + - Looking at the list of writers, it seems that only HTML would + require anything other than monolithic output. Perhaps "Writer" + variants, one for each output distribution type? - - In a single tree-shaped data structure in memory. + - How to represent a multi-file document (files & directories) in + the API? - - Some other set of data structures in memory. + Responsibilities: - @@@ Distributors are currently just an idea; they may or may not - be practical. Issues: + - Read data from the input source and/or write data to the output + destination. - Is it better for the writer to control the distributor, or - vice versa? Or should they be equals? + Examples of input sources: - Looking at the list of writers, it seems that only HTML would - require anything other than monolithic output. Perhaps merge - the HTML "distributor" into "writer" variants? + - A single file on disk or a stream (implemented as + docutils.io.FileIO). - Perhaps translator/writer instead of writer/distributor? Or - "filer" instead of "distributor"? + - Multiple files on disk (MultiFileIO?). - Responsibilities: + - Python source files: modules and packages. - - Do raw output to the destination. + - Python strings, as received from a client application + (implemented as docutils.io.StringIO). - - Transform references per incarnation (method of distribution). + Examples of output destinations: - Examples: + - A single file on disk or a stream (implemented as + docutils.io.FileIO). - - Single file. + - A tree of directories and files on disk. - - Multiple files & directories. + - A Python string, returned to a client application (implemented + as docutils.io.StringIO). - - Objects in memory. + - A single tree-shaped data structure in memory. + + - Some other set of data structures in memory. Docutils Package Structure @@ -469,13 +310,25 @@ Specification - Package "docutils". + - Class "Component" is a base class for Docutils components. + - Module "docutils.core" contains facade class "Publisher" and - convenience function "publish()". See `Publisher API`_ below. + convenience function "publish()". See `Publisher`_ above. + + - Module "docutils.frontend" provides command-line and option + processing for Docutils front-ends. + + - Module "docutils.io" provides a uniform API for low-level + input and output. - Module "docutils.nodes" contains the Docutils document tree element class library plus Visitor pattern base classes. See `Document Tree`_ below. + - Module "docutils.optik" provides option parsing and + command-line help; from Greg Ward's http://optik.sf.net/ + project, included for convenience. + - Module "docutils.roman" contains Roman numeral conversion routines. @@ -507,9 +360,12 @@ Specification module by name or alias. Class "Reader" is the base class of specific readers. (docutils/readers/__init__.py) - - Module "docutils.readers.standalone": reads independent + - Module "docutils.readers.standalone" reads independent document files. + - Module "docutils.readers.pep" reads PEPs (Python Enhancement + Proposals). + - Readers to be added for: Python source code (structure & docstrings), PEPs, email, FAQ, and perhaps Wiki and others. @@ -526,8 +382,8 @@ Specification Markup Language document tree writer for HTML 4.01 and CSS1. - Writers to be added: HTML 3.2 or 4.01-loose, XML (various - forms, such as DocBook and the raw internal doctree), TeX, - plaintext, reStructuredText, and perhaps others. + forms, such as DocBook and the raw internal doctree), PDF, + TeX, plaintext, reStructuredText, and perhaps others. - Package "docutils.transforms": tree transform classes. @@ -565,19 +421,39 @@ Specification Docutils, in the interfaces between components; it is defined in the docutils.nodes module. It is not required that this data structure be used *internally* by any of the components, just - *between* components. This data structure is similar to a DOM - tree whose schema is documented in an XML DTD (eXtensible Markup - Language Document Type Definition), which comes in two parts: - - - the Docutils Generic DTD, docutils.dtd [6], and - - - the OASIS Exchange Table Model, soextbl.dtd [7]. + *between* components. + + Custom node types are allowed, providing that either (A) a + transform converts them to standard Docutils nodes before they + reach the Writer proper, or (B) the custom node is explicitly + supported by certain Writers, and is wrapped in a filtered + "pending" node. An example of condition A is the `Python Source + Reader`_ (see below), where a "stylist" transform converts custom + nodes. The HTML <meta> tag is an example of condition B; it is + supported by the HTML Writer but not by others. The + reStructuredText ".. meta::" directive creates a "pending" node, + which contains knowledge that the embedded "meta" node can only be + handled by HTML-compatible writers. The "pending" node is + resolved by the "transforms.components.Filter" transform, which + checks that the calling writer supports HTML; if it doesn't, the + "meta" node is removed from the document. + + The document tree data structure is similar to a DOM tree, but + with specific node names (classes) instead of DOM's generic nodes. + The schema is documented in an XML DTD (eXtensible Markup Language + Document Type Definition), which comes in two parts: + + - the Docutils Generic DTD, docutils.dtd [2], and + + - the OASIS Exchange Table Model, soextbl.dtd [3]. The DTD defines a rich set of elements, suitable for many input and output formats. The DTD retains all information necessary to reconstruct the original input text, or a reasonable facsimile thereof. + See "The Docutils Document Tree" [4] for details (incomplete). + Error Handling ============== @@ -595,13 +471,13 @@ Specification messages are not reported. - Level-2, "WARNING": an issue that should be addressed. If - ignored, there may be unpredictable problems with the output. - Typically level-2 system messages are reported but do not halt - processing + ignored, there may be minor problems with the output. Typically + level-2 system messages are reported but do not halt processing - Level-3, "ERROR": a major issue that should be addressed. If - ignored, the output will contain errors. Typically level-3 - system messages are reported but do not halt processing + ignored, the output will contain unpredictable errors. + Typically level-3 system messages are reported but do not halt + processing - Level-4, "SEVERE": a critical error that must be addressed. Typically level-4 system messages are turned into exceptions @@ -610,9 +486,376 @@ Specification Although the initial message levels were devised independently, they have a strong correspondence to VMS error condition severity - levels [8]; the names in quotes for levels 1 through 4 were + levels [5]; the names in quotes for levels 1 through 4 were borrowed from VMS. Error handling has since been influenced by - the log4j project [9]. + the log4j project [6]. + + + Python Source Reader + ==================== + + The Python Source Reader ("PySource") is a major and non-trivial + Docutils component, currently under experimental development in + the Docutils sandbox. High-level design issues are presented + here. + + + Processing Model + ---------------- + + This model will evolve over time, incorporating experience and + discoveries. + + 1. The PySource Reader uses an I/O class to read in some Python + packages and modules, into a tree of strings. + + 2. The Python modules are parsed, converting the tree of strings + into a tree of abstract syntax trees. + + 3. The abstract syntax trees are converted into an internal + representation of the packages/modules. Docstrings are + extracted, as well as code structure details. See `AST + Mining`_ below. Namespaces are constructed for lookup in step + 6. + + 4. One at a time, the docstrings are parsed, producing standard + Docutils doctrees. + + 5. PySource assembles all the individual docstrings' doctrees into + a Python-specific custom Docutils tree parallelling the + package/module/class structure; this is a custom + Reader-specific internal representation (see the Docutils + Python Source DTD [7]). Namespaces must be merged: Python + identifiers, hyperlink targets. + + 6. Cross-references from docstrings (interpreted text) to Python + identifiers are resolved according to the Python namespace + lookup rules. See `Identifier Cross-References`_ below. + + 7. A "Stylist" transform is applied to the custom doctree, custom + nodes are rendered using standard nodes as primitives, and a + standard document tree is emitted. See `Stylist Transforms`_ + below. + + 8. Other transforms are applied to the standard doctree. + + 9. The standard doctree is sent to a Writer, which translates the + document into a concrete format (HTML, PDF, etc.). + + 10. The Writer uses an I/O class to write the resulting data to + its destination (disk file, directories and files, etc.). + + + AST Mining + ---------- + + Abstract Syntax Tree mining code will be written that scans a + parsed Python module, and returns an ordered tree containing the + names, docstrings (including attribute and additional docstrings; + see below), and additional info (in parentheses below) of all of + the following objects: + + - packages + - modules + - module attributes (+ initial values) + - classes (+ inheritance) + - class attributes (+ initial values) + - instance attributes (+ initial values) + - methods (+ parameters & defaults) + - functions (+ parameters & defaults) + + (Extract comments too? For example, comments at the start of a + module would be a good place for bibliographic field lists.) + + In order to evaluate interpreted text cross-references, namespaces + for each of the above will also be required. + + See python-dev/docstring-develop thread "AST mining", started on + 2001-08-14. + + + Docstring Extraction Rules + -------------------------- + + 1. What to examine: + + a) If the "__all__" variable is present in the module being + documented, only identifiers listed in "__all__" are + examined for docstrings. + + b) In the absense of "__all__", all identifiers are examined, + except those whose names are private (names begin with "_" + but don't begin and end with "__"). + + c) 1a and 1b can be overridden by a parameter or command-line + option. + + 2. Where: + + Docstrings are string literal expressions, and are recognized + in the following places within Python modules: + + a) At the beginning of a module, function definition, class + definition, or method definition, after any comments. This + is the standard for Python __doc__ attributes. + + b) Immediately following a simple assignment at the top level + of a module, class definition, or __init__ method + definition, after any comments. See "Attribute Docstrings" + below. + + c) Additional string literals found immediately after the + docstrings in (a) and (b) will be recognized, extracted, and + concatenated. See "Additional Docstrings" below. + + d) @@@ 2.2-style "properties" with attribute docstrings? + + 3. How: + + Whenever possible, Python modules should be parsed by Docutils, + not imported. There are several reasons: + + - Importing untrusted code is inherently insecure. + + - Information from the source is lost when using introspection + to examine an imported module, such as comments and the order + of definitions. + + - Docstrings are to be recognized in places where the bytecode + compiler ignores string literal expressions (2b and 2c + above), meaning importing the module will lose these + docstrings. + + Of course, standard Python parsing tools such as the "parser" + library module should be used. + + When the Python source code for a module is not available + (i.e. only the .pyc file exists) or for C extension modules, to + access docstrings the module can only be imported, and any + limitations must be lived with. + + Since attribute docstrings and additional docstrings are ignored + by the Python bytecode compiler, no namespace pollution or runtime + bloat will result from their use. They are not assigned to + __doc__ or to any other attribute. The initial parsing of a + module may take a slight performance hit. + + + Attribute Docstrings + ```````````````````` + + (This is a simplified version of PEP 224 [8] by Marc-Andre + Lemberg.) + + A string literal immediately following an assignment statement is + interpreted by the docstring extration machinery as the docstring + of the target of the assignment statement, under the following + conditions: + + 1. The assignment must be in one of the following contexts: + + a) At the top level of a module (i.e., not nested inside a + compound statement such as a loop or conditional): a module + attribute. + + b) At the top level of a class definition: a class attribute. + + c) At the top level of the "__init__" method definition of a + class: an instance attribute. + + Since each of the above contexts are at the top level (i.e., in + the outermost suite of a definition), it may be necessary to + place dummy assignments for attributes assigned conditionally + or in a loop. + + 2. The assignment must be to a single target, not to a list or a + tuple of targets. + + 3. The form of the target: + + a) For contexts 1a and 1b above, the target must be a simple + identifier (not a dotted identifier, a subscripted + expression, or a sliced expression). + + b) For context 1c above, the target must be of the form + "self.attrib", where "self" matches the "__init__" method's + first parameter (the instance parameter) and "attrib" is a + simple indentifier as in 3a. + + Blank lines may be used after attribute docstrings to emphasize + the connection between the assignment and the docstring. + + Examples:: + + g = 'module attribute (module-global variable)' + """This is g's docstring.""" + + class AClass: + + c = 'class attribute' + """This is AClass.c's docstring.""" + + def __init__(self): + self.i = 'instance attribute' + """This is self.i's docstring.""" + + + Additional Docstrings + ````````````````````` + + (This idea was adapted from PEP 216, Docstring Format [9], by + Moshe Zadka.) + + Many programmers would like to make extensive use of docstrings + for API documentation. However, docstrings do take up space in + the running program, so some of these programmers are reluctant to + "bloat up" their code. Also, not all API documentation is + applicable to interactive environments, where __doc__ would be + displayed. + + The docstring processing system's extraction tools will + concatenate all string literal expressions which appear at the + beginning of a definition or after a simple assignment. Only the + first strings in definitions will be available as __doc__, and can + be used for brief usage text suitable for interactive sessions; + subsequent string literals and all attribute docstrings are + ignored by the Python bytecode compiler and may contain more + extensive API information. + + Example:: + + def function(arg): + """This is __doc__, function's docstring.""" + """ + This is an additional docstring, ignored by the bytecode + compiler, but extracted by the Docutils. + """ + pass + + Issue: This breaks "from __future__ import" statements in Python + 2.1 for multiple module docstrings. The Python Reference Manual + specifies: + + A future statement must appear near the top of the module. + The only lines that can appear before a future statement are: + + * the module docstring (if any), + * comments, + * blank lines, and + * other future statements. + + Resolution? + + 1. Should we search for docstrings after a __future__ statement? + Very ugly. + + 2. Redefine __future__ statements to allow multiple preceeding + string literals? + + 3. Or should we not even worry about this? There shouldn't be + __future__ statements in production code, after all. Will + modules with __future__ statements simply have to put up with + the single-docstring limitation? + + + Choice of Docstring Format + -------------------------- + + Rather than force everyone to use a single docstring format, + multiple input formats are allowed by the processing system. A + special variable, __docformat__, may appear at the top level of a + module before any function or class definitions. Over time or + through decree, a standard format or set of formats should emerge. + + The __docformat__ variable is a string containing the name of the + format being used, a case-insensitive string matching the input + parser's module or package name (i.e., the same name as required + to "import" the module or package), or a registered alias. If no + __docformat__ is specified, the default format is "plaintext" for + now; this may be changed to the standard format once determined. + + The __docformat__ string may contain an optional second field, + separated from the format name (first field) by a single space: a + case-insensitive language identifier as defined in RFC 1766 [10]. + A typical language identifier consists of a 2-letter language code + from ISO 639 [11] (3-letter codes used only if no 2-letter code + exists; RFC 1766 is currently being revised to allow 3-letter + codes). If no language identifier is specified, the default is + "en" for English. The language identifier is passed to the parser + and can be used for language-dependent markup features. + + + Identifier Cross-References + --------------------------- + + In Python docstrings, interpreted text is used to classify and + mark up program identifiers, such as the names of variables, + functions, classes, and modules. If the identifier alone is + given, its role is inferred implicitly according to the Python + namespace lookup rules. For functions and methods (even when + dynamically assigned), parentheses ('()') may be included:: + + This function uses `another()` to do its work. + + For class, instance and module attributes, dotted identifiers are + used when necessary. For example (using reStructuredText + markup):: + + class Keeper(Storer): + + """ + Extend `Storer`. Class attribute `instances` keeps track + of the number of `Keeper` objects instantiated. + """ + + instances = 0 + """How many `Keeper` objects are there?""" + + def __init__(self): + """ + Extend `Storer.__init__()` to keep track of instances. + + Keep count in `self.instances`, data in `self.data`. + """ + Storer.__init__(self) + self.instances += 1 + + self.data = [] + """Store data in a list, most recent last.""" + + def storedata(self, data): + """ + Extend `Storer.storedata()`; append new `data` to a + list (in `self.data`). + """ + self.data = data + + Each of the identifiers quoted with backquotes ("`") will become + references to the definitions of the identifiers themselves. + + + Stylist Transforms + ------------------ + + Stylist transforms are specialized transforms specific to a + Reader. The PySource Reader doesn't have to make any decisions as + to style; it just produces a logically constructed document tree, + parsed and linked, including custom node types. Stylist + transforms understand the custom nodes created by the Reader and + convert them into standard Docutils nodes. + + Multiple Stylist transforms may be implemented and one can be + chosen at runtime (through a "--style" or "--stylist" command-line + option). Each Stylist transform implements a different layout or + style; thus the name. They decouple the context-understanding + part of the Reader from the layout-generating part of processing, + resulting in a more flexible and robust system. This also serves + to "separate style from content", the SGML/XML ideal. + + By keeping the piece of code that does the styling small and + modular, it becomes much easier for people to roll their own + styles. The "barrier to entry" is too high with existing tools; + extracting the stylist code will lower the barrier considerably. References and Footnotes @@ -620,26 +863,31 @@ References and Footnotes [1] PEP 256, Docstring Processing System Framework, Goodger http://www.python.org/peps/pep-0256.html - [2] PEP 224, Attribute Docstrings, Lemburg - http://www.python.org/peps/pep-0224.html + [2] http://docutils.sourceforge.net/spec/docutils.dtd - [3] PEP 216, Docstring Format, Zadka - http://www.python.org/peps/pep-0216.html + [3] http://docutils.sourceforge.net/spec/soextblx.dtd - [4] http://www.rfc-editor.org/rfc/rfc1766.txt + [4] http://docutils.sourceforge.net/spec/doctree.txt - [5] http://lcweb.loc.gov/standards/iso639-2/englangn.html + [5] http://www.openvms.compaq.com:8000/73final/5841/ + 5841pro_027.html#error_cond_severity - [6] http://docutils.sourceforge.net/spec/docutils.dtd + [6] http://jakarta.apache.org/log4j/ - [7] http://docstring.sourceforge.net/spec/soextblx.dtd + [7] http://docutils.sourceforge.net/spec/pysource.dtd - [8] http://www.openvms.compaq.com:8000/73final/5841/ - 5841pro_027.html#error_cond_severity + [8] PEP 224, Attribute Docstrings, Lemburg + http://www.python.org/peps/pep-0224.html + + [9] PEP 216, Docstring Format, Zadka + http://www.python.org/peps/pep-0216.html + + [10] http://www.rfc-editor.org/rfc/rfc1766.txt + + [11] http://lcweb.loc.gov/standards/iso639-2/englangn.html - [9] http://jakarta.apache.org/log4j/ + [12] http://www.python.org/sigs/doc-sig/ - [10] http://www.python.org/sigs/doc-sig/ Project Web Site @@ -656,7 +904,7 @@ Copyright Acknowledgements This document borrows ideas from the archives of the Python - Doc-SIG [10]. Thanks to all members past & present. + Doc-SIG [12]. Thanks to all members past & present. -- cgit v1.2.1 From d171053fc76b894268ec44e0143e9a42ca36bc6d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:48:54 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@230 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 10 ++++++++++ docs/peps/pep-0287.txt | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index f25ebde7a..c24f0d10a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -110,6 +110,8 @@ Specific: - 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: @@ -188,9 +190,14 @@ Specific: - 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. * docutils/writers/pseudoxml.py: Renamed from pprint.py. +* spec/doctree.txt: Changed the title to "The Docutils Document Tree". + * spec/docutils.dtd: - Added ``decoration``, ``header``, and ``footer`` elements. @@ -210,6 +217,9 @@ Specific: - 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. diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index ecfa3186c..51ce5762a 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -703,23 +703,25 @@ Questions & Answers 11. I want to write all my strings in Unicode. Will anything break? - The parser will fully support Unicode. It may not yet, but - only because nobody's gotten around to implementing or testing - Unicode support. Contributions are always welcome! + The parser fully supports Unicode. Docutils supports + arbitrary input encodings. 12. Why does the community need a new structured text design? The existing structured text designs are deficient, for the - reasons given in "Rationale" above. + reasons given in "Rationale" above. reStructuredText aims to + be a complete markup syntax, within the limitations of the + "readable plaintext" medium. 13. What is wrong with existing documentation methodologies? What existing methodologies? For Python docstrings, there is **no** official standard markup format, let alone a - documentation methodology. The question of methodology is at - a much higher level than syntax (what this PEP addresses), - potentially much more controversial and difficult to resolve, - and is intentionally left out of this discussion. + documentation methodology, akin to JavaDoc. The question of + methodology is at a much higher level than syntax (which this + PEP addresses). It is potentially much more controversial and + difficult to resolve, and is intentionally left out of this + discussion. References & Footnotes -- cgit v1.2.1 From 7478c5e11f04e31b322d4b9db4173297e1e8408e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 00:52:19 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@231 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 +++ docs/dev/todo.txt | 37 ++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index c24f0d10a..497cbc292 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -208,6 +208,9 @@ Specific: * 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: - Minor edits. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index d0fdd2871..ab8b92cb9 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -63,15 +63,23 @@ General - Document! - - Internal module documentation. + - Internal module documentation (docstrings). - - User docs. + - Implementation docs. + + - spec/doctree.txt: Doctree nodes (DTD element) semantics: + + - External (public) attributes (node.attributes). + - Internal attributes (node.*). + - Linking mechanism. + + - How a Writer works & how to write one - - Doctree nodes (DTD element) semantics: + - Howto: Transforms - - External (public) attributes (node.attributes). - - Internal attributes (node.*). - - Linking mechanism. + - Howto: Directives + + - User docs. - Refactor @@ -104,8 +112,8 @@ General - Implement a specialized PEP/HTML writer? Or implement a generic `templating system`_, with PEP/HTML as one application? -- @@ Add _`support for character set encodings` on input & output, - Unicode internally. +- @@ (Done.) Add _`support for character set encodings` on input & + output, Unicode internally. To determine the encoding, use these heuristics in order: @@ -211,11 +219,12 @@ General - Need a Unicode -> HTML entities codec for HTML writer? -- Distributor/filer object passed to Writer, equivalent passed to - Reader, to provide I/O access with a uniform API? (Names for input - object: inputter, sourcer, scanner.) Simple vs. complex I/O - structure: single file or string, vs. directory/package or tree of - strings. Simple string I/O is default? +- (Done, in io.py.) Distributor/filer object passed to Writer, + equivalent passed to Reader, to provide I/O access with a uniform + API? (Names for input object: inputter, sourcer, scanner.) Simple + vs. complex I/O structure: single file or string, + vs. directory/package or tree of strings. Simple file I/O is + default. - Name ideas: importer/exporter. Perhaps reader/writer should be applied to lower-level tasks? "PySource Reader" or "PySource @@ -286,6 +295,8 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +- Clean up the code; refactor as required. + - Add motivation sections for constructs in spec. - Allow very long titles (on two or more lines)? -- cgit v1.2.1 From c06d0f016cf4f539db28a4ea6142855cc7bb92aa Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 23:07:42 +0000 Subject: Applied patch from Simon Budig, simplifying regexps by with symbolic names. Also, Inliner.groups and Body.explicit.groups have been removed. The patch pointed out a bug in interpreted text parsing code, to be resolved. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@232 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 198 ++++++++++++++++++----------------------- 1 file changed, 89 insertions(+), 109 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index aff499625..ffce6171b 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -402,10 +402,6 @@ class Inliner: self.parent = parent pattern = self.patterns.initial dispatch = self.dispatch - start = self.groups.initial.start - 1 - backquote = self.groups.initial.backquote - 1 - refend = self.groups.initial.refend - 1 - fnend = self.groups.initial.fnend - 1 remaining = escape2null(text) processed = [] unprocessed = [] @@ -413,11 +409,11 @@ class Inliner: while remaining: match = pattern.search(remaining) if match: - groups = match.groups() - before, inlines, remaining, sysmessages = \ - dispatch[groups[start] or groups[backquote] - or groups[refend] - or groups[fnend]](self, match, lineno) + groupdict = match.groupdict() + method = dispatch[groupdict["start"] or groupdict["backquote"] + or groupdict["refend"] or groupdict["fnend"]] + before, inlines, remaining, sysmessages = method(self, match, + lineno) unprocessed.append(before) messages += sysmessages if inlines: @@ -434,14 +430,12 @@ class Inliner: openers = '\'"([{<' closers = '\'")]}>' - start_string_prefix = (r'(?:(?<=^)|(?<=[-/: \n%s]))' - % re.escape(openers)) - end_string_suffix = (r'(?:(?=$)|(?=[-/:.,;!? \n%s]))' - % re.escape(closers)) + start_string_prefix = (r'((?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) + end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n%s]))' % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' non_whitespace_after = r'(?![ \n])' - simplename = r'[a-zA-Z0-9](?:[-_.a-zA-Z0-9]*[a-zA-Z0-9])?' + simplename = r'[a-zA-Z0-9]([-_.a-zA-Z0-9]*[a-zA-Z0-9])?' uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" urilast = r"""[_~/\]a-zA-Z0-9]""" emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" @@ -450,7 +444,7 @@ class Inliner: r""" %s # start-string prefix ( - ( # start-strings only (group 2): + (?P<start> # start-strings only: \*\* # strong | \* # emphasis @@ -464,27 +458,27 @@ class Inliner: ) %s # no whitespace after | # *OR* - ( # whole constructs (group 3): - (%s) # reference name (4) - (__?) # end-string (5) + (?P<whole> # whole constructs: + (?P<refname>%s) # reference name + (?P<refend>__?) # end-string | \[ # footnote_reference or # citation_reference start - ( # label (group 6): + (?P<footnotelabel> # label: [0-9]+ # manually numbered | # *OR* - \#(?:%s)? # auto-numbered (w/ label?) + \#(%s)? # auto-numbered (w/ label?) | # *OR* \* # auto-symbol | # *OR* - (%s) # citation reference (group 7) + (?P<citationlabel>%s) # citation reference ) - (\]_) # end-string (group 8) + (?P<fnend>\]_) # end-string ) %s # end-string suffix | # *OR* - ((?::%s:)?) # optional role (group 9) - ( # start-string (group 10) + (?P<role>(:%s:)?) # optional role + (?P<backquote> # start-string ` # interpreted text # or phrase reference (?!`) # but not literal @@ -505,9 +499,9 @@ class Inliner: strong=re.compile(non_whitespace_escape_before + r'(\*\*)' + end_string_suffix), interpreted_or_phrase_ref=re.compile( - '%s(`(:%s:|__?)?)%s' % (non_whitespace_escape_before, - simplename, - end_string_suffix)), + '%s(`(?P<suffix>:%s:|__?)?)%s' % (non_whitespace_escape_before, + simplename, + end_string_suffix)), literal=re.compile(non_whitespace_before + '(``)' + end_string_suffix), target=re.compile(non_whitespace_escape_before @@ -518,33 +512,33 @@ class Inliner: uri=re.compile( r""" %s # start-string prefix - ( - ( # absolute URI (group 2) - ( # scheme (http, ftp, mailto) - [a-zA-Z][a-zA-Z0-9.+-]* # (group 3) + (?P<whole> + (?P<absolute> # absolute URI + (?P<scheme> # scheme (http, ftp, mailto) + [a-zA-Z][a-zA-Z0-9.+-]* ) : - (?: - (?: # either: - (?://?)? # hierarchical URI + ( + ( # either: + (//?)? # hierarchical URI %s* # URI characters %s # final URI char ) - (?: # optional query + ( # optional query \?%s* # URI characters %s # final URI char )? - (?: # optional fragment + ( # optional fragment \#%s* # URI characters %s # final URI char )? ) ) | # *OR* - ( # email address (group 4) - %s+(?:\.%s+)* # name + (?P<email> # email address + %s+(\.%s+)* # name @ # at - %s+(?:\.%s*)* # host + %s+(\.%s*)* # host %s # final URI char ) ) @@ -553,11 +547,6 @@ class Inliner: uric, urilast, emailc, emailc, emailc, emailc, urilast, end_string_suffix,), re.VERBOSE)) - groups = Stuff(initial=Stuff(start=2, whole=3, refname=4, refend=5, - footnotelabel=6, citationlabel=7, - fnend=8, role=9, backquote=10), - interpreted_or_phrase_ref=Stuff(suffix=2), - uri=Stuff(whole=1, absolute=2, scheme=3, email=4)) def quoted_start(self, match): """Return 1 if inline markup start-string is 'quoted', 0 if not.""" @@ -581,8 +570,8 @@ class Inliner: def inline_obj(self, match, lineno, pattern, nodeclass, restore_backslashes=0): string = match.string - matchstart = match.start(self.groups.initial.start) - matchend = match.end(self.groups.initial.start) + matchstart = match.start('start') + matchend = match.end('start') if self.quoted_start(match): return (string[:matchend], [], string[matchend:], [], '') endmatch = pattern.search(string[matchend:]) @@ -621,13 +610,11 @@ class Inliner: def interpreted_or_phrase_ref(self, match, lineno): pattern = self.patterns.interpreted_or_phrase_ref - rolegroup = self.groups.initial.role - backquote = self.groups.initial.backquote string = match.string - matchstart = match.start(backquote) - matchend = match.end(backquote) - rolestart = match.start(rolegroup) - role = match.group(rolegroup) + matchstart = match.start('backquote') + matchend = match.end('backquote') + rolestart = match.start('role') + role = match.group('role') position = '' if role: role = role[1:-1] @@ -680,13 +667,12 @@ class Inliner: def interpreted(self, before, after, endmatch, role, position, lineno, escaped, rawsource, text): - suffix = self.groups.interpreted_or_phrase_ref.suffix - if endmatch.group(suffix): + if endmatch.group('suffix'): if role: msg = self.reporter.warning('Multiple roles in interpreted ' 'text at line %s.' % lineno) return (before + rawsource, [], after, [msg]) - role = endmatch.group(suffix)[1:-1] + role = endmatch.group('suffix')[1:-1] position = 'suffix' if role: atts = {'role': role, 'position': position} @@ -743,9 +729,9 @@ class Inliner: Handles `nodes.footnote_reference` and `nodes.citation_reference` elements. """ - label = match.group(self.groups.initial.footnotelabel) + label = match.group('footnotelabel') refname = normalize_name(label) - if match.group(self.groups.initial.citationlabel): + if match.group('citationlabel'): refnode = nodes.citation_reference('[%s]_' % label, refname=refname) refnode += nodes.Text(label) @@ -767,16 +753,15 @@ class Inliner: refnode['refname'] = refname self.document.note_footnote_ref(refnode) string = match.string - matchstart = match.start(self.groups.initial.whole) - matchend = match.end(self.groups.initial.whole) + matchstart = match.start('whole') + matchend = match.end('whole') return (string[:matchstart], [refnode], string[matchend:], []) def reference(self, match, lineno, anonymous=None): - referencename = match.group(self.groups.initial.refname) + referencename = match.group('refname') refname = normalize_name(referencename) - referencenode = nodes.reference( - referencename + match.group(self.groups.initial.refend), - referencename) + referencenode = nodes.reference(referencename + match.group('refend'), + referencename) if anonymous: referencenode['anonymous'] = 1 self.document.note_anonymous_ref(referencenode) @@ -784,22 +769,21 @@ class Inliner: referencenode['refname'] = refname self.document.note_refname(referencenode) string = match.string - matchstart = match.start(self.groups.initial.whole) - matchend = match.end(self.groups.initial.whole) + matchstart = match.start('whole') + matchend = match.end('whole') return (string[:matchstart], [referencenode], string[matchend:], []) def anonymous_reference(self, match, lineno): return self.reference(match, lineno, anonymous=1) def standalone_uri(self, match, lineno): - scheme = self.groups.uri.scheme - if not match.group(scheme) or urischemes.schemes.has_key( - match.group(scheme).lower()): - if match.group(self.groups.uri.email): + if not match.group('scheme') or urischemes.schemes.has_key( + match.group('scheme').lower()): + if match.group('email'): addscheme = 'mailto:' else: addscheme = '' - text = match.group(self.groups.uri.whole) + text = match.group('whole') unescaped = unescape(text, 0) return [nodes.reference(unescape(text, 1), unescaped, refuri=addscheme + unescaped)] @@ -1289,54 +1273,52 @@ class Body(RSTState): explicit.patterns = Stuff( target=re.compile(r""" - (?: - _ # anonymous target - | # *OR* - (`?) # optional open quote - (?![ `]) # first char. not space or backquote - ( # reference name + ( + _ # anonymous target + | # *OR* + (?P<quote>`?) # optional open quote + (?![ `]) # first char. not space or + # backquote + (?P<name> # reference name .+? ) - %s # not whitespace or escape - \1 # close quote if open quote used + %s # not whitespace or escape + (?P=quote) # close quote if open quote used ) - %s # not whitespace or escape - : # end of reference name - (?:[ ]+|$) # followed by whitespace + %s # not whitespace or escape + : # end of reference name + ([ ]+|$) # followed by whitespace """ % (Inliner.non_whitespace_escape_before, Inliner.non_whitespace_escape_before), re.VERBOSE), reference=re.compile(r""" - (?: - (%s)_ # simple reference name - | # *OR* - ` # open backquote - (?![ ]) # not space - (.+?) # hyperlink phrase - %s # not whitespace or escape - `_ # close backquote, reference mark + ( + (?P<simple>%s)_ # simple reference name + | # *OR* + ` # open backquote + (?![ ]) # not space + (?P<phrase>.+?) # hyperlink phrase + %s # not whitespace or escape + `_ # close backquote, + # reference mark ) - $ # end of string + $ # end of string """ % (Inliner.simplename, Inliner.non_whitespace_escape_before,), re.VERBOSE), substitution=re.compile(r""" - (?: - (?![ ]) # first char. not space - (.+?) # substitution text - %s # not whitespace or escape - \| # close delimiter + ( + (?![ ]) # first char. not space + (?P<name>.+?) # substitution text + %s # not whitespace or escape + \| # close delimiter ) - (?:[ ]+|$) # followed by whitespace + ([ ]+|$) # followed by whitespace """ % Inliner.non_whitespace_escape_before, re.VERBOSE),) - explicit.groups = Stuff( - target=Stuff(quote=1, name=2), - reference=Stuff(simple=1, phrase=2), - substitution=Stuff(name=1)) def footnote(self, match): indented, indent, offset, blank_finish = \ @@ -1382,7 +1364,6 @@ class Body(RSTState): def hyperlink_target(self, match): pattern = self.explicit.patterns.target - namegroup = self.explicit.groups.target.name lineno = self.state_machine.abs_line_number() block, indent, offset, blank_finish = \ self.state_machine.get_first_known_indented( @@ -1408,7 +1389,7 @@ class Body(RSTState): refname = self.is_reference(reference) if refname: target = nodes.target(blocktext, '', refname=refname) - self.add_target(targetmatch.group(namegroup), '', target) + self.add_target(targetmatch.group('name'), '', target) self.document.note_indirect_target(target) return [target], blank_finish nodelist = [] @@ -1423,7 +1404,7 @@ class Body(RSTState): else: unescaped = unescape(reference) target = nodes.target(blocktext, '') - self.add_target(targetmatch.group(namegroup), unescaped, target) + self.add_target(targetmatch.group('name'), unescaped, target) nodelist.append(target) return nodelist, blank_finish @@ -1431,8 +1412,7 @@ class Body(RSTState): match = self.explicit.patterns.reference.match(normalize_name(reference)) if not match: return None - return unescape(match.group(self.explicit.groups.reference.simple) - or match.group(self.explicit.groups.reference.phrase)) + return unescape(match.group('simple') or match.group('phrase')) def add_target(self, targetname, refuri, target): if targetname: @@ -1475,7 +1455,7 @@ class Body(RSTState): if not block[0]: del block[0] offset += 1 - subname = subdefmatch.group(self.explicit.groups.substitution.name) + subname = subdefmatch.group('name') name = normalize_name(subname) substitutionnode = nodes.substitution_definition( blocktext, name=name, alt=subname) @@ -1592,13 +1572,13 @@ class Body(RSTState): \* # auto-symbol footnote ) \] - (?:[ ]+|$) # whitespace or end of line + ([ ]+|$) # whitespace or end of line """ % Inliner.simplename, re.VERBOSE)), (citation, re.compile(r""" \.\.[ ]+ # explicit markup start \[(%s)\] # citation label - (?:[ ]+|$) # whitespace or end of line + ([ ]+|$) # whitespace or end of line """ % Inliner.simplename, re.VERBOSE)), (hyperlink_target, re.compile(r""" @@ -1617,7 +1597,7 @@ class Body(RSTState): \.\.[ ]+ # explicit markup start (%s) # directive name :: # directive delimiter - (?:[ ]+|$) # whitespace or end of line + ([ ]+|$) # whitespace or end of line """ % Inliner.simplename, re.VERBOSE))] def explicit_markup(self, match, context, next_state): -- cgit v1.2.1 From cf75163e28905f66f2822c5e5bcc472940b0b40a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 23:09:04 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@233 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_inline_markup.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index 2212935a5..f142ad424 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -443,10 +443,8 @@ Invalid phrase reference: <paragraph> Invalid phrase reference: <paragraph> - :role: <problematic id="id2" refid="id1"> - ` - phrase reference`_ + :role:`phrase reference`_ <system_message backrefs="id2" id="id1" level="2" type="WARNING"> <paragraph> Mismatch: inline interpreted text start-string and role with phrase-reference end-string at line 3. @@ -461,9 +459,11 @@ Invalid phrase reference: <paragraph> Invalid phrase reference: <paragraph> - <interpreted> - phrase reference - :role:_ + <problematic id="id2" refid="id1"> + `phrase reference`:role:_ + <system_message backrefs="id2" id="id1" level="2" type="WARNING"> + <paragraph> + Mismatch: inline interpreted text start-string and role with phrase-reference end-string at line 3. """], ["""\ `phrase reference_ without closing backquote -- cgit v1.2.1 From 39867aa9d565d6f741a9764a906f54287ebc7bdb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Jun 2002 23:19:05 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@235 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 497cbc292..8bb5e3f87 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,14 +17,14 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - Aahz, David Ascher, Fred Drake, Dethe Elza, Jim Fulton, Peter - Funk, Engelbert Gruber, Doug Hellmann, Juergen Hermann, Tony Ibbs, - Alan Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, - Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, - Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Mark - Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli Schlaepfer, tav, Bob - Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward - Welbourne, Ka-Ping Yee, Moshe Zadka + Aahz, David Ascher, Simon Budig, Fred Drake, Dethe Elza, Jim + Fulton, Peter Funk, Engelbert Gruber, Doug Hellmann, Juergen + Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, Garth Kidd, + Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, + Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim + Peters, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli + Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, + Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -142,6 +142,8 @@ Specific: ``/`` 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``. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. -- cgit v1.2.1 From 018f10690d622c0534a2815812ab50d7a5a973c5 Mon Sep 17 00:00:00 2001 From: richard <richard@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 1 Jul 2002 04:19:27 +0000 Subject: Added a quickie section on images. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@236 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickstart.txt | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index 1de7abf59..e2bda81fd 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -286,6 +286,40 @@ their name. To link to the Lists_ heading, I write "``Lists_``". If the heading has a space in it like `text styles`_, we need to quote the heading "```text styles`_``". +Images +------ + +(quickref__) + +__ quickref.html#directives + +To include an image in your document, you use the the ``image`` directive__. +For example:: + + .. image:: images/biohazard.png + +results in: + +.. image:: images/biohazard.png + +The ``images/biohazard.png`` part indicates the filname of the image you +wish to appear +in the document. There's no restriction placed on the image (format, size +etc). If the image is to appear in HTML and you wish to supply additional +information, you may:: + + .. image:: images/biohazard.png + :height: 100 + :width: 200 + :scale: 50 + :alt: alternate text + +See the full image directive documentation__ for more info. + +__ ../../spec/rst/directives.html +__ ../../spec/rst/directives.html#images + + What Next? ---------- -- cgit v1.2.1 From d0307b9ca6000b9b67a36d628b5d0fc9b83c5762 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 1 Jul 2002 13:58:31 +0000 Subject: not just PNG! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@237 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 +- docs/ref/rst/restructuredtext.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 8012ee9ed..d39f488c3 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -96,7 +96,7 @@ stripped of leading and trailing whitespace and joined together. Optionally, the image link block may end with a flat field list, the _`image attributes`. For example:: - .. image:: picture.png + .. image:: picture.jpeg :height: 100 :width: 200 :scale: 50 diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 3d90489d4..e26ce2a21 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1591,7 +1591,7 @@ available when processing the document. For example, here's how an image may be placed:: - .. image:: mylogo.png + .. image:: mylogo.jpeg A figure (a graphic with a caption) may placed like this:: -- cgit v1.2.1 From fbaab75dffd78697fd9fcd8cb747bed50d2773a1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 1 Jul 2002 13:59:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@238 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index ab8b92cb9..964c35b17 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -608,11 +608,12 @@ Directives (And arguably invalid, since in Japanese the word "haiku" contains three syllables.) - Directive/construct name alternatives: verse, addressblock, - address, lineblock, lines, multiline, freeform, keeplines, nowrap, - haiku, keepbreaks, linebreaks, obeylines, linewise, textblock, - textart, text, linetext. Current favorites: "line_block" for - element name, "lines" for directive name. + Directive/construct name alternatives: verse, address block, + address, line block, lines, multi-line, free-form, keep lines, + no-wrap, haiku, keep breaks, line breaks, obey lines, line-wise, + text block, text art, text, line text, line list. Current + favorites: "line_block" for element name, "lines" for directive + name. - _`body.example`: Examples; suggested by Simon Hefti. Semantics as per Docbook's "example"; admonition-style, numbered, reference, -- cgit v1.2.1 From 15717892479e478467487d48f4e2e5f43eb66d10 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:19:02 +0000 Subject: Added ``source_path`` & ``destination_path`` for later reference. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@239 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 73 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 689bf4d80..13f9b996c 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -23,17 +23,22 @@ class IO: Base class for abstract input/output wrappers. """ - source = None - destination = None - - def __init__(self, options, source=None, destination=None): - """ - :Parameters: - - `options`: a `docutils.optik.Values` object. - - `source`: identifies the source of input data. - - `destination`: identifies the destination for output data. - """ + def __init__(self, options, source=None, source_path=None, + destination=None, destination_path=None): self.options = options + """A `docutils.optik.Values` object.""" + + self.source = source + """The source of input data.""" + + self.source_path = source_path + """A text reference to the source.""" + + self.destination = destination + """The destination for output data.""" + + self.destination_path = destination_path + """A text reference to the destination.""" def __repr__(self): return '%s: source=%r, destination=%r' % (self.__class__, self.source, @@ -61,7 +66,7 @@ class IO: try: decoded = unicode(data, enc) return decoded - except UnicodeError: + except (UnicodeError, LookupError): pass raise UnicodeError( 'Unable to decode input data. Tried the following encodings: %s.' @@ -71,32 +76,34 @@ class IO: class FileIO(IO): """ - IO for single, simple files. + IO for single, simple file-like objects. """ - def __init__(self, options, source=None, destination=None): + def __init__(self, options, source=None, source_path=None, + destination=None, destination_path=None): """ :Parameters: - - `source`: one of (a) a file-like object, which is read directly; - (b) a path to a file, which is opened and then read; or (c) - `None`, which implies `sys.stdin`. - - `destination`: one of (a) a file-like object, which is written - directly; (b) a path to a file, which is opened and then - written; or (c) `None`, which implies `sys.stdout`. - """ - IO.__init__(self, options) - if hasattr(source, 'read'): - self.source = source - elif source is None: - self.source = sys.stdin - else: - self.source = open(source) - if hasattr(destination, 'write'): - self.destination = destination - elif destination is None: - self.destination = sys.stdout - else: - self.destination = open(destination, 'w') + - `source`: either a file-like object (which is read directly), or + `None` (which implies `sys.stdin` if no `source_path` given). + - `source_path`: a path to a file, which is opened and then read. + - `destination`: either a file-like object (which is written + directly) or `None` (which implies `sys.stdout` if no + `destination_path` given). + - `destination_path`: a path to a file, which is opened and then + written. + """ + IO.__init__(self, options, source, source_path, destination, + destination_path) + if source is None: + if source_path: + self.source = open(source_path) + else: + self.source = sys.stdin + if destination is None: + if destination_path: + self.destination = open(destination_path, 'w') + else: + self.destination = sys.stdout def read(self, reader): """ -- cgit v1.2.1 From 606baf1b20ec93778e127d90c11d60321ea2ae4e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:21:21 +0000 Subject: - Converted regexps from ``'%s' % var`` to ``'%(var)s' % locals()``. - Fixed a bug in ``Inliner.interpreted_or_phrase_ref()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@240 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 192 ++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 99 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ffce6171b..f3be937d6 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -400,18 +400,18 @@ class Inliner: self.reporter = memo.reporter self.document = memo.document self.parent = parent - pattern = self.patterns.initial + pattern_search = self.patterns.initial.search dispatch = self.dispatch remaining = escape2null(text) processed = [] unprocessed = [] messages = [] while remaining: - match = pattern.search(remaining) + match = pattern_search(remaining) if match: - groupdict = match.groupdict() - method = dispatch[groupdict["start"] or groupdict["backquote"] - or groupdict["refend"] or groupdict["fnend"]] + groups = match.groupdict() + method = dispatch[groups['start'] or groups['backquote'] + or groups['refend'] or groups['fnend']] before, inlines, remaining, sysmessages = method(self, match, lineno) unprocessed.append(before) @@ -437,12 +437,12 @@ class Inliner: non_whitespace_after = r'(?![ \n])' simplename = r'[a-zA-Z0-9]([-_.a-zA-Z0-9]*[a-zA-Z0-9])?' uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" - urilast = r"""[_~/\]a-zA-Z0-9]""" + urilast = r"""[_~/\]a-zA-Z0-9]""" # no punctuation emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" patterns = Stuff( initial=re.compile( r""" - %s # start-string prefix + %(start_string_prefix)s ( (?P<start> # start-strings only: \*\* # strong @@ -456,52 +456,53 @@ class Inliner: | \| # substitution_reference start ) - %s # no whitespace after + %(non_whitespace_after)s | # *OR* (?P<whole> # whole constructs: - (?P<refname>%s) # reference name - (?P<refend>__?) # end-string + (?P<refname>%(simplename)s) # reference name + (?P<refend>__?) # end-string | \[ # footnote_reference or # citation_reference start (?P<footnotelabel> # label: [0-9]+ # manually numbered | # *OR* - \#(%s)? # auto-numbered (w/ label?) + \#(%(simplename)s)? # auto-numbered (w/ label?) | # *OR* \* # auto-symbol | # *OR* - (?P<citationlabel>%s) # citation reference + (?P<citationlabel> + %(simplename)s) # citation reference ) (?P<fnend>\]_) # end-string ) - %s # end-string suffix + %(end_string_suffix)s | # *OR* - (?P<role>(:%s:)?) # optional role + (?P<role>(:%(simplename)s:)?) # optional role (?P<backquote> # start-string ` # interpreted text # or phrase reference (?!`) # but not literal ) - %s # no whitespace after + %(non_whitespace_after)s # no whitespace after ) - """ % (start_string_prefix, - non_whitespace_after, - simplename, - simplename, - simplename, - end_string_suffix, - simplename, - non_whitespace_after,), - re.VERBOSE), + """ % locals(), re.VERBOSE), emphasis=re.compile(non_whitespace_escape_before + r'(\*)' + end_string_suffix), strong=re.compile(non_whitespace_escape_before + r'(\*\*)' + end_string_suffix), interpreted_or_phrase_ref=re.compile( - '%s(`(?P<suffix>:%s:|__?)?)%s' % (non_whitespace_escape_before, - simplename, - end_string_suffix)), + r""" + %(non_whitespace_escape_before)s + ( + ` + (?P<suffix> + (?P<role>:%(simplename)s:)? + (?P<refend>__?)? + ) + ) + %(end_string_suffix)s + """ % locals(), re.VERBOSE), literal=re.compile(non_whitespace_before + '(``)' + end_string_suffix), target=re.compile(non_whitespace_escape_before @@ -511,7 +512,7 @@ class Inliner: + end_string_suffix), uri=re.compile( r""" - %s # start-string prefix + %(start_string_prefix)s (?P<whole> (?P<absolute> # absolute URI (?P<scheme> # scheme (http, ftp, mailto) @@ -521,32 +522,29 @@ class Inliner: ( ( # either: (//?)? # hierarchical URI - %s* # URI characters - %s # final URI char + %(uric)s* # URI characters + %(urilast)s # final URI char ) ( # optional query - \?%s* # URI characters - %s # final URI char + \?%(uric)s* + %(urilast)s )? ( # optional fragment - \#%s* # URI characters - %s # final URI char + \#%(uric)s* + %(urilast)s )? ) ) | # *OR* (?P<email> # email address - %s+(\.%s+)* # name - @ # at - %s+(\.%s*)* # host - %s # final URI char + %(emailc)s+(\.%(emailc)s+)* # name + @ # at + %(emailc)s+(\.%(emailc)s*)* # host + %(urilast)s # final URI char ) ) - %s # end-string suffix - """ % (start_string_prefix, uric, urilast, uric, urilast, - uric, urilast, emailc, emailc, emailc, emailc, urilast, - end_string_suffix,), - re.VERBOSE)) + %(end_string_suffix)s + """ % locals(), re.VERBOSE)) def quoted_start(self, match): """Return 1 if inline markup start-string is 'quoted', 0 if not.""" @@ -567,22 +565,21 @@ class Inliner: pass return 0 - def inline_obj(self, match, lineno, pattern, nodeclass, + def inline_obj(self, match, lineno, end_pattern, nodeclass, restore_backslashes=0): string = match.string matchstart = match.start('start') matchend = match.end('start') if self.quoted_start(match): return (string[:matchend], [], string[matchend:], [], '') - endmatch = pattern.search(string[matchend:]) + endmatch = end_pattern.search(string[matchend:]) if endmatch and endmatch.start(1): # 1 or more chars text = unescape(endmatch.string[:endmatch.start(1)], restore_backslashes) - rawsource = unescape(string[matchstart:matchend+endmatch.end(1)], - 1) + textend = matchend + endmatch.end(1) + rawsource = unescape(string[matchstart:textend], 1) return (string[:matchstart], [nodeclass(rawsource, text)], - string[matchend:][endmatch.end(1):], [], - endmatch.group(1)) + string[textend:], [], endmatch.group(1)) msg = self.reporter.warning( 'Inline %s start-string without end-string ' 'at line %s.' % (nodeclass.__name__, lineno)) @@ -609,7 +606,7 @@ class Inliner: return before, inlines, remaining, sysmessages def interpreted_or_phrase_ref(self, match, lineno): - pattern = self.patterns.interpreted_or_phrase_ref + end_pattern = self.patterns.interpreted_or_phrase_ref string = match.string matchstart = match.start('backquote') matchend = match.end('backquote') @@ -621,40 +618,44 @@ class Inliner: position = 'prefix' elif self.quoted_start(match): return (string[:matchend], [], string[matchend:], []) - endmatch = pattern.search(string[matchend:]) + endmatch = end_pattern.search(string[matchend:]) if endmatch and endmatch.start(1): # 1 or more chars + textend = matchend + endmatch.end() + if endmatch.group('role'): + if role: + msg = self.reporter.warning( + 'Multiple roles in interpreted text at line %s (both ' + 'prefix and suffix present; only one allowed).' + % lineno) + text = unescape(string[rolestart:textend], 1) + prb = self.problematic(text, text, msg) + return string[:rolestart], [prb], string[textend:], [msg] + role = endmatch.group('suffix')[1:-1] + position = 'suffix' escaped = endmatch.string[:endmatch.start(1)] text = unescape(escaped, 0) - rawsource = unescape( - string[match.start():matchend+endmatch.end()], 1) + rawsource = unescape(string[matchstart:textend], 1) if rawsource[-1:] == '_': if role: msg = self.reporter.warning( - 'Mismatch: inline interpreted text start-string and' - ' role with phrase-reference end-string at line %s.' - % lineno) - text = unescape(string[matchstart:matchend], 1) - rawsource = unescape(string[matchstart:matchend], 1) - prb = self.problematic(text, rawsource, msg) - return (string[:matchstart], [prb], string[matchend:], - [msg]) - return self.phrase_ref( - string[:matchstart], string[matchend:][endmatch.end():], - text, rawsource) + 'Mismatch: both interpreted text role %s and ' + 'reference suffix at line %s.' % (position, lineno)) + text = unescape(string[rolestart:textend], 1) + prb = self.problematic(text, text, msg) + return string[:rolestart], [prb], string[textend:], [msg] + return self.phrase_ref(string[:matchstart], string[textend:], + rawsource, text) else: - return self.interpreted( - string[:rolestart], string[matchend:][endmatch.end():], - endmatch, role, position, lineno, - escaped, rawsource, text) + return self.interpreted(string[:rolestart], string[textend:], + rawsource, text, role, position) msg = self.reporter.warning( 'Inline interpreted text or phrase reference start-string ' 'without end-string at line %s.' % lineno) text = unescape(string[matchstart:matchend], 1) - rawsource = unescape(string[matchstart:matchend], 1) - prb = self.problematic(text, rawsource, msg) + prb = self.problematic(text, text, msg) return string[:matchstart], [prb], string[matchend:], [msg] - def phrase_ref(self, before, after, text, rawsource): + def phrase_ref(self, before, after, rawsource, text): refname = normalize_name(text) reference = nodes.reference(rawsource, text) if rawsource[-2:] == '__': @@ -665,15 +666,7 @@ class Inliner: self.document.note_refname(reference) return before, [reference], after, [] - def interpreted(self, before, after, endmatch, role, position, lineno, - escaped, rawsource, text): - if endmatch.group('suffix'): - if role: - msg = self.reporter.warning('Multiple roles in interpreted ' - 'text at line %s.' % lineno) - return (before + rawsource, [], after, [msg]) - role = endmatch.group('suffix')[1:-1] - position = 'suffix' + def interpreted(self, before, after, rawsource, text, role, position): if role: atts = {'role': role, 'position': position} else: @@ -797,7 +790,8 @@ class Inliner: """ Check each of the patterns in `self.implicit` for a match, and dispatch to the stored method for the pattern. Recursively check the - text before and after the match. + text before and after the match. Return a list of `nodes.Text` and + inline element nodes. """ if not text: return [] @@ -805,13 +799,20 @@ class Inliner: match = pattern.search(text) if match: try: - return (self.implicit_inline(text[:match.start()], lineno) + return (self.text(text[:match.start()]) + dispatch(self, match, lineno) + self.implicit_inline(text[match.end():], lineno)) except MarkupMismatch: pass return [nodes.Text(unescape(text))] + def text(self, text): + """Return a list containing one `nodes.Text` node or nothing.""" + if not text: + return [] + return [nodes.Text(unescape(text))] + + dispatch = {'*': emphasis, '**': strong, '`': interpreted_or_phrase_ref, @@ -1282,43 +1283,35 @@ class Body(RSTState): (?P<name> # reference name .+? ) - %s # not whitespace or escape + %(non_whitespace_escape_before)s (?P=quote) # close quote if open quote used ) - %s # not whitespace or escape + %(non_whitespace_escape_before)s : # end of reference name ([ ]+|$) # followed by whitespace - """ - % (Inliner.non_whitespace_escape_before, - Inliner.non_whitespace_escape_before), - re.VERBOSE), + """ % vars(Inliner), re.VERBOSE), reference=re.compile(r""" ( - (?P<simple>%s)_ # simple reference name + (?P<simple>%(simplename)s)_ | # *OR* ` # open backquote (?![ ]) # not space (?P<phrase>.+?) # hyperlink phrase - %s # not whitespace or escape + %(non_whitespace_escape_before)s `_ # close backquote, # reference mark ) $ # end of string - """ % - (Inliner.simplename, - Inliner.non_whitespace_escape_before,), - re.VERBOSE), + """ % vars(Inliner), re.VERBOSE), substitution=re.compile(r""" ( (?![ ]) # first char. not space (?P<name>.+?) # substitution text - %s # not whitespace or escape + %(non_whitespace_escape_before)s \| # close delimiter ) ([ ]+|$) # followed by whitespace - """ % - Inliner.non_whitespace_escape_before, - re.VERBOSE),) + """ % vars(Inliner), re.VERBOSE),) def footnote(self, match): indented, indent, offset, blank_finish = \ @@ -1409,7 +1402,8 @@ class Body(RSTState): return nodelist, blank_finish def is_reference(self, reference): - match = self.explicit.patterns.reference.match(normalize_name(reference)) + match = self.explicit.patterns.reference.match( + normalize_name(reference)) if not match: return None return unescape(match.group('simple') or match.group('phrase')) -- cgit v1.2.1 From 426ed7ac0d7dc20b8dcd6df6c91b5f3627078227 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:22:14 +0000 Subject: Fixed source reference; bug pointed out by Simon Budig. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@241 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 053527faf..fbd0ee8fc 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -86,7 +86,8 @@ class Reader(Component): def new_document(self): """Create and return a new empty document tree (root node).""" document = utils.new_document(self.options) - document['source'] = self.source + if self.source.source_path: + document['source'] = self.source.source_path return document -- cgit v1.2.1 From 9830aac6db5c209b7b022e61dbdcb76540b14acf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:23:50 +0000 Subject: Rearranged footer. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@242 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index e9553cb13..e4ad65b48 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -57,6 +57,14 @@ class Decorations(Transform): options = self.document.options if options.generator or options.datestamp or options.source_link: text = [] + if options.source_link and self.document.hasattr('source'): + text.extend([ + nodes.reference('', 'View document source', + refuri=self.document['source']), + nodes.Text('. ')]) + if options.datestamp: + datestamp = time.strftime(options.datestamp, time.gmtime()) + text.append(nodes.Text('Generated on: ' + datestamp + '. ')) if options.generator: text.extend([ nodes.Text('Generated by '), @@ -66,14 +74,6 @@ class Decorations(Transform): nodes.reference('', 'reStructuredText', refuri='http://' 'docutils.sourceforge.net/rst.html'), nodes.Text(' source. ')]) - if options.source_link: - text.extend([ - nodes.reference('', 'View document source', - refuri=self.document['source']), - nodes.Text('. ')]) - if options.datestamp: - datestamp = time.strftime(options.datestamp, time.gmtime()) - text.append(nodes.Text('Date: ' + datestamp + '. ')) footer = nodes.footer() footer += nodes.paragraph('', '', *text) return footer -- cgit v1.2.1 From 08508d8729f833bab10c4b382a013c523e5837f9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:25:05 +0000 Subject: Added "xml" alias. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@243 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 24d1cf384..4dabe2241 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -84,7 +84,8 @@ _writer_aliases = { 'html': 'html4css1', 'pprint': 'pseudoxml', 'pformat': 'pseudoxml', - 'pdf': 'rlpdf',} + 'pdf': 'rlpdf', + 'xml': 'docutils_xml',} def get_writer_class(writer_name): """Return the Writer class from the `writer_name` module.""" -- cgit v1.2.1 From 094e23351675a455639b6a313c43a344d69628e8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:25:46 +0000 Subject: Added to project; trivial writer of the Docutils internal doctree in XML. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@244 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/docutils_xml.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docutils/writers/docutils_xml.py diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py new file mode 100644 index 000000000..698908b27 --- /dev/null +++ b/docutils/writers/docutils_xml.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Simple internal document tree Writer, writes Docutils XML. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import writers + + +class Writer(writers.Writer): + + supported = ('xml',) + """Formats this writer supports.""" + + cmdline_options = ( + '"Docutils XML" Writer Options', + 'Warning: these options may adversely affect whitespace; use them ' + 'only for reading convenience.', + (('Generate XML with newlines before and after tags.', + ['--newlines'], {'action': 'store_true'}), + ('Generate XML with indents and newlines.', + ['--indents'], {'action': 'store_true'}),),) + + output = None + """Final translated form of `document`.""" + + def translate(self): + indent = newline = '' + if self.document.options.newlines: + newline = '\n' + if self.document.options.indents: + newline = '\n' + indent = ' ' + self.output = self.document.asdom().toprettyxml(indent, newline) -- cgit v1.2.1 From 46c86afe527c5cfa915ea67b42737494971dde83 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:26:57 +0000 Subject: Exposed modular output in Writer class. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@245 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4c8a6d9cc..cda74eb0c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -19,7 +19,6 @@ __docformat__ = 'reStructuredText' import sys import time -import string import re from types import ListType from docutils import writers, nodes, languages @@ -44,6 +43,11 @@ class Writer(writers.Writer): visitor = HTMLTranslator(self.document) self.document.walkabout(visitor) self.output = visitor.astext() + self.head_prefix = visitor.head_prefix + self.head = visitor.head + self.body_prefix = visitor.body_prefix + self.body = visitor.body + self.body_suffix = visitor.body_suffix class HTMLTranslator(nodes.NodeVisitor): -- cgit v1.2.1 From 02b1f1efbb561ab4e396cd44f4edb4fa5f671863 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:29:40 +0000 Subject: - Added ``locale.setlocale()`` calls to front-ends. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@246 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/html.py | 3 +++ tools/publish.py | 3 +++ tools/quicktest.py | 3 +++ 3 files changed, 9 insertions(+) diff --git a/tools/html.py b/tools/html.py index faee09f9c..c1c29b2b6 100755 --- a/tools/html.py +++ b/tools/html.py @@ -10,6 +10,9 @@ A minimal front-end to the Docutils Publisher, producing HTML. """ +import locale +locale.setlocale(locale.LC_ALL, '') + from docutils.core import publish diff --git a/tools/publish.py b/tools/publish.py index 14c0ea09a..6e814ea67 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -10,6 +10,9 @@ A minimal front-end to the Docutils Publisher, producing pseudo-XML. """ +import locale +locale.setlocale(locale.LC_ALL, '') + from docutils.core import publish diff --git a/tools/quicktest.py b/tools/quicktest.py index cf3884875..9517b95cc 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -10,6 +10,9 @@ :Copyright: This module has been placed in the public domain. """ +import locale +locale.setlocale(locale.LC_ALL, '') + import sys import os import getopt -- cgit v1.2.1 From 0fd8121cc0dcf7cc0a8bd9c30856844e4e917134 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:31:27 +0000 Subject: Added to project. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@247 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils-xml.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 tools/docutils-xml.py diff --git a/tools/docutils-xml.py b/tools/docutils-xml.py new file mode 100755 index 000000000..9269376bf --- /dev/null +++ b/tools/docutils-xml.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +A minimal front-end to the Docutils Publisher, producing Docutils XML. +""" + +import locale +locale.setlocale(locale.LC_ALL, '') + +from docutils.core import publish + + +usage = '%prog [options] [source [destination]]' +description = ('Generate Docutils XML from standalone reStructuredText ' + 'sources.') + +publish(writer_name='xml', usage=usage, description=description) -- cgit v1.2.1 From be8b2373908f3c5f02b983b0f65016a0911ad921 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 01:36:18 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@248 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 18 ++++++++++++++---- docs/dev/todo.txt | 6 ++++++ docutils/core.py | 6 +++--- docutils/statemachine.py | 1 - test/test_parsers/test_rst/test_inline_markup.py | 16 ++++++++++++++-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 8bb5e3f87..323b14db6 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -144,6 +144,8 @@ Specific: - 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()``. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -198,6 +200,9 @@ Specific: * 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. + * spec/doctree.txt: Changed the title to "The Docutils Document Tree". * spec/docutils.dtd: @@ -253,15 +258,20 @@ Specific: * test/test_pep/: Subpackage added to project; PEP testing. -* tools: Updated html.py and publish.py front-ends 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. +* tools: + + - Updated html.py and publish.py front-ends 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-ends. * tools/default.css: - Added support for ``header`` and ``footer`` elements. +* tools/docutils-xml.py: Added to project. + * tools/quicktest.py: Added the "--attributes" option, hacked a bit. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 964c35b17..6149a1bdb 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -22,6 +22,12 @@ you'd like to tackle, please do! Bugs ---- +- The move to I/O classes (io.py) has broken the "view source" links. + (Pointed out by Simon Budig.) + + Perhaps add attributes to I/O classes, like ``IO.source_path``? + Include logic to skip link creation if ``IO.source_path`` is empty. + - (Fixed, I think.) When there are duplicate implicit target names (e.g., section headers), a named hyperlink will link to the last of them. It shouldn't link to any at all, and should report an error. diff --git a/docutils/core.py b/docutils/core.py index c0f9f4375..27a0e60b6 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -101,9 +101,9 @@ class Publisher: if argv is None: argv = sys.argv[1:] self.options, source, destination = option_parser.parse_args(argv) - self.source = self.source_class(self.options, source=source) - self.destination = self.destination_class(self.options, - destination=destination) + self.source = self.source_class(self.options, source_path=source) + self.destination = self.destination_class( + self.options, destination_path=destination) def publish(self, argv=None, usage=None, description=None, option_spec=None): diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 621be35b5..b8496d3e0 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -107,7 +107,6 @@ __docformat__ = 'restructuredtext' import sys import re -import string class StateMachine: diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index f142ad424..12e0638eb 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -290,6 +290,18 @@ totest['interpreted'] = [ interpreted """], ["""\ +:role:`interpreted`:role: +""", +"""\ +<document> + <paragraph> + <problematic id="id2" refid="id1"> + :role:`interpreted`:role: + <system_message backrefs="id2" id="id1" level="2" type="WARNING"> + <paragraph> + Multiple roles in interpreted text at line 1 (both prefix and suffix present; only one allowed). +"""], +["""\ :role:`:not-role: interpreted` """, """\ @@ -447,7 +459,7 @@ Invalid phrase reference: :role:`phrase reference`_ <system_message backrefs="id2" id="id1" level="2" type="WARNING"> <paragraph> - Mismatch: inline interpreted text start-string and role with phrase-reference end-string at line 3. + Mismatch: both interpreted text role prefix and reference suffix at line 3. """], ["""\ Invalid phrase reference: @@ -463,7 +475,7 @@ Invalid phrase reference: `phrase reference`:role:_ <system_message backrefs="id2" id="id1" level="2" type="WARNING"> <paragraph> - Mismatch: inline interpreted text start-string and role with phrase-reference end-string at line 3. + Mismatch: both interpreted text role suffix and reference suffix at line 3. """], ["""\ `phrase reference_ without closing backquote -- cgit v1.2.1 From 34254daf176750a594863ebb5b68f3582e009c19 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Jul 2002 02:23:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@249 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 323b14db6..afe78e021 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -190,6 +190,7 @@ Specific: 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`` -- cgit v1.2.1 From 12890db2c498ead8c6a618d2240322fb388c48fa Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 5 Jul 2002 02:29:19 +0000 Subject: Added a better example for table alternative 3, and a new alternative 6. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@251 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/problems.txt | 53 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt index 677708ce5..1d1e8b208 100644 --- a/docs/dev/rst/problems.txt +++ b/docs/dev/rst/problems.txt @@ -376,19 +376,22 @@ documentation. Alternatives: 3. A minimalist alternative is as follows:: - ======== ======== ======== - Header 2 & 3 Span - ------------------ - Header 1 Header 2 Header 3 - ======== ======== ======== - Each line is a new row. - Each row consists of one line only. - Row spans are not possible. - The last column may spill over to the right. - Column spans are possible with an underline joining columns. - ---------------------------- - The span is limited to the row above the underline. - ======== ======== ======== + ==== ===== ======== ======== ======= ==== ===== ===== + Old State Input Action New State Notes + ----------- -------- ----------------- ----------- + ids types new type sys.msg. dupname ids types + ==== ===== ======== ======== ======= ==== ===== ===== + -- -- explicit -- -- new True + -- -- implicit -- -- new False + None False explicit -- -- new True + old False explicit implicit old new True + None True explicit explicit new None True + old True explicit explicit new,old None True [1] + None False implicit implicit new None False + old False implicit implicit new,old None False + None True implicit implicit new None True + old True implicit implicit new old True + ==== ===== ======== ======== ======= ==== ===== ===== The table begins with a top border of equals signs with one or more spaces at each column boundary (regardless of spans). There must @@ -404,6 +407,23 @@ documentation. Alternatives: consists of '=' underlines. A blank line is required following a table. + This table sums up the features. Using all the features in such a + small space is not pretty though:: + + ======== ======== ======== + Header 2 & 3 Span + ------------------ + Header 1 Header 2 Header 3 + ======== ======== ======== + Each line is a new row. + Each row consists of one line only. + Row spans are not possible. + The last column may spill over to the right. + Column spans are possible with an underline joining columns. + ---------------------------- + The span is limited to the row above the underline. + ======== ======== ======== + 4. As a variation of alternative 3, bullet list syntax in the first column could be used to indicate row starts. Multi-line rows are possible, but row spans are not. For example:: @@ -447,7 +467,12 @@ documentation. Alternatives: - Cells in the first column *must* contain some text; blank cells would lead to a misinterpretation. -Alternative #1 has been adopted by reStructuredText. +6. Combining alternative 3 and 4, a bullet list in the first column + could mean multi-line rows, and no bullet list means single-line + rows only. + +Alternative #1 has been adopted by reStructuredText. Alternatives 3-6 +are under consideration. Delimitation of Inline Markup -- cgit v1.2.1 From 5c1d1c93ddd584c9e2217a122f6650bc86de2543 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 6 Jul 2002 02:55:23 +0000 Subject: twiddled git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@253 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cda74eb0c..956303fad 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -34,7 +34,7 @@ class Writer(writers.Writer): None, (('Specify a stylesheet file. Default is "default.css".', ['--stylesheet'], - {'default': 'default.css', 'metavar': '<file>'}),),) + {'default': 'default.css', 'metavar': '<file>'}),)) output = None """Final translated form of `document`.""" @@ -78,7 +78,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body_prefix = ['</head>\n<body>\n'] self.body = [] self.body_suffix = ['</body>\n</html>\n'] - self.sectionlevel = 0 + self.section_level = 0 self.context = [] self.topic_class = '' @@ -667,11 +667,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</tr>\n') def visit_section(self, node): - self.sectionlevel += 1 + self.section_level += 1 self.body.append(self.starttag(node, 'div', CLASS='section')) def depart_section(self, node): - self.sectionlevel -= 1 + self.section_level -= 1 self.body.append('</div>\n') def visit_status(self, node): @@ -787,19 +787,20 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( self.starttag(node, 'p', '', CLASS='topic-title')) self.context.append('</p>\n') - elif self.sectionlevel == 0: + elif self.section_level == 0: + # document title self.head.append('<title>%s\n' % self.encode(node.astext())) self.body.append(self.starttag(node, 'h1', '', CLASS='title')) self.context.append('\n') else: self.body.append( - self.starttag(node, 'h%s' % self.sectionlevel, '')) + self.starttag(node, 'h%s' % self.section_level, '')) context = '' if node.hasattr('refid'): self.body.append('' % node['refid']) context = '' - self.context.append('%s\n' % (context, self.sectionlevel)) + self.context.append('%s\n' % (context, self.section_level)) def depart_title(self, node): self.body.append(self.context.pop()) -- cgit v1.2.1 From 4a0d5fdbd47b04f30b3de5190ab3914f3cfb301c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Jul 2002 02:56:38 +0000 Subject: Added NodeFound exception, for use in Visitors. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@254 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 9324814a3..5a640daca 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1258,6 +1258,17 @@ class SkipDeparture(TreePruningException): pass +class NodeFound(TreePruningException): + + """ + Raise to indicate that the target of a search has been found. This + exception must be caught by the client; it is not caught by the traversal + code. + """ + + pass + + def make_id(string): """ Convert `string` into an identifier and return it. -- cgit v1.2.1 From 0f210b84d6279337e7897f79d66ce7cf08729b94 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Jul 2002 03:00:23 +0000 Subject: Modified ``IO.decode()`` encoding order and prepared for failure. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@255 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 13f9b996c..91bd436f7 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -55,11 +55,19 @@ class IO: Decode a string, `data`, heuristically. Raise UnicodeError if unsuccessful. """ - encodings = [self.options.input_encoding, - locale.getlocale()[1], - 'utf-8', - locale.getdefaultlocale()[1],] - # is locale.getdefaultlocale() platform-specific? + encodings = [self.options.input_encoding, 'utf-8'] + try: + encodings.append(locale.nl_langinfo(locale.CODESET)) + except: + pass + try: + encodings.append(locale.getlocale()[1]) + except: + pass + try: + encodings.append(locale.getdefaultlocale()[1]) + except: + pass for enc in encodings: if not enc: continue -- cgit v1.2.1 From 9a98f9a98ee1aec3a1e67a6e84bc5286814501f8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Jul 2002 03:01:17 +0000 Subject: Changed "--report" and "--halt" options to "choice" type. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@256 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index cb0a11681..0e1158024 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -22,6 +22,12 @@ class OptionParser(optik.OptionParser): Parser for command-line and library use. The `cmdline_options` specification here and in other Docutils components are merged """ + threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split() + """Possible inputs for for --report and --halt threshold values.""" + + thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} + """Lookup table for --report and --halt threshold values.""" + cmdline_options = ( 'General Docutils Options', None, @@ -47,9 +53,9 @@ class OptionParser(optik.OptionParser): 'dest': 'source_link'}), ('Set verbosity threshold; report system messages at or higher than ' ' (by name or number: "info" or "1", warning/2, error/3, ' - 'severe/4; also, "none" or 5+). Default is 2 (warning).', - ['--report', '-r'], {'dest': 'report_level', 'default': 2, - 'metavar': ''}), + 'severe/4; also, "none" or "5"). Default is 2 (warning).', + ['--report', '-r'], {'choices': threshold_choices, 'default': 2, + 'dest': 'report_level', 'metavar': ''}), ('Report all system messages, info-level and higher. (Same as ' '"--report=info".)', ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', @@ -57,8 +63,8 @@ class OptionParser(optik.OptionParser): ('Set the threshold () at or above which system messages are ' 'converted to exceptions, halting execution immediately. Levels ' 'as in --report. Default is 4 (severe).', - ['--halt'], {'dest': 'halt_level', 'default': 4, - 'metavar': ''}), + ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level', + 'default': 4, 'metavar': ''}), ('Same as "--halt=info": halt processing at the slightest problem.', ['--strict'], {'action': 'store_const', 'const': 'info', 'dest': 'halt_level'}), @@ -92,9 +98,6 @@ class OptionParser(optik.OptionParser): list of single options. Option specs from Docutils components are also used (see `populate_from_components()`).""" - thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} - """Lookup table for --report and --halt threshold values.""" - version_template = '%%prog (Docutils %s)' % docutils.__version__ def __init__(self, components=(), defaults={}, *args, **kwargs): -- cgit v1.2.1 From 7f5c468171236cb0dd3a7f5301ec1c931c0e88f4 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Jul 2002 03:04:57 +0000 Subject: Added "Hyperlink Bookkeeping" section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@257 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index e58a4f306..476c57868 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -234,6 +234,45 @@ The ``%text.model;`` parameter entity Appendix: Miscellaneous Topics -------------------------------- +Hyperlink Bookkeeping +===================== + +``document.nameids`` maps names to IDs, while ``document.nametypes`` +maps names to booleans representing hyperlink type (True==explicit, +False==implicit). The ``document.set_name_id_map()`` method updates +the mappings. + +The following state transition table shows how ``nameids`` ("ids") and +``nametypes`` ("types") change with new input (a call to +``document.set_name_id_map()``), and what actions are performed:: + + ==== ===== ======== ======== ======= ==== ===== ===== + Old State Input Action New State Notes + ----------- -------- ----------------- ----------- + ids types new type sys.msg. dupname ids types + ==== ===== ======== ======== ======= ==== ===== ===== + -- -- explicit -- -- new True + -- -- implicit -- -- new False + None False explicit -- -- new True + old False explicit implicit old new True + None True explicit explicit new None True + old True explicit explicit new,old None True [1] + None False implicit implicit new None False + old False implicit implicit new,old None False + None True implicit implicit new None True + old True implicit implicit new old True + ==== ===== ======== ======== ======= ==== ===== ===== + +Note 1: Do not clear the name->id map or invalidate the old target if +both old and new targets are external and refer to identical URIs. +The new target is invalidated regardless. + +(The above is an example of `table syntax alternative 3`__; not +implemented yet, but I'm thinking about it.) + +__ rst/problems.html#tables + + Representation of Horizontal Rules ================================== -- cgit v1.2.1 From 87775b59e4ba4b6cb20baa1f563a8751e8dbd7c0 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 6 Jul 2002 03:06:21 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@258 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 +- docs/dev/todo.txt | 324 ++++++++---------------------------------------------- 2 files changed, 51 insertions(+), 280 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index afe78e021..178515db4 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -97,6 +97,8 @@ Specific: - 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. * docutils/optik.py: Added to project. Combined from the Optik package, with added option groups and other modifications. The use @@ -204,7 +206,10 @@ Specific: * docutils/writers/docutils_xml.py: Added to project; trivial writer of the Docutils internal doctree in XML. -* spec/doctree.txt: Changed the title to "The Docutils Document Tree". +* spec/doctree.txt: + + - Changed the title to "The Docutils Document Tree". + - Added "Hyperlink Bookkeeping" section. * spec/docutils.dtd: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 6149a1bdb..b77fcf2ba 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1,9 +1,12 @@ ================= Docutils_ Notes ================= +:Author: David Goodger (with input from many) +:Contact: goodger@users.sourceforge.net :Date: $Date$ :Revision: $Revision$ + .. _Docutils: http://docutils.sourceforge.net/ .. contents:: @@ -22,46 +25,7 @@ you'd like to tackle, please do! Bugs ---- -- The move to I/O classes (io.py) has broken the "view source" links. - (Pointed out by Simon Budig.) - - Perhaps add attributes to I/O classes, like ``IO.source_path``? - Include logic to skip link creation if ``IO.source_path`` is empty. - -- (Fixed, I think.) When there are duplicate implicit target names - (e.g., section headers), a named hyperlink will link to the last of - them. It shouldn't link to any at all, and should report an error. - - - nodes.document.nameids maps names to IDs. When there is a - duplicate, the last one stays. Idea: have a parallel - nodes.document.nametype mapping, name -> boolean (explicit name?). - :: - - ==== ===== ======== ======== ======= ==== ===== ===== - Old State Input Action New State Notes - ----------- -------- ----------------- ----------- - id type new type sys.msg. dupname id type - ==== ===== ======== ======== ======= ==== ===== ===== - -- -- explicit -- -- new True - -- -- implicit -- -- new False - None False explicit -- -- new True - old False explicit implicit old new True - None True explicit explicit new None True - old True explicit explicit new,old None True [1] - None False implicit implicit new None False - old False implicit implicit new,old None False - None True implicit implicit new None True - old True implicit implicit new old True - ==== ===== ======== ======== ======= ==== ===== ===== - - (The above is an example of `table syntax alternative 3`__; not - implemented yet, but I'm thinking about it.) - - Note 1: Do not clear the name->id map or invalidate the old target - if both old and new targets are external and refer to an identical - URI. The new target is invalidated regardless. - - __ rst/problems.html#tables +None reported. General @@ -118,148 +82,8 @@ General - Implement a specialized PEP/HTML writer? Or implement a generic `templating system`_, with PEP/HTML as one application? -- @@ (Done.) Add _`support for character set encodings` on input & - output, Unicode internally. - - To determine the encoding, use these heuristics in order: - - - Try the encoding specified by a command-line option, if any. - - - Try the encoding specified by an "encoding" directive, and/or an - "encoding" field in field lists & PEP headers, if any. See the - misc.encoding_ directive below. - - - Try the locale's encoding. - - - Try UTF-8. - - - Try platform-specific encodings: CP-1252 on Windows, Mac-Roman on - MacOS, perhaps Latin-9 (iso-8859-15) otherwise. - - Some questions: - - - Does the application have to call - ``locale.setlocale(locale.LC_ALL, '')``, and if so, where? Is it OK - to call setlocale from within the decoding function, or should it be - left up to the client application? - - - Should I use the result of ``locale.getlocale()``? On - Win2K/Python2.2.1, I get this:: - - >>> import locale - >>> locale.getlocale() - (None, None) - >>> locale.getdefaultlocale() - ('en_US', 'cp1252') - - Looks good so far. - - >>> locale.setlocale(locale.LC_ALL, '') - 'English_United States.1252' - >>> locale.getlocale() - ['English_United States', '1252'] - - "1252"? What happened to the "cp"? - - >>> s='abcd' - >>> s.decode('1252') - Traceback (most recent call last): - File "", line 1, in ? - LookupError: unknown encoding - - How can I use ``locale.getlocale()`` when it doesn't return a - known encoding? Or put another way, how can I get a known - encoding out of ``locale.getlocale()``? - - - Does ``locale.getdefaultlocale()[1]`` reliably produce the - platform-specific encoding? - - From Skip Montanaro's `Using Unicode in Python`_ ("Console Input" - section):: - - def encode_heuristically(s, enc=None): - "try interpreting s using several possible encodings" - try: - x = unicode(s, "ascii") - # if it's ascii, just return the plain string - return s - # you might want to return a Unicode object instead - # return x - except UnicodeError: - encodings = ["cp1252", "utf-8", "iso-8859-15", "iso-8859-1"] - # try any caller-provided encoding first - if enc: encodings.insert(0, enc) - for enc in encodings: - try: - x = unicode(s , enc) - except UnicodeError: - pass - else: - return x - # punt - return s - - .. _Using Unicode in Python: - http://manatee.mojam.com/~skip/unicode/unicode/ - - Windows CP-1252 and MacOS Mac-Roman are full 8-bit encodings, so - there's no point trying anything after them; they'll match any byte - string. UTF-8 is almost a full 8-bit encoding; it only uses up to - 0xFD but 0xFE & 0xFF are likely unused by most texts in other - encodings anyhow (a notable exception is UTF-16, in which 0xFEFF is - used as a "byte order mark"; but we'll ignore UTF-16 as it's - incompatible with ASCII). UTF-8 does have the advantage of a - verifyable encoding scheme, which is unlikely to be achieved by - accident in an 8-bit text. (I assume the UTF-8 codec verifies the - encoding.) So it makes sense to check for UTF-8 before - platform-dependent encodings (like CP-1252). - - ISO-8859-15 is an update of ISO-8859-1, and they share the same code - space (0x00-0x7F, 0xA0-0xFF), so there's no point in checking for - both. If one succeeds, the other one inevitably will too. - - `Introduction to i18n`_ by Tomohiro KUBOTA is a good reference. - - .. _Introduction to i18n: - http://www.debian.org/doc/manuals/intro-i18n/ - - Need a Unicode -> HTML entities codec for HTML writer? -- (Done, in io.py.) Distributor/filer object passed to Writer, - equivalent passed to Reader, to provide I/O access with a uniform - API? (Names for input object: inputter, sourcer, scanner.) Simple - vs. complex I/O structure: single file or string, - vs. directory/package or tree of strings. Simple file I/O is - default. - -- Name ideas: importer/exporter. Perhaps reader/writer should be - applied to lower-level tasks? "PySource Reader" or "PySource - Importer"? "HTML Writer" or "HTML Exporter"? I like the names - "Reader" & "Writer" for the high-level classes. So if we stick with - the status quo, what to call the components that do low-level I/O? - - - IOReader, IOWriter - - DataReader, DataWriter - - Inputter, Outputter - - Scanner, Recorder? - - Lector?, Scribe - - Loader, Storer/Stower/Recorder - - InputStorage, OutputStorage - - Input, Output - - Source, Destination - - Perhaps subclasses of a single class, a abstraction for - file/string/etc. reading & writing. - - - Storage (thus InputStorage/OutputStorage) - - IO (SourceIO/DestIO; InputIO/OutputIO) - - Implement as a single module (``docutils/storage.py``)? Or as a - subpackage (``docutils/storage/*.py``)? Decision: use a single - module for now, possibly switching to a package if it gets too big. - - See `support for character set encodings`_ above. - - Fix tests to run standalone. I.e., allow:: cd test/test_rst @@ -712,23 +536,9 @@ Index HTML Writer ----------- -- Allow for style sheet info to be passed in. (Done, with the - ``--stylesheet`` command-line option.) - - @@@ Construct a _`templating system`, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. -- Improve the granularity of document parts in the HTML writer, so - that one could just grab the parts needed. (Done.) - -- @@@ Return a string instead of writing to a file? Leave all I/O up - to the client? Or up to an explicit distributor/filer? - -- Add an option to generate a "View source text" link. (Done.) - -- Add an option to generate a "Generated by Docutils [from - reStructuredText source?]" message, with links. (Done.) - - If a list's items contain single paragraphs only, omit the

    tags? Recursively? (if item == list whose items are single paragraphs only...) Optional, with "--compact-lists" and "--no-compact-lists"? @@ -736,95 +546,51 @@ HTML Writer of all list items lack a

    (perhaps "--compact-all-lists" and "--compact-simple-lists")? + Tried it; not easy. If you're interested, email me for a copy of + the patch. + Front-Ends ---------- -@@@ Rather than a single all-purpose program, it is probably -preferable to have a bunch of small front-ends, each specialized for a -specific reader (and possibly writer as well; each could have a name -of the form "context2format"). Each of the front-ends would depend on -a common option-processing module, as described below. - -- Combine the common code from the existing front-ends into a single - module, and add option processing. - - - Named docutils.frontend.OptionParser. Supporting parameters have - been added to docutils.core.Publisher/publish(): ``argv`` & - ``usage``. (Done.) - - - Use Optik to do modular command-line option processing. (Done.) - - - An Optik 'option Values' object is attached to the document. - - - The Optik 'option Values' object is used even when *not* using a - front-end (i.e., when docutils is imported by an unrelated - client). An artificial argv list can be constructed & passed to - publish(), or a default Values object can be created and - modified manually:: - - pub = Publisher(...) - pub.process_command_line(argv=[]) - pub.options.an_option = "my default value" - pub.publish() - - - The core supports all common options (--verbose, --date, etc.). - (Done.) - - - Each component adds its own specific options (HTML: --stylesheet, - etc.). (Done.) - - - Disables common options that don't apply? - - - Added/removed dynamically (during option processing)? Is this - possible with Optik? Is it desirable? (See dynamic_ below.) - - - Perhaps each component could have an ``init_options`` method, - which can do surgery on the option list? - - - Common and component-specific options must not conflict. Reserve - short options for the core, and restrict components to long - options? - - - Build an OptionParser dynamically based on the known Reader & - Writer. Store a data structure in each component containing its - specific options, merge with the common option data, and - instantiate an OptionParser. (Done.) - - - What about if we don't know which Reader and/or Writer we are - going to use? If the Reader/Writer is specified on the - command-line? (Will this ever happen?) - - Perhaps have different types of front ends: - - a) _`Fully qualified`: Reader and Writer are hard-coded into the - front-end (e.g. ``pep2html [options]``, ``pysource2pdf - [options]``). - - b) _`Partially qualified`: Reader is hard-coded, and the Writer is - specified a sub-command (e.g. ``pep2 html [options]``, - ``pysource2 pdf [options]``). The Writer is known before - option processing happens, allowing the OptionParser to be - built dynamically. - - c) _`Unqualified`: Reader and Writer are specified as subcommands - (e.g. ``publish pep html [options]``, ``publish pysource pdf - [options]``). A single front-end would be sufficient, but - probably only useful for testing purposes. - - d) _`Dynamic`: Reader and/or Writer are specified by options, with - defaults if unspecified (e.g. ``publish --writer pdf - [options]``). Is this possible? The option parser would have - to be told about new options it needs to handle, on the fly. - Component-specific options would have to be specified *after* - the component-specifying option. - - Allow common options before subcommands, as in CVS? Or group all - options together? In the case of the `fully qualified`_ - front-ends, all the options will have to be grouped together - anyway, so there's no advantage (we can't use it to avoid - conflicts) to splitting common and component-specific options - apart. +- Common and component-specific options must not conflict. Reserve + short options for the core, and restrict components to long + options? + +- What about if we don't know which Reader and/or Writer we are + going to use? If the Reader/Writer is specified on the + command-line? (Will this ever happen?) + + Perhaps have different types of front ends: + + a) _`Fully qualified`: Reader and Writer are hard-coded into the + front-end (e.g. ``pep2html [options]``, ``pysource2pdf + [options]``). + + b) _`Partially qualified`: Reader is hard-coded, and the Writer is + specified a sub-command (e.g. ``pep2 html [options]``, + ``pysource2 pdf [options]``). The Writer is known before + option processing happens, allowing the OptionParser to be + built dynamically. + + c) _`Unqualified`: Reader and Writer are specified as subcommands + (e.g. ``publish pep html [options]``, ``publish pysource pdf + [options]``). A single front-end would be sufficient, but + probably only useful for testing purposes. + + d) _`Dynamic`: Reader and/or Writer are specified by options, with + defaults if unspecified (e.g. ``publish --writer pdf + [options]``). Is this possible? The option parser would have + to be told about new options it needs to handle, on the fly. + Component-specific options would have to be specified *after* + the component-specifying option. + + Allow common options before subcommands, as in CVS? Or group all + options together? In the case of the `fully qualified`_ + front-ends, all the options will have to be grouped together + anyway, so there's no advantage (we can't use it to avoid + conflicts) to splitting common and component-specific options + apart. Project Policies -- cgit v1.2.1 From cd0f776806d83251e5cb34e29ec6252cd795464b Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 8 Jul 2002 12:46:43 +0000 Subject: fixed typos git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@260 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/introduction.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/introduction.txt b/docs/ref/rst/introduction.txt index 4ffb2d053..3ca6de778 100644 --- a/docs/ref/rst/introduction.txt +++ b/docs/ref/rst/introduction.txt @@ -7,7 +7,7 @@ :Date: $Date$ reStructuredText_ is an easy-to-read, what-you-see-is-what-you-get -plaintext markup syntax and parser system. It is useful for in-line +plaintext markup syntax and parser system. It is useful for inline program documentation (such as Python docstrings), for quickly creating simple web pages, and for standalone documents. reStructuredText_ is a proposed revision and reinterpretation of the @@ -63,9 +63,9 @@ beginning with the most important: 2. Unobtrusive. The markup that is used should be as simple and unobtrusive as possible. The simplicity of markup constructs - should be roughly proporional to their frequency of use. The most + should be roughly proportional to their frequency of use. The most common constructs, with natural and obvious markup, should be the - simplest and most unobtrusive. Less common contstructs, for which + simplest and most unobtrusive. Less common constructs, for which there is no natural or obvious markup, should be distinctive. 3. Unambiguous. The rules for markup must not be open for -- cgit v1.2.1 From 173329c4c4950fbb3289eb20cbd4604ad9cf3f77 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Jul 2002 01:47:45 +0000 Subject: Updated "Authors" bibliographic field behavior. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@261 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index e26ce2a21..1e84feff5 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -825,20 +825,29 @@ The registered bibliographic field names and their corresponding DTD elements are as follows: - Field name "Author": author element. -- "Authors": authors. May contain either: a single paragraph - consisting of a list of authors, separated by ";" or ","; or a - bullet list whose elements each contain a single paragraph per - author. +- "Authors": authors. - "Organization": organization. - "Contact": contact. - "Version": version. - "Status": status. - "Date": date. - "Copyright": copyright. -- "Abstract": topic. May contain arbitrary body elements. Only one - abstract is allowed. The abstract becomes a topic element with - title "Abstract" (or language equivalent) immediately following the - docinfo element. +- "Abstract": topic. + +The "Authors" field may contain either: a single paragraph consisting +of a list of authors, separated by ";" or ","; or a bullet list whose +elements each contain a single paragraph per author. ";" is checked +first, so "Doe, Jane; Doe, John" will work. In some languages +(e.g. Swedish), there is no singular/plural distinction between +"Author" and "Authors", so only an "Authors" field is provided, and a +single name is interpreted as an "Author". If a single name contains +a comma, end it with a semicolon to disambiguate: ":Authors: Doe, +Jane;". + +The "Abstract" field may contain arbitrary body elements. Only one +abstract is allowed. The abstract becomes a topic element with title +"Abstract" (or language equivalent) immediately following the docinfo +element. This field-name-to-element mapping can be extended, or replaced for other languages. See the `DocInfo transform`_ implementation -- cgit v1.2.1 From e521880b4a16e6500b171d673e1c6ef50d92e7e2 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Jul 2002 01:49:35 +0000 Subject: - Allowed non-ASCII in "simple names" (directive names, field names, references, etc.). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@262 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index f3be937d6..12174c5de 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -435,7 +435,7 @@ class Inliner: non_whitespace_before = r'(? Date: Thu, 11 Jul 2002 01:50:40 +0000 Subject: In ``DocInfo.extract_authors``, check for a single "author" in an "authors" group, and convert it to a single "author" element. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@263 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index c5aaa0d1e..f61e828a1 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -328,7 +328,12 @@ class DocInfo(Transform): authors = self.authors_from_paragraphs(field) authornodes = [nodes.author('', '', *author) for author in authors if author] - docinfo.append(nodes.authors('', *authornodes)) + if len(authornodes) > 1: + docinfo.append(nodes.authors('', *authornodes)) + elif len(authornodes) == 1: + docinfo.append(authornodes[0]) + else: + raise TransformError except TransformError: field[-1] += self.document.reporter.warning( 'Bibliographic field "%s" incompatible with extraction: ' @@ -348,7 +353,7 @@ class DocInfo(Transform): if len(authornames) > 1: break authornames = [author.strip() for author in authornames] - authors = [[nodes.Text(author)] for author in authornames] + authors = [[nodes.Text(author)] for author in authornames if author] return authors def authors_from_bullet_list(self, field): -- cgit v1.2.1 From a71975394bb6d99904ae388d33e481e8e77709bf Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Jul 2002 01:52:21 +0000 Subject: Added "name" attribute to TOC topic depending on its title. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@264 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 7a6d97219..8543de1ca 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -45,17 +45,20 @@ class Contents(Transform): # section/document top-level? Drag it up until it is? while not isinstance(startnode, nodes.Structural): startnode = startnode.parent - if not title: - title = [] else: startnode = self.document if not title: title = nodes.title('', self.language.labels['contents']) contents = self.build_contents(startnode) if len(contents): - topic += title + if title: + topic['name'] = title.astext() + topic += title + else: + topic['name'] = self.language.labels['contents'] topic += contents self.startnode.parent.replace(self.startnode, topic) + self.document.note_implicit_target(topic) else: self.startnode.parent.remove(self.startnode) -- cgit v1.2.1 From 0b3ab52210c5a244aa2e56dd82e2df832aaece71 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 11 Jul 2002 01:54:17 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@265 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 22 +++++++++++++-------- docs/dev/todo.txt | 12 ++++++++++++ test/test_transforms/test_contents.py | 36 ++++++++++++++++++++++++++++++----- test/test_transforms/test_docinfo.py | 12 ++++++++++++ 4 files changed, 69 insertions(+), 13 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 178515db4..2ecdad2ba 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,14 +17,14 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - Aahz, David Ascher, Simon Budig, Fred Drake, Dethe Elza, Jim - Fulton, Peter Funk, Engelbert Gruber, Doug Hellmann, Juergen - Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, Garth Kidd, - Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, - Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim - Peters, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli - Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, - Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Aahz, David Ascher, Simon Budig, Adam Chodorowski, Fred Drake, + Dethe Elza, Jim Fulton, Peter Funk, Engelbert Gruber, Doug + Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, + Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, + Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam + Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, + Ueli Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van + Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -148,6 +148,8 @@ Specific: 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()``. + - Allow non-ASCII in "simple names" (directive names, field names, + references, etc.). * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -166,6 +168,10 @@ Specific: * 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. + * docutils/transforms/peps.py: Added to project; PEP-specific. * docutils/transforms/parts.py: Renamed from old components.py. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b77fcf2ba..933294fe4 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -95,6 +95,12 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? +- Add "NullIO" degenerate ``docutils.io.IO`` subclass. + +- Add a command-line option & directive attribute to control TOC + backlinks: no TOC backlinks, backlinks to TOC entries, or backlinks + to TOC itself only. + Specification ------------- @@ -549,6 +555,12 @@ HTML Writer Tried it; not easy. If you're interested, email me for a copy of the patch. +- Add more support for elements, especially for navigation + bars. + +- "name" attributes only on these tags: a, applet, form, frame, + iframe, img, map. + Front-Ends ---------- diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index a05430b3e..fe066e75d 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -47,7 +47,7 @@ Paragraph 4. """, """\ - + Contents <bullet_list> @@ -103,7 +103,7 @@ Paragraph 2. """, """\ <document> - <topic class="contents"> + <topic class="contents" id="table-of-contents" name="Table of Contents"> <title> Table of Contents <bullet_list> @@ -142,7 +142,7 @@ Paragraph 2. """, """\ <document> - <topic class="contents"> + <topic class="contents" id="there-s-an-image-in-title-2" name="There's an image in Title 2"> <title> There's an image in Title 2 <bullet_list> @@ -189,7 +189,7 @@ Paragraph 4. """, """\ <document> - <topic class="contents"> + <topic class="contents" id="contents" name="Contents"> <title> Contents <bullet_list> @@ -253,7 +253,7 @@ Paragraph 4. <section id="title-1" name="title 1"> <title> Title 1 - <topic class="contents"> + <topic class="contents" id="contents" name="Contents"> <bullet_list> <list_item id="id1"> <paragraph> @@ -287,6 +287,32 @@ Paragraph 4. Paragraph 4. """], ["""\ +.. contents:: + :local: + +Test duplicate name "Contents". + +Contents +-------- +Paragraph. +""", +"""\ +<document> + <topic class="contents" id="id2" name="Contents"> + <bullet_list> + <list_item id="id1"> + <paragraph> + <reference refid="contents"> + Contents + <paragraph> + Test duplicate name "Contents". + <section id="contents" name="contents"> + <title refid="id1"> + Contents + <paragraph> + Paragraph. +"""], +["""\ .. contents:: Degenerate case, no table of contents generated. diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index d5dd4b873..a734bfd3b 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -212,6 +212,18 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ Third """], ["""\ +:Authors: Only One +:Authors: One, Only; +""", +"""\ +<document> + <docinfo> + <author> + Only One + <author> + One, Only +"""], +["""\ :Authors: :Authors: 1. One -- cgit v1.2.1 From 76e5acfa2c9d733f002cc9371a97e012221b0864 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 11 Jul 2002 01:54:22 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@266 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 2ecdad2ba..f9e537a46 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -148,7 +148,7 @@ Specific: 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()``. - - Allow non-ASCII in "simple names" (directive names, field names, + - Allowed non-ASCII in "simple names" (directive names, field names, references, etc.). * docutils/parsers/rst/directives/html.py: Changed the ``meta`` @@ -178,6 +178,7 @@ Specific: - 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. * docutils/transforms/references.py: Fixed indirect target resolution in ``Hyperlinks`` transform. @@ -257,6 +258,7 @@ Specific: - Clarified purpose of directives. - Added ``-/:`` characters to inline markup's start string prefix, ``/`` to end string suffix. + - Updated "Authors" bibliographic field behavior. * test: Made test modules standalone (subdirectories became packages). -- cgit v1.2.1 From 62c797a5507d27137959b8ec1578246fce30480f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:52:01 +0000 Subject: Added "Inline External Targets" section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@267 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 296 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 4faae1f98..2bd12e784 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1324,6 +1324,302 @@ ugly or confusing (depending on which alternative is chosen). Advantages: explicit, any enumeration sequence possible. Disadvantages: a bit ugly. + +Inline External Targets +======================= + +Currently reStructuredText has two hyperlink syntax variations: + +* Named hyperlinks:: + + This is a named reference_ of one word ("reference"). Here is + a `phrase reference`_. Phrase references may even cross `line + boundaries`_. + + .. _reference: http://www.example.org/reference/ + .. _phrase reference: http://www.example.org/phrase_reference/ + .. _line boundaries: http://www.example.org/line_boundaries/ + + + Advantages: + + - The plaintext is readable. + - Each target may be reused multiple times (e.g., just write + ``"reference_"`` again). + - No syncronized ordering of references and targets is necessary. + + + Disadvantages: + + - The reference text must be repeated as target names; could lead + to mistakes. + - The target URLs may be located far from the references, and hard + to find in the plaintext. + +* Anonymous hyperlinks (in current reStructuredText):: + + This is a named reference__ of one word ("reference"). Here is + a `phrase reference`__. Phrase references may even cross `line + boundaries`__. + + __ http://www.example.org/reference/ + __ http://www.example.org/phrase_reference/ + __ http://www.example.org/line_boundaries/ + + + Advantages: + + - The plaintext is readable. + - The reference text does not have to be repeated. + + + Disadvantages: + + - References and targets must be kept in sync. + - Targets cannot be reused. + - The target URLs may be located far from the references. + +For comparison and historical background, StructuredText also has two +syntaxes for hyperlinks: + +* First, ``"reference text":URL``:: + + This is a named "reference":http://www.example.org/reference/ + of one word ("reference"). Here is a "phrase + reference":http://www.example.org/phrase_reference/. + +* Second, ``"reference text", http://example.com/absolute_URL``:: + + This is a named "reference", http://www.example.org/reference/ + of one word ("reference"). Here is a "phrase reference", + http://www.example.org/phrase_reference/. + +Both syntaxes share advantages and disadvantages: + ++ Advantages: + + - The target is specified immediately adjacent to the reference. + ++ Disadvantages: + + - Poor plaintext readability. + - Targets cannot be reused. + - Both syntaxes use double quotes, common in ordinary text. + - In the first syntax, the URL and the last word are stuck + together, exacerbating the line wrap problem. + - The second syntax is too magical; text could easily be written + that way by accident (although only absolute URLs are recognized + here, perhaps because of the potential for ambiguity). + +A new type of "inline external hyperlink" has been proposed. + +1. On 2002-06-28, Simon Budig proposed__ a new syntax for + reStructuredText hyperlinks:: + + This is a reference_(http://www.example.org/reference/) of one + word ("reference"). Here is a `phrase + reference`_(http://www.example.org/phrase_reference/). Are + these examples, (single-underscore), named? If so, `anonymous + references`__(http://www.example.org/anonymous/) using two + underscores would probably be preferable. + + __ http://mail.python.org/pipermail/doc-sig/2002-June/002648.html + + The syntax, advantages, and disadvantages are similar to those of + StructuredText. + + + Advantages: + + - The target is specified immediately adjacent to the reference. + + + Disadvantages: + + - Poor plaintext readability. + - Targets cannot be reused (unless named, but the semantics are + unclear). + + + Problems: + + - The "`ref`_(URL)" syntax forces the last word of the reference + text to be joined to the URL, making a potentially very long + word that can't be wrapped (URLs can be very long). The + reference and the URL should be separate. This is a symptom + of the following point: + + - The syntax produces a single compound construct made up of two + equally important parts, *with syntax in the middle*, *between* + the reference and the target. This is unprecedented in + reStructuredText. + + - The "inline hyperlink" text is *not* a named reference (there's + no lookup by name), so it shouldn't look like one. + + - According to the IETF standards RFC 2396 and RFC 2732, + parentheses are legal URI characters and curly braces are legal + email characters, making their use prohibitively difficult. + + - The named/anonymous semantics are unclear. + +2. After an analysis__ of the syntax of (1) above, we came up with the + following compromise syntax:: + + This is an anonymous reference__ + __<http://www.example.org/reference/> of one word + ("reference"). Here is a `phrase reference`__ + __<http://www.example.org/phrase_reference/>. `Named + references`_ _<http://www.example.org/anonymous/> use single + underscores. + + __ http://mail.python.org/pipermail/doc-sig/2002-July/002670.html + + The syntax builds on that of the existing "inline internal + targets": ``an _`inline internal target`.`` + + + Advantages: + + - The target is specified immediately adjacent to the reference, + improving maintainability: + + - References and targets are easily kept in sync. + - The reference text does not have to be repeated. + + - The construct is executed in two parts: references identical to + existing references, and targets that are new but not too big a + stretch from current syntax. + + - There's overwhelming precedent for quoting URLs with angle + brackets [#]_. + + + Disadvantages: + + - Poor plaintext readability. + - Lots of "line noise". + - Targets cannot be reused (unless named; see below). + + To alleviate the readability issue slightly, we could allow the + target to appear later, such as after the end of the sentence:: + + This is a named reference__ of one word ("reference"). + __<http://www.example.org/reference/> Here is a `phrase + reference`__. __<http://www.example.org/phrase_reference/> + + Problem: this could only work for one reference at a time + (reference/target pairs must be proximate [refA trgA refB trgB], + not interleaved [refA refB trgA trgB] or nested [refA refB trgB + trgA]). This variation is too problematic; references and inline + external targets will have to be kept imediately adjacent (see (3) + below). + + The ``"reference__ __<target>"`` syntax is actually for "anonymous + inline external targets", emphasized by the double underscores. It + follows that single trailing and leading underscores would lead to + *implicitly named* inline external targets. This would allow the + reuse of targets by name. So after ``"reference_ _<target>"``, + another ``"reference_"`` would point to the same target. + + .. [#] + From RFC 2396 (URI syntax): + + The angle-bracket "<" and ">" and double-quote (") + characters are excluded [from URIs] because they are often + used as the delimiters around URI in text documents and + protocol fields. + + Using <> angle brackets around each URI is especially + recommended as a delimiting style for URI that contain + whitespace. + + From RFC 822 (email headers): + + Angle brackets ("<" and ">") are generally used to indicate + the presence of a one machine-usable reference (e.g., + delimiting mailboxes), possibly including source-routing to + the machine. + +3. If it is best for references and inline external targets to be + immediately adjacent, then they might as well be integrated. + Here's an alternative syntax embedding the target URL in the + reference:: + + This is an anonymous `reference <http://www.example.org + /reference/>`__ of one word ("reference"). Here is a `phrase + reference <http://www.example.org/phrase_reference/>`__. + + Advantages and disadvantages are similar to those in (2). + Readability is still an issue, but the syntax is a bit less + heavyweight (reduced line noise). + + Problem: how to refer to a title like "HTML Anchors: <a>" (which + ends with an HTML/SGML/XML tag)? We could either require more + syntax on the target (like ``"`reference text + __<http://example.com/>`__"``), or require the odd conflicting + title to be escaped (like ``"`HTML Anchors: \<a>`__"``). The + latter seems preferable, and not too onerous. + + Similarly to (2) above, a single trailing underscore would convert + the reference & inline external target from anonymous to implicitly + named, allowing reuse of targets by name. + + I think this is the least objectionable of the syntax alternatives. + +With any kind of inline external target syntax it comes down to the +conflict between maintainability and plaintext readability. I don't +see a major problem with reStructuredText's maintainability, and I +don't want to sacrifice plaintext readability to "improve" it. + +The proponents of inline external targets want them for easily +maintainable web pages. The arguments go something like this: + +- Named hyperlinks are difficult to maintain because the reference + text is duplicated as the target name. + + To which I said, "So use anonymous hyperlinks." + +- Anonymous hyperlinks are difficult to maintain becuase the + references and targets have to be kept in sync. + + "So keep the targets close to the references, grouped after each + paragraph. Maintenance is trivial." + +- But targets grouped after paragraphs break the flow of text. + + "Surely less than URLs embedded in the text! And if the intent is + to produce web pages, not readable plaintext, then who cares about + the flow of text?" + +Many participants have voiced their objections to the proposed syntax: + + Garth Kidd: "I strongly prefer the current way of doing it. + Inline is spectactularly messy, IMHO." + + Tony Ibbs: "I vehemently agree... that the inline alternatives + being suggested look messy - there are/were good reasons they've + been taken out... I don't believe I would gain from the new + syntaxes." + + Paul Moore: "I agree as well. The proposed syntax is far too + punctuation-heavy, and any of the alternatives discussed are + ambiguous or too subtle." + +Others have voiced their support: + + fantasai: "I agree with Simon. In many cases, though certainly + not in all, I find parenthesizing the url in plain text flows + better than relegating it to a footnote." + + Ken Manheimer: "I'd like to weigh in requesting some kind of easy, + direct inline reference link." + +(Interesting that those *against* the proposal have been using +reStructuredText for a while, and those *for* the proposal are either +new to the list ["fantasai", background unknown] or longtime +StructuredText users [Ken Manheimer].) + +As is probably obvious, I'm ambivalent/against the proposed "inline +external targets". I value reStructuredText's readability very +highly, and although the proposed syntax offers convenience, I don't +know if the convenience is worth the cost in ugliness. Does the +proposed syntax compromise readability too much, or should the choice +be left up to the author? Perhaps if the syntax is *allowed* but its +use strongly *discouraged*, for aesthetic reasons? Or would that just +be hypocritical? Dilemma. + .. Local Variables: -- cgit v1.2.1 From 94e191e2a5157768c7b2327fda83943ca1f0950b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:53:20 +0000 Subject: Changed "inline hyperlink targets" to "inline internal targets". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@268 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 1e84feff5..d996adf7a 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -57,7 +57,7 @@ Here are examples of `body elements`_: external hyperlinks (Python_), internal cross-references (example_), footnote references ([1]_), citation references ([CIT2002]_), substitution references (|example|), and _`inline - hyperlink targets`. + internal targets`. Paragraphs are separated by blank lines and are left-aligned. @@ -1460,7 +1460,7 @@ indirect. .. _Doc-SIG: http://mail.python.org/pipermail/doc-sig/ An inline form of internal hyperlink target is available; see - `Inline Hyperlink Targets`_. + `Inline Internal Targets`_. 2. _`External hyperlink targets` have an absolute or relative URI in their link blocks. For example, take the following input:: @@ -1944,7 +1944,7 @@ identical start-strings and end-strings to indicate the markup: Three constructs use different start-strings and end-strings: -- `inline hyperlink targets`_: "_`" and "`" +- `inline internal targets`_: "_`" and "`" - `footnote references`_: "[" and "]_" - `hyperlink references`_: "`" and "\`_" (phrases), or just a trailing "_" (single words) @@ -2005,7 +2005,7 @@ each character. The inline markup recognition order is as follows: - Asterisks: `Strong emphasis`_ ("**") is recognized before emphasis_ ("*"). -- Backquotes: `Inline literals`_ ("``"), `inline hyperlink targets`_ +- Backquotes: `Inline literals`_ ("``"), `inline internal targets`_ (leading "_`", trailing "`"), are mutually independent, and are recognized before phrase `hyperlink references`_ (leading "`", trailing "\`_") and `interpreted text`_ ("`"). @@ -2153,17 +2153,17 @@ match references to targets, but otherwise behave similarly to named hyperlinks. -Inline Hyperlink Targets +Inline Internal Targets ------------------------ DTD element: target. Start-string = "_`", end-string = "`". -Inline hyperlink targets are the equivalent of explicit `internal +Inline internal targets are the equivalent of explicit `internal hyperlink targets`_, but may appear within running text. The syntax begins with an underscore and a backquote, is followed by a hyperlink -name or phrase, and ends with a backquote. Inline hyperlink targets +name or phrase, and ends with a backquote. Inline internal targets may not be anonymous. For example, the following paragraph contains a hyperlink target named -- cgit v1.2.1 From 2d59493f745d0d6d2f9ba78bd76add03b29cc511 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:55:08 +0000 Subject: Changed "inline hyperlink target" to "inline internal target". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@269 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index 0ae99bfcd..aa0d8f3ed 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -20,7 +20,7 @@ <p align="right"><em><a href="http://docutils.sourceforge.net/docs/rst/quickref.html" >http://docutils.sourceforge.net/docs/rst/quickref.html</a></em> <br align="right"><em>Being a cheat-sheet for reStructuredText</em> - <br align="right"><em>Version 0.8 of 2002-04-19</em> + <br align="right"><em>Version 0.8a of 2002-07-12</em> <p>The full details may be found on the @@ -116,8 +116,8 @@ See <a href="#hyperlink-targets">Hyperlinks</a>. <tr valign="top"> - <td nowrap><samp>_`inline hyperlink target`</samp> - <td><a name="inline-hyperlink-target">inline hyperlink target</a> + <td nowrap><samp>_`inline internal target`</samp> + <td><a name="inline-internal-target">inline internal target</a> <td>A crossreference target within text. See <a href="#hyperlink-targets">Hyperlinks</a>. -- cgit v1.2.1 From 0cd6e450ebc86185487cadf3a91fbffcbfa0fd1e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:56:19 +0000 Subject: Added ``NullIO`` class. Added docstrings. Simplified. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@270 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 91bd436f7..aa9d27c41 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -84,7 +84,7 @@ class IO: class FileIO(IO): """ - IO for single, simple file-like objects. + I/O for single, simple file-like objects. """ def __init__(self, options, source=None, source_path=None, @@ -114,16 +114,12 @@ class FileIO(IO): self.destination = sys.stdout def read(self, reader): - """ - Read and decode a single file and return the data. - """ + """Read and decode a single file and return the data.""" data = self.source.read() return self.decode(data) def write(self, data): - """ - Encode and write `data` to a single file. - """ + """Encode and write `data` to a single file.""" output = data.encode(self.options.output_encoding) self.destination.write(output) @@ -131,27 +127,29 @@ class FileIO(IO): class StringIO(IO): """ - Direct string IO. + Direct string I/O. """ - def __init__(self, options, source=None, destination=None): - """ - :Parameters: - - `source`: a string containing input data. - - `destination`: not used. - """ - IO.__init__(self, options) - self.source = source - def read(self, reader): - """ - Decode and return the source string. - """ + """Decode and return the source string.""" return self.decode(self.source) def write(self, data): - """ - Encode and return `data`. - """ + """Encode and return `data`.""" self.destination = data.encode(self.options.output_encoding) return self.destination + + +class NullIO(IO): + + """ + Degenerate I/O: read & write nothing. + """ + + def read(self, reader): + """Return a null string.""" + return u'' + + def write(self, data): + """Do nothing (send data to the bit bucket).""" + pass -- cgit v1.2.1 From 5f80cbfd8f3d292c3de19c67b658127df3dd9e92 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:57:11 +0000 Subject: Added ``document.has_name()`` method. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@271 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 5a640daca..84ce615a3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -710,6 +710,9 @@ class document(Root, Structural, Element): backrefs=[id]) msgnode += msg + def has_name(self, name): + return self.nameids.has_key(name) + def note_implicit_target(self, target, msgnode=None): id = self.set_id(target, msgnode) self.set_name_id_map(target, id, msgnode, explicit=None) -- cgit v1.2.1 From a30c5f64519795f4e64b3475910bdad9d84f8270 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:58:45 +0000 Subject: Fixed TOC "name" attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@272 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 8543de1ca..d109d3552 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -52,12 +52,15 @@ class Contents(Transform): contents = self.build_contents(startnode) if len(contents): if title: - topic['name'] = title.astext() + name = title.astext() topic += title else: - topic['name'] = self.language.labels['contents'] + name = self.language.labels['contents'] topic += contents self.startnode.parent.replace(self.startnode, topic) + name = utils.normalize_name(name) + if not self.document.has_name(name): + topic['name'] = name self.document.note_implicit_target(topic) else: self.startnode.parent.remove(self.startnode) -- cgit v1.2.1 From 36e8c4fdb6ac9dc864c9afea3486f259b55b1137 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 02:59:13 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@273 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 2c51fa861..70775c930 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -26,6 +26,7 @@ from docutils.transforms import Transform, TransformError class Headers(Transform): """ + Process fields in a PEP's initial RFC-2822 header. """ pep_cvs_url = ('http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/' -- cgit v1.2.1 From f598ea8f0de41e066fa59badcf0299026dabbb84 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 03:01:44 +0000 Subject: fixed link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@274 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 2bd12e784..92681bb2e 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1436,11 +1436,11 @@ A new type of "inline external hyperlink" has been proposed. + Problems: - - The "`ref`_(URL)" syntax forces the last word of the reference - text to be joined to the URL, making a potentially very long - word that can't be wrapped (URLs can be very long). The - reference and the URL should be separate. This is a symptom - of the following point: + - The ``"`ref`_(URL)"`` syntax forces the last word of the + reference text to be joined to the URL, making a potentially + very long word that can't be wrapped (URLs can be very long). + The reference and the URL should be separate. This is a + symptom of the following point: - The syntax produces a single compound construct made up of two equally important parts, *with syntax in the middle*, *between* -- cgit v1.2.1 From 88804d77d0b560dbc7b80893770b052dfc765c37 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 03:05:45 +0000 Subject: - Converted ``Inliner.patterns.initial`` to be dynamically built from parts with ``build_regexp()`` function. - Changed ``Inliner.inline_target`` to ``.inline_internal_target``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@275 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 103 +++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 12174c5de..6c26b779b 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -105,7 +105,7 @@ __docformat__ = 'reStructuredText' import sys import re -import string +from types import TupleType from docutils import nodes, statemachine, utils, roman, urischemes from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS @@ -377,6 +377,29 @@ class RSTState(StateWS): % (node_name, self.state_machine.abs_line_number() + 1))) +def build_regexp(definition, compile=1): + """ + Build, compile and return a regular expression based on `definition`. + + :Parameter: `definition`: a 4-tuple (group name, prefix, suffix, parts), + where "parts" is a list of regular expressions and/or regular + expression definitions to be joined into an or-group. + """ + name, prefix, suffix, parts = definition + part_strings = [] + for part in parts: + if type(part) is TupleType: + part_strings.append(build_regexp(part, None)) + else: + part_strings.append(part) + or_group = '|'.join(part_strings) + regexp = '%(prefix)s(?P<%(name)s>%(or_group)s)%(suffix)s' % locals() + if compile: + return re.compile(regexp, re.UNICODE) + else: + return regexp + + class Inliner: """ @@ -439,54 +462,34 @@ class Inliner: uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" urilast = r"""[_~/\]a-zA-Z0-9]""" # no punctuation emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" + parts = ('initial_inline', start_string_prefix, '', + [('start', '', non_whitespace_after, # simple start-strings + [r'\*\*', # strong + r'\*(?!\*)', # emphasis but not strong + r'``', # literal + r'_`', # inline internal target + r'\|'] # substitution reference + ), + ('whole', '', end_string_suffix, # whole constructs + [# reference name & end-string + r'(?P<refname>%s)(?P<refend>__?)' % simplename, + ('footnotelabel', r'\[', r'(?P<fnend>\]_)', + [r'[0-9]+', # manually numbered + r'\#(%s)?' % simplename, # auto-numbered (w/ label?) + r'\*', # auto-symbol + r'(?P<citationlabel>%s)' % simplename] # citation reference + ) + ] + ), + ('backquote', # interpreted text or phrase reference + '(?P<role>(:%s:)?)' % simplename, # optional role + non_whitespace_after, + ['`(?!`)'] # but not literal + ) + ] + ) patterns = Stuff( - initial=re.compile( - r""" - %(start_string_prefix)s - ( - (?P<start> # start-strings only: - \*\* # strong - | - \* # emphasis - (?!\*) # but not strong - | - `` # literal - | - _` # inline hyperlink target - | - \| # substitution_reference start - ) - %(non_whitespace_after)s - | # *OR* - (?P<whole> # whole constructs: - (?P<refname>%(simplename)s) # reference name - (?P<refend>__?) # end-string - | - \[ # footnote_reference or - # citation_reference start - (?P<footnotelabel> # label: - [0-9]+ # manually numbered - | # *OR* - \#(%(simplename)s)? # auto-numbered (w/ label?) - | # *OR* - \* # auto-symbol - | # *OR* - (?P<citationlabel> - %(simplename)s) # citation reference - ) - (?P<fnend>\]_) # end-string - ) - %(end_string_suffix)s - | # *OR* - (?P<role>(:%(simplename)s:)?) # optional role - (?P<backquote> # start-string - ` # interpreted text - # or phrase reference - (?!`) # but not literal - ) - %(non_whitespace_after)s # no whitespace after - ) - """ % locals(), re.VERBOSE | re.UNICODE), + initial=build_regexp(parts), emphasis=re.compile(non_whitespace_escape_before + r'(\*)' + end_string_suffix), strong=re.compile(non_whitespace_escape_before @@ -679,7 +682,7 @@ class Inliner: restore_backslashes=1) return before, inlines, remaining, sysmessages - def inline_target(self, match, lineno): + def inline_internal_target(self, match, lineno): before, inlines, remaining, sysmessages, endstring = self.inline_obj( match, lineno, self.patterns.target, nodes.target) if inlines and isinstance(inlines[0], nodes.target): @@ -817,7 +820,7 @@ class Inliner: '**': strong, '`': interpreted_or_phrase_ref, '``': literal, - '_`': inline_target, + '_`': inline_internal_target, ']_': footnote_reference, '|': substitution_reference, '_': reference, -- cgit v1.2.1 From 005c5319f9cbf6f4776e117e5bb6b690f3cf3374 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 13 Jul 2002 03:06:48 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@276 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 28 ++++++++++++++++++---------- docs/dev/todo.txt | 17 ++++++++++++++--- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index f9e537a46..9b4e27013 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,14 +17,15 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - Aahz, David Ascher, Simon Budig, Adam Chodorowski, Fred Drake, - Dethe Elza, Jim Fulton, Peter Funk, Engelbert Gruber, Doug - Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard Jones, - Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, - Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam - Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, - Ueli Schlaepfer, tav, Bob Tolbert, Laurence Tratt, Guido van - Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Aahz, David Ascher, Fred Bremmer, Simon Budig, Adam Chodorowski, + Fred Drake, Dethe Elza, Jim Fulton, Peter Funk, Engelbert Gruber, + Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard + Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang + Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, + Sam Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ollie + Rutherfurd, Ueli Schlaepfer, tav, Bob Tolbert, Laurence Tratt, + Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, + Moshe Zadka Thank you! @@ -99,6 +100,7 @@ Specific: ``nametypes`` attribute and ``set_name_id_map`` method. - Added ``NodeFound`` exception, for use with ``NodeVisitor`` traversals. + - Added ``document.has_name()`` method. * docutils/optik.py: Added to project. Combined from the Optik package, with added option groups and other modifications. The use @@ -150,6 +152,9 @@ Specific: - 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``. * docutils/parsers/rst/directives/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -243,8 +248,10 @@ Specific: * 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. +* spec/rst/alternatives.txt: + + - Expanded auto-enumerated list idea; thanks to Fred Bremmer. + - Added "Inline External Targets" section. * spec/rst/problems.txt: @@ -259,6 +266,7 @@ Specific: - 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". * test: Made test modules standalone (subdirectories became packages). diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 933294fe4..a42f8d74f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -25,7 +25,20 @@ you'd like to tackle, please do! Bugs ---- -None reported. +- The "contents" directive now automatically names the "topic" + produced (using its title), so that it can be referred to by name. + However, this naming happens late in the game, after most references + have been resolved. So the following indirect target produces a + warning because the name "contents" is not available when resolved:: + + .. contents:: + + .. _alternate name for contents: contents_ + + Fixing this may be tricky, and isn't a high priority. + + Idea: two-pass hyperlink resolution, ignoring errors on the first + pass? General @@ -95,8 +108,6 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -- Add "NullIO" degenerate ``docutils.io.IO`` subclass. - - Add a command-line option & directive attribute to control TOC backlinks: no TOC backlinks, backlinks to TOC entries, or backlinks to TOC itself only. -- cgit v1.2.1 From c21a148798856797bbf693ff1f5c8ba9c604cce1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 02:45:41 +0000 Subject: Undid a mistake. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@278 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 6c26b779b..9b4114b80 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -802,18 +802,14 @@ class Inliner: match = pattern.search(text) if match: try: - return (self.text(text[:match.start()]) + # Must recurse on strings before *and* after the match; + # there may be multiple patterns. + return (self.implicit_inline(text[:match.start()], lineno) + dispatch(self, match, lineno) + self.implicit_inline(text[match.end():], lineno)) except MarkupMismatch: pass return [nodes.Text(unescape(text))] - - def text(self, text): - """Return a list containing one `nodes.Text` node or nothing.""" - if not text: - return [] - return [nodes.Text(unescape(text))] dispatch = {'*': emphasis, -- cgit v1.2.1 From 6d6d20b280a38ca0d7b20b018d09c8bd3402758a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 02:47:41 +0000 Subject: Added a transform to insert a table of contents. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@279 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 1 + docutils/transforms/peps.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b7fabebb9..a4dc17cf1 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -29,6 +29,7 @@ class Reader(standalone.Reader): transforms = (references.Substitutions, peps.Headers, + peps.Contents, references.Footnotes, references.Hyperlinks,) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 70775c930..d33e0989d 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -21,6 +21,7 @@ import time from docutils import nodes, utils from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError +from docutils.transforms import parts class Headers(Transform): @@ -98,3 +99,17 @@ class Headers(Transform): para[:] = [nodes.reference('', date, refuri=uri)] elif name == 'version' and len(body): utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) + + +class Contents(Transform): + + """ + Insert a table of contents into the document after the RFC 2822 header. + """ + + + def transform(self): + pending = nodes.pending(parts.Contents, 'last reader', + {'title': None}) + self.document.insert(1, pending) + self.document.note_pending(pending) -- cgit v1.2.1 From baa38a937c93e341f6805c9220d42515d18a94b1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 02:51:19 +0000 Subject: - Added the translator class as instance variable to the Writer, to make it easily subclassable. - Modified the ``field_body`` output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@280 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 956303fad..9c5e14c62 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -39,8 +39,12 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = HTMLTranslator + def translate(self): - visitor = HTMLTranslator(self.document) + visitor = self.translator_class(self.document) self.document.walkabout(visitor) self.output = visitor.astext() self.head_prefix = visitor.head_prefix @@ -402,11 +406,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</span>') def visit_field_body(self, node): - self.body.append(':</p>\n</td><td>') - self.body.append(self.starttag(node, 'div', CLASS='field-body')) + self.body.append(':</p>\n</td><td>\n') + #self.body.append(self.starttag(node, 'div', CLASS='field-body')) def depart_field_body(self, node): - self.body.append('</div></td>\n') + #self.body.append('</div></td>\n') + self.body.append('</td>\n') def visit_field_list(self, node): self.body.append(self.starttag(node, 'table', frame='void', -- cgit v1.2.1 From c81e34a5e7c0dd16fa6863908ff354c3b96f03b3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 02:58:29 +0000 Subject: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@281 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 docutils/writers/pep_html.py diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py new file mode 100644 index 000000000..37825d331 --- /dev/null +++ b/docutils/writers/pep_html.py @@ -0,0 +1,66 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +PEP HTML Writer. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes +from docutils.writers import html4css1 + + +class Writer(html4css1.Writer): + + cmdline_options = ( + 'PEP/HTML-Specific Options', + None, + (('Specify a stylesheet file. Default is "rststyle.css".', + ['--stylesheet'], + {'default': 'rststyle.css', 'metavar': '<file>'}), + ('Specify a template file. Default is "peptemplate.html".', + ['--template'], + {'default': 'peptemplate.html', 'metavar': '<file>'}), + ('Python\'s home URL. Default is "http://www.python.org".', + ['--python-home'], + {'default': 'http://www.python.org', 'metavar': '<URL>'}), + ('Home URL for this PEP. Default is "." (current directory).', + ['--pep-home'], + {'default': '.', 'metavar': '<URL>'}),)) + + def __init__(self): + html4css1.Writer.__init__(self) + self.translator_class = HTMLTranslator + + def translate(self): + html4css1.Writer.translate(self) + options = self.document.options + template = open(options.template).read() + pyhome = options.python_home + pephome = options.pep_home + index = self.document.first_child_matching_class(nodes.field_list) + header = self.document[index] + pep = header[0][1].astext() + try: + pepnum = '%04i' % int(pep) + except: + pepnum = pep + title = self.document[1][1].astext() + body = ''.join(self.body) + body_suffix = ''.join(self.body_suffix) + self.output = template % locals() + + +class HTMLTranslator(html4css1.HTMLTranslator): + + def depart_field_list(self, node): + html4css1.HTMLTranslator.depart_field_list(self, node) + if node.hasattr('class') and node['class'] == 'rfc2822': + self.body.append('<hr />\n') -- cgit v1.2.1 From 87a70f1ac5fb68d2d2303a49916eefdb06da4f13 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:01:02 +0000 Subject: Updated. Added "Roadmap to the Doctring PEPs" section. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@282 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0256.txt | 64 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index 92c8e7f61..7f438a8d8 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -32,6 +32,39 @@ Abstract implementation details. +Roadmap to the Doctring PEPs + + There are many aspects to docstring processing. The "Docstring + PEPs" have broken up the issues in order to deal with each of them + in isolation, or as close as possible. The individual aspects and + associated PEPs are as follows: + + * Docstring syntax. PEP 287, reStructuredText Docstring Format, + proposes a syntax for Python docstrings, PEPs, and other uses. + + * Docstring semantics consist of at least two aspects: + + - Conventions: the high-level structure of docstrings. Dealt + with in PEP 257, Docstring Conventions. + + - Methodology: rules for the informational content of + docstrings. Not addressed. + + * Processing mechanisms. This PEP outlines the high-level issues + and specification of an abstract docstring processing system + (DPS). PEP 258, Docutils Design Specification, is an overview + of the design and implementation of one DPS under development. + + * Output styles: developers want the documentation generated from + their source code to look good, and there are many different + ideas about what that means. PEP 258 touches on "Stylist + Transforms". This aspect of docstring processing has yet to be + fully explored. + + By separating out the issues, we can form consensus more easily + (smaller fights ;-), and accept divergence more readily. + + Rationale There are standard inline documentation systems for some other @@ -63,20 +96,22 @@ Rationale These systems, each with different goals, have had varying degrees of success. A problem with many of the above systems was over-ambition combined with inflexibility. They provided a - self-contained set of components: a docstring extraction system, - a markup parser, an internal processing system and one or more - output format writers. Inevitably, one or more aspects of each - system had serious shortcomings, and they were not easily extended - or modified, preventing them from being adopted as standard tools. + self-contained set of components: a docstring extraction system, a + markup parser, an internal processing system and one or more + output format writers with a fixed style. Inevitably, one or more + aspects of each system had serious shortcomings, and they were not + easily extended or modified, preventing them from being adopted as + standard tools. It has become clear (to this author, at least) that the "all or nothing" approach cannot succeed, since no monolithic self-contained system could possibly be agreed upon by all interested parties. A modular component approach designed for extension, where components may be multiply implemented, may be - the only chance for success. By separating out the issues, we can - form consensus more easily (smaller fights ;-), and accept - divergence more readily. + the only chance for success. Standard inter-component APIs will + make the DPS components comprehensible without requiring detailed + knowledge of the whole, lowering the barrier for contributions, + and ultimately resulting in a rich and varied system. Each of the components of a docstring processing system should be developed independently. A 'best of breed' system should be @@ -169,16 +204,19 @@ Specification 3. Docstring processing system implementation. - 4. Input markup specifications: docstring syntax. PEP 2xx, - reStructuredText Standard Docstring Format [15]_, proposes a - standard syntax. + 4. Input markup specifications: docstring syntax. PEP 287, + reStructuredText Docstring Format [15]_, proposes a standard + syntax. 5. Input parser implementations. 6. Input context readers ("modes": Python source code, PEP, standalone text file, email, etc.) and implementations. - 7. Output formats (HTML, XML, TeX, DocBook, info, etc.) and writer + 7. Stylists: certain input context readers may have associated + stylists which allow for a variety of output document styles. + + 8. Output formats (HTML, XML, TeX, DocBook, info, etc.) and writer implementations. Components 1, 2/3, and 4/5 are the subject of individual companion @@ -227,7 +265,7 @@ References and Footnotes [14] PEP 257, Docstring Conventions, Goodger, Van Rossum http://www.python.org/peps/pep-0257.html - [15] PEP 287, reStructuredText Standard Docstring Format, Goodger + [15] PEP 287, reStructuredText Docstring Format, Goodger http://www.python.org/peps/pep-0287.html [16] http://www.python.org/sigs/doc-sig/ -- cgit v1.2.1 From 971268e6bf94ff9dd7792a96ebdd10e669f2fe2b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:01:47 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@283 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0258.txt | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 9360fcf11..a66feeb95 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -16,7 +16,13 @@ Abstract This PEP documents design issues and implementation details for Docutils, a Python Docstring Processing System (DPS). The rationale and high-level concepts of a DPS are documented in PEP - 256, "Docstring Processing System Framework" [1]. + 256, "Docstring Processing System Framework" [1]. Also see PEP + 256 for a "Roadmap to the Doctring PEPs". + + Docutils is being designed modularly so that any of its components + can be replaced easily. In addition, Docutils is not limited to + the processing of Python docstrings; it processes standalone + documents as well, in several contexts. No changes to the core Python language are required by this PEP. Its deliverables consist of a package for the standard library and @@ -48,14 +54,14 @@ Specification | I/O | | PARSER |...| reader | | writer | | I/O | +-----+ +--------+ | transforms | | transforms | +-----+ | | | | - | - docinfo | | - styling | - | - titles | | - writer- | - | - linking | | specific | - | - lookups | | - etc. | - | - reader- | +------------+ - | specific | - | - parser- | - | specific | + | - docinfo | | - system | + | - titles | | messages | + | - linking | | - final | + | - lookups | | checks | + | - reader- | | - writer- | + | specific | | specific | + | - parser- | | - etc. | + | specific | +------------+ | - layout | | (stylist) | | - etc. | @@ -494,10 +500,12 @@ Specification Python Source Reader ==================== - The Python Source Reader ("PySource") is a major and non-trivial - Docutils component, currently under experimental development in - the Docutils sandbox. High-level design issues are presented - here. + The Python Source Reader ("PySource") is the Docutils component + that reads Python source files, extracts docstrings in context, + then parses, links, and assembles the docstrings into a cohesive + whole. It is a major and non-trivial component, currently under + experimental development in the Docutils sandbox. High-level + design issues are presented here. Processing Model -- cgit v1.2.1 From 0d96dc848e8d1066ff28c81add99bbe9c7dc8b72 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:05:12 +0000 Subject: Renamed to "reStructuredText Docstring Format" and updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@284 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 54 +++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 51ce5762a..96a8ff3c8 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -1,5 +1,5 @@ PEP: 287 -Title: reStructuredText Standard Docstring Format +Title: reStructuredText Docstring Format Version: $Revision$ Last-Modified: $Date$ Author: goodger@users.sourceforge.net (David Goodger) @@ -23,11 +23,11 @@ Abstract plaintext markup syntax. Only the low-level syntax of docstrings is addressed here. This - PEP is not concerned with docstring semantics or processing at - all. Nor is it an attempt to deprecate pure plaintext docstrings, - which are always going to be legitimate. The reStructuredText - markup is an alternative for those who want more expressive - docstrings. + PEP is not concerned with docstring semantics or processing at all + (see PEP 256 for a "Roadmap to the Doctring PEPs"). Nor is it an + attempt to deprecate pure plaintext docstrings, which are always + going to be legitimate. The reStructuredText markup is an + alternative for those who want more expressive docstrings. Benefits @@ -48,26 +48,26 @@ Benefits and software systems; readers are only meant to see the processed form, either on paper or via browser software. ReStructuredText is different: it is intended to be easily readable in source form, - without prior knowledge of the markup. ReStructuredText is + without prior knowledge of the markup. ReStructuredText is entirely readable in plaintext format, and many of the markup forms match common usage (e.g., ``*emphasis*``), so it reads quite naturally. Yet it is rich enough to produce complex documents, and extensible so that there are few limits. Of course, to write - reStructuredText documents prior knowledge is required. + reStructuredText documents some prior knowledge is required. The reStructuredText parser is available now. The Docutils project is at the point where standalone reStructuredText documents can be converted to HTML; other output format writers will become available over time. Work is progressing on a Python - source "Reader" which will implement auto-documentation. Authors - of existing auto-documentation tools are encouraged to integrate - the reStructuredText parser into their projects, or better yet, to - join forces to produce a world-class toolset for the Python - standard library. + source "Reader" which will implement auto-documentation from + docstrings. Authors of existing auto-documentation tools are + encouraged to integrate the reStructuredText parser into their + projects, or better yet, to join forces to produce a world-class + toolset for the Python standard library. Tools will become available in the near future, which will allow programmers to generate HTML for online help, XML for multiple - purposes, and eventually PDF/DocBook/LaTeX for printed + purposes, and eventually PDF, DocBook, and LaTeX for printed documentation, essentially "for free" from the existing docstrings. The adoption of a standard will, at the very least, benefit docstring processing tools by preventing further @@ -76,7 +76,7 @@ Benefits Eventually PyDoc, the one existing standard auto-documentation tool, could have reStructuredText support added. In the interim it will have no problem with reStructuredText markup, since it - treats all docstrings as plaintext. + treats all docstrings as preformatted plaintext. Goals @@ -166,12 +166,12 @@ Rationale others): 1. Docstrings written within Python code are available from within - the interactive interpreter, and can be 'print'ed. Thus the + the interactive interpreter, and can be "print"ed. Thus the use of plaintext for easy readability. 2. Programmers want to add structure to their docstrings, without sacrificing raw docstring readability. Unadorned plaintext - cannot be transformed ('up-translated') into useful structured + cannot be transformed ("up-translated") into useful structured formats. 3. Explicit markup (like XML or TeX) is widely considered @@ -225,7 +225,7 @@ Rationale Early on, variants of Setext (Structure Enhanced Text), including Zope Corp's StructuredText, were proposed for Python docstring formatting. Hereafter these variants will - collectively be call 'STexts'. STexts have the advantage of + collectively be called "STexts". STexts have the advantage of being easy to read without special knowledge, and relatively easy to write. @@ -577,11 +577,14 @@ Questions & Answers This PEP proposes adding `frungible doodads`_ to the core. It extends PEP 9876 [#pep9876]_ via the BCA [#]_ mechanism. - .. _frungible doodads: http://www.example.org/ + ... + + References & Footnotes + ====================== - .. [#pep9876] `PEP 9876`__, Let's Hope We Never Get Here + .. _frungible doodads: http://www.example.org/ - __ http://www.python.org/peps/pep-9876.html + .. [#pep9876] PEP 9876, Let's Hope We Never Get Here .. [#] "Bogus Complexity Addition" @@ -597,7 +600,7 @@ Questions & Answers URL references can be named ("frungible doodads"), and can be referenced from multiple places in the document without additional definitions. When converted to HTML, references - will be replaced with inline hyperlinks (HTML <A> tags). The + will be replaced with inline hyperlinks (HTML <a> tags). The two footnotes are automatically numbered, so they will always stay in sync. The first footnote also contains an internal reference name, "pep9876", so it's easier to see the connection @@ -610,7 +613,7 @@ Questions & Answers It extends PEP 9876 [PEP9876]_ ... - .. [PEP9876] `PEP 9876`_, Let's Hope We Never Get Here + .. [PEP9876] PEP 9876, Let's Hope We Never Get Here Footnotes are numbered, whereas citations use text for their references. @@ -779,8 +782,9 @@ References & Footnotes [22] http://docutils.sourceforge.net/ - [23] From "The Zen of Python (by Tim Peters)", - http://www.python.org/doc/Humor.html#zen (or ``import this``) + [23] From "The Zen of Python (by Tim Peters)" + (http://www.python.org/doc/Humor.html#zen or just + "``import this``" in Python) [24] PEP 216, Docstring Format, Zadka http://www.python.org/peps/pep-0216.html -- cgit v1.2.1 From 0f70ab017321ae0f80a4aeaa2adcafb12dd26cb3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:10:30 +0000 Subject: Changed stylesheet & template file names. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@285 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 37825d331..e1452a5e0 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -22,12 +22,12 @@ class Writer(html4css1.Writer): cmdline_options = ( 'PEP/HTML-Specific Options', None, - (('Specify a stylesheet file. Default is "rststyle.css".', + (('Specify a stylesheet file. Default is "pep.css".', ['--stylesheet'], - {'default': 'rststyle.css', 'metavar': '<file>'}), - ('Specify a template file. Default is "peptemplate.html".', + {'default': 'pep.css', 'metavar': '<file>'}), + ('Specify a template file. Default is "pep-template.html".', ['--template'], - {'default': 'peptemplate.html', 'metavar': '<file>'}), + {'default': 'pep-template.html', 'metavar': '<file>'}), ('Python\'s home URL. Default is "http://www.python.org".', ['--python-home'], {'default': 'http://www.python.org', 'metavar': '<URL>'}), -- cgit v1.2.1 From 8139dee08117675b9882c2c5fc02be7c66a9341e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:14:29 +0000 Subject: Added to project; stylesheet for PEPs. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@286 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 206 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tools/stylesheets/pep.css diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css new file mode 100644 index 000000000..00e586c50 --- /dev/null +++ b/tools/stylesheets/pep.css @@ -0,0 +1,206 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date$ +:version: $Revision$ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the PEP HTML output of Docutils. +*/ + +.navigation { + width: 100% ; + background: #99ccff } + +.navigation .navicon { + width: 150px ; + height: 35 } + +.navigation .textlinks { + padding-left: 1em ; + text-align: left } + +.rfc2822 { + margin-top: 0.5em ; + margin-left: 1em ; + margin-right: 1em } + +.rfc2822 div.field-body { + text-align: left } + +.rfc2822 p.field-name { + text-align: right ; + font-family: sans-serif ; + padding-right: 0.5em ; + font-weight: bold ; + margin-bottom: 0em } + +a.footnote-reference { + font-size: smaller ; + vertical-align: super } + +a.target { + color: blue } + +body { + margin: 0px ; + margin-bottom: 1em ; + padding: 0px } + +code { + background-color: #eeeeee } + +div.section { + margin-left: 1em ; + margin-right: 1em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.footer p { + margin-left: 1em ; + margin-right: 1em } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1 { + font-family: sans-serif ; + font-size: large } + +h2 { + font-family: sans-serif ; + font-size: medium } + +h3 { + font-family: sans-serif ; + font-size: small } + +h4 { + font-family: sans-serif ; + font-style: italic ; + font-size: small } + +h5 { + font-family: sans-serif; + font-size: x-small } + +h6 { + font-family: sans-serif; + font-style: italic ; + font-size: x-small } + +.section hr { + width: 75% } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +dd p:first-child { + margin-top: 0px } + +li p:first-child { + margin-top: 0px } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.field-name { + font-weight: bold ; + margin-bottom: 1em } + +p.label { + white-space: nowrap } + +p.topic-title { + font-family: sans-serif ; + font-weight: bold } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.field-argument { + font-style: italic } + +span.interpreted { + font-family: sans-serif } + +span.option-argument { + font-style: italic } + +span.problematic { + color: red } + +table.citation { + margin-bottom: 1em } + +table.footnote { + margin-bottom: 1em } -- cgit v1.2.1 From 4f9dc43240ea31269c8fdc2aa877ffed51f7060c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:15:19 +0000 Subject: Added to project; template for PEP HTML. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@287 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-template.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tools/pep-template.html diff --git a/tools/pep-template.html b/tools/pep-template.html new file mode 100644 index 000000000..eabd3bcb8 --- /dev/null +++ b/tools/pep-template.html @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta name="generator" content="Docutils: http://docutils.sourceforge.net/"> + <title>PEP %(pep)s -- %(title)s + + + + + + +%(body)s +%(body_suffix)s -- cgit v1.2.1 From 078916ea45ccd1d7e40328c148be92e69ad25519 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 14 Jul 2002 03:18:57 +0000 Subject: Added to project; PEP to HTML front-end. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@288 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 tools/pep.py diff --git a/tools/pep.py b/tools/pep.py new file mode 100755 index 000000000..acaab10c4 --- /dev/null +++ b/tools/pep.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +A minimal front-end to the Docutils Publisher, producing HTML from PEP +(Python Enhancement Proposal) documents. +""" + +import locale +locale.setlocale(locale.LC_ALL, '') + +from docutils.core import publish + + +usage = 'usage:\n %prog [options] [source [destination]]' + +publish(reader_name='pep', writer_name='pep_html', usage=usage) -- cgit v1.2.1 From 45342c40e8549076254dc482c588844032eaf406 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 14 Jul 2002 03:22:34 +0000 Subject: Converted to reStructuredText. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@289 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 1308 ++++++++++++++++++++++++------------------------ 1 file changed, 649 insertions(+), 659 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 96a8ff3c8..20e937105 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -12,802 +12,792 @@ Replaces: 216 Abstract +======== - When plaintext hasn't been expressive enough for inline - documentation, Python programmers have sought out a format for - docstrings. This PEP proposes that the reStructuredText markup - [1]_ be adopted as a standard markup format for structured - plaintext documentation in Python docstrings, and for PEPs and - ancillary documents as well. reStructuredText is a rich and - extensible yet easy-to-read, what-you-see-is-what-you-get - plaintext markup syntax. +When plaintext hasn't been expressive enough for inline documentation, +Python programmers have sought out a format for docstrings. This PEP +proposes that the `reStructuredText markup`_ be adopted as a standard +markup format for structured plaintext documentation in Python +docstrings, and for PEPs and ancillary documents as well. +reStructuredText is a rich and extensible yet easy-to-read, +what-you-see-is-what-you-get plaintext markup syntax. - Only the low-level syntax of docstrings is addressed here. This - PEP is not concerned with docstring semantics or processing at all - (see PEP 256 for a "Roadmap to the Doctring PEPs"). Nor is it an - attempt to deprecate pure plaintext docstrings, which are always - going to be legitimate. The reStructuredText markup is an - alternative for those who want more expressive docstrings. +Only the low-level syntax of docstrings is addressed here. This PEP +is not concerned with docstring semantics or processing at all (see +PEP 256 for a "Roadmap to the Doctring PEPs"). Nor is it an attempt +to deprecate pure plaintext docstrings, which are always going to be +legitimate. The reStructuredText markup is an alternative for those +who want more expressive docstrings. Benefits - - Programmers are by nature a lazy breed. We reuse code with - functions, classes, modules, and subsystems. Through its - docstring syntax, Python allows us to document our code from - within. The "holy grail" of the Python Documentation Special - Interest Group (Doc-SIG) [2]_ has been a markup syntax and toolset - to allow auto-documentation, where the docstrings of Python - systems can be extracted in context and processed into useful, - high-quality documentation for multiple purposes. - - Document markup languages have three groups of customers: the - authors who write the documents, the software systems that process - the data, and the readers, who are the final consumers and the - most important group. Most markups are designed for the authors - and software systems; readers are only meant to see the processed - form, either on paper or via browser software. ReStructuredText - is different: it is intended to be easily readable in source form, - without prior knowledge of the markup. ReStructuredText is - entirely readable in plaintext format, and many of the markup - forms match common usage (e.g., ``*emphasis*``), so it reads quite - naturally. Yet it is rich enough to produce complex documents, - and extensible so that there are few limits. Of course, to write - reStructuredText documents some prior knowledge is required. - - The reStructuredText parser is available now. The Docutils - project is at the point where standalone reStructuredText - documents can be converted to HTML; other output format writers - will become available over time. Work is progressing on a Python - source "Reader" which will implement auto-documentation from - docstrings. Authors of existing auto-documentation tools are - encouraged to integrate the reStructuredText parser into their - projects, or better yet, to join forces to produce a world-class - toolset for the Python standard library. - - Tools will become available in the near future, which will allow - programmers to generate HTML for online help, XML for multiple - purposes, and eventually PDF, DocBook, and LaTeX for printed - documentation, essentially "for free" from the existing - docstrings. The adoption of a standard will, at the very least, - benefit docstring processing tools by preventing further - "reinventing the wheel". - - Eventually PyDoc, the one existing standard auto-documentation - tool, could have reStructuredText support added. In the interim - it will have no problem with reStructuredText markup, since it - treats all docstrings as preformatted plaintext. +======== + +Programmers are by nature a lazy breed. We reuse code with functions, +classes, modules, and subsystems. Through its docstring syntax, +Python allows us to document our code from within. The "holy grail" +of the Python Documentation Special Interest Group (Doc-SIG_) has been +a markup syntax and toolset to allow auto-documentation, where the +docstrings of Python systems can be extracted in context and processed +into useful, high-quality documentation for multiple purposes. + +Document markup languages have three groups of customers: the authors +who write the documents, the software systems that process the data, +and the readers, who are the final consumers and the most important +group. Most markups are designed for the authors and software +systems; readers are only meant to see the processed form, either on +paper or via browser software. ReStructuredText is different: it is +intended to be easily readable in source form, without prior knowledge +of the markup. ReStructuredText is entirely readable in plaintext +format, and many of the markup forms match common usage (e.g., +``*emphasis*``), so it reads quite naturally. Yet it is rich enough +to produce complex documents, and extensible so that there are few +limits. Of course, to write reStructuredText documents some prior +knowledge is required. + +The reStructuredText parser is available now. The Docutils project is +at the point where standalone reStructuredText documents can be +converted to HTML; other output format writers will become available +over time. Work is progressing on a Python source "Reader" which will +implement auto-documentation from docstrings. Authors of existing +auto-documentation tools are encouraged to integrate the +reStructuredText parser into their projects, or better yet, to join +forces to produce a world-class toolset for the Python standard +library. + +Tools will become available in the near future, which will allow +programmers to generate HTML for online help, XML for multiple +purposes, and eventually PDF, DocBook, and LaTeX for printed +documentation, essentially "for free" from the existing docstrings. +The adoption of a standard will, at the very least, benefit docstring +processing tools by preventing further "reinventing the wheel". + +Eventually PyDoc, the one existing standard auto-documentation tool, +could have reStructuredText support added. In the interim it will +have no problem with reStructuredText markup, since it treats all +docstrings as preformatted plaintext. Goals +===== - These are the generally accepted goals for a docstring format, as - discussed in the Doc-SIG: +These are the generally accepted goals for a docstring format, as +discussed in the Doc-SIG: - 1. It must be readable in source form by the casual observer. +1. It must be readable in source form by the casual observer. - 2. It must be easy to type with any standard text editor. +2. It must be easy to type with any standard text editor. - 3. It must not need to contain information which can be deduced - from parsing the module. +3. It must not need to contain information which can be deduced from + parsing the module. - 4. It must contain sufficient information (structure) so it can be - converted to any reasonable markup format. +4. It must contain sufficient information (structure) so it can be + converted to any reasonable markup format. - 5. It must be possible to write a module's entire documentation in - docstrings, without feeling hampered by the markup language. +5. It must be possible to write a module's entire documentation in + docstrings, without feeling hampered by the markup language. - reStructuredText meets and exceeds all of these goals, and sets - its own goals as well, even more stringent. See - "Docstring-Significant Features" below. +reStructuredText meets and exceeds all of these goals, and sets its +own goals as well, even more stringent. See `Docstring-Significant +Features`_ below. - The goals of this PEP are as follows: +The goals of this PEP are as follows: - 1. To establish reStructuredText as a standard structured - plaintext format for docstrings (inline documentation of Python - modules and packages), PEPs, README-type files and other - standalone documents. "Accepted" status will be sought through - Python community consensus and eventual BDFL pronouncement. +1. To establish reStructuredText as a standard structured plaintext + format for docstrings (inline documentation of Python modules and + packages), PEPs, README-type files and other standalone documents. + "Accepted" status will be sought through Python community consensus + and eventual BDFL pronouncement. - Please note that reStructuredText is being proposed as *a* - standard, not *the only* standard. Its use will be entirely - optional. Those who don't want to use it need not. + Please note that reStructuredText is being proposed as *a* + standard, not *the only* standard. Its use will be entirely + optional. Those who don't want to use it need not. - 2. To solicit and address any related concerns raised by the - Python community. +2. To solicit and address any related concerns raised by the Python + community. - 3. To encourage community support. As long as multiple competing - markups are out there, the development community remains - fractured. Once a standard exists, people will start to use - it, and momentum will inevitably gather. +3. To encourage community support. As long as multiple competing + markups are out there, the development community remains fractured. + Once a standard exists, people will start to use it, and momentum + will inevitably gather. - 4. To consolidate efforts from related auto-documentation - projects. It is hoped that interested developers will join - forces and work on a joint/merged/common implementation. +4. To consolidate efforts from related auto-documentation projects. + It is hoped that interested developers will join forces and work on + a joint/merged/common implementation. - Once reStructuredText is a Python standard, effort can be focused - on tools instead of arguing for a standard. Python needs a - standard set of documentation tools. +Once reStructuredText is a Python standard, effort can be focused on +tools instead of arguing for a standard. Python needs a standard set +of documentation tools. - With regard to PEPs, one or both of the following strategies may - be applied: +With regard to PEPs, one or both of the following strategies may be +applied: - a) Keep the existing PEP section structure constructs (one-line - section headers, indented body text). Subsections can either - be forbidden, or supported with reStructuredText-style - underlined headers in the indented body text. +a) Keep the existing PEP section structure constructs (one-line + section headers, indented body text). Subsections can either be + forbidden, or supported with reStructuredText-style underlined + headers in the indented body text. - b) Replace the PEP section structure constructs with the - reStructuredText syntax. Section headers will require - underlines, subsections will be supported out of the box, - and body text need not be indented (except for block - quotes). +b) Replace the PEP section structure constructs with the + reStructuredText syntax. Section headers will require underlines, + subsections will be supported out of the box, and body text need + not be indented (except for block quotes). - Support for RFC 2822 headers has been added to the - reStructuredText parser for PEPs (unambiguous given a specific - context: the first contiguous block of the document). It may be - desired to concretely specify what over/underline styles are - allowed for PEP section headers, for uniformity. +Support for RFC 2822 headers has been added to the reStructuredText +parser for PEPs (unambiguous given a specific context: the first +contiguous block of the document). It may be desired to concretely +specify what over/underline styles are allowed for PEP section +headers, for uniformity. Rationale +========= + +The lack of a standard syntax for docstrings has hampered the +development of standard tools for extracting and converting docstrings +into documentation in standard formats (e.g., HTML, DocBook, TeX). +There have been a number of proposed markup formats and variations, +and many tools tied to these proposals, but without a standard +docstring format they have failed to gain a strong following and/or +floundered half-finished. + +Throughout the existence of the Doc-SIG, consensus on a single +standard docstring format has never been reached. A lightweight, +implicit markup has been sought, for the following reasons (among +others): - The lack of a standard syntax for docstrings has hampered the - development of standard tools for extracting and converting - docstrings into documentation in standard formats (e.g., HTML, - DocBook, TeX). There have been a number of proposed markup - formats and variations, and many tools tied to these proposals, - but without a standard docstring format they have failed to gain a - strong following and/or floundered half-finished. - - Throughout the existence of the Doc-SIG, consensus on a single - standard docstring format has never been reached. A lightweight, - implicit markup has been sought, for the following reasons (among - others): +1. Docstrings written within Python code are available from within the + interactive interpreter, and can be "print"ed. Thus the use of + plaintext for easy readability. - 1. Docstrings written within Python code are available from within - the interactive interpreter, and can be "print"ed. Thus the - use of plaintext for easy readability. +2. Programmers want to add structure to their docstrings, without + sacrificing raw docstring readability. Unadorned plaintext cannot + be transformed ("up-translated") into useful structured formats. - 2. Programmers want to add structure to their docstrings, without - sacrificing raw docstring readability. Unadorned plaintext - cannot be transformed ("up-translated") into useful structured - formats. +3. Explicit markup (like XML or TeX) is widely considered unreadable + by the uninitiated. - 3. Explicit markup (like XML or TeX) is widely considered - unreadable by the uninitiated. +4. Implicit markup is aesthetically compatible with the clean and + minimalist Python syntax. - 4. Implicit markup is aesthetically compatible with the clean and - minimalist Python syntax. +Many alternative markups for docstrings have been proposed on the +Doc-SIG over the years; a representative sample is listed below. Each +is briefly analyzed in terms of the goals stated above. Please note +that this is *not* intended to be an exclusive list of all existing +markup systems; there are many other markups (Texinfo, Doxygen, TIM, +YODL, AFT, ...) which are not mentioned. - Many alternative markups for docstrings have been proposed on the - Doc-SIG over the years; a representative sample is listed below. - Each is briefly analyzed in terms of the goals stated above. - Please note that this is *not* intended to be an exclusive list of - all existing markup systems; there are many other markups - (Texinfo, Doxygen, TIM, YODL, AFT, ...) which are not mentioned. +- XML_, SGML_, DocBook_, HTML_, XHTML_ - - XML [3]_, SGML [4]_, DocBook [5]_, HTML [6]_, XHTML [7]_ + XML and SGML are explicit, well-formed meta-languages suitable for + all kinds of documentation. XML is a variant of SGML. They are + best used behind the scenes, because to untrained eyes they are + verbose, difficult to type, and too cluttered to read comfortably as + source. DocBook, HTML, and XHTML are all applications of SGML + and/or XML, and all share the same basic syntax and the same + shortcomings. - XML and SGML are explicit, well-formed meta-languages suitable - for all kinds of documentation. XML is a variant of SGML. They - are best used behind the scenes, because to untrained eyes they - are verbose, difficult to type, and too cluttered to read - comfortably as source. DocBook, HTML, and XHTML are all - applications of SGML and/or XML, and all share the same basic - syntax and the same shortcomings. +- TeX_ - - TeX [8]_ + TeX is similar to XML/SGML in that it's explicit, but not very easy + to write, and not easy for the uninitiated to read. - TeX is similar to XML/SGML in that it's explicit, but not very - easy to write, and not easy for the uninitiated to read. +- `Perl POD`_ - - Perl POD [9]_ + Most Perl modules are documented in a format called POD (Plain Old + Documentation). This is an easy-to-type, very low level format with + strong integration with the Perl parser. Many tools exist to turn + POD documentation into other formats: info, HTML and man pages, + among others. However, the POD syntax takes after Perl itself in + terms of readability. - Most Perl modules are documented in a format called POD (Plain - Old Documentation). This is an easy-to-type, very low level - format with strong integration with the Perl parser. Many tools - exist to turn POD documentation into other formats: info, HTML - and man pages, among others. However, the POD syntax takes - after Perl itself in terms of readability. +- JavaDoc_ - - JavaDoc [10]_ + Special comments before Java classes and functions serve to document + the code. A program to extract these, and turn them into HTML + documentation is called javadoc, and is part of the standard Java + distribution. However, JavaDoc has a very intimate relationship + with HTML, using HTML tags for most markup. Thus it shares the + readability problems of HTML. - Special comments before Java classes and functions serve to - document the code. A program to extract these, and turn them - into HTML documentation is called javadoc, and is part of the - standard Java distribution. However, JavaDoc has a very - intimate relationship with HTML, using HTML tags for most - markup. Thus it shares the readability problems of HTML. +- Setext_, StructuredText_ - - Setext [11]_, StructuredText [12]_ + Early on, variants of Setext (Structure Enhanced Text), including + Zope Corp's StructuredText, were proposed for Python docstring + formatting. Hereafter these variants will collectively be called + "STexts". STexts have the advantage of being easy to read without + special knowledge, and relatively easy to write. - Early on, variants of Setext (Structure Enhanced Text), - including Zope Corp's StructuredText, were proposed for Python - docstring formatting. Hereafter these variants will - collectively be called "STexts". STexts have the advantage of - being easy to read without special knowledge, and relatively - easy to write. + Although used by some (including in most existing Python + auto-documentation tools), until now STexts have failed to become + standard because: - Although used by some (including in most existing Python - auto-documentation tools), until now STexts have failed to - become standard because: + - STexts have been incomplete. Lacking "essential" constructs that + people want to use in their docstrings, STexts are rendered less + than ideal. Note that these "essential" constructs are not + universal; everyone has their own requirements. - - STexts have been incomplete. Lacking "essential" constructs - that people want to use in their docstrings, STexts are - rendered less than ideal. Note that these "essential" - constructs are not universal; everyone has their own - requirements. + - STexts have been sometimes surprising. Bits of text are + unexpectedly interpreted as being marked up, leading to user + frustration. - - STexts have been sometimes surprising. Bits of text are - unexpectedly interpreted as being marked up, leading to user - frustration. + - SText implementations have been buggy. - - SText implementations have been buggy. + - Most STexts have have had no formal specification except for the + implementation itself. A buggy implementation meant a buggy spec, + and vice-versa. - - Most STexts have have had no formal specification except for - the implementation itself. A buggy implementation meant a - buggy spec, and vice-versa. + - There has been no mechanism to get around the SText markup rules + when a markup character is used in a non-markup context. In other + words, no way to escape markup. - - There has been no mechanism to get around the SText markup - rules when a markup character is used in a non-markup context. - In other words, no way to escape markup. - - Proponents of implicit STexts have vigorously opposed proposals - for explicit markup (XML, HTML, TeX, POD, etc.), and the debates - have continued off and on since 1996 or earlier. +Proponents of implicit STexts have vigorously opposed proposals for +explicit markup (XML, HTML, TeX, POD, etc.), and the debates have +continued off and on since 1996 or earlier. - reStructuredText is a complete revision and reinterpretation of - the SText idea, addressing all of the problems listed above. +reStructuredText is a complete revision and reinterpretation of the +SText idea, addressing all of the problems listed above. Specification +============= - The specification and user documentaton for reStructuredText is - quite extensive. Rather than repeating or summarizing it all - here, links to the originals are provided. +The specification and user documentaton for reStructuredText is +quite extensive. Rather than repeating or summarizing it all +here, links to the originals are provided. - Please first take a look at "A ReStructuredText Primer" [13]_, a - short and gentle introduction. The "Quick reStructuredText" user - reference [14]_ quickly summarizes all of the markup constructs. - For complete and extensive details, please refer to the following - documents: +Please first take a look at `A ReStructuredText Primer`_, a short and +gentle introduction. The `Quick reStructuredText`_ user reference +quickly summarizes all of the markup constructs. For complete and +extensive details, please refer to the following documents: - - An Introduction to reStructuredText [15]_ +- `An Introduction to reStructuredText`_ - - reStructuredText Markup Specification [16]_ +- `reStructuredText Markup Specification`_ - - reStructuredText Directives [17]_ +- `reStructuredText Directives`_ - In addition, "Problems With StructuredText" [18]_ explains many - markup decisions made with regards to StructuredText, and "A - Record of reStructuredText Syntax Alternatives" [19]_ records - markup decisions made independently. +In addition, `Problems With StructuredText`_ explains many markup +decisions made with regards to StructuredText, and `A Record of +reStructuredText Syntax Alternatives`_ records markup decisions made +independently. Docstring-Significant Features +============================== + +- A markup escaping mechanism. + + Backslashes (``\``) are used to escape markup characters when needed + for non-markup purposes. However, the inline markup recognition + rules have been constructed in order to minimize the need for + backslash-escapes. For example, although asterisks are used for + *emphasis*, in non-markup contexts such as "*" or "(*)" or "x * y", + the asterisks are not interpreted as markup and are left unchanged. + For many non-markup uses of backslashes (e.g., describing regular + expressions), inline literals or literal blocks are applicable; see + the next item. + +- Markup to include Python source code and Python interactive + sessions: inline literals, literal blocks, and doctest blocks. + + Inline literals use ``double-backquotes`` to indicate program I/O or + code snippets. No markup interpretation (including backslash-escape + [``\``] interpretation) is done within inline literals. + + Literal blocks (block-level literal text, such as code excerpts or + ASCII graphics) are indented, and indicated with a double-colon + ("::") at the end of the preceding paragraph (right here -->):: + + if literal_block: + text = 'is left as-is' + spaces_and_linebreaks = 'are preserved' + markup_processing = None + + Doctest blocks begin with ">>> " and end with a blank line. Neither + indentation nor literal block double-colons are required. For + example:: + + Here's a doctest block: + + >>> print 'Python-specific usage examples; begun with ">>>"' + Python-specific usage examples; begun with ">>>" + >>> print '(cut and pasted from interactive sessions)' + (cut and pasted from interactive sessions) + +- Markup that isolates a Python identifier: interpreted text. + + Text enclosed in single backquotes is recognized as "interpreted + text", whose interpretation is application-dependent. In the + context of a Python docstring, the default interpretation of + interpreted text is as Python identifiers. The text will be marked + up with a hyperlink connected to the documentation for the + identifier given. Lookup rules are the same as in Python itself: + LGB namespace lookups (local, global, builtin). The "role" of the + interpreted text (identifying a class, module, function, etc.) is + determined implicitly from the namespace lookup. For example:: + + class Keeper(Storer): + + """ + Keep data fresher longer. - - A markup escaping mechanism. - - Backslashes (``\``) are used to escape markup characters when - needed for non-markup purposes. However, the inline markup - recognition rules have been constructed in order to minimize the - need for backslash-escapes. For example, although asterisks are - used for *emphasis*, in non-markup contexts such as "*" or "(*)" - or "x * y", the asterisks are not interpreted as markup and are - left unchanged. For many non-markup uses of backslashes (e.g., - describing regular expressions), inline literals or literal - blocks are applicable; see the next item. - - - Markup to include Python source code and Python interactive - sessions: inline literals, literal blocks, and doctest blocks. - - Inline literals use ``double-backquotes`` to indicate program - I/O or code snippets. No markup interpretation (including - backslash-escape [``\``] interpretation) is done within inline - literals. - - Literal blocks (block-level literal text, such as code excerpts - or ASCII graphics) are indented, and indicated with a - double-colon ("::") at the end of the preceding paragraph (right - here -->):: - - if literal_block: - text = 'is left as-is' - spaces_and_linebreaks = 'are preserved' - markup_processing = None - - Doctest blocks begin with ">>> " and end with a blank line. - Neither indentation nor literal block double-colons are - required. For example:: - - Here's a doctest block: - - >>> print 'Python-specific usage examples; begun with ">>>"' - Python-specific usage examples; begun with ">>>" - >>> print '(cut and pasted from interactive sessions)' - (cut and pasted from interactive sessions) - - - Markup that isolates a Python identifier: interpreted text. - - Text enclosed in single backquotes is recognized as "interpreted - text", whose interpretation is application-dependent. In the - context of a Python docstring, the default interpretation of - interpreted text is as Python identifiers. The text will be - marked up with a hyperlink connected to the documentation for - the identifier given. Lookup rules are the same as in Python - itself: LGB namespace lookups (local, global, builtin). The - "role" of the interpreted text (identifying a class, module, - function, etc.) is determined implicitly from the namespace - lookup. For example:: - - class Keeper(Storer): + Extend `Storer`. Class attribute `instances` keeps track + of the number of `Keeper` objects instantiated. + """ + instances = 0 + """How many `Keeper` objects are there?""" + + def __init__(self): + """ + Extend `Storer.__init__()` to keep track of + instances. Keep count in `self.instances` and data + in `self.data`. """ - Keep data fresher longer. + Storer.__init__(self) + self.instances += 1 - Extend `Storer`. Class attribute `instances` keeps track - of the number of `Keeper` objects instantiated. + self.data = [] + """Store data in a list, most recent last.""" + + def storedata(self, data): + """ + Extend `Storer.storedata()`; append new `data` to a + list (in `self.data`). """ + self.data = data - instances = 0 - """How many `Keeper` objects are there?""" + Each piece of interpreted text is looked up according to the local + namespace of the block containing its docstring. - def __init__(self): - """ - Extend `Storer.__init__()` to keep track of - instances. Keep count in `self.instances` and data - in `self.data`. - """ - Storer.__init__(self) - self.instances += 1 +- Markup that isolates a Python identifier and specifies its type: + interpreted text with roles. - self.data = [] - """Store data in a list, most recent last.""" + Although the Python source context reader is designed not to require + explicit roles, they may be used. To classify identifiers + explicitly, the role is given along with the identifier in either + prefix or suffix form:: - def storedata(self, data): - """ - Extend `Storer.storedata()`; append new `data` to a - list (in `self.data`). - """ - self.data = data + Use :method:`Keeper.storedata` to store the object's data in + `Keeper.data`:instance_attribute:. - Each piece of interpreted text is looked up according to the - local namespace of the block containing its docstring. + The syntax chosen for roles is verbose, but necessarily so (if + anyone has a better alternative, please post it to the Doc-SIG_). + The intention of the markup is that there should be little need to + use explicit roles; their use is to be kept to an absolute minimum. - - Markup that isolates a Python identifier and specifies its type: - interpreted text with roles. +- Markup for "tagged lists" or "label lists": field lists. - Although the Python source context reader is designed not to - require explicit roles, they may be used. To classify - identifiers explicitly, the role is given along with the - identifier in either prefix or suffix form:: + Field lists represent a mapping from field name to field body. + These are mostly used for extension syntax, such as "bibliographic + field lists" (representing document metadata such as author, date, + and version) and extension attributes for directives (see below). + They may be used to implement methodologies (docstring semantics), + such as identifying parameters, exceptions raised, etc.; such usage + is beyond the scope of this PEP. - Use :method:`Keeper.storedata` to store the object's data in - `Keeper.data`:instance_attribute:. + A modified RFC 2822 syntax is used, with a colon *before* as well as + *after* the field name. Field bodies are more versatile as well; + they may contain multiple field bodies (even nested field lists). + For example:: - The syntax chosen for roles is verbose, but necessarily so (if - anyone has a better alternative, please post it to the Doc-SIG). - The intention of the markup is that there should be little need - to use explicit roles; their use is to be kept to an absolute - minimum. + :Date: 2002-03-22 + :Version: 1 + :Authors: + - Me + - Myself + - I - - Markup for "tagged lists" or "label lists": field lists. + Standard RFC 2822 header syntax cannot be used for this construct + because it is ambiguous. A word followed by a colon at the + beginning of a line is common in written text. - Field lists represent a mapping from field name to field body. - These are mostly used for extension syntax, such as - "bibliographic field lists" (representing document metadata such - as author, date, and version) and extension attributes for - directives (see below). They may be used to implement - methodologies (docstring semantics), such as identifying - parameters, exceptions raised, etc.; such usage is beyond the - scope of this PEP. +- Markup extensibility: directives and substitutions. - A modified RFC 2822 syntax is used, with a colon *before* as - well as *after* the field name. Field bodies are more versatile - as well; they may contain multiple field bodies (even nested - field lists). For example:: + Directives are used as an extension mechanism for reStructuredText, + a way of adding support for new block-level constructs without + adding new syntax. Directives for images, admonitions (note, + caution, etc.), and tables of contents generation (among others) + have been implemented. For example, here's how to place an image:: - :Date: 2002-03-22 - :Version: 1 - :Authors: - - Me - - Myself - - I + .. image:: mylogo.png - Standard RFC 2822 header syntax cannot be used for this - construct because it is ambiguous. A word followed by a colon - at the beginning of a line is common in written text. + Substitution definitions allow the power and flexibility of + block-level directives to be shared by inline text. For example:: - - Markup extensibility: directives and substitutions. + The |biohazard| symbol must be used on containers used to + dispose of medical waste. - Directives are used as an extension mechanism for - reStructuredText, a way of adding support for new block-level - constructs without adding new syntax. Directives for images, - admonitions (note, caution, etc.), and tables of contents - generation (among others) have been implemented. For example, - here's how to place an image:: + .. |biohazard| image:: biohazard.png - .. image:: mylogo.png +- Section structure markup. - Substitution definitions allow the power and flexibility of - block-level directives to be shared by inline text. For - example:: + Section headers in reStructuredText use adornment via underlines + (and possibly overlines) rather than indentation. For example:: - The |biohazard| symbol must be used on containers used to - dispose of medical waste. + This is a Section Title + ======================= - .. |biohazard| image:: biohazard.png + This is a Subsection Title + -------------------------- - - Section structure markup. + This paragraph is in the subsection. - Section headers in reStructuredText use adornment via underlines - (and possibly overlines) rather than indentation. For example:: + This is Another Section Title + ============================= - This is a Section Title - ======================= + This paragraph is in the second section. - This is a Subsection Title - -------------------------- - This paragraph is in the subsection. +Questions & Answers +=================== + +1. Is reStructuredText rich enough? + + Yes, it is for most people. If it lacks some construct that is + required for a specific application, it can be added via the + directive mechanism. If a useful and common construct has been + overlooked and a suitably readable syntax can be found, it can be + added to the specification and parser. + +2. Is reStructuredText *too* rich? + + For specific applications or individuals, perhaps. In general, no. + + Since the very beginning, whenever a docstring markup syntax has + been proposed on the Doc-SIG_, someone has complained about the + lack of support for some construct or other. The reply was often + something like, "These are docstrings we're talking about, and + docstrings shouldn't have complex markup." The problem is that a + construct that seems superfluous to one person may be absolutely + essential to another. + + reStructuredText takes the opposite approach: it provides a rich + set of implicit markup constructs (plus a generic extension + mechanism for explicit markup), allowing for all kinds of + documents. If the set of constructs is too rich for a particular + application, the unused constructs can either be removed from the + parser (via application-specific overrides) or simply omitted by + convention. - This is Another Section Title - ============================= +3. Why not use indentation for section structure, like StructuredText + does? Isn't it more "Pythonic"? + + Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG post: + + I still think that using indentation to indicate sectioning is + wrong. If you look at how real books and other print + publications are laid out, you'll notice that indentation is + used frequently, but mostly at the intra-section level. + Indentation can be used to offset lists, tables, quotations, + examples, and the like. (The argument that docstrings are + different because they are input for a text formatter is wrong: + the whole point is that they are also readable without + processing.) + + I reject the argument that using indentation is Pythonic: text + is not code, and different traditions and conventions hold. + People have been presenting text for readability for over 30 + centuries. Let's not innovate needlessly. + + See `Section Structure via Indentation`__ in `Problems With + StructuredText`_ for further elaboration. + + __ http://docutils.sourceforge.net/spec/rst/problems.html + #section-structure-via-indentation + +4. Why use reStructuredText for PEPs? What's wrong with the existing + standard? + + The existing standard for PEPs is very limited in terms of general + expressibility, and referencing is especially lacking for such a + reference-rich document type. PEPs are currently converted into + HTML, but the results (mostly monospaced text) are less than + attractive, and most of the value-added potential of HTML + (especially inline hyperlinks) is untapped. + + Making reStructuredText a standard markup for PEPs will enable much + richer expression, including support for section structure, inline + markup, graphics, and tables. In several PEPs there are ASCII + graphics diagrams, which are all that plaintext documents can + support. Since PEPs are made available in HTML form, the ability + to include proper diagrams would be immediately useful. + + Current PEP practices allow for reference markers in the form "[1]" + in the text, and the footnotes/references themselves are listed in + a section toward the end of the document. There is currently no + hyperlinking between the reference marker and the + footnote/reference itself (it would be possible to add this to + pep2html.py, but the "markup" as it stands is ambiguous and + mistakes would be inevitable). A PEP with many references (such as + this one ;-) requires a lot of flipping back and forth. When + revising a PEP, often new references are added or unused references + deleted. It is painful to renumber the references, since it has to + be done in two places and can have a cascading effect (insert a + single new reference 1, and every other reference has to be + renumbered; always adding new references to the end is suboptimal). + It is easy for references to go out of sync. + + PEPs use references for two purposes: simple URL references and + footnotes. reStructuredText differentiates between the two. A PEP + might contain references like this:: + + Abstract + + This PEP proposes adding frungible doodads [1] to the core. + It extends PEP 9876 [2] via the BCA [3] mechanism. + + References and Footnotes + + [1] http://www.example.org/ + + [2] PEP 9876, Let's Hope We Never Get Here + http://www.python.org/peps/pep-9876.html + + [3] "Bogus Complexity Addition" + + Reference 1 is a simple URL reference. Reference 2 is a footnote + containing text and a URL. Reference 3 is a footnote containing + text only. Rewritten using reStructuredText, this PEP could look + like this:: + + Abstract + ======== + + This PEP proposes adding `frungible doodads`_ to the core. It + extends PEP 9876 [#pep9876]_ via the BCA [#]_ mechanism. + + ... + + References & Footnotes + ====================== + + .. _frungible doodads: http://www.example.org/ + + .. [#pep9876] PEP 9876, Let's Hope We Never Get Here + + .. [#] "Bogus Complexity Addition" + + URLs and footnotes can be defined close to their references if + desired, making them easier to read in the source text, and making + the PEPs easier to revise. The "References and Footnotes" section + can be auto-generated with a document tree transform. Footnotes + from throughout the PEP would be gathered and displayed under a + standard header. If URL references should likewise be written out + explicitly (in citation form), another tree transform could be + used. + + URL references can be named ("frungible doodads"), and can be + referenced from multiple places in the document without additional + definitions. When converted to HTML, references will be replaced + with inline hyperlinks (HTML tags). The two footnotes are + automatically numbered, so they will always stay in sync. The + first footnote also contains an internal reference name, "pep9876", + so it's easier to see the connection between reference and footnote + in the source text. Named footnotes can be referenced multiple + times, maintaining consistent numbering. + + The "#pep9876" footnote could also be written in the form of a + citation:: + + It extends PEP 9876 [PEP9876]_ ... + + .. [PEP9876] PEP 9876, Let's Hope We Never Get Here + + Footnotes are numbered, whereas citations use text for their + references. + +5. Wouldn't it be better to keep the docstring and PEP proposals + separate? + + The PEP markup proposal may be removed if it is deemed that there + is no need for PEP markup, or it could be made into a separate PEP. + If accepted, PEP 1, PEP Purpose and Guidelines [PEP-1]_, and PEP 9, + Sample PEP Template [PEP-9]_ will be updated. + + It seems natural to adopt a single consistent markup standard for + all uses of structured plaintext in Python, and to propose it all + in one place. + +6. The existing pep2html.py script converts the existing PEP format to + HTML. How will the new-format PEPs be converted to HTML? - This paragraph is in the second section. + One of the deliverables of the Docutils_ project will be a new + version of pep2html.py with integrated reStructuredText parsing. + The Docutils project will support PEPs with a "PEP Reader" + component, including all functionality currently in pep2html.py + (auto-recognition of PEP & RFC references). +7. Who's going to convert the existing PEPs to reStructuredText? -Questions & Answers + PEP authors or volunteers may convert existing PEPs if they like, + but there is no requirement to do so. The reStructuredText-based + PEPs will coexist with the old PEP standard. The pep2html.py + mentioned in answer 6 will process both old and new standards. + +8. Why use reStructuredText for README and other ancillary files? - 1. Is reStructuredText rich enough? - - Yes, it is for most people. If it lacks some construct that is - required for a specific application, it can be added via the - directive mechanism. If a useful and common construct has been - overlooked and a suitably readable syntax can be found, it can - be added to the specification and parser. - - 2. Is reStructuredText *too* rich? - - For specific applications or individuals, perhaps. In general, - no. - - Since the very beginning, whenever a docstring markup syntax - has been proposed on the Doc-SIG, someone has complained about - the lack of support for some construct or other. The reply was - often something like, "These are docstrings we're talking - about, and docstrings shouldn't have complex markup." The - problem is that a construct that seems superfluous to one - person may be absolutely essential to another. - - reStructuredText takes the opposite approach: it provides a - rich set of implicit markup constructs (plus a generic - extension mechanism for explicit markup), allowing for all - kinds of documents. If the set of constructs is too rich for a - particular application, the unused constructs can either be - removed from the parser (via application-specific overrides) or - simply omitted by convention. - - 3. Why not use indentation for section structure, like - StructuredText does? Isn't it more "Pythonic"? - - Guido van Rossum wrote the following in a 2001-06-13 Doc-SIG - post: - - I still think that using indentation to indicate sectioning - is wrong. If you look at how real books and other print - publications are laid out, you'll notice that indentation - is used frequently, but mostly at the intra-section level. - Indentation can be used to offset lists, tables, - quotations, examples, and the like. (The argument that - docstrings are different because they are input for a text - formatter is wrong: the whole point is that they are also - readable without processing.) - - I reject the argument that using indentation is Pythonic: - text is not code, and different traditions and conventions - hold. People have been presenting text for readability for - over 30 centuries. Let's not innovate needlessly. - - See "Section Structure via Indentation" in "Problems With - StructuredText" [18 ]_ for further elaboration. - - 4. Why use reStructuredText for PEPs? What's wrong with the - existing standard? - - The existing standard for PEPs is very limited in terms of - general expressibility, and referencing is especially lacking - for such a reference-rich document type. PEPs are currently - converted into HTML, but the results (mostly monospaced text) - are less than attractive, and most of the value-added potential - of HTML (especially inline hyperlinks) is untapped. - - Making reStructuredText a standard markup for PEPs will enable - much richer expression, including support for section - structure, inline markup, graphics, and tables. In several - PEPs there are ASCII graphics diagrams, which are all that - plaintext documents can support. Since PEPs are made available - in HTML form, the ability to include proper diagrams would be - immediately useful. - - Current PEP practices allow for reference markers in the form - "[1]" in the text, and the footnotes/references themselves are - listed in a section toward the end of the document. There is - currently no hyperlinking between the reference marker and the - footnote/reference itself (it would be possible to add this to - pep2html.py, but the "markup" as it stands is ambiguous and - mistakes would be inevitable). A PEP with many references - (such as this one ;-) requires a lot of flipping back and - forth. When revising a PEP, often new references are added or - unused references deleted. It is painful to renumber the - references, since it has to be done in two places and can have - a cascading effect (insert a single new reference 1, and every - other reference has to be renumbered; always adding new - references to the end is suboptimal). It is easy for - references to go out of sync. - - PEPs use references for two purposes: simple URL references and - footnotes. reStructuredText differentiates between the two. A - PEP might contain references like this:: - - Abstract - - This PEP proposes adding frungible doodads [1] to the - core. It extends PEP 9876 [2] via the BCA [3] - mechanism. - - References and Footnotes - - [1] http://www.example.org/ - - [2] PEP 9876, Let's Hope We Never Get Here - http://www.python.org/peps/pep-9876.html - - [3] "Bogus Complexity Addition" - - Reference 1 is a simple URL reference. Reference 2 is a - footnote containing text and a URL. Reference 3 is a footnote - containing text only. Rewritten using reStructuredText, this - PEP could look like this:: - - Abstract - ======== - - This PEP proposes adding `frungible doodads`_ to the core. - It extends PEP 9876 [#pep9876]_ via the BCA [#]_ mechanism. - - ... - - References & Footnotes - ====================== - - .. _frungible doodads: http://www.example.org/ - - .. [#pep9876] PEP 9876, Let's Hope We Never Get Here - - .. [#] "Bogus Complexity Addition" - - URLs and footnotes can be defined close to their references if - desired, making them easier to read in the source text, and - making the PEPs easier to revise. The "References and - Footnotes" section can be auto-generated with a document tree - transform. Footnotes from throughout the PEP would be gathered - and displayed under a standard header. If URL references - should likewise be written out explicitly (in citation form), - another tree transform could be used. - - URL references can be named ("frungible doodads"), and can be - referenced from multiple places in the document without - additional definitions. When converted to HTML, references - will be replaced with inline hyperlinks (HTML tags). The - two footnotes are automatically numbered, so they will always - stay in sync. The first footnote also contains an internal - reference name, "pep9876", so it's easier to see the connection - between reference and footnote in the source text. Named - footnotes can be referenced multiple times, maintaining - consistent numbering. - - The "#pep9876" footnote could also be written in the form of a - citation:: - - It extends PEP 9876 [PEP9876]_ ... - - .. [PEP9876] PEP 9876, Let's Hope We Never Get Here - - Footnotes are numbered, whereas citations use text for their - references. - - 5. Wouldn't it be better to keep the docstring and PEP proposals - separate? - - The PEP markup proposal may be removed if it is deemed that - there is no need for PEP markup, or it could be made into a - separate PEP. If accepted, PEP 1, PEP Purpose and Guidelines - [20]_, and PEP 9, Sample PEP Template [21]_ will be updated. - - It seems natural to adopt a single consistent markup standard - for all uses of structured plaintext in Python, and to propose - it all in one place. - - 6. The existing pep2html.py script converts the existing PEP - format to HTML. How will the new-format PEPs be converted to - HTML? - - One of the deliverables of the Docutils project [22]_ will be a - new version of pep2html.py with integrated reStructuredText - parsing. The Docutils project will support PEPs with a "PEP - Reader" component, including all functionality currently in - pep2html.py (auto-recognition of PEP & RFC references). - - 7. Who's going to convert the existing PEPs to reStructuredText? - - PEP authors or volunteers may convert existing PEPs if they - like, but there is no requirement to do so. The - reStructuredText-based PEPs will coexist with the old PEP - standard. The pep2html.py mentioned in answer 6 will process - both old and new standards. - - 8. Why use reStructuredText for README and other ancillary files? + The reasoning given for PEPs in answer 4 above also applies to + README and other ancillary files. By adopting a standard markup, + these files can be converted to attractive cross-referenced HTML + and put up on python.org. Developers of Python projects can also + take advantage of this facility for their own documentation. - The reasoning given for PEPs in answer 4 above also applies to - README and other ancillary files. By adopting a standard - markup, these files can be converted to attractive - cross-referenced HTML and put up on python.org. Developers of - Python projects can also take advantage of this facility for - their own documentation. +9. Won't the superficial similarity to existing markup conventions + cause problems, and result in people writing invalid markup (and + not noticing, because the plaintext looks natural)? How forgiving + is reStructuredText of "not quite right" markup? - 9. Won't the superficial similarity to existing markup conventions - cause problems, and result in people writing invalid markup - (and not noticing, because the plaintext looks natural)? How - forgiving is reStructuredText of "not quite right" markup? - - There will be some mis-steps, as there would be when moving - from one programming language to another. As with any - language, proficiency grows with experience. Luckily, - reStructuredText is a very little language indeed. - - As with any syntax, there is the possibility of syntax errors. - It is expected that a user will run the processing system over - their input and check the output for correctness. - - In a strict sense, the reStructuredText parser is very - unforgiving (as it should be; "In the face of ambiguity, refuse - the temptation to guess" [23]_ applies to parsing markup as - well as computer languages). Here's design goal 3 from "An - Introduction to reStructuredText" [15 ]_: - - Unambiguous. The rules for markup must not be open for - interpretation. For any given input, there should be one - and only one possible output (including error output). - - While unforgiving, at the same time the parser does try to be - helpful by producing useful diagnostic output ("system - messages"). The parser reports problems, indicating their - level of severity (from least to most: debug, info, warning, - error, severe). The user or the client software can decide on - reporting thresholds; they can ignore low-level problems or - cause high-level problems to bring processing to an immediate - halt. Problems are reported during the parse as well as - included in the output, often with two-way links between the - source of the problem and the system message explaining it. - - 10. Will the docstrings in the Python standard library modules be - converted to reStructuredText? - - No. Python's library reference documentation is maintained - separately from the source. Docstrings in the Python standard - library should not try to duplicate the library reference - documentation. The current policy for docstrings in the - Python standard library is that they should be no more than - concise hints, simple and markup-free (although many *do* - contain ad-hoc implicit markup). - - 11. I want to write all my strings in Unicode. Will anything - break? - - The parser fully supports Unicode. Docutils supports - arbitrary input encodings. - - 12. Why does the community need a new structured text design? - - The existing structured text designs are deficient, for the - reasons given in "Rationale" above. reStructuredText aims to - be a complete markup syntax, within the limitations of the - "readable plaintext" medium. - - 13. What is wrong with existing documentation methodologies? - - What existing methodologies? For Python docstrings, there is - **no** official standard markup format, let alone a - documentation methodology, akin to JavaDoc. The question of - methodology is at a much higher level than syntax (which this - PEP addresses). It is potentially much more controversial and - difficult to resolve, and is intentionally left out of this - discussion. + There will be some mis-steps, as there would be when moving from + one programming language to another. As with any language, + proficiency grows with experience. Luckily, reStructuredText is a + very little language indeed. + + As with any syntax, there is the possibility of syntax errors. It + is expected that a user will run the processing system over their + input and check the output for correctness. + + In a strict sense, the reStructuredText parser is very unforgiving + (as it should be; "In the face of ambiguity, refuse the temptation + to guess" [#Zen]_ applies to parsing markup as well as computer + languages). Here's design goal 3 from `An Introduction to + reStructuredText`_: + + Unambiguous. The rules for markup must not be open for + interpretation. For any given input, there should be one and + only one possible output (including error output). + + While unforgiving, at the same time the parser does try to be + helpful by producing useful diagnostic output ("system messages"). + The parser reports problems, indicating their level of severity + (from least to most: debug, info, warning, error, severe). The + user or the client software can decide on reporting thresholds; + they can ignore low-level problems or cause high-level problems to + bring processing to an immediate halt. Problems are reported + during the parse as well as included in the output, often with + two-way links between the source of the problem and the system + message explaining it. + +10. Will the docstrings in the Python standard library modules be + converted to reStructuredText? + + No. Python's library reference documentation is maintained + separately from the source. Docstrings in the Python standard + library should not try to duplicate the library reference + documentation. The current policy for docstrings in the Python + standard library is that they should be no more than concise + hints, simple and markup-free (although many *do* contain ad-hoc + implicit markup). + +11. I want to write all my strings in Unicode. Will anything + break? + + The parser fully supports Unicode. Docutils supports arbitrary + input and output encodings. + +12. Why does the community need a new structured text design? + + The existing structured text designs are deficient, for the + reasons given in "Rationale" above. reStructuredText aims to be a + complete markup syntax, within the limitations of the "readable + plaintext" medium. + +13. What is wrong with existing documentation methodologies? + + What existing methodologies? For Python docstrings, there is + **no** official standard markup format, let alone a documentation + methodology, akin to JavaDoc. The question of methodology is at a + much higher level than syntax (which this PEP addresses). It is + potentially much more controversial and difficult to resolve, and + is intentionally left out of this discussion. References & Footnotes +====================== + +.. _reStructuredText markup: http://docutils.sourceforge.net/spec/rst.html - [1] http://docutils.sourceforge.net/spec/rst.html +.. _Doc-SIG: http://www.python.org/sigs/doc-sig/ - [2] http://www.python.org/sigs/doc-sig/ +.. _XML: http://www.w3.org/XML/ - [3] http://www.w3.org/XML/ +.. _SGML: http://www.oasis-open.org/cover/general.html - [4] http://www.oasis-open.org/cover/general.html +.. _DocBook: http://docbook.org/tdg/en/html/docbook.html - [5] http://docbook.org/tdg/en/html/docbook.html +.. _HTML: http://www.w3.org/MarkUp/ - [6] http://www.w3.org/MarkUp/ +.. _XHTML: http://www.w3.org/MarkUp/#xhtml1 - [7] http://www.w3.org/MarkUp/#xhtml1 +.. _TeX: http://www.tug.org/interest.html - [8] http://www.tug.org/interest.html +.. _Perl POD: http://www.perldoc.com/perl5.6/pod/perlpod.html - [9] http://www.perldoc.com/perl5.6/pod/perlpod.html +.. _JavaDoc: http://java.sun.com/j2se/javadoc/ - [10] http://java.sun.com/j2se/javadoc/ +.. _Setext: http://docutils.sourceforge.net/mirror/setext.html - [11] http://docutils.sourceforge.net/mirror/setext.html +.. _StructuredText: + http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage - [12] http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage +.. _A ReStructuredText Primer: + http://docutils.sourceforge.net/docs/rst/quickstart.html - [13] A ReStructuredText Primer - http://docutils.sourceforge.net/docs/rst/quickstart.html +.. _Quick reStructuredText: + http://docutils.sourceforge.net/docs/rst/quickref.html - [14] Quick reStructuredText - http://docutils.sourceforge.net/docs/rst/quickref.html +.. _An Introduction to reStructuredText: + http://docutils.sourceforge.net/spec/rst/introduction.html - [15] An Introduction to reStructuredText - http://docutils.sourceforge.net/spec/rst/introduction.html +.. _reStructuredText Markup Specification: + http://docutils.sourceforge.net/spec/rst/reStructuredText.html - [16] reStructuredText Markup Specification - http://docutils.sourceforge.net/spec/rst/reStructuredText.html +.. _reStructuredText Directives: + http://docutils.sourceforge.net/spec/rst/directives.html - [17] reStructuredText Directives - http://docutils.sourceforge.net/spec/rst/directives.html +.. _Problems with StructuredText: + http://docutils.sourceforge.net/spec/rst/problems.html - [18] Problems with StructuredText - http://docutils.sourceforge.net/spec/rst/problems.html +.. _A Record of reStructuredText Syntax Alternatives: + http://docutils.sourceforge.net/spec/rst/alternatives.html - [19] A Record of reStructuredText Syntax Alternatives - http://docutils.sourceforge.net/spec/rst/alternatives.html +.. [PEP-1] PEP 1, PEP Guidelines, Warsaw, Hylton + (http://www.python.org/peps/pep-0001.html) - [20] PEP 1, PEP Guidelines, Warsaw, Hylton - http://www.python.org/peps/pep-0001.html +.. [PEP-9] PEP 9, Sample PEP Template, Warsaw + (http://www.python.org/peps/pep-0009.html) - [21] PEP 9, Sample PEP Template, Warsaw - http://www.python.org/peps/pep-0009.html +.. _Docutils: http://docutils.sourceforge.net/ - [22] http://docutils.sourceforge.net/ +.. [#Zen] From `The Zen of Python (by Tim Peters)`__ (or just + "``import this``" in Python) - [23] From "The Zen of Python (by Tim Peters)" - (http://www.python.org/doc/Humor.html#zen or just - "``import this``" in Python) + __ http://www.python.org/doc/Humor.html#zen - [24] PEP 216, Docstring Format, Zadka - http://www.python.org/peps/pep-0216.html +.. [PEP-216] PEP 216, Docstring Format, Zadka + (http://www.python.org/peps/pep-0216.html) Copyright +========= - This document has been placed in the public domain. +This document has been placed in the public domain. Acknowledgements +================ - Some text is borrowed from PEP 216, Docstring Format [24]_, by - Moshe Zadka. +Some text is borrowed from PEP 216, Docstring Format [PEP-216]_, by +Moshe Zadka. - Special thanks to all members past & present of the Python - Doc-SIG. +Special thanks to all members past & present of the Python Doc-SIG_. -Local Variables: -mode: indented-text -indent-tabs-mode: nil -sentence-end-double-space: t -fill-column: 70 -End: +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: -- cgit v1.2.1 From 455515ae2a1e31dbcdf3867cbfa396b9bffa168d Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 14 Jul 2002 03:24:36 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@290 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 21 ++++++++++++++++++++- test/test_readers/test_pep/test_inline_markup.py | 20 ++++++++++++++++++++ test/test_transforms/test_contents.py | 14 +++++++------- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 9b4e27013..5b9ea8da8 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -212,6 +212,12 @@ Specific: - 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. + - Modified the ``field_body`` output. + +* docutils/writers/pep_html.py: Added to project; HTML Writer for + PEPs (subclass of ``html4css1.Writer``). * docutils/writers/pseudoxml.py: Renamed from pprint.py. @@ -231,6 +237,9 @@ Specific: * 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 @@ -238,8 +247,10 @@ Specific: * 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: @@ -294,7 +305,15 @@ Specific: * tools/docutils-xml.py: Added to project. -* tools/quicktest.py: Added the "--attributes" option, hacked a bit. +* tools/pep.py: Added to project; PEP to HTML front-end. + +* tools/pep-template.html: Added to project; template for PEP HTML. + +* tools/quicktest.py: Added the "--attributes" option, hacked a bit. + +* tools/stylesheets/: Subdirectory added to project. + +* tools/stylesheets/pep.css: Added to project; stylesheet for PEPs. Release 0.1 (2002-04-20) diff --git a/test/test_readers/test_pep/test_inline_markup.py b/test/test_readers/test_pep/test_inline_markup.py index a0d19b9fa..a21b755c8 100644 --- a/test/test_readers/test_pep/test_inline_markup.py +++ b/test/test_readers/test_pep/test_inline_markup.py @@ -69,6 +69,26 @@ RFC RFC 2822 """], +["""\ +Test PEP-specific implicit references before a URL: + +PEP 287 (http://www.python.org/peps/pep-0287.html), RFC 2822. +""", +"""\ + + + Test PEP-specific implicit references before a URL: + + + PEP 287 + ( + + http://www.python.org/peps/pep-0287.html + ), \n\ + + RFC 2822 + . +"""], ] totest['miscellaneous'] = [ diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index fe066e75d..4ac93ef68 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -47,7 +47,7 @@ Paragraph 4. """, """\ - + Contents <bullet_list> @@ -103,7 +103,7 @@ Paragraph 2. """, """\ <document> - <topic class="contents" id="table-of-contents" name="Table of Contents"> + <topic class="contents" id="table-of-contents" name="table of contents"> <title> Table of Contents <bullet_list> @@ -142,7 +142,7 @@ Paragraph 2. """, """\ <document> - <topic class="contents" id="there-s-an-image-in-title-2" name="There's an image in Title 2"> + <topic class="contents" id="there-s-an-image-in-title-2" name="there's an image in title 2"> <title> There's an image in Title 2 <bullet_list> @@ -166,7 +166,7 @@ Paragraph 2. Paragraph 2. <substitution_definition name="title 2"> <image alt="Title 2" uri="title2.png"> -"""], +"""], # emacs cruft: " ["""\ .. contents:: :depth: 2 @@ -189,7 +189,7 @@ Paragraph 4. """, """\ <document> - <topic class="contents" id="contents" name="Contents"> + <topic class="contents" id="contents" name="contents"> <title> Contents <bullet_list> @@ -253,7 +253,7 @@ Paragraph 4. <section id="title-1" name="title 1"> <title> Title 1 - <topic class="contents" id="contents" name="Contents"> + <topic class="contents" id="contents" name="contents"> <bullet_list> <list_item id="id1"> <paragraph> @@ -298,7 +298,7 @@ Paragraph. """, """\ <document> - <topic class="contents" id="id2" name="Contents"> + <topic class="contents" id="id2"> <bullet_list> <list_item id="id1"> <paragraph> -- cgit v1.2.1 From acb21b5d5622d284a3ed98236bf15ee70bb03069 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Jul 2002 03:40:35 +0000 Subject: parameterized the stylesheet reference git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@291 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 1 + tools/pep-template.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index e1452a5e0..fe3c5b059 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -43,6 +43,7 @@ class Writer(html4css1.Writer): html4css1.Writer.translate(self) options = self.document.options template = open(options.template).read() + stylesheet = options.stylesheet pyhome = options.python_home pephome = options.pep_home index = self.document.first_child_matching_class(nodes.field_list) diff --git a/tools/pep-template.html b/tools/pep-template.html index eabd3bcb8..49e989ba4 100644 --- a/tools/pep-template.html +++ b/tools/pep-template.html @@ -5,7 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="generator" content="Docutils: http://docutils.sourceforge.net/"> <title>PEP %(pep)s -- %(title)s - + Date: Sun, 14 Jul 2002 04:04:41 +0000 Subject: fixed the page title git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@294 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index fe3c5b059..9cfaa0a89 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -53,7 +53,7 @@ class Writer(html4css1.Writer): pepnum = '%04i' % int(pep) except: pepnum = pep - title = self.document[1][1].astext() + title = header[1][1].astext() body = ''.join(self.body) body_suffix = ''.join(self.body_suffix) self.output = template % locals() -- cgit v1.2.1 From 365c0cbc8335aabae0e7447e380f586cdb28b38e Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 15 Jul 2002 03:47:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@296 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a42f8d74f..089c5c4a7 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -51,7 +51,7 @@ General - Implementation docs. - spec/doctree.txt: Doctree nodes (DTD element) semantics: - + - External (public) attributes (node.attributes). - Internal attributes (node.*). - Linking mechanism. @@ -290,6 +290,19 @@ __ rst/alternatives.html#or-not-to-do Tony Ibbs spoke out against this idea (2002-06-14 Doc-SIG thread "docutils feedback"). +- Generalize the "literal block" construct to allow blocks with a + per-line quoting to avoid indentation? For example, an email reply + quoting the original:: + + John Doe wrote:: + + > Great idea! + > + > Why didn't I think of that? + + Every line of the literal block would have to begin with the same + non-alphanumeric non-whitespace character. + Directives `````````` -- cgit v1.2.1 From d23cdd89d86fd2bad2a067b67db87f229e52b25d Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 17 Jul 2002 00:49:09 +0000 Subject: Remove the 12 pixel cell spacing in option lists. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@297 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9c5e14c62..db291ddee 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -593,7 +593,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_option_list(self, node): self.body.append( self.starttag(node, 'table', CLASS='option-list', - frame="void", rules="none", cellspacing=12)) + frame="void", rules="none")) self.body.append('\n' '\n' '\n') -- cgit v1.2.1 From d55f974593d719d4a2be200f6cf2ac73bb44334a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 00:50:18 +0000 Subject: ws git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@298 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 0e1158024..d7dbf914f 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -90,7 +90,6 @@ class OptionParser(optik.OptionParser): # Hidden options, for development use only: (optik.SUPPRESS_HELP, ['--dump-internal-document-attributes'], {'action': 'store_true'}),)) - """Command-line option specifications, common to all Docutils front-ends. Option group title, description, and a list/tuple of tuples: ``('help text', [list of option strings], {keyword arguments})``. Group title -- cgit v1.2.1 From fda31a72bed007ad8a39d6ad109cb093028cbbec Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 00:51:13 +0000 Subject: - Fixed DOM generation for list-attributes. - Added category class ``Labeled`` (used by footnotes & citations). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@299 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 84ce615a3..77e4a2ce6 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -242,6 +242,8 @@ class Element(Node): def _rooted_dom_node(self, domroot): element = domroot.createElement(self.tagname) for attribute, value in self.attributes.items(): + if type(value) is ListType: + value = ' '.join(value) element.setAttribute(attribute, str(value)) for child in self.children: element.appendChild(child._rooted_dom_node(domroot)) @@ -541,6 +543,9 @@ class Targetable(Resolvable): referenced = 0 +class Labeled: + """Contains a `label` as its first element.""" + # ============== # Root Element @@ -636,7 +641,7 @@ class document(Root, Structural, Element): def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() - domroot.appendChild(Element._rooted_dom_node(self, domroot)) + domroot.appendChild(self._rooted_dom_node(domroot)) return domroot def set_id(self, node, msgnode=None): @@ -921,8 +926,8 @@ class warning(Admonition, Element): pass class comment(Special, PreBibliographic, TextElement): pass class substitution_definition(Special, TextElement): pass class target(Special, Inline, TextElement, Targetable): pass -class footnote(General, Element, BackLinkable): pass -class citation(General, Element, BackLinkable): pass +class footnote(General, Element, Labeled, BackLinkable): pass +class citation(General, Element, Labeled, BackLinkable): pass class label(Part, TextElement): pass class figure(General, Element): pass class caption(Part, TextElement): pass -- cgit v1.2.1 From 6b456ac082f235f368eaa37e4b4905222a76028d Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 00:52:40 +0000 Subject: - Updated docstrings. - Changed "table" to "grid_table"; added "simple_table" support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@300 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 161 ++++++++++++++++++++++++++++++----------- 1 file changed, 119 insertions(+), 42 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9b4114b80..04a9ea605 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -44,11 +44,11 @@ the reStructuredText parser. It defines the following: Parser Overview =============== -The reStructuredText parser is implemented as a state machine, examining its -input one line at a time. To understand how the parser works, please first -become familiar with the `docutils.statemachine` module. In the description -below, references are made to classes defined in this module; please see the -individual classes for details. +The reStructuredText parser is implemented as a recursive state machine, +examining its input one line at a time. To understand how the parser works, +please first become familiar with the `docutils.statemachine` module. In the +description below, references are made to classes defined in this module; +please see the individual classes for details. Parsing proceeds as follows: @@ -60,26 +60,27 @@ Parsing proceeds as follows: 2. The method associated with the matched transition pattern is called. A. Some transition methods are self-contained, appending elements to the - document tree ('doctest' parses a doctest block). The parser's current - line index is advanced to the end of the element, and parsing continues - with step 1. + document tree (`Body.doctest` parses a doctest block). The parser's + current line index is advanced to the end of the element, and parsing + continues with step 1. - B. Others trigger the creation of a nested state machine, whose job is to - parse a compound construct ('indent' does a block quote, 'bullet' does a - bullet list, 'overline' does a section [first checking for a valid - section header]). + B. Other transition methods trigger the creation of a nested state machine, + whose job is to parse a compound construct ('indent' does a block quote, + 'bullet' does a bullet list, 'overline' does a section [first checking + for a valid section header], etc.). - - In the case of lists and explicit markup, a new state machine is - created and run to parse the first item. + - In the case of lists and explicit markup, a one-off state machine is + created and run to parse contents of the first item. - A new state machine is created and its initial state is set to the appropriate specialized state (`BulletList` in the case of the - 'bullet' transition). This state machine is run to parse the compound - element (or series of explicit markup elements), and returns as soon - as a non-member element is encountered. For example, the `BulletList` - state machine aborts as soon as it encounters an element which is not - a list item of that bullet list. The optional omission of - inter-element blank lines is handled by the nested state machine. + 'bullet' transition; see `SpecializedBody` for more detail). This + state machine is run to parse the compound element (or series of + explicit markup elements), and returns as soon as a non-member element + is encountered. For example, the `BulletList` state machine ends as + soon as it encounters an element which is not a list item of that + bullet list. The optional omission of inter-element blank lines is + enabled by this nested state machine. - The current line index is advanced to the end of the elements parsed, and parsing continues with step 1. @@ -110,8 +111,7 @@ from docutils import nodes, statemachine, utils, roman, urischemes from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.utils import normalize_name -from docutils.parsers.rst import directives, languages -from docutils.parsers.rst.tableparser import TableParser, TableMarkupError +from docutils.parsers.rst import directives, languages, tableparser class MarkupError(DataError): pass @@ -858,10 +858,14 @@ class Body(RSTState): enum.sequenceregexps[sequence] = re.compile( enum.sequencepats[sequence] + '$') - table_top_pat = re.compile(r'\+-[-+]+-\+ *$') - """Matches the top (& bottom) of a table).""" + grid_table_top_pat = re.compile(r'\+-[-+]+-\+ *$') + """Matches the top (& bottom) of a full table).""" - tableparser = TableParser() + simple_table_top_pat = re.compile('=+( +=+)+ *$') + """Matches the top of a simple table.""" + + simple_table_border_pat = re.compile('=+[ =]*$') + """Matches the bottom & header bottom of a simple table.""" pats = {} """Fragments of patterns used by transitions.""" @@ -888,7 +892,8 @@ class Body(RSTState): 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, 'doctest': r'>>>( +|$)', - 'table_top': table_top_pat, + 'grid_table_top': grid_table_top_pat, + 'simple_table_top': simple_table_top_pat, 'explicit_markup': r'\.\.( +|$)', 'anonymous': r'__( +|$)', 'line': r'(%(nonalphanum7bit)s)\1\1\1+ *$' % pats, @@ -899,7 +904,8 @@ class Body(RSTState): 'field_marker', 'option_marker', 'doctest', - 'table_top', + 'grid_table_top', + 'simple_table_top', 'explicit_markup', 'anonymous', 'line', @@ -1159,9 +1165,22 @@ class Body(RSTState): self.parent += nodes.doctest_block(data, data) return [], next_state, [] - def table_top(self, match, context, next_state): - """Top border of a table.""" - nodelist, blank_finish = self.table() + def grid_table_top(self, match, context, next_state): + """Top border of a full table.""" + return self.table_top(match, context, next_state, + self.isolate_grid_table, + tableparser.GridTableParser) + + def simple_table_top(self, match, context, next_state): + """Top border of a simple table.""" + return self.table_top(match, context, next_state, + self.isolate_simple_table, + tableparser.SimpleTableParser) + + def table_top(self, match, context, next_state, + isolate_function, parser_class): + """Top border of a generic table.""" + nodelist, blank_finish = self.table(isolate_function, parser_class) self.parent += nodelist if not blank_finish: msg = self.reporter.warning( @@ -1170,23 +1189,24 @@ class Body(RSTState): self.parent += msg return [], next_state, [] - def table(self): + def table(self, isolate_function, parser_class): """Parse a table.""" - block, messages, blank_finish = self.isolate_table() + block, messages, blank_finish = isolate_function() if block: try: - tabledata = self.tableparser.parse(block) + parser = parser_class() + tabledata = parser.parse(block) tableline = (self.state_machine.abs_line_number() - len(block) + 1) table = self.build_table(tabledata, tableline) nodelist = [table] + messages - except TableMarkupError, detail: + except tableparser.TableMarkupError, detail: nodelist = self.malformed_table(block, str(detail)) + messages else: nodelist = messages return nodelist, blank_finish - def isolate_table(self): + def isolate_grid_table(self): messages = [] blank_finish = 1 try: @@ -1204,11 +1224,11 @@ class Body(RSTState): self.state_machine.previous_line(len(block) - i) del block[i:] break - if not self.table_top_pat.match(block[-1]): # find bottom + if not self.grid_table_top_pat.match(block[-1]): # find bottom blank_finish = 0 # from second-last to third line of table: for i in range(len(block) - 2, 1, -1): - if self.table_top_pat.match(block[i]): + if self.grid_table_top_pat.match(block[i]): self.state_machine.previous_line(len(block) - i + 1) del block[i+1:] break @@ -1221,6 +1241,47 @@ class Body(RSTState): return [], messages, blank_finish return block, messages, blank_finish + def isolate_simple_table(self): + start = self.state_machine.line_offset + lines = self.state_machine.input_lines + limit = len(lines) - 1 + toplen = len(lines[start].strip()) + pattern_match = self.simple_table_border_pat.match + found = 0 + found_at = None + i = start + 1 + while i <= limit: + line = lines[i] + match = pattern_match(line) + if match: + if len(line.strip()) != toplen: + self.state_machine.next_line(i - start) + messages = self.malformed_table( + lines[start:i+1], 'Bottom/header table border does ' + 'not match top border.') + return [], messages, i == limit or not lines[i+1].strip() + found += 1 + found_at = i + if found == 2 or i == limit or not lines[i+1].strip(): + end = i + break + i += 1 + else: # reached end of input_lines + if found: + extra = ' or no blank line after table bottom' + self.state_machine.next_line(found_at - start) + block = lines[start:found_at+1] + else: + extra = '' + self.state_machine.next_line(i - start - 1) + block = lines[start:] + messages = self.malformed_table( + block, 'No bottom table border found%s.' % extra) + return [], messages, not extra + self.state_machine.next_line(end - start) + block = lines[start:end+1] + return block, [], end == limit or not lines[end+1].strip() + def malformed_table(self, block, detail=''): data = '\n'.join(block) message = 'Malformed table at line %s; formatting as a ' \ @@ -1738,10 +1799,25 @@ class RFC2822Body(Body): class SpecializedBody(Body): """ - Superclass for second and subsequent compound element members. - - All transition methods are disabled. Override individual methods in - subclasses to re-enable. + Superclass for second and subsequent compound element members. Compound + elements are lists and list-like constructs. + + All transition methods are disabled (redefined as `invalid_input`). + Override individual methods in subclasses to re-enable. + + For example, once an initial bullet list item, say, is recognized, the + `BulletList` subclass takes over, with a "bullet_list" node as its + container. Upon encountering the initial bullet list item, `Body.bullet` + calls its ``self.nested_list_parse`` (`RSTState.nested_list_parse`), which + starts up a nested parsing session with `BulletList` as the initial state. + Only the ``bullet`` transition method is enabled in `BulletList`; as long + as only bullet list items are encountered, they are parsed and inserted + into the container. The first construct which is *not* a bullet list item + triggers the `invalid_input` method, which ends the nested parse and + closes the container. `BulletList` needs to recognize input that is + invalid in the context of a bullet list, which means everything *other + than* bullet list items, so it inherits the transition list created in + `Body`. """ def invalid_input(self, match=None, context=None, next_state=None): @@ -1755,7 +1831,8 @@ class SpecializedBody(Body): field_marker = invalid_input option_marker = invalid_input doctest = invalid_input - table_top = invalid_input + grid_table_top = invalid_input + simple_table_top = invalid_input explicit_markup = invalid_input anonymous = invalid_input line = invalid_input -- cgit v1.2.1 From 80dbe0f7f7d7ddc5d9850562e76912c93a7c2261 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 00:53:21 +0000 Subject: - Changed ``TableParser`` to ``GridTableParser``. - Added ``SimpleTableParser``. - Refactored naming. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@301 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 345 ++++++++++++++++++++++++++++-------- 1 file changed, 272 insertions(+), 73 deletions(-) diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 3f7575040..51beb6b97 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -5,20 +5,25 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -This module defines the `TableParser` class, which parses a plaintext-graphic -table and produces a well-formed data structure suitable for building a CALS -table. +This module defines table parser classes,which parse plaintext-graphic tables +and produce a well-formed data structure suitable for building a CALS table. + +:Classes: + - `GridTableParser`: Parse fully-formed tables represented with a grid. + - `SimpleTableParser`: Parse simple tables, delimited by top & bottom + borders. :Exception class: `TableMarkupError` :Function: - `update_dictoflists()`: Merge two dictionaries containing list values. + `update_dict_of_lists()`: Merge two dictionaries containing list values. """ __docformat__ = 'reStructuredText' import re +import sys from docutils import DataError @@ -28,9 +33,53 @@ class TableMarkupError(DataError): pass class TableParser: """ - Parse a plaintext graphic table using `parse()`. + Abstract superclass for the common parts of the syntax-specific parsers. + """ - Here's an example of a plaintext graphic table:: + head_body_separator_pat = None + """Matches the row separator between head rows and body rows.""" + + def parse(self, block): + """ + Analyze the text `block` and return a table data structure. + + Given a plaintext-graphic table in `block` (list of lines of text; no + whitespace padding), parse the table, construct and return the data + necessary to construct a CALS table or equivalent. + + Raise `TableMarkupError` if there is any problem with the markup. + """ + self.setup(block) + self.find_head_body_sep() + self.parse_table() + structure = self.structure_from_cells() + return structure + + def find_head_body_sep(self): + """Look for a head/body row separator line; store the line index.""" + for i in range(len(self.block)): + line = self.block[i] + if self.head_body_separator_pat.match(line): + if self.head_body_sep: + raise TableMarkupError( + 'Multiple head/body row separators in table (at line ' + 'offset %s and %s); only one allowed.' + % (self.head_body_sep, i)) + else: + self.head_body_sep = i + self.block[i] = line.replace('=', '-') + if self.head_body_sep == 0 or self.head_body_sep == (len(self.block) + - 1): + raise TableMarkupError('The head/body row separator may not be ' + 'the first or last line of the table.') + + +class GridTableParser(TableParser): + + """ + Parse a grid table using `parse()`. + + Here's an example of a grid table:: +------------------------+------------+----------+----------+ | Header row, column 1 | Header 2 | Header 3 | Header 4 | @@ -79,54 +128,19 @@ class TableParser: and the cell contents, a list of lines of text. """ - headbodyseparatorpat = re.compile(r'\+=[=+]+=\+$') - """Matches the row separator between head rows and body rows.""" - - def parse(self, block): - """ - Analyze the text `block` and return a table data structure. - - Given a plaintext-graphic table in `block` (list of lines of text; no - whitespace padding), parse the table, construct and return the data - necessary to construct a CALS table or equivalent. - - Raise `TableMarkupError` if there is any problem with the markup. - """ - self.setup(block) - self.findheadbodysep() - self.parsegrid() - structure = self.structurefromcells() - return structure + head_body_separator_pat = re.compile(r'\+=[=+]+=\+ *$') def setup(self, block): self.block = block[:] # make a copy; it may be modified self.bottom = len(block) - 1 self.right = len(block[0]) - 1 - self.headbodysep = None + self.head_body_sep = None self.done = [-1] * len(block[0]) self.cells = [] self.rowseps = {0: [0]} self.colseps = {0: [0]} - def findheadbodysep(self): - """Look for a head/body row separator line; store the line index.""" - for i in range(len(self.block)): - line = self.block[i] - if self.headbodyseparatorpat.match(line): - if self.headbodysep: - raise TableMarkupError, ( - 'Multiple head/body row separators in table (at line ' - 'offset %s and %s); only one allowed.' - % (self.headbodysep, i)) - else: - self.headbodysep = i - self.block[i] = line.replace('=', '-') - if self.headbodysep == 0 or self.headbodysep == len(self.block) - 1: - raise TableMarkupError, ( - 'The head/body row separator may not be the first or last ' - 'line of the table.' % (self.headbodysep, i)) - - def parsegrid(self): + def parse_table(self): """ Start with a queue of upper-left corners, containing the upper-left corner of the table itself. Trace out one rectangular cell, remember @@ -144,21 +158,21 @@ class TableParser: if top == self.bottom or left == self.right \ or top <= self.done[left]: continue - result = self.scancell(top, left) + result = self.scan_cell(top, left) if not result: continue bottom, right, rowseps, colseps = result - update_dictoflists(self.rowseps, rowseps) - update_dictoflists(self.colseps, colseps) - self.markdone(top, left, bottom, right) - cellblock = self.getcellblock(top, left, bottom, right) + update_dict_of_lists(self.rowseps, rowseps) + update_dict_of_lists(self.colseps, colseps) + self.mark_done(top, left, bottom, right) + cellblock = self.get_cell_block(top, left, bottom, right) self.cells.append((top, left, bottom, right, cellblock)) corners.extend([(top, right), (bottom, left)]) corners.sort() - if not self.checkparsecomplete(): - raise TableMarkupError, 'Malformed table; parse incomplete.' + if not self.check_parse_complete(): + raise TableMarkupError('Malformed table; parse incomplete.') - def markdone(self, top, left, bottom, right): + def mark_done(self, top, left, bottom, right): """For keeping track of how much of each text column has been seen.""" before = top - 1 after = bottom - 1 @@ -166,7 +180,7 @@ class TableParser: assert self.done[col] == before self.done[col] = after - def checkparsecomplete(self): + def check_parse_complete(self): """Each text column should have been completely seen.""" last = self.bottom - 1 for col in range(self.right): @@ -174,7 +188,7 @@ class TableParser: return None return 1 - def getcellblock(self, top, left, bottom, right): + def get_cell_block(self, top, left, bottom, right): """Given the corners, extract the text of a cell.""" cellblock = [] margin = right @@ -182,18 +196,18 @@ class TableParser: line = self.block[lineno][left + 1 : right].rstrip() cellblock.append(line) if line: - margin = margin and min(margin, len(line) - len(line.lstrip())) + margin = min(margin, len(line) - len(line.lstrip())) if 0 < margin < right: cellblock = [line[margin:] for line in cellblock] return cellblock - def scancell(self, top, left): + def scan_cell(self, top, left): """Starting at the top-left corner, start tracing out a cell.""" assert self.block[top][left] == '+' - result = self.scanright(top, left) + result = self.scan_right(top, left) return result - def scanright(self, top, left): + def scan_right(self, top, left): """ Look for the top-right corner of the cell, and make note of all column boundaries ('+'). @@ -203,16 +217,16 @@ class TableParser: for i in range(left + 1, self.right + 1): if line[i] == '+': colseps[i] = [top] - result = self.scandown(top, left, i) + result = self.scan_down(top, left, i) if result: bottom, rowseps, newcolseps = result - update_dictoflists(colseps, newcolseps) + update_dict_of_lists(colseps, newcolseps) return bottom, i, rowseps, colseps elif line[i] != '-': return None return None - def scandown(self, top, left, right): + def scan_down(self, top, left, right): """ Look for the bottom-right corner of the cell, making note of all row boundaries. @@ -221,16 +235,16 @@ class TableParser: for i in range(top + 1, self.bottom + 1): if self.block[i][right] == '+': rowseps[i] = [right] - result = self.scanleft(top, left, i, right) + result = self.scan_left(top, left, i, right) if result: newrowseps, colseps = result - update_dictoflists(rowseps, newrowseps) + update_dict_of_lists(rowseps, newrowseps) return i, rowseps, colseps elif self.block[i][right] != '|': return None return None - def scanleft(self, top, left, bottom, right): + def scan_left(self, top, left, bottom, right): """ Noting column boundaries, look for the bottom-left corner of the cell. It must line up with the starting point. @@ -244,14 +258,16 @@ class TableParser: return None if line[left] != '+': return None - result = self.scanup(top, left, bottom, right) + result = self.scan_up(top, left, bottom, right) if result is not None: rowseps = result return rowseps, colseps return None - def scanup(self, top, left, bottom, right): - """Noting row boundaries, see if we can return to the starting point.""" + def scan_up(self, top, left, bottom, right): + """ + Noting row boundaries, see if we can return to the starting point. + """ rowseps = {} for i in range(bottom - 1, top, -1): if self.block[i][left] == '+': @@ -260,9 +276,9 @@ class TableParser: return None return rowseps - def structurefromcells(self): + def structure_from_cells(self): """ - From the data colledted by `scancell()`, convert to the final data + From the data colledted by `scan_cell()`, convert to the final data structure. """ rowseps = self.rowseps.keys() # list of row boundaries @@ -274,7 +290,7 @@ class TableParser: colseps.sort() colindex = {} for i in range(len(colseps)): - colindex[colseps[i]] = i # column boundary -> col number mapping + colindex[colseps[i]] = i # column boundary -> col number map colspecs = [(colseps[i] - colseps[i - 1] - 1) for i in range(1, len(colseps))] # list of column widths # prepare an empty table with the correct number of rows & columns @@ -294,8 +310,8 @@ class TableParser: # write the cell into the table rows[rownum][colnum] = (morerows, morecols, top + 1, block) assert remaining == 0, 'Unused cells remaining.' - if self.headbodysep: # separate head rows from body rows - numheadrows = rowindex[self.headbodysep] + if self.head_body_sep: # separate head rows from body rows + numheadrows = rowindex[self.head_body_sep] headrows = rows[:numheadrows] bodyrows = rows[numheadrows:] else: @@ -304,7 +320,190 @@ class TableParser: return (colspecs, headrows, bodyrows) -def update_dictoflists(master, newdata): +class SimpleTableParser(TableParser): + + """ + Parse a simple table using `parse()`. + + Here's an example of a simple table:: + + ===== ===== + col 1 col 2 + ===== ===== + 1 Second column of row 1. + 2 Second column of row 2. + Second line of paragraph. + 3 - Second column of row 3. + + - Second item in bullet + list (row 3, column 2). + 4 is a span + ------------ + 5 + ===== ===== + + Top and bottom borders use '=', column span underlines use '-', column + separation is indicated with spaces. + + Passing the above table to the `parse()` method will result in the + following data structure, whose interpretation is the same as for + `GridTableParser`:: + + ([5, 25], + [[(0, 0, 1, ['col 1']), + (0, 0, 1, ['col 2'])]], + [[(0, 0, 3, ['1']), + (0, 0, 3, ['Second column of row 1.'])], + [(0, 0, 4, ['2']), + (0, 0, 4, ['Second column of row 2.', + 'Second line of paragraph.'])], + [(0, 0, 6, ['3']), + (0, 0, 6, ['- Second column of row 3.', + '', + '- Second item in bullet', + ' list (row 3, column 2).'])], + [(0, 1, 10, ['4 is a span'])], + [(0, 0, 12, ['5']), + (0, 0, 12, [''])]]) + """ + + head_body_separator_pat = re.compile('=[ =]*$') + span_pat = re.compile('-[ -]*$') + + def setup(self, block): + self.block = block[:] # make a copy; it will be modified + # Convert top & bottom borders to column span underlines: + self.block[0] = self.block[0].replace('=', '-') + self.block[-1] = self.block[-1].replace('=', '-') + self.head_body_sep = None + self.columns = [] + self.table = [] + self.done = [-1] * len(block[0]) + self.rowseps = {0: [0]} + self.colseps = {0: [0]} + + def parse_table(self): + """ + First determine the column boundaries from the top border, then + process rows. Each row may consist of multiple lines; accumulate + lines until a row is complete. Call `self.parse_row` to finish the + job. + """ + # Top border must fully describe all table columns. + self.columns = self.parse_columns(self.block[0]) + firststart, firstend = self.columns[0] + block = self.block[1:] + offset = 0 + # Container for accumulating text lines until a row is complete: + rowlines = [] + while block: + line = block.pop(0) + offset += 1 + if self.span_pat.match(line): + # Column span underline or border; row is complete. + self.parse_row(rowlines, line) + rowlines = [] + elif line[firststart:firstend].strip(): + # First column not blank, therefore it's a new row. + if rowlines: + self.parse_row(rowlines) + rowlines = [(line, offset)] + else: + # Accumulate lines of incomplete row. + rowlines.append((line, offset)) + + def parse_columns(self, line): + """ + Given a column span underline, return a list of (begin, end) pairs. + """ + cols = [] + end = 0 + while 1: + begin = line.find('-', end) + end = line.find(' ', begin) + if begin < 0: + break + if end < 0: + end = len(line) + cols.append((begin, end)) + return cols + + def init_row(self, colspec, offset): + i = 0 + cells = [] + for start, end in colspec: + morecols = 0 + try: + assert start == self.columns[i][0] + while end != self.columns[i][1]: + i += 1 + morecols += 1 + except (AssertionError, IndexError): + raise TableMarkupError('Column span alignment problem at ' + 'line offset %s.' % offset) + cells.append((0, morecols, offset, [])) + i += 1 + return cells + + def parse_row(self, lines, spanline=None): + """ + Given the text `lines` of a row, parse it and append to `self.table`. + + The row is parsed according to the current column spec (either + `spanline` if provided or `self.columns`). For each column, extract + text from each line, and check for text in column margins. Finally, + adjust for insigificant whitespace. + """ + if spanline: + columns = self.parse_columns(spanline) + else: + columns = self.columns[:] + row = self.init_row(columns, lines[0][1]) + # "Infinite" value for a dummy last column's beginning, used to + # check for text overflow: + columns.append((sys.maxint, None)) + lastcol = len(columns) - 2 + for i in range(len(columns) - 1): + start, end = columns[i] + nextstart = columns[i+1][0] + block = [] + margin = sys.maxint + for line, offset in lines: + if i == lastcol and line[end:].strip(): + text = line[start:].rstrip() + columns[lastcol] = (start, start + len(text)) + self.adjust_last_column(start + len(text)) + elif line[end:nextstart].strip(): + raise TableMarkupError('Text in column margin at line ' + 'offset %s.' % offset) + else: + text = line[start:end].rstrip() + block.append(text) + if text: + margin = min(margin, len(text) - len(text.lstrip())) + if 0 < margin < sys.maxint: + block = [line[margin:] for line in block] + row[i][3].extend(block) + self.table.append(row) + + def adjust_last_column(self, new_end): + start, end = self.columns[-1] + if new_end > end: + self.columns[-1] = (start, new_end) + + def structure_from_cells(self): + colspecs = [end - start for start, end in self.columns] + first_body_row = 0 + if self.head_body_sep: + for i in range(len(self.table)): + if self.table[i][0][2] > self.head_body_sep: + first_body_row = i + break + return (colspecs, self.table[:first_body_row], + self.table[first_body_row:]) + + +def update_dict_of_lists(master, newdata): """ Extend the list values of `master` with those from `newdata`. -- cgit v1.2.1 From 356d554c756d9b37284f6a1667995962f4ec2c67 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 00:57:31 +0000 Subject: - Added ``Contents`` to insert TOC. - Added ``PEPZero`` for PEP 0 special processing. - Masked email address of "Author" field. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@302 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 61 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index d33e0989d..0df6fa246 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -10,6 +10,8 @@ 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' @@ -52,6 +54,11 @@ class Headers(Transform): 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, 'last reader', {}) + self.document.insert(1, pending) + self.document.note_pending(pending) for field in header: name = field[0].astext().lower() body = field[1] @@ -73,15 +80,18 @@ class Headers(Transform): else: continue para = body[0] - if name == 'title': - title = body.astext() - # @@@ Insert a "pending" element here, since we don't really - # want a separate document title? - elif name in ('author', 'discussions-to'): + if name == 'author': for node in para: if isinstance(node, nodes.reference) \ - and node.has_key('refuri') \ - and node['refuri'][:7] == 'mailto:': + and node.has_key('refuri') \ + and node['refuri'].startswith('mailto:'): + replacement = node.astext().replace('@', ' at ') + node.parent.replace(node, nodes.Text(replacement)) + elif name == 'discussions-to': + for node in para: + if isinstance(node, nodes.reference) \ + and node.has_key('refuri') \ + and node['refuri'].startswith('mailto:'): node['refuri'] += '?subject=PEP%%20%s' % pep elif name in ('replaces', 'replaced-by'): newbody = [] @@ -113,3 +123,40 @@ class Contents(Transform): {'title': None}) self.document.insert(1, pending) self.document.note_pending(pending) + + +class PEPZero(Transform): + + """ + Special processing for PEP 0. + """ + + def transform(self): + visitor = EmailMasker(self.document) + self.document.walk(visitor) + self.startnode.parent.remove(self.startnode) + + +class EmailMasker(nodes.SparseNodeVisitor): + + """ + For all email-address references such as "user@host", mask the address as + "user at host" (text) to thwart simple email address harvesters. + """ + + non_masked_addresses = ('peps@python.org', + 'python-list@python.org', + 'python-dev@python.org') + + def unknown_visit(self, node): + pass + + def visit_reference(self, node): + if node.hasattr('refuri') and node['refuri'].startswith('mailto:') \ + and node['refuri'][8:] not in self.non_masked_addresses: + replacement = node.astext().replace('@', ' at ') + node.parent.replace(node, nodes.Text(replacement)) + + def visit_field_list(self, node): + if node.hasattr('class') and node['class'] == 'rfc2822': + raise nodes.SkipNode -- cgit v1.2.1 From e57505e14b9a33b25b2daf344eae89150e2e37b0 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:28:42 +0000 Subject: Changed default template name & Python's home. Made Python graphic random. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@303 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 9cfaa0a89..bd11d3752 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -13,6 +13,8 @@ PEP HTML Writer. __docformat__ = 'reStructuredText' +import sys +import random from docutils import nodes from docutils.writers import html4css1 @@ -25,12 +27,12 @@ class Writer(html4css1.Writer): (('Specify a stylesheet file. Default is "pep.css".', ['--stylesheet'], {'default': 'pep.css', 'metavar': ''}), - ('Specify a template file. Default is "pep-template.html".', + ('Specify a template file. Default is "pep-html-template".', ['--template'], - {'default': 'pep-template.html', 'metavar': ''}), - ('Python\'s home URL. Default is "http://www.python.org".', + {'default': 'pep-html-template', 'metavar': ''}), + ('Python\'s home URL. Default is ".." (parent directory).', ['--python-home'], - {'default': 'http://www.python.org', 'metavar': ''}), + {'default': '..', 'metavar': ''}), ('Home URL for this PEP. Default is "." (current directory).', ['--pep-home'], {'default': '.', 'metavar': ''}),)) @@ -46,9 +48,14 @@ class Writer(html4css1.Writer): stylesheet = options.stylesheet pyhome = options.python_home pephome = options.pep_home + if pyhome == '..': + pepindex = '.' + else: + pepindex = pyhome + '/peps/' index = self.document.first_child_matching_class(nodes.field_list) header = self.document[index] pep = header[0][1].astext() + banner = random.randrange(64) try: pepnum = '%04i' % int(pep) except: -- cgit v1.2.1 From 6e0d115d7619215b4b5c03ead6f53f0c153246cc Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:31:37 +0000 Subject: - Modified field list output. - Added backlinks to footnotes & citations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@304 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index db291ddee..8c6e2f2d4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -209,6 +209,7 @@ class HTMLTranslator(nodes.NodeVisitor): '\n' '\n' '\n' @@ -318,13 +319,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.head.append('\n' % (name, self.attval(node.astext()))) self.body.append(self.starttag(node, 'tr', '')) - self.body.append('') + self.body.append('\n') def visit_doctest_block(self, node): self.body.append(self.starttag(node, 'pre', suffix='', @@ -406,16 +405,15 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_field_body(self, node): - self.body.append(':

    \n') + self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) def depart_field_body(self, node): - #self.body.append('\n') self.body.append('\n') def visit_field_list(self, node): self.body.append(self.starttag(node, 'table', frame='void', - rules='none')) + rules='none', CLASS='field-list')) self.body.append('\n' '\n' '\n') @@ -424,8 +422,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') def visit_field_name(self, node): - self.body.append('

    \n') - self.body.append(self.starttag(node, 'p', '', CLASS='field-name')) + self.body.append(self.starttag(node, 'td', '', CLASS='field-name')) def depart_field_name(self, node): """ @@ -457,6 +454,23 @@ class HTMLTranslator(nodes.NodeVisitor): '
    \n') + self.footnote_backrefs(node) + + def footnote_backrefs(self, node): + if node.hasattr('backrefs'): + backrefs = node['backrefs'] + if len(backrefs) == 1: + self.body.append('' % backrefs[0]) + self.context.append(('', '')) + else: + i = 1 + backlinks = [] + for backref in backrefs: + backlinks.append('%s' % (backref, i)) + i += 1 + self.context.append(('', '(%s) ' % ', '.join(backlinks))) + else: + self.context.append(('', '')) def depart_footnote(self, node): self.body.append('
    \n') + self.body.append(']%s

    \n' + '
    %s\n' % self.context.pop()) def visit_legend(self, node): self.body.append(self.starttag(node, 'div', CLASS='legend')) @@ -721,7 +735,7 @@ class HTMLTranslator(nodes.NodeVisitor): backlinks.append('%s' % (backref, i)) i += 1 self.body.append('%s (%s; level %s system message)

    \n' - % (node['type'], '|'.join(backlinks), + % (node['type'], ', '.join(backlinks), node['level'])) else: self.body.append('%s (level %s system message)

    \n' -- cgit v1.2.1 From d2293256dba0cdc32d801cbc60d8796fe4be165d Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:33:32 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@305 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 476c57868..d138a8b2c 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -244,33 +244,28 @@ the mappings. The following state transition table shows how ``nameids`` ("ids") and ``nametypes`` ("types") change with new input (a call to -``document.set_name_id_map()``), and what actions are performed:: - - ==== ===== ======== ======== ======= ==== ===== ===== - Old State Input Action New State Notes - ----------- -------- ----------------- ----------- - ids types new type sys.msg. dupname ids types - ==== ===== ======== ======== ======= ==== ===== ===== - -- -- explicit -- -- new True - -- -- implicit -- -- new False - None False explicit -- -- new True - old False explicit implicit old new True - None True explicit explicit new None True - old True explicit explicit new,old None True [1] - None False implicit implicit new None False - old False implicit implicit new,old None False - None True implicit implicit new None True - old True implicit implicit new old True - ==== ===== ======== ======== ======= ==== ===== ===== - -Note 1: Do not clear the name->id map or invalidate the old target if -both old and new targets are external and refer to identical URIs. -The new target is invalidated regardless. - -(The above is an example of `table syntax alternative 3`__; not -implemented yet, but I'm thinking about it.) - -__ rst/problems.html#tables +``document.set_name_id_map()``), and what actions are performed: + +==== ===== ======== ======== ======= ==== ===== ===== + Old State Input Action New State Notes +----------- -------- ----------------- ----------- ----- +ids types new type sys.msg. dupname ids types +==== ===== ======== ======== ======= ==== ===== ===== +-- -- explicit -- -- new True +-- -- implicit -- -- new False +None False explicit -- -- new True +old False explicit implicit old new True +None True explicit explicit new None True +old True explicit explicit new,old None True [#]_ +None False implicit implicit new None False +old False implicit implicit new,old None False +None True implicit implicit new None True +old True implicit implicit new old True +==== ===== ======== ======== ======= ==== ===== ===== + +.. [#] Do not clear the name->id map or invalidate the old target if + both old and new targets are external and refer to identical URIs. + The new target is invalidated regardless. Representation of Horizontal Rules -- cgit v1.2.1 From 46db8cb85f96053f20e7f15f980f84b1ed52a245 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:35:13 +0000 Subject: minor edits git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@306 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 20e937105..74112d2c5 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -612,8 +612,8 @@ Questions & Answers The PEP markup proposal may be removed if it is deemed that there is no need for PEP markup, or it could be made into a separate PEP. - If accepted, PEP 1, PEP Purpose and Guidelines [PEP-1]_, and PEP 9, - Sample PEP Template [PEP-9]_ will be updated. + If accepted, PEP 1, PEP Purpose and Guidelines [#PEP-1]_, and PEP + 9, Sample PEP Template [#PEP-9]_ will be updated. It seems natural to adopt a single consistent markup standard for all uses of structured plaintext in Python, and to propose it all @@ -706,7 +706,7 @@ Questions & Answers What existing methodologies? For Python docstrings, there is **no** official standard markup format, let alone a documentation - methodology, akin to JavaDoc. The question of methodology is at a + methodology akin to JavaDoc. The question of methodology is at a much higher level than syntax (which this PEP addresses). It is potentially much more controversial and difficult to resolve, and is intentionally left out of this discussion. @@ -761,20 +761,20 @@ References & Footnotes .. _A Record of reStructuredText Syntax Alternatives: http://docutils.sourceforge.net/spec/rst/alternatives.html -.. [PEP-1] PEP 1, PEP Guidelines, Warsaw, Hylton +.. _Docutils: http://docutils.sourceforge.net/ + +.. [#PEP-1] PEP 1, PEP Guidelines, Warsaw, Hylton (http://www.python.org/peps/pep-0001.html) -.. [PEP-9] PEP 9, Sample PEP Template, Warsaw +.. [#PEP-9] PEP 9, Sample PEP Template, Warsaw (http://www.python.org/peps/pep-0009.html) -.. _Docutils: http://docutils.sourceforge.net/ - .. [#Zen] From `The Zen of Python (by Tim Peters)`__ (or just "``import this``" in Python) __ http://www.python.org/doc/Humor.html#zen -.. [PEP-216] PEP 216, Docstring Format, Zadka +.. [#PEP-216] PEP 216, Docstring Format, Zadka (http://www.python.org/peps/pep-0216.html) @@ -787,7 +787,7 @@ This document has been placed in the public domain. Acknowledgements ================ -Some text is borrowed from PEP 216, Docstring Format [PEP-216]_, by +Some text is borrowed from PEP 216, Docstring Format [#PEP-216]_, by Moshe Zadka. Special thanks to all members past & present of the Python Doc-SIG_. -- cgit v1.2.1 From 6927e19091214c51280889c64eb4ba1eb3489767 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:36:52 +0000 Subject: Added "simple table" syntax to supplement the existing but newly-renamed "grid tables". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@307 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 171 ++++++++++++++++++++++++++++++++------ 1 file changed, 146 insertions(+), 25 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index d996adf7a..659e952d9 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -136,15 +136,26 @@ Here are examples of `body elements`_: >>> print '(cut and pasted from interactive Python sessions)' (cut and pasted from interactive Python sessions) -- Tables_:: +- Two syntaxes for tables_: - +------------------------+------------+----------+ - | Header row, column 1 | Header 2 | Header 3 | - +========================+============+==========+ - | body row 1, column 1 | column 2 | column 3 | - +------------------------+------------+----------+ - | body row 2 | Cells may span | - +------------------------+-----------------------+ + 1. `Grid tables`_; complete, but complex and verbose:: + + +------------------------+------------+----------+ + | Header row, column 1 | Header 2 | Header 3 | + +========================+============+==========+ + | body row 1, column 1 | column 2 | column 3 | + +------------------------+------------+----------+ + | body row 2 | Cells may span | + +------------------------+-----------------------+ + + 2. `Simple tables`_; easy and compact, but limited:: + + ==================== ========== ========== + Header row, column 1 Header 2 Header 3 + ==================== ========== ========== + body row 1, column 1 column 2 column 3 + body row 2 Cells may span columns + ==================== ====================== - `Explicit markup blocks`_ all begin with an explicit block marker, two periods and a space: @@ -1109,17 +1120,38 @@ Tables DTD elements: table, tgroup, colspec, thead, tbody, row, entry. -Tables are described with a visual outline made up of the characters +ReStructuredText provides two syntaxes for delineating table cells: +`Grid Tables`_ and `Simple Tables`_. + +As with other body elements, blank lines are required before and after +tables. Tables' left edges should align with the left edge of +preceding text blocks; if indented, the table is considered to be part +of a block quote. + +Once isolated, each table cell is treated as a miniature document; the +top and bottom cell boundaries act as delimiting blank lines. Each +cell contains zero or more body elements. Cell contents may include +left and/or right margins, which are removed before processing. + + +Grid Tables +``````````` + +Grid tables provide a complete table representation via grid-like +"ASCII art". Grid tables allow arbitrary cell contents (body +elements), and both row and column spans. However, grid tables can be +cumbersome to produce, especially for simple data sets. The `Emacs +table mode`_ is a tool that allows easy editing of grid tables, in +Emacs. See `Simple Tables`_ for a simpler (but limited) +representation. + +Grid tables are described with a visual grid made up of the characters "-", "=", "|", and "+". The hyphen ("-") is used for horizontal lines (row separators). The equals sign ("=") may be used to separate -optional header rows from the table body. The vertical bar ("|") is -used for vertical lines (column separators). The plus sign ("+") is -used for intersections of horizontal and vertical lines. - -Each table cell is treated as a miniature document; the top and bottom -cell boundaries act as delimiting blank lines. Each cell contains -zero or more body elements. Cell contents may include left and/or -right margins, which are removed before processing. Example:: +optional header rows from the table body (not supported by the `Emacs +table mode`_). The vertical bar ("|") is used for vertical lines +(column separators). The plus sign ("+") is used for intersections of +horizontal and vertical lines. Example:: +------------------------+------------+----------+----------+ | Header row, column 1 | Header 2 | Header 3 | Header 4 | @@ -1134,14 +1166,9 @@ right margins, which are removed before processing. Example:: | body row 4 | | - body elements. | +------------------------+------------+---------------------+ -As with other body elements, blank lines are required before and after -tables. Tables' left edges should align with the left edge of -preceding text blocks; otherwise, the table is considered to be part -of a block quote. - -Some care must be taken with tables to avoid undesired interactions -with cell text in rare cases. For example, the following table -contains a cell in row 2 spanning from column 2 to column 4:: +Some care must be taken with grid tables to avoid undesired +interactions with cell text in rare cases. For example, the following +table contains a cell in row 2 spanning from column 2 to column 4:: +--------------+----------+-----------+-----------+ | row 1, col 1 | column 2 | column 3 | column 4 | @@ -1186,6 +1213,100 @@ Another possibility is to add an extra line to row 2:: +--------------+----------+-----------+-----------+ +Simple Tables +````````````` + +Simple tables provide a compact and easy to type but limited +row-oriented table representation for simple data sets. Cell contents +are typically single paragraphs, although arbitrary body elements may +be represented in most cells. Simple tables allow multi-line rows and +column spans, but not row spans. See `Grid Tables`_ above for a +complete table representation. + +Simple tables are described with horizontal borders made up of "=" and +"-" characters. The equals sign ("=") is used for top and bottom +table borders, and to separate optional header rows from the table +body. The hyphen ("-") is used to indicate column spans in a single +row by underlining the joined columns. + +A simple table begins with a top border of equals signs with one or +more spaces at each column boundary (two or more spaces recommended). +Regardless of spans, the top border *must* fully describe all table +columns. There must be at least two columns in the table (to +differentiate it from section headers). The last of the optional +header rows is underlined with '=', again with spaces at column +boundaries. There may not be a blank line below the header row +separator; it would be interpreted as the bottom border of the table. +The bottom boundary of the table consists of '=' underlines, also with +spaces at column boundaries. For example, here is a truth table, a +three-column table with one header row and four body rows:: + + ===== ===== ======= + A B A and B + ===== ===== ======= + False False False + True False False + False True False + True True True + ===== ===== ======= + +Underlines of '-' may be used to indicate column spans by "filling in" +column margins to join adjacent columns. Column span underlines must +be complete (they must cover all columns) and align with established +column boundaries. Text lines containing column span underlines may +not contain any other text. A column span underline applies only to +one row immediately above it. For example, here is a table with a +column span in the header:: + + ===== ===== ====== + Inputs Output + ------------ ------ + A B A or B + ===== ===== ====== + False False False + True False True + False True True + True True True + ===== ===== ====== + +Each line of text must contain spaces at column boundaries, except +where cells have been joined by column spans. Each line of text +starts a new row, except when there is a blank cell in the first +column. In that case, that line of text is parsed as a continuation +line. For this reason, cells in the first column of new rows (*not* +continuation lines) *must* contain some text; blank cells would lead +to a misinterpretation. An empty comment ("..") is sufficient and +will be omitted from the processed output. Also, cells in the first +column are limited to one line of text. + +Blank lines are permitted within simple tables. Their interpretation +depends on the context. Blank lines *between* rows are ignored. +Blank lines *within* multi-line rows may separate paragraphs or other +body elements within cells. + +The rightmost column is unbounded; text may continue past the edge of +the table (as indicated by the table borders). However, it is +recommended that borders be made long enough to contain the entire +text. + +The following example illustrates continuation lines (row 2 consists +of two lines of text, and four lines for row 3), a blank line +separating paragraphs (row 3, column 2), and text extending past the +right edge of the table:: + + ===== ===== + col 1 col 2 + ===== ===== + 1 Second column of row 1. + 2 Second column of row 2. + Second line of paragraph. + 3 - Second column of row 3. + + - Second item in bullet + list (row 3, column 2). + ===== ===== + + Explicit Markup Blocks ---------------------- -- cgit v1.2.1 From a6e799cb8524fc622f92e3a7d3c185bf0532f0ec Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:38:19 +0000 Subject: - Added support for simple tables. - Refactored naming. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@308 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 178 +++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 67 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 76e3a36e0..00afa10f5 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -23,8 +23,10 @@ Exports the following: - `CustomTestCase` - `ParserTestSuite` - `ParserTestCase` - - `TableParserTestSuite` - - `TableParserTestCase` + - `GridTableParserTestSuite` + - `GridTableParserTestCase` + - `SimpleTableParserTestSuite` + - `SimpleTableParserTestCase` """ __docformat__ = 'reStructuredText' @@ -68,7 +70,7 @@ class CustomTestSuite(unittest.TestSuite): """Identifier for the TestSuite. Prepended to the TestCase identifiers to make identification easier.""" - nextTestCaseId = 0 + next_test_case_id = 0 """The next identifier to use for non-identified test cases.""" def __init__(self, tests=(), id=None): @@ -97,8 +99,8 @@ class CustomTestSuite(unittest.TestSuite): else: self.id = id - def addTestCase(self, testCaseClass, methodName, input, expected, - id=None, runInDebugger=0, shortDescription=None, + def addTestCase(self, test_case_class, method_name, input, expected, + id=None, run_in_debugger=0, short_description=None, **kwargs): """ Create a custom TestCase in the CustomTestSuite. @@ -106,24 +108,24 @@ class CustomTestSuite(unittest.TestSuite): Arguments: - testCaseClass -- - methodName -- + test_case_class -- + method_name -- input -- input to the parser. expected -- expected output from the parser. id -- unique test identifier, used by the test framework. - runInDebugger -- if true, run this test under the pdb debugger. - shortDescription -- override to default test description. + run_in_debugger -- if true, run this test under the pdb debugger. + short_description -- override to default test description. """ if id is None: # generate id if required - id = self.nextTestCaseId - self.nextTestCaseId += 1 + id = self.next_test_case_id + self.next_test_case_id += 1 # test identifier will become suiteid.testid tcid = '%s: %s' % (self.id, id) # generate and add test case - tc = testCaseClass(methodName, input, expected, tcid, - runInDebugger=runInDebugger, - shortDescription=shortDescription, - **kwargs) + tc = test_case_class(method_name, input, expected, tcid, + run_in_debugger=run_in_debugger, + short_description=short_description, + **kwargs) self.addTest(tc) return tc @@ -133,26 +135,26 @@ class CustomTestCase(unittest.TestCase): compare = difflib.Differ().compare """Comparison method shared by all subclasses.""" - def __init__(self, methodName, input, expected, id, - runInDebugger=0, shortDescription=None): + def __init__(self, method_name, input, expected, id, + run_in_debugger=0, short_description=None): """ Initialise the CustomTestCase. Arguments: - methodName -- name of test method to run. + method_name -- name of test method to run. input -- input to the parser. expected -- expected output from the parser. id -- unique test identifier, used by the test framework. - runInDebugger -- if true, run this test under the pdb debugger. - shortDescription -- override to default test description. + run_in_debugger -- if true, run this test under the pdb debugger. + short_description -- override to default test description. """ self.id = id self.input = input self.expected = expected - self.runInDebugger = runInDebugger + self.run_in_debugger = run_in_debugger # Ring your mother. - unittest.TestCase.__init__(self, methodName) + unittest.TestCase.__init__(self, method_name) def __str__(self): """ @@ -164,7 +166,7 @@ class CustomTestCase(unittest.TestCase): def __repr__(self): return "<%s %s>" % (self.id, unittest.TestCase.__repr__(self)) - def compareOutput(self, input, output, expected): + def compare_output(self, input, output, expected): """`input`, `output`, and `expected` should all be strings.""" try: self.assertEquals('\n' + output, '\n' + expected) @@ -208,10 +210,10 @@ class TransformTestSuite(CustomTestSuite): for name, (transforms, cases) in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - runInDebugger = 0 + run_in_debugger = 0 if len(case)==3: if case[2]: - runInDebugger = 1 + run_in_debugger = 1 else: continue self.addTestCase( @@ -219,7 +221,7 @@ class TransformTestSuite(CustomTestSuite): transforms=transforms, parser=self.parser, input=case[0], expected=case[1], id='%s[%r][%s]' % (dictname, name, casenum), - runInDebugger=runInDebugger) + run_in_debugger=run_in_debugger) class TransformTestCase(CustomTestCase): @@ -252,17 +254,17 @@ class TransformTestCase(CustomTestCase): return 1 def test_transforms(self): - if self.runInDebugger: + if self.run_in_debugger: pdb.set_trace() document = utils.new_document(self.options) self.parser.parse(self.input, document) for transformClass in (self.transforms + universal.test_transforms): transformClass(document, self).transform() output = document.pformat() - self.compareOutput(self.input, output, self.expected) + self.compare_output(self.input, output, self.expected) def test_transforms_verbosely(self): - if self.runInDebugger: + if self.run_in_debugger: pdb.set_trace() print '\n', self.id print '-' * 70 @@ -276,7 +278,7 @@ class TransformTestCase(CustomTestCase): output = document.pformat() print '-' * 70 print output - self.compareOutput(self.input, output, self.expected) + self.compare_output(self.input, output, self.expected) class ParserTestCase(CustomTestCase): @@ -298,12 +300,12 @@ class ParserTestCase(CustomTestCase): options.debug = package_unittest.debug def test_parser(self): - if self.runInDebugger: + if self.run_in_debugger: pdb.set_trace() document = utils.new_document(self.options) self.parser.parse(self.input, document) output = document.pformat() - self.compareOutput(self.input, output, self.expected) + self.compare_output(self.input, output, self.expected) class ParserTestSuite(CustomTestSuite): @@ -331,17 +333,17 @@ class ParserTestSuite(CustomTestSuite): for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - runInDebugger = 0 + run_in_debugger = 0 if len(case)==3: if case[2]: - runInDebugger = 1 + run_in_debugger = 1 else: continue self.addTestCase( self.test_case_class, 'test_parser', input=case[0], expected=case[1], id='%s[%r][%s]' % (dictname, name, casenum), - runInDebugger=runInDebugger) + run_in_debugger=run_in_debugger) class PEPParserTestCase(ParserTestCase): @@ -359,22 +361,48 @@ class PEPParserTestSuite(ParserTestSuite): test_case_class = PEPParserTestCase -class TableParserTestSuite(CustomTestSuite): +class GridTableParserTestCase(CustomTestCase): + + parser = tableparser.GridTableParser() + + def test_parse_table(self): + self.parser.setup(string2lines(self.input)) + try: + self.parser.find_head_body_sep() + self.parser.parse_table() + output = self.parser.cells + except Exception, details: + output = '%s: %s' % (details.__class__.__name__, details) + self.compare_output(self.input, pformat(output) + '\n', + pformat(self.expected) + '\n') + + def test_parse(self): + try: + output = self.parser.parse(string2lines(self.input)) + except Exception, details: + output = '%s: %s' % (details.__class__.__name__, details) + self.compare_output(self.input, pformat(output) + '\n', + pformat(self.expected) + '\n') + + +class GridTableParserTestSuite(CustomTestSuite): """ - A collection of TableParserTestCases. + A collection of GridTableParserTestCases. - A TableParserTestSuite instance manufactures TableParserTestCases, - keeps track of them, and provides a shared test fixture (a-la - setUp and tearDown). + A GridTableParserTestSuite instance manufactures GridTableParserTestCases, + keeps track of them, and provides a shared test fixture (a-la setUp and + tearDown). """ + test_case_class = GridTableParserTestCase + def generateTests(self, dict, dictname='totest'): """ Stock the suite with test cases generated from a test data dictionary. Each dictionary key (test type name) maps to a list of tests. Each - test is a list: an input table, expected output from parsegrid(), + test is a list: an input table, expected output from parse_table(), expected output from parse(), optional modifier. The optional fourth entry, a behavior modifier, can be 0 (temporarily disable this test) or 1 (run this test under the pdb debugger). Tests should be @@ -383,41 +411,57 @@ class TableParserTestSuite(CustomTestSuite): for name, cases in dict.items(): for casenum in range(len(cases)): case = cases[casenum] - runInDebugger = 0 + run_in_debugger = 0 if len(case) == 4: - if case[3]: - runInDebugger = 1 + if case[-1]: + run_in_debugger = 1 else: continue - self.addTestCase(TableParserTestCase, 'test_parsegrid', + self.addTestCase(self.test_case_class, 'test_parse_table', input=case[0], expected=case[1], id='%s[%r][%s]' % (dictname, name, casenum), - runInDebugger=runInDebugger) - self.addTestCase(TableParserTestCase, 'test_parse', + run_in_debugger=run_in_debugger) + self.addTestCase(self.test_case_class, 'test_parse', input=case[0], expected=case[2], id='%s[%r][%s]' % (dictname, name, casenum), - runInDebugger=runInDebugger) + run_in_debugger=run_in_debugger) -class TableParserTestCase(CustomTestCase): +class SimpleTableParserTestCase(GridTableParserTestCase): - parser = tableparser.TableParser() + parser = tableparser.SimpleTableParser() - def test_parsegrid(self): - self.parser.setup(string2lines(self.input)) - try: - self.parser.findheadbodysep() - self.parser.parsegrid() - output = self.parser.cells - except Exception, details: - output = '%s: %s' % (details.__class__.__name__, details) - self.compareOutput(self.input, pformat(output) + '\n', - pformat(self.expected) + '\n') - def test_parse(self): - try: - output = self.parser.parse(string2lines(self.input)) - except Exception, details: - output = '%s: %s' % (details.__class__.__name__, details) - self.compareOutput(self.input, pformat(output) + '\n', - pformat(self.expected) + '\n') +class SimpleTableParserTestSuite(CustomTestSuite): + + """ + A collection of SimpleTableParserTestCases. + """ + + test_case_class = SimpleTableParserTestCase + + def generateTests(self, dict, dictname='totest'): + """ + Stock the suite with test cases generated from a test data dictionary. + + Each dictionary key (test type name) maps to a list of tests. Each + test is a list: an input table, expected output from parse(), optional + modifier. The optional third entry, a behavior modifier, can be 0 + (temporarily disable this test) or 1 (run this test under the pdb + debugger). Tests should be self-documenting and not require external + comments. + """ + for name, cases in dict.items(): + for casenum in range(len(cases)): + case = cases[casenum] + run_in_debugger = 0 + if len(case) == 3: + if case[-1]: + run_in_debugger = 1 + else: + continue + self.addTestCase(self.test_case_class, 'test_parse', + input=case[0], expected=case[1], + id='%s[%r][%s]' % (dictname, name, casenum), + run_in_debugger=run_in_debugger) + -- cgit v1.2.1 From 849dd8bcd4d2193fadb3357bdff6b410581adf4e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:39:17 +0000 Subject: added to project git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@309 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_SimpleTableParser.py | 101 +++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 test/test_parsers/test_rst/test_SimpleTableParser.py diff --git a/test/test_parsers/test_rst/test_SimpleTableParser.py b/test/test_parsers/test_rst/test_SimpleTableParser.py new file mode 100644 index 000000000..dca3798c0 --- /dev/null +++ b/test/test_parsers/test_rst/test_SimpleTableParser.py @@ -0,0 +1,101 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for states.py. +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.SimpleTableParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['simple_tables'] = [ +["""\ +============ ============ +A table with two columns. +============ ============ +""", +([12, 12], + [], + [[(0, 0, 1, ['A table with']), + (0, 0, 1, ['two columns.'])]])], +["""\ +============ ============ +A table with two columns +and two rows. +============ ============ +""", +([12, 12], + [], + [[(0, 0, 1, ['A table with']), + (0, 0, 1, ['two columns'])], + [(0, 0, 2, ['and']), + (0, 0, 2, ['two rows.'])]])], +["""\ +========== =========== +A table with four rows, +----------------------- +and two columns. +First and last rows +contain column spans. +======================= +""", +([10, 11], + [], + [[(0, 1, 1, ['A table with four rows,'])], + [(0, 0, 3, ['and two']), + (0, 0, 3, ['columns.'])], + [(0, 0, 4, ['First and']), + (0, 0, 4, ['last rows'])], + [(0, 1, 5, ['contain column spans.'])]])], +["""\ +======= ===== ====== +A bad table cell 2 +cell 3 cell 4 +============ ====== +""", +'TableMarkupError: Text in column margin at line offset 1.'], +["""\ +=========== ================ +A table with two header rows, +----------------------------- +the first with a span. +=========== ================ +Two body rows, +the second with a span. +============================= +""", +([11, 16], + [[(0, 1, 1, ['A table with two header rows,'])], + [(0, 0, 3, ['the first']), + (0, 0, 3, ['with a span.'])]], + [[(0, 0, 5, ['Two body']), + (0, 0, 5, ['rows,'])], + [(0, 1, 6, ['the second with a span.'])]])], +["""\ +============ ============= +A table with two head/body +============ ============= +row separators. +============ ============= +That's bad. +============ ============= +""", +'TableMarkupError: Multiple head/body row separators in table ' +'(at line offset 2 and 4); only one allowed.'], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From fea3c6179eb45005a3a561d6ce5f1c48eceb4bb2 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:40:16 +0000 Subject: tweaking git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@310 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index ffeec0d69..81de8ba2c 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -43,12 +43,6 @@ div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } -div.field-body { - margin-bottom: 1em } - -div.field-list { - margin-bottom: -1em } - div.figure { margin-left: 2em } @@ -111,14 +105,6 @@ p.credits { font-style: italic ; font-size: smaller } -p.docinfo-name { - font-weight: bold ; - text-align: right } - -p.field-name { - font-weight: bold ; - margin-bottom: 1em } - p.label { white-space: nowrap } @@ -163,3 +149,10 @@ table.docinfo { table.footnote { border-left: solid thin black ; padding-left: 0.5ex } + +td.docinfo-name { + font-weight: bold ; + text-align: right } + +td.field-name { + font-weight: bold } -- cgit v1.2.1 From 32367a27ba4aa267d9d0ecfe10c8395e4044ad47 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:43:09 +0000 Subject: Parameterized the Python graphic. Separately parematerized the PEP index path. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@311 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-template.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/pep-template.html b/tools/pep-template.html index 49e989ba4..de0c0d4c8 100644 --- a/tools/pep-template.html +++ b/tools/pep-template.html @@ -12,11 +12,11 @@ width="100%%" border="0">
    %(body)s -- cgit v1.2.1 From d502067bbf507b4f370972b7ee8cc54645ca3ccc Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:44:22 +0000 Subject: Renamed pep-template.html to pep-html-template git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@312 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-html-template | 23 +++++++++++++++++++++++ tools/pep-template.html | 23 ----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 tools/pep-html-template delete mode 100644 tools/pep-template.html diff --git a/tools/pep-html-template b/tools/pep-html-template new file mode 100644 index 000000000..de0c0d4c8 --- /dev/null +++ b/tools/pep-html-template @@ -0,0 +1,23 @@ + + + + + + + PEP %(pep)s -- %(title)s + + + + + + +%(body)s +%(body_suffix)s diff --git a/tools/pep-template.html b/tools/pep-template.html deleted file mode 100644 index de0c0d4c8..000000000 --- a/tools/pep-template.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - PEP %(pep)s -- %(title)s - - - - - - -%(body)s -%(body_suffix)s -- cgit v1.2.1 From 072c69c92964642a05d2b9c91b4e4321890d933b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 01:48:14 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@313 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 27 +- docs/dev/rst/problems.txt | 3 +- docs/dev/todo.txt | 21 +- test/test_parsers/test_rst/test_TableParser.py | 5 +- test/test_parsers/test_rst/test_tables.py | 395 ++++++++++++++++++++++++- tools/stylesheets/pep.css | 2 +- 6 files changed, 439 insertions(+), 14 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 5b9ea8da8..9f9ea70d3 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -101,6 +101,8 @@ Specific: - 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). * docutils/optik.py: Added to project. Combined from the Optik package, with added option groups and other modifications. The use @@ -155,6 +157,14 @@ Specific: - 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/html.py: Changed the ``meta`` directive to use a ``pending`` element, used only by HTML writers. @@ -214,7 +224,9 @@ Specific: with Unicode. - Added the translator class as instance variable to the Writer, to make it easily subclassable. - - Modified the ``field_body`` output. + - Improved option list spacing (thanks to Richard Jones). + - Modified field list output. + - Added backlinks to footnotes & citations. * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). @@ -278,11 +290,16 @@ Specific: ``/`` 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". * test: Made test modules standalone (subdirectories became packages). -* test/DocutilsTestSupport.py: Support for PEP extensions to - reStructuredText. +* 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. @@ -291,6 +308,8 @@ Specific: * 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-ends to use the new @@ -307,7 +326,7 @@ Specific: * tools/pep.py: Added to project; PEP to HTML front-end. -* tools/pep-template.html: Added to project; template for PEP HTML. +* tools/pep-html-template: Added to project. * tools/quicktest.py: Added the "--attributes" option, hacked a bit. diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt index 1d1e8b208..25fda8136 100644 --- a/docs/dev/rst/problems.txt +++ b/docs/dev/rst/problems.txt @@ -465,7 +465,8 @@ documentation. Alternatives: - Cells in the first column are limited to one line of text. - Cells in the first column *must* contain some text; blank cells - would lead to a misinterpretation. + would lead to a misinterpretation. An empty comment ("..") is + sufficient. 6. Combining alternative 3 and 4, a bullet list in the first column could mean multi-line rows, and no bullet list means single-line diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 089c5c4a7..092c7e8ab 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -40,6 +40,11 @@ Bugs Idea: two-pass hyperlink resolution, ignoring errors on the first pass? +- Section headers must have underlines at least 4 characters long. + But when the section title is only 3 characters long, it's natural + to underline with "===" (I just did). The parser should produce a + warning in such cases. + General ------- @@ -230,9 +235,6 @@ __ rst/alternatives.html#or-not-to-do the left edge of the first line if it began on the same line as the field name. -- Make footnotes two-way, GNU-style? What if there are multiple - references to a single footnote? - - Allow for variant styles by interpreting indented lists as if they weren't indented? For example, currently the list below will be parsed as a list within a block quote:: @@ -296,13 +298,17 @@ __ rst/alternatives.html#or-not-to-do John Doe wrote:: - > Great idea! + >> Great idea! > > Why didn't I think of that? - Every line of the literal block would have to begin with the same + The literal block would have to be a continuous text block (the + first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. +- The parser doesn't know anything about double-width characters such + as Chinese hanza & Japanese kanji/kana. + Directives `````````` @@ -628,6 +634,11 @@ Front-Ends conflicts) to splitting common and component-specific options apart. +- Allow multiple option groups per component (thus enabling component + subclasses to easily incorporate their superclass' options). + +- Parameterize help text & defaults somehow? Perhaps a callback? + Project Policies ================ diff --git a/test/test_parsers/test_rst/test_TableParser.py b/test/test_parsers/test_rst/test_TableParser.py index d79c2c58d..daba2c1b0 100755 --- a/test/test_parsers/test_rst/test_TableParser.py +++ b/test/test_parsers/test_rst/test_TableParser.py @@ -13,13 +13,13 @@ Tests for states.py. from __init__ import DocutilsTestSupport def suite(): - s = DocutilsTestSupport.TableParserTestSuite() + s = DocutilsTestSupport.GridTableParserTestSuite() s.generateTests(totest) return s totest = {} -totest['tables'] = [ +totest['grid_tables'] = [ ["""\ +-------------------------------------+ | A table with one cell and one line. | @@ -192,6 +192,7 @@ totest['tables'] = [ '(at line offset 2 and 4); only one allowed.'], ] + if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_tables.py b/test/test_parsers/test_rst/test_tables.py index b6f1be993..e74c7cfb5 100755 --- a/test/test_parsers/test_rst/test_tables.py +++ b/test/test_parsers/test_rst/test_tables.py @@ -19,7 +19,7 @@ def suite(): totest = {} -totest['tables'] = [ +totest['full_tables'] = [ ["""\ +-------------------------------------+ | A table with one cell and one line. | @@ -559,6 +559,399 @@ No blank line after table. """], ] +totest['simple_tables'] = [ +["""\ +============ ============ +A table with two columns. +============ ============ + +Paragraph. +""", +"""\ + + + + + + + + + + A table with + + + two columns. + + Paragraph. +"""], +["""\ +============ ============ +A table with two columns +and two rows. +============ ============ +""", +"""\ + +
    + + + + + + + + A table with + + + two columns + + + + and + + + two rows. +"""], +["""\ +============ ============== +A table with two columns, +two rows, and a column span. +============================ +""", +"""\ + +
    + + + + + + + + A table with + + + two columns, + + + + two rows, and a column span. +"""], +["""\ +== =========== =========== +1 A table with three rows, +-- ------------------------ +2 and three columns. +3 First and last rows + contain column spans. + + This last row is a multi-line row, and overflows to the right. +== ======================== +""", +"""\ + +
    + + + + + + + + + 1 + + + A table with three rows, + + + + 2 + + + and three + + + columns. + + + + 3 + + + First and last rows + contain column spans. + + This last row is a multi-line row, and overflows to the right. +"""], +["""\ +======= ========= ======== +A table with three columns. +================== ======== +""", +"""\ + +
    + + + + + + + + + A table with three + + + columns. +"""], +["""\ +============== ====== +A simple table with +no bottom border +""", +"""\ + + + + Malformed table at line 1; formatting as a literal block. + No bottom table border found. + + ============== ====== + A simple table with + no bottom border +"""], +["""\ +============== ====== +A simple table cell 2 +cell 3 cell 4 +============== ====== +No blank line after table. +""", +"""\ + + + + Malformed table at line 1; formatting as a literal block. + No bottom table border found or no blank line after table bottom. + + ============== ====== + A simple table cell 2 + cell 3 cell 4 + ============== ====== + + + Blank line required after table at line 5. + + No blank line after table. +"""], +["""\ +============== ====== +A simple table cell 2 +============== ====== +cell 3 cell 4 +============== ====== +No blank line after table. +""", +"""\ + +
    + + + + + + + + A simple table + + + cell 2 + + + + + cell 3 + + + cell 4 + + + Blank line required after table at line 6. + + No blank line after table. +"""], +["""\ +============== ====== +A simple table cell 2 +cell 3 cell 4 +============== ====== + Unexpected indent and no blank line after table. +""", +"""\ + + + + Malformed table at line 1; formatting as a literal block. + No bottom table border found or no blank line after table bottom. + + ============== ====== + A simple table cell 2 + cell 3 cell 4 + ============== ====== + + + Blank line required after table at line 5. + + + Unexpected indent and no blank line after table. +"""], +["""\ +============== ====== +A bad table cell 2 +cell 3 cell 4 +============ ======== +""", +"""\ + + + + Malformed table at line 1; formatting as a literal block. + Column span alignment problem at line offset 2. + + ============== ====== + A bad table cell 2 + cell 3 cell 4 + ============ ======== +"""], +["""\ +======== ========= +A bad table cell 2 +cell 3 cell 4 +======== ========= +""", +"""\ + + + + Malformed table at line 1; formatting as a literal block. + Text in column margin at line offset 1. + + ======== ========= + A bad table cell 2 + cell 3 cell 4 + ======== ========= +"""], +["""\ +== ============================ +1 This table contains another. +2 ======= ====== ======== + A table within a table. + ======= ====== ======== + + The outer table does have to + have at least two columns + though. +== ============================ +""", +"""\ + +
    + + + + + + + + 1 + + + This table contains another. + + + + 2 + +
    + + + + + + + + + A table + + + within + + + a table. + + The outer table does have to + have at least two columns + though. +"""], +["""\ +================ ====== +A simple table +with empty cells +================ ====== +""", +"""\ + +
    + + + + + + + + A simple table + + + + + with empty cells + +"""], +["""\ +============== ======== + A table with +============== ======== + centered cells. + +============== ======== +""", +"""\ + +
    + + + + + + + + A table + + + with + + + + + centered + + + cells. +"""], +] + + if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 00e586c50..69fc0f087 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -28,7 +28,7 @@ Default cascading style sheet for the PEP HTML output of Docutils. .rfc2822 div.field-body { text-align: left } -.rfc2822 p.field-name { +.rfc2822 td.field-name { text-align: right ; font-family: sans-serif ; padding-right: 0.5em ; -- cgit v1.2.1 From 8a2a8c7bb67756e1c7f4429094bcf2e02139ac5b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 02:00:37 +0000 Subject: fixed link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@314 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 659e952d9..abf85b19c 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2454,12 +2454,13 @@ Markup errors are handled according to the specification in `PEP .. _DocTitle transform: .. _DocInfo transform: http://docutils.sourceforge.net/docutils/transforms/frontmatter.py -.. _doctest module: - http://www.python.org/doc/current/lib/module-doctest.html .. _getopt.py: http://www.python.org/doc/current/lib/module-getopt.html .. _GNU libc getopt_long(): http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_516.html +.. _doctest module: + http://www.python.org/doc/current/lib/module-doctest.html +.. _Emacs table mode: http://table.sourceforge.net/ .. _Index of WWW Addressing Schemes: http://www.w3.org/Addressing/schemes.html .. _World Wide Web Consortium: http://www.w3.org/ -- cgit v1.2.1 From ecdd69c2c799b5e32d80a4d76fbb9f62c3c927e5 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 03:13:48 +0000 Subject: SourceForge's Python segfaults on "import random"; workaround. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@316 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index bd11d3752..3aef311d1 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -14,8 +14,8 @@ __docformat__ = 'reStructuredText' import sys -import random -from docutils import nodes +#import random +from docutils import nodes, optik from docutils.writers import html4css1 @@ -35,7 +35,9 @@ class Writer(html4css1.Writer): {'default': '..', 'metavar': ''}), ('Home URL for this PEP. Default is "." (current directory).', ['--pep-home'], - {'default': '.', 'metavar': ''}),)) + {'default': '.', 'metavar': ''}), + (optik.SUPPRESS_HELP, ['--no-random'], + {'action': 'store_true'}),)) def __init__(self): html4css1.Writer.__init__(self) @@ -55,7 +57,11 @@ class Writer(html4css1.Writer): index = self.document.first_child_matching_class(nodes.field_list) header = self.document[index] pep = header[0][1].astext() - banner = random.randrange(64) + if options.no_random: + banner = 0 + else: + import random + banner = random.randrange(64) try: pepnum = '%04i' % int(pep) except: -- cgit v1.2.1 From f52c536ec05af5ba12b897db5276d24989436893 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 18 Jul 2002 03:20:12 +0000 Subject: Added "latin-1" as final fallback encoding. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@318 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/io.py b/docutils/io.py index aa9d27c41..397886c18 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -68,6 +68,7 @@ class IO: encodings.append(locale.getdefaultlocale()[1]) except: pass + encodings.append('latin-1') for enc in encodings: if not enc: continue -- cgit v1.2.1 From 2a27bb35bdadbee15b24709e03c1cca08c7c8615 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:05:40 +0000 Subject: From python/nondist/peps. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@319 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100755 tools/pep2html.py diff --git a/tools/pep2html.py b/tools/pep2html.py new file mode 100755 index 000000000..47cf1be1e --- /dev/null +++ b/tools/pep2html.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python +""" +convert PEP's to (X)HTML - courtesy of /F + +Usage: %(PROGRAM)s [options] [peps] + +Options: + + -u/--user + SF username + + -b/--browse + After generating the HTML, direct your web browser to view it + (using the Python webbrowser module). If both -i and -b are + given, this will browse the on-line HTML; otherwise it will + browse the local HTML. If no pep arguments are given, this + will browse PEP 0. + + -i/--install + After generating the HTML, install it and the plain text source file + (.txt) SourceForge. In that case the user's name is used in the scp + and ssh commands, unless -u sf_username is given (in which case, it is + used instead). Without -i, -u is ignored. + + -q/--quiet + Turn off verbose messages. + + -h/--help + Print this help message and exit. + +The optional argument `peps' is a list of either pep numbers or .txt files. +""" + +import sys +import os +import re +import cgi +import glob +import getopt +import errno +import random +import time + +PROGRAM = sys.argv[0] +RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' +PEPURL = 'pep-%04d.html' +PEPCVSURL = 'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/nondist/peps/pep-%04d.txt' +PEPDIRRUL = 'http://www.python.org/peps/' + + +HOST = "www.python.org" # host for update +HDIR = "/ftp/ftp.python.org/pub/www.python.org/peps" # target host directory +LOCALVARS = "Local Variables:" + +# The generated HTML doesn't validate -- you cannot use
    and

    inside +#
     tags.  But if I change that, the result doesn't look very nice...
    +DTD = ('')
    +
    +fixpat = re.compile("((http|ftp):[-_a-zA-Z0-9/.+~:?#$=&,]+)|(pep-\d+(.txt)?)|"
    +                    "(RFC[- ]?(?P\d+))|"
    +                    "(PEP\s+(?P\d+))|"
    +                    ".")
    +
    +EMPTYSTRING = ''
    +SPACE = ' '
    +
    +
    +
    +def usage(code, msg=''):
    +    print >> sys.stderr, __doc__ % globals()
    +    if msg:
    +        print >> sys.stderr, msg
    +    sys.exit(code)
    +
    +
    +
    +def fixanchor(current, match):
    +    text = match.group(0)
    +    link = None
    +    if text.startswith('http:') or text.startswith('ftp:'):
    +        # Strip off trailing punctuation.  Pattern taken from faqwiz.
    +        ltext = list(text)
    +        while ltext:
    +            c = ltext.pop()
    +            if c not in '();:,.?\'"<>':
    +                ltext.append(c)
    +                break
    +        link = EMPTYSTRING.join(ltext)
    +    elif text.startswith('pep-') and text <> current:
    +        link = os.path.splitext(text)[0] + ".html"
    +    elif text.startswith('PEP'):
    +        pepnum = int(match.group('pepnum'))
    +        link = PEPURL % pepnum
    +    elif text.startswith('RFC'):
    +        rfcnum = int(match.group('rfcnum'))
    +        link = RFCURL % rfcnum
    +    if link:
    +        return '%s' % (link, cgi.escape(text))
    +    return cgi.escape(match.group(0)) # really slow, but it works...
    +
    +
    +
    +NON_MASKED_EMAILS = [
    +    'peps@python.org',
    +    'python-list@python.org',
    +    'python-dev@python.org',
    +    ]
    +
    +def fixemail(address, pepno):
    +    if address.lower() in NON_MASKED_EMAILS:
    +        # return hyperlinked version of email address
    +        return linkemail(address, pepno)
    +    else:
    +        # return masked version of email address
    +        parts = address.split('@', 1)
    +        return '%s at %s' % (parts[0], parts[1])
    +
    +
    +def linkemail(address, pepno):
    +    parts = address.split('@', 1)
    +    return (''
    +            '%s at %s'
    +            % (parts[0], parts[1], pepno, parts[0], parts[1]))
    +
    +
    +def fixfile(infile, outfile):
    +    basename = os.path.basename(infile)
    +    # convert plain text pep to minimal XHTML markup
    +    try:
    +        fi = open(infile)
    +    except IOError, e:
    +        if e.errno <> errno.ENOENT: raise
    +        print >> sys.stderr, 'Error: Skipping missing PEP file:', e.filename
    +        return
    +    fo = open(outfile, "w")
    +    print >> fo, DTD
    +    print >> fo, ''
    +    print >> fo, ''
    +    # head
    +    header = []
    +    pep = ""
    +    title = ""
    +    while 1:
    +        line = fi.readline()
    +        if not line.strip():
    +            break
    +        if line[0].strip():
    +            if ":" not in line:
    +                break
    +            key, value = line.split(":", 1)
    +            value = value.strip()
    +            header.append((key, value))
    +        else:
    +            # continuation line
    +            key, value = header[-1]
    +            value = value + line
    +            header[-1] = key, value
    +        if key.lower() == "title":
    +            title = value
    +        elif key.lower() == "pep":
    +            pep = value
    +    if pep:
    +        title = "PEP " + pep + " -- " + title
    +    if title:
    +        print >> fo, '  %s' % cgi.escape(title)
    +    print >> fo, '  '
    +    print >> fo, ''
    +    # body
    +    print >> fo, ''
    +    print >> fo, '

    > fo, ' width="100%" border="0">' + print >> fo, '' + print >> fo, '' + print >> fo, '

    \n' + for k, v in header: + if k.lower() in ('author', 'discussions-to'): + mailtos = [] + for addr in v.split(): + if '@' in addr: + if k.lower() == 'discussions-to': + m = linkemail(addr, pep) + else: + m = fixemail(addr, pep) + mailtos.append(m) + elif addr.startswith('http:'): + mailtos.append( + '%s' % (addr, addr)) + else: + mailtos.append(addr) + v = SPACE.join(mailtos) + elif k.lower() in ('replaces', 'replaced-by'): + otherpeps = '' + for otherpep in v.split(): + otherpep = int(otherpep) + otherpeps += '%i ' % (otherpep, + otherpep) + v = otherpeps + elif k.lower() in ('last-modified',): + url = PEPCVSURL % int(pep) + date = v or time.strftime('%d-%b-%Y', + time.localtime(os.stat(infile)[8])) + v = '%s ' % (url, cgi.escape(date)) + else: + v = cgi.escape(v) + print >> fo, ' ' \ + % (cgi.escape(k), v) + print >> fo, '
    %s: %s
    ' + print >> fo, '
    ' + print >> fo, '
    ' + print >> fo, '
    ' + need_pre = 1 + while 1: + line = fi.readline() + if not line: + break + if line[0] == '\f': + continue + if line.strip() == LOCALVARS: + break + if line[0].strip(): + if line.strip() == LOCALVARS: + break + if not need_pre: + print >> fo, '' + print >> fo, '

    %s

    ' % line.strip() + need_pre = 1 + elif not line.strip() and need_pre: + continue + else: + # PEP 0 has some special treatment + if basename == 'pep-0000.txt': + parts = line.split() + if len(parts) > 1 and re.match(r'\s*\d{1,4}', parts[1]): + # This is a PEP summary line, which we need to hyperlink + url = PEPURL % int(parts[1]) + if need_pre: + print >> fo, '
    '
    +                        need_pre = 0
    +                    print >> fo, re.sub(
    +                        parts[1],
    +                        '%s' % (url, parts[1]),
    +                        line, 1),
    +                    continue
    +                elif parts and '@' in parts[-1]:
    +                    # This is a pep email address line, so filter it.
    +                    url = fixemail(parts[-1], pep)
    +                    if need_pre:
    +                        print >> fo, '
    '
    +                        need_pre = 0
    +                    print >> fo, re.sub(
    +                        parts[-1], url, line, 1),
    +                    continue
    +            line = fixpat.sub(lambda x, c=infile: fixanchor(c, x), line)
    +            if need_pre:
    +                print >> fo, '
    '
    +                need_pre = 0
    +            fo.write(line)
    +    if not need_pre:
    +        print >> fo, '
    ' + print >> fo, '
    ' + print >> fo, '' + print >> fo, '' + fo.close() + os.chmod(outfile, 0664) + + + +def find_pep(pep_str): + """Find the .txt file indicated by a cmd line argument""" + if os.path.exists(pep_str): + return pep_str + num = int(pep_str) + return "pep-%04d.txt" % num + +def make_html(file, verbose=0): + newfile = os.path.splitext(file)[0] + ".html" + if verbose: + print file, "->", newfile + fixfile(file, newfile) + return newfile + +def push_pep(htmlfiles, txtfiles, username, verbose): + if verbose: + quiet = "" + else: + quiet = "-q" + if username: + username = username + "@" + target = username + HOST + ":" + HDIR + files = htmlfiles[:] + files.extend(txtfiles) + files.append("style.css") + filelist = SPACE.join(files) + rc = os.system("scp %s %s %s" % (quiet, filelist, target)) + if rc: + sys.exit(rc) + rc = os.system("ssh %s%s chmod 664 %s/*" % (username, HOST, HDIR)) + if rc: + sys.exit(rc) + + +def browse_file(pep): + import webbrowser + file = find_pep(pep) + if file.endswith(".txt"): + file = file[:-3] + "html" + file = os.path.abspath(file) + url = "file:" + file + webbrowser.open(url) + +def browse_remote(pep): + import webbrowser + file = find_pep(pep) + if file.endswith(".txt"): + file = file[:-3] + "html" + url = PEPDIRRUL + file + webbrowser.open(url) + + +def main(): + # defaults + update = 0 + username = '' + verbose = 1 + browse = 0 + + try: + opts, args = getopt.getopt( + sys.argv[1:], 'bihqu:', + ['browse', 'install', 'help', 'quiet', 'user=']) + except getopt.error, msg: + usage(1, msg) + + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-i', '--install'): + update = 1 + elif opt in ('-u', '--user'): + username = arg + elif opt in ('-q', '--quiet'): + verbose = 0 + elif opt in ('-b', '--browse'): + browse = 1 + + if args: + peptxt = [] + html = [] + for pep in args: + file = find_pep(pep) + peptxt.append(file) + newfile = make_html(file, verbose=verbose) + html.append(newfile) + if browse and not update: + browse_file(pep) + else: + # do them all + peptxt = [] + files = glob.glob("pep-*.txt") + files.sort() + for file in files: + peptxt.append(file) + make_html(file, verbose=verbose) + html = ["pep-*.html"] + if browse and not update: + browse_file("0") + + if update: + push_pep(html, peptxt, username, verbose) + if browse: + if args: + for pep in args: + browse_remote(pep) + else: + browse_remote("0") + + + +if __name__ == "__main__": + main() -- cgit v1.2.1 From 43f13c2ca5dfb0f9862044b1bcb84c1ca864fcc9 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:25:33 +0000 Subject: Simplified ``OptionParser.__init__()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@320 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index d7dbf914f..d056dbce5 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -88,7 +88,8 @@ class OptionParser(optik.OptionParser): ('Show this help message and exit.', ['--help', '-h'], {'action': 'help'}), # Hidden options, for development use only: - (optik.SUPPRESS_HELP, ['--dump-internal-document-attributes'], + (optik.SUPPRESS_HELP, + ['--dump-internal-document-attributes'], {'action': 'store_true'}),)) """Command-line option specifications, common to all Docutils front-ends. Option group title, description, and a list/tuple of tuples: ``('help @@ -99,7 +100,7 @@ class OptionParser(optik.OptionParser): version_template = '%%prog (Docutils %s)' % docutils.__version__ - def __init__(self, components=(), defaults={}, *args, **kwargs): + def __init__(self, components=(), *args, **kwargs): """ `components` is a list of Docutils components each containing a ``.cmdline_options`` attribute. `defaults` is a mapping of option @@ -110,7 +111,6 @@ class OptionParser(optik.OptionParser): if not self.version: self.version = self.version_template self.populate_from_components(tuple(components) + (self,)) - self.set_defaults(**defaults) def populate_from_components(self, components): for component in components: -- cgit v1.2.1 From 65e978f5040e8eceddd3b46797177212cc940729 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:27:04 +0000 Subject: Updated ``Publisher.set_options()``; now returns option values object. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@321 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 27a0e60b6..24355d094 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -76,16 +76,17 @@ class Publisher: def set_options(self, option_spec=None, **defaults): """ - Set default option values (keyword arguments). + Set and return default option values (keyword arguments). Set components first (`self.set_reader` & `self.set_writer`). Explicitly setting options disables command line option processing from `self.publish()`. """ option_parser = OptionParser( - components=(option_spec, self.reader, self.parser, self.writer), - defaults=defaults) + components=(option_spec, self.reader, self.parser, self.writer)) + option_parser.set_defaults(**defaults) self.options = option_parser.get_default_values() + return self.options def process_command_line(self, argv=None, usage=None, description=None, option_spec=None): -- cgit v1.2.1 From ca710cf8381d71f1e1ab9c1ddf4cd83768e3414a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:28:05 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@322 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/io.py b/docutils/io.py index 397886c18..265e49851 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -26,7 +26,8 @@ class IO: def __init__(self, options, source=None, source_path=None, destination=None, destination_path=None): self.options = options - """A `docutils.optik.Values` object.""" + """An option values object with "input_encoding" and "output_encoding" + attributes (typically a `docutils.optik.Values` object).""" self.source = source """The source of input data.""" -- cgit v1.2.1 From 0de4a32f1c295a4a63e3e24905eb8a4c654b4f24 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:30:30 +0000 Subject: Changed ``EmailMasker`` to ``PEPZeroSpecial``, and added PEP table processing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@323 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 48 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 0df6fa246..42db98177 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -32,6 +32,7 @@ class Headers(Transform): Process fields in a PEP's initial RFC-2822 header. """ + pep_url = 'pep-%04d.html' pep_cvs_url = ('http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/' 'python/nondist/peps/pep-%04d.txt') rcs_keyword_substitutions = ( @@ -65,7 +66,7 @@ class Headers(Transform): if len(body) > 1: raise DataError('PEP header field body contains multiple ' 'elements:\n%s' % field.pformat(level=1)) - elif len(body): + 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' @@ -78,6 +79,7 @@ class Headers(Transform): uri = self.pep_cvs_url % int(pep) body[0][:] = [nodes.reference('', date, refuri=uri)] else: + # empty continue para = body[0] if name == 'author': @@ -99,7 +101,7 @@ class Headers(Transform): for refpep in body.astext().split(): pepno = int(refpep) newbody.append(nodes.reference( - refpep, refpep, refuri='pep-%04d.html' % pepno)) + refpep, refpep, refuri=self.pep_url % pepno)) newbody.append(space) para[:] = newbody[:-1] # drop trailing space elif name == 'last-modified': @@ -132,21 +134,29 @@ class PEPZero(Transform): """ def transform(self): - visitor = EmailMasker(self.document) + visitor = PEPZeroSpecial(self.document) self.document.walk(visitor) self.startnode.parent.remove(self.startnode) -class EmailMasker(nodes.SparseNodeVisitor): +class PEPZeroSpecial(nodes.SparseNodeVisitor): """ - For all email-address references such as "user@host", mask the address as - "user at host" (text) to thwart simple email address harvesters. + Perform the special processing needed by PEP 0: + + - For all email-address references 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` and addresses in the + "Discussions-To" field). + + - Link PEP numbers in the second column of 4-column tables to the PEPs + themselves. """ non_masked_addresses = ('peps@python.org', 'python-list@python.org', 'python-dev@python.org') + pep_url = Headers.pep_url def unknown_visit(self, node): pass @@ -160,3 +170,29 @@ class EmailMasker(nodes.SparseNodeVisitor): def visit_field_list(self, node): if node.hasattr('class') and node['class'] == 'rfc2822': raise nodes.SkipNode + + def visit_tgroup(self, node): + if node['cols'] != 4: + raise nodes.SkipNode + self.entry = 0 + + def visit_colspec(self, node): + self.entry += 1 + if self.entry == 2: + node['class'] = 'num' + + def visit_row(self, node): + self.entry = 0 + + def visit_entry(self, node): + self.entry += 1 + if self.entry == 2 and len(node) == 1: + p = node[0] + if isinstance(p, nodes.paragraph) and len(p) == 1: + text = p.astext() + try: + pep = int(text) + ref = self.pep_url % pep + p[0] = nodes.reference(text, text, refuri=ref) + except ValueError: + pass -- cgit v1.2.1 From a36de5cadda56268df1f266d72559d0d983568b9 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:35:11 +0000 Subject: - Added percentage widths to "" tags (from colspec). - Option lists: "" changed to "", ``option_argument`` "" changed to "". - Inline literals: "" changed to "". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@324 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 50 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8c6e2f2d4..7482bfdfe 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -85,6 +85,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.section_level = 0 self.context = [] self.topic_class = '' + self.colspecs = [] def astext(self): return ''.join(self.head_prefix + self.head @@ -235,15 +236,21 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_colspec(self, node): - atts = {} - # @@@ colwidth attributes don't seem to work well in HTML - #if node.has_key('colwidth'): - # atts['width'] = str(node['colwidth']) + '*' - self.body.append(self.emptytag(node, 'col', **atts)) + self.colspecs.append(node) def depart_colspec(self, node): pass + def write_colspecs(self): + width = 0 + for node in self.colspecs: + width += node['colwidth'] + for node in self.colspecs: + colwidth = int(node['colwidth'] * 100.0 / width + 0.5) + self.body.append(self.emptytag(node, 'col', + colwidth='%i%%' % colwidth)) + self.colspecs = [] + def visit_comment(self, node, sub=re.compile('-(?=-)').sub): """Escape double-dashes in comment text.""" @@ -337,10 +344,6 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_document(self, node): self.body.append('\n') - #self.body.append( - # '

    HTML generated from %s on %s ' - # 'by Docutils.' - # '

    \n' % (node['source'], time.strftime('%Y-%m-%d'))) def visit_emphasis(self, node): self.body.append('') @@ -468,7 +471,8 @@ class HTMLTranslator(nodes.NodeVisitor): for backref in backrefs: backlinks.append('%s' % (backref, i)) i += 1 - self.context.append(('', '(%s) ' % ', '.join(backlinks))) + self.context.append(('', ('

    (%s)

    \n' + % ', '.join(backlinks)))) else: self.context.append(('', '')) @@ -549,10 +553,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('
  4. \n') def visit_literal(self, node): - self.body.append('') + self.body.append('') def depart_literal(self, node): - self.body.append('') + self.body.append('') def visit_literal_block(self, node): self.body.append(self.starttag(node, 'pre', suffix='', @@ -582,11 +586,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_option_argument(self, node): self.body.append(node.get('delimiter', ' ')) - self.body.append(self.starttag(node, 'span', '', - CLASS='option-argument')) + self.body.append(self.starttag(node, 'var', '')) def depart_option_argument(self, node): - self.body.append('') + self.body.append('') def visit_option_group(self, node): atts = {} @@ -596,12 +599,12 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.context.append('') self.body.append(self.starttag(node, 'td', **atts)) - self.body.append('

    ') + self.body.append('

    ') self.context.append(0) def depart_option_group(self, node): self.context.pop() - self.body.append('

    \n') + self.body.append('

    \n') self.body.append(self.context.pop()) def visit_option_list(self, node): @@ -763,7 +766,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_tbody(self, node): - self.body.append(self.context.pop()) # '\n' or '' + self.write_colspecs() + #self.body.append(self.context.pop()) # '\n' or '' self.body.append(self.starttag(node, 'tbody', valign='top')) def depart_tbody(self, node): @@ -780,15 +784,17 @@ class HTMLTranslator(nodes.NodeVisitor): pass def visit_tgroup(self, node): - self.body.append(self.starttag(node, 'colgroup')) - self.context.append('\n') + #self.body.append(self.starttag(node, 'colgroup')) + #self.context.append('\n') + pass def depart_tgroup(self, node): pass def visit_thead(self, node): - self.body.append(self.context.pop()) # '\n' - self.context.append('') + self.write_colspecs() + #self.body.append(self.context.pop()) # '\n' + #self.context.append('') self.body.append(self.starttag(node, 'thead', valign='bottom')) def depart_thead(self, node): -- cgit v1.2.1 From cd07b6e5b46d5b93d730de78148159a96ce306ed Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:35:39 +0000 Subject: comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@325 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 3aef311d1..4eff60057 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -36,8 +36,10 @@ class Writer(html4css1.Writer): ('Home URL for this PEP. Default is "." (current directory).', ['--pep-home'], {'default': '.', 'metavar': ''}), - (optik.SUPPRESS_HELP, ['--no-random'], - {'action': 'store_true'}),)) + # Workaround for SourceForge's broken Python + # (``import random`` causes a segfault). + (optik.SUPPRESS_HELP, + ['--no-random'], {'action': 'store_true'}),)) def __init__(self): html4css1.Writer.__init__(self) -- cgit v1.2.1 From c999a0671a217dcdd8a6e2bd38332a021d48632a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:38:13 +0000 Subject: Added support for reStructuredText PEPs. Refactored naming in ``fixfile``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@326 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 170 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 115 insertions(+), 55 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 47cf1be1e..d5d3221d0 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -125,24 +125,17 @@ def linkemail(address, pepno): def fixfile(infile, outfile): - basename = os.path.basename(infile) + basename = os.path.basename(infile.name) # convert plain text pep to minimal XHTML markup - try: - fi = open(infile) - except IOError, e: - if e.errno <> errno.ENOENT: raise - print >> sys.stderr, 'Error: Skipping missing PEP file:', e.filename - return - fo = open(outfile, "w") - print >> fo, DTD - print >> fo, '' - print >> fo, '' + print >> outfile, DTD + print >> outfile, '' + print >> outfile, '' # head header = [] pep = "" title = "" while 1: - line = fi.readline() + line = infile.readline() if not line.strip(): break if line[0].strip(): @@ -163,27 +156,27 @@ def fixfile(infile, outfile): if pep: title = "PEP " + pep + " -- " + title if title: - print >> fo, ' %s' % cgi.escape(title) - print >> fo, ' ' - print >> fo, '' + print >> outfile, ' %s' % cgi.escape(title) + print >> outfile, ' ' + print >> outfile, '' # body - print >> fo, '' - print >> fo, '> fo, ' width="100%" border="0">' - print >> fo, '' + print >> outfile, '' + print >> outfile, '
    ' + print >> outfile, '
    ' need_pre = 1 while 1: - line = fi.readline() + line = infile.readline() if not line: break if line[0] == '\f': @@ -233,8 +226,8 @@ def fixfile(infile, outfile): if line.strip() == LOCALVARS: break if not need_pre: - print >> fo, '' - print >> fo, '

    %s

    ' % line.strip() + print >> outfile, '' + print >> outfile, '

    %s

    ' % line.strip() need_pre = 1 elif not line.strip() and need_pre: continue @@ -246,9 +239,9 @@ def fixfile(infile, outfile): # This is a PEP summary line, which we need to hyperlink url = PEPURL % int(parts[1]) if need_pre: - print >> fo, '
    '
    +                        print >> outfile, '
    '
                             need_pre = 0
    -                    print >> fo, re.sub(
    +                    print >> outfile, re.sub(
                             parts[1],
                             '%s' % (url, parts[1]),
                             line, 1),
    @@ -257,26 +250,86 @@ def fixfile(infile, outfile):
                         # This is a pep email address line, so filter it.
                         url = fixemail(parts[-1], pep)
                         if need_pre:
    -                        print >> fo, '
    '
    +                        print >> outfile, '
    '
                             need_pre = 0
    -                    print >> fo, re.sub(
    +                    print >> outfile, re.sub(
                             parts[-1], url, line, 1),
                         continue
    -            line = fixpat.sub(lambda x, c=infile: fixanchor(c, x), line)
    +            line = fixpat.sub(lambda x, c=infile.name: fixanchor(c, x), line)
                 if need_pre:
    -                print >> fo, '
    '
    +                print >> outfile, '
    '
                     need_pre = 0
    -            fo.write(line)
    +            outfile.write(line)
         if not need_pre:
    -        print >> fo, '
    ' - print >> fo, '
    ' - print >> fo, '' - print >> fo, '' - fo.close() - os.chmod(outfile, 0664) + print >> outfile, '' + print >> outfile, '' + print >> outfile, '' + print >> outfile, '' + +def fix_rst_pep(infile, outfile): + from docutils import core, io + pub = core.Publisher() + pub.set_reader(reader_name='pep', parser_name='restructuredtext', + parser=None) + pub.set_writer(writer_name='pep_html') + options = pub.set_options(generator=1, datestamp='%Y-%m-%d %H:%M UTC') + pub.source = io.FileIO(options, source=infile, source_path=infile.name) + pub.destination = io.FileIO(options, destination=outfile, + destination_path=outfile.name) + pub.publish() + + +underline = re.compile('[!-/:-@[-`{-~]{4,}$') + +def check_rst_pep(infile): + """ + Check if `infile` is a reStructuredText PEP. Return 1 for yes, 0 for no. + + If the result is indeterminate, return None. Reset `infile` to the + beginning. + """ + result = None + underline_match = underline.match + # Find the end of the RFC 2822 header (first blank line): + while 1: + line = infile.readline().strip() + if not line: + break + # Determine if the PEP is old-style or new (reStructuredText): + while result is None: + line = infile.readline() + if not line: + break + line = line.rstrip() + if len(line.lstrip()) < len(line): + # Indented section; this is an old-style PEP. + result = 0 + elif underline_match(line): + # Matched a section header underline; + # this is a reStructuredText PEP. + result = 1 + infile.seek(0) + return result +def open_files(inpath, outpath): + try: + infile = open(inpath) + except IOError, e: + if e.errno <> errno.ENOENT: raise + print >> sys.stderr, 'Error: Skipping missing PEP file:', e.filename + sys.stderr.flush() + return None, None + outfile = open(outpath, "w") + return infile, outfile + +def close_files(infile, outfile): + infile.close() + outfile.close() + os.chmod(outfile.name, 0664) + + def find_pep(pep_str): """Find the .txt file indicated by a cmd line argument""" if os.path.exists(pep_str): @@ -284,12 +337,19 @@ def find_pep(pep_str): num = int(pep_str) return "pep-%04d.txt" % num -def make_html(file, verbose=0): - newfile = os.path.splitext(file)[0] + ".html" +def make_html(inpath, verbose=0): + outpath = os.path.splitext(inpath)[0] + ".html" if verbose: - print file, "->", newfile - fixfile(file, newfile) - return newfile + print inpath, "->", outpath + sys.stdout.flush() + infile, outfile = open_files(inpath, outpath) + if infile is not None: + if check_rst_pep(infile): + fix_rst_pep(infile, outfile) + else: + fixfile(infile, outfile) + close_files(infile, outfile) + return outpath def push_pep(htmlfiles, txtfiles, username, verbose): if verbose: -- cgit v1.2.1 From d485602ebab4977879b816aa4f2ba0c9eaedf6b3 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 02:42:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@328 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 23 ++++++++++++++++------- docs/dev/todo.txt | 33 ++++++++++++--------------------- tools/stylesheets/default.css | 9 ++------- tools/stylesheets/pep.css | 8 ++------ 4 files changed, 32 insertions(+), 41 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 9f9ea70d3..09488059f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -19,13 +19,13 @@ and related projects: Aahz, David Ascher, Fred Bremmer, Simon Budig, Adam Chodorowski, Fred Drake, Dethe Elza, Jim Fulton, Peter Funk, Engelbert Gruber, - Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan Jaffray, Richard - Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang - Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, - Sam Penrose, Tim Peters, Mark Pilgrim, Tavis Rudd, Ollie - Rutherfurd, Ueli Schlaepfer, tav, Bob Tolbert, Laurence Tratt, - Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, - Moshe Zadka + Simon Hefti, Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan + Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre + Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, + Michel Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis + Rudd, Ollie Rutherfurd, Ueli Schlaepfer, tav, Bob Tolbert, + Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, + Ka-Ping Yee, Moshe Zadka Thank you! @@ -72,6 +72,8 @@ Specific: - 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. * docutils/frontend.py: Added to project; support for front-end (command-line) scripts. Option specifications may be augmented by @@ -227,6 +229,10 @@ Specific: - Improved option list spacing (thanks to Richard Jones). - Modified field list output. - Added backlinks to footnotes & citations. + - Added percentage widths to "" tags (from colspec). + - Option lists: "" changed to "", ``option_argument`` + "" changed to "". + - Inline literals: "" changed to "". * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). @@ -328,6 +334,9 @@ Specific: * 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. * tools/stylesheets/: Subdirectory added to project. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 092c7e8ab..29f79947d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -94,12 +94,6 @@ General permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) -- @@@ Implement a PEP reader. (Reader for RST-PEP format done. - Writer support needed.) - - - Implement a specialized PEP/HTML writer? Or implement a generic - `templating system`_, with PEP/HTML as one application? - - Need a Unicode -> HTML entities codec for HTML writer? - Fix tests to run standalone. I.e., allow:: @@ -108,7 +102,7 @@ General test_inline_markup.py Raises an exception with path processing on GNU/Linux (but only - sometimes?). + sometimes???). - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? @@ -126,6 +120,7 @@ Specification - Fill in the blanks in API details. - Specify the nodes.py internal data structure implementation. + Or link to doctree.txt? [Tibs:] Eventually we need to have direct documentation in there on how it all hangs together - the DTD is not enough @@ -324,9 +319,9 @@ Directives - _`html.imagemap` (Useful outside of HTML? If not, replace with image only in non-HTML writers?) - - _`parts.endnotes` + - _`parts.endnotes`: See `Footnote & Citation Gathering`_. - - _`parts.citations` + - _`parts.citations`: See `Footnote & Citation Gathering`_. - _`parts.topic` (maybe "body.topic") @@ -404,12 +399,6 @@ Directives lists). Without special syntax, this directive becomes low priority. - - _`body.columns`: Multi-column table/list. Number of columns as - argument? Several `alternative syntaxes`__ are proposed that - might not need a directive.. - - __ rst/problems.html#tables - - @@ _`body.verse`: Paragraphs with linebreaks preserved, *and* inline markup support too. Use cases: verse (poetry, song lyrics, etc.), address blocks. A directive would be easy; what about a @@ -515,10 +504,11 @@ Directives Unimplemented Transforms ------------------------ -Footnote Gathering -`````````````````` +Footnote & Citation Gathering +````````````````````````````` -Collect and move footnotes to the end of a document. +Collect and move footnotes & citations to the end of a document. +(Separate transforms.) Hyperlink Target Gathering @@ -582,8 +572,8 @@ HTML Writer of all list items lack a

    (perhaps "--compact-all-lists" and "--compact-simple-lists")? - Tried it; not easy. If you're interested, email me for a copy of - the patch. + Tried it. Twice. Not easy. If you're interested, email me for a + copy of the patches. - Add more support for elements, especially for navigation bars. @@ -637,7 +627,8 @@ Front-Ends - Allow multiple option groups per component (thus enabling component subclasses to easily incorporate their superclass' options). -- Parameterize help text & defaults somehow? Perhaps a callback? +- Parameterize help text & defaults somehow? Perhaps a callback? Or + initialize ``cmdline_options`` in ``__init__``? Project Policies diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 81de8ba2c..b5b2d148c 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -15,9 +15,6 @@ a.footnote-reference { a.target { color: blue } -code { - background-color: #eeeeee } - div.abstract { margin: 2em 5em } @@ -91,12 +88,10 @@ ol.upperroman { list-style: upper-roman } dd p:first-child { - margin-top: 0px; -} + margin-top: 0px } li p:first-child { - margin-top: 0px; -} + margin-top: 0px } p.caption { font-style: italic } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 69fc0f087..e84b7a7cf 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -47,8 +47,8 @@ body { margin-bottom: 1em ; padding: 0px } -code { - background-color: #eeeeee } +col.num { + text-align: center } div.section { margin-left: 1em ; @@ -163,10 +163,6 @@ p.credits { font-style: italic ; font-size: smaller } -p.field-name { - font-weight: bold ; - margin-bottom: 1em } - p.label { white-space: nowrap } -- cgit v1.2.1 From 8c5bac9a5e09bef0828fab7620bee1faa2fd157b Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 03:08:44 +0000 Subject: Fixed bug in ``PEPZeroSpecial``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@329 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 42db98177..5a50bc57c 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -172,13 +172,12 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): raise nodes.SkipNode def visit_tgroup(self, node): - if node['cols'] != 4: - raise nodes.SkipNode + self.pep_table = node['cols'] == 4 self.entry = 0 def visit_colspec(self, node): self.entry += 1 - if self.entry == 2: + if self.pep_table and self.entry == 2: node['class'] = 'num' def visit_row(self, node): @@ -186,7 +185,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): def visit_entry(self, node): self.entry += 1 - if self.entry == 2 and len(node) == 1: + if self.pep_table and self.entry == 2 and len(node) == 1: p = node[0] if isinstance(p, nodes.paragraph) and len(p) == 1: text = p.astext() -- cgit v1.2.1 From 8d80ab42497a14aa1ede2efed478ed241db51b52 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 03:09:24 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@330 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 29f79947d..2ed81757a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -111,6 +111,9 @@ General backlinks: no TOC backlinks, backlinks to TOC entries, or backlinks to TOC itself only. +- Add resource file support (~/.docutils?): overrides application + defaults, overridden by command-line options. What syntax to use? + Specification ------------- -- cgit v1.2.1 From 57c2313e76a82fb1ed8cfea7bb5dbcbe16a77292 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 03:29:22 +0000 Subject: Put "" back; Mozilla needs it. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@331 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 7482bfdfe..372b9783c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -767,7 +767,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_tbody(self, node): self.write_colspecs() - #self.body.append(self.context.pop()) # '\n' or '' + self.body.append(self.context.pop()) # '\n' or '' self.body.append(self.starttag(node, 'tbody', valign='top')) def depart_tbody(self, node): @@ -784,8 +784,9 @@ class HTMLTranslator(nodes.NodeVisitor): pass def visit_tgroup(self, node): - #self.body.append(self.starttag(node, 'colgroup')) - #self.context.append('\n') + # Mozilla needs : + self.body.append(self.starttag(node, 'colgroup')) + self.context.append('\n') pass def depart_tgroup(self, node): @@ -793,8 +794,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_thead(self, node): self.write_colspecs() - #self.body.append(self.context.pop()) # '\n' - #self.context.append('') + self.body.append(self.context.pop()) # '\n' + # There may or may not be a ; this is for to use: + self.context.append('') self.body.append(self.starttag(node, 'thead', valign='bottom')) def depart_thead(self, node): -- cgit v1.2.1 From ea747618b09fb9af746d6df7d0ae7c5797c5289e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 19 Jul 2002 03:34:01 +0000 Subject: Improved inline literals. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@332 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 372b9783c..f9a30b1ce 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -553,7 +553,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_literal(self, node): - self.body.append('') + self.body.append(self.starttag(node, 'tt', '', CLASS='literal')) def depart_literal(self, node): self.body.append('') -- cgit v1.2.1 From c64f5a97435ccac6a66c79622e5836e4ed8a9b53 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 03:15:22 +0000 Subject: - Added support for configuration files (/etc/docutils.conf, ./docutils.conf, ~/.docutils). - Added ``Publisher.setup_option_parser()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@335 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 24355d094..5f2af0be3 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -17,9 +17,10 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' import sys +import os.path from docutils import Component from docutils import readers, parsers, writers, io -from docutils.frontend import OptionParser +from docutils.frontend import OptionParser, ConfigParser class Publisher: @@ -28,6 +29,12 @@ class Publisher: A facade encapsulating the high-level logic of a Docutils system. """ + config_files = ('/etc/docutils.conf', # system-wide + './docutils.conf', # project-specific + os.path.expanduser('~/.docutils')) # user-specific + """Docutils configuration files, using ConfigParser syntax (section + 'options'). Later files override earlier ones.""" + def __init__(self, reader=None, parser=None, writer=None, source=None, source_class=io.FileIO, destination=None, destination_class=io.FileIO, @@ -74,7 +81,21 @@ class Publisher: writer_class = writers.get_writer_class(writer_name) self.writer = writer_class() - def set_options(self, option_spec=None, **defaults): + def setup_option_parser(self, usage=None, description=None, + option_spec=None, **defaults): + config = ConfigParser() + config.read(self.config_files) + if config.has_section('options'): + for option in config.options('options'): + defaults[option] = config.get('options', option) + option_parser = OptionParser( + components=(option_spec, self.reader, self.parser, self.writer), + usage=usage, description=description) + option_parser.set_defaults(**defaults) + return option_parser + + def set_options(self, usage=None, description=None, + option_spec=None, **defaults): """ Set and return default option values (keyword arguments). @@ -82,23 +103,21 @@ class Publisher: Explicitly setting options disables command line option processing from `self.publish()`. """ - option_parser = OptionParser( - components=(option_spec, self.reader, self.parser, self.writer)) - option_parser.set_defaults(**defaults) + option_parser = self.setup_option_parser(usage, description, + option_spec, **defaults) self.options = option_parser.get_default_values() return self.options def process_command_line(self, argv=None, usage=None, description=None, - option_spec=None): + option_spec=None, **defaults): """ Pass an empty list to `argv` to avoid reading `sys.argv` (the default). Set components first (`self.set_reader` & `self.set_writer`). """ - option_parser = OptionParser( - components=(option_spec, self.reader, self.parser, self.writer), - usage=usage, description=description) + option_parser = self.setup_option_parser(usage, description, + option_spec, **defaults) if argv is None: argv = sys.argv[1:] self.options, source, destination = option_parser.parse_args(argv) -- cgit v1.2.1 From d6cdc2f926410ac99acdcfe9415b486b0baed8b5 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 03:18:30 +0000 Subject: Support for ConfigParser. Support for multiple option groups per ``cmdline_options``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@336 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index d056dbce5..f0a4f8974 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -12,6 +12,7 @@ Command-line and common processing for Docutils front-ends. __docformat__ = 'reStructuredText' +import ConfigParser as CP import docutils from docutils import optik @@ -92,11 +93,12 @@ class OptionParser(optik.OptionParser): ['--dump-internal-document-attributes'], {'action': 'store_true'}),)) """Command-line option specifications, common to all Docutils front-ends. - Option group title, description, and a list/tuple of tuples: ``('help - text', [list of option strings], {keyword arguments})``. Group title - and/or description may be `None`; no group title implies no group, just a - list of single options. Option specs from Docutils components are also - used (see `populate_from_components()`).""" + One or more sets of option group title, description, and a + list/tuple of tuples: ``('help text', [list of option strings], + {keyword arguments})``. Group title and/or description may be + `None`; no group title implies no group, just a list of single + options. Option specs from Docutils components are also used (see + `populate_from_components()`).""" version_template = '%%prog (Docutils %s)' % docutils.__version__ @@ -114,16 +116,20 @@ class OptionParser(optik.OptionParser): def populate_from_components(self, components): for component in components: - if component is not None and component.cmdline_options: - title, description, option_spec = component.cmdline_options - if title: - group = optik.OptionGroup(self, title, description) - self.add_option_group(group) - else: - group = self # single options - for (help_text, option_strings, kwargs) in option_spec: - group.add_option(help=help_text, *option_strings, - **kwargs) + if component is not None: + i = 0 + cmdline_options = component.cmdline_options + while i < len(cmdline_options): + title, description, option_spec = cmdline_options[i:i+3] + if title: + group = optik.OptionGroup(self, title, description) + self.add_option_group(group) + else: + group = self # single options + for (help_text, option_strings, kwargs) in option_spec: + group.add_option(help=help_text, *option_strings, + **kwargs) + i += 3 def check_values(self, values, args): values.report_level = self.check_threshold(values.report_level) @@ -149,3 +155,12 @@ class OptionParser(optik.OptionParser): if args: self.error('Maximum 2 arguments allowed.') return source, destination + + +class ConfigParser(CP.ConfigParser): + + def optionxform(self, optionstr): + """ + Transform '-' to '_' so the cmdline form of option names can be used. + """ + return optionstr.lower().replace('-', '_') -- cgit v1.2.1 From c9ec2074f21a9bcd08f1f64e81ab743e6fbf2c65 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 03:20:21 +0000 Subject: Tweaked option names; PEP/HTML options are now in addition to HTML options, instead of replacing them. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@337 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 4eff60057..2a0c273ea 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -21,19 +21,20 @@ from docutils.writers import html4css1 class Writer(html4css1.Writer): - cmdline_options = ( + cmdline_options = html4css1.Writer.cmdline_options + ( 'PEP/HTML-Specific Options', None, - (('Specify a stylesheet file. Default is "pep.css".', - ['--stylesheet'], - {'default': 'pep.css', 'metavar': ''}), + (("Specify a PEP stylesheet file. Default is --stylesheet's value. " + 'If given, --pep-stylesheet overrides --stylesheet.', + ['--pep-stylesheet'], + {'metavar': ''}), ('Specify a template file. Default is "pep-html-template".', - ['--template'], + ['--pep-template'], {'default': 'pep-html-template', 'metavar': ''}), ('Python\'s home URL. Default is ".." (parent directory).', ['--python-home'], {'default': '..', 'metavar': ''}), - ('Home URL for this PEP. Default is "." (current directory).', + ('Home URL prefix for PEPs. Default is "." (current directory).', ['--pep-home'], {'default': '.', 'metavar': ''}), # Workaround for SourceForge's broken Python @@ -48,8 +49,10 @@ class Writer(html4css1.Writer): def translate(self): html4css1.Writer.translate(self) options = self.document.options - template = open(options.template).read() - stylesheet = options.stylesheet + template = open(options.pep_template).read() + stylesheet = options.pep_stylesheet + if stylesheet is None: + stylesheet = options.stylesheet pyhome = options.python_home pephome = options.pep_home if pyhome == '..': -- cgit v1.2.1 From 1369e61bed0ec3e1da3ed2cc4d7eedbe409f6844 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 03:21:42 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@338 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 ++++++ docs/dev/todo.txt | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 09488059f..32ccba231 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -74,6 +74,9 @@ Specific: - 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()``. * docutils/frontend.py: Added to project; support for front-end (command-line) scripts. Option specifications may be augmented by @@ -247,6 +250,9 @@ Specific: - Changed the title to "The Docutils Document Tree". - Added "Hyperlink Bookkeeping" section. +* spec/docutils.conf: Added to project. Not a spec itself, but a + configuration file for Docutils processing of the specs. + * spec/docutils.dtd: - Added ``decoration``, ``header``, and ``footer`` elements. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 2ed81757a..2d244ab0c 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -68,6 +68,10 @@ General - Howto: Directives - User docs. + + - How to use the front-ends (docs/tools.txt). + + - Configuration file syntax & recognized entries. - Refactor @@ -111,9 +115,6 @@ General backlinks: no TOC backlinks, backlinks to TOC entries, or backlinks to TOC itself only. -- Add resource file support (~/.docutils?): overrides application - defaults, overridden by command-line options. What syntax to use? - Specification ------------- -- cgit v1.2.1 From 0108383e3af5f7c3eaaa11aff693877b669e5ddb Mon Sep 17 00:00:00 2001 From: chodorowski Date: Sat, 20 Jul 2002 13:09:46 +0000 Subject: Ignore generated files. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@339 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/.cvsignore | 1 + test/test_parsers/test_rst/.cvsignore | 1 + test/test_parsers/test_rst/test_directives/.cvsignore | 1 + test/test_readers/test_pep/.cvsignore | 1 + test/test_transforms/.cvsignore | 1 + 5 files changed, 5 insertions(+) create mode 100644 test/.cvsignore create mode 100644 test/test_parsers/test_rst/.cvsignore create mode 100644 test/test_parsers/test_rst/test_directives/.cvsignore create mode 100644 test/test_readers/test_pep/.cvsignore create mode 100644 test/test_transforms/.cvsignore diff --git a/test/.cvsignore b/test/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/test/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/test/test_parsers/test_rst/.cvsignore b/test/test_parsers/test_rst/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/test/test_parsers/test_rst/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/test/test_parsers/test_rst/test_directives/.cvsignore b/test/test_parsers/test_rst/test_directives/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/test/test_readers/test_pep/.cvsignore b/test/test_readers/test_pep/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/test/test_readers/test_pep/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/test/test_transforms/.cvsignore b/test/test_transforms/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/test/test_transforms/.cvsignore @@ -0,0 +1 @@ +*.pyc -- cgit v1.2.1 From 5d18b5a5ff40245f8ae170af01ba474a23680a7b Mon Sep 17 00:00:00 2001 From: chodorowski Date: Sat, 20 Jul 2002 13:11:43 +0000 Subject: Ignore 'build' directory. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@340 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .cvsignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .cvsignore diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..378eac25d --- /dev/null +++ b/.cvsignore @@ -0,0 +1 @@ +build -- cgit v1.2.1 From 442077e5397b31c810e7c730b95150e8dc226c0a Mon Sep 17 00:00:00 2001 From: chodorowski Date: Sat, 20 Jul 2002 13:14:12 +0000 Subject: Swedish language mappings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@341 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 57 ++++++++++++++++++++++++++++++++++++ docutils/parsers/rst/languages/sv.py | 39 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 docutils/languages/sv.py create mode 100644 docutils/parsers/rst/languages/sv.py diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py new file mode 100644 index 000000000..e70479359 --- /dev/null +++ b/docutils/languages/sv.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python + +""" +:Author: Adam Chodorowski +:Contact: chodorowski@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Swedish language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +labels = { + 'author': 'Frfattare', + 'authors': 'Frfattare', + 'organization': 'Organisation', + 'contact': 'Kontakt', + 'version': 'Version', + 'revision': 'Revision', + 'status': 'Status', + 'date': 'Datum', + 'copyright': 'Copyright', + 'abstract': 'Sammanfattning', + 'attention': 'Observera!', + 'caution': 'Varning!', + 'danger': 'FARA!', + 'error': 'Fel', + 'hint': 'Vgledning', + 'important': 'Viktigt', + 'note': 'Notera', + 'tip': 'Tips', + 'warning': 'Varning', + 'contents': 'Innehll'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'frfattare': nodes.authors, + 'organisation': nodes.organization, + 'kontakt': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'datum': nodes.date, + 'copyright': nodes.copyright, + 'sammanfattning': nodes.topic} +"""Field name (lowcased) to node class name mapping for bibliographic fields +(field_list).""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py new file mode 100644 index 000000000..ad2454cb9 --- /dev/null +++ b/docutils/parsers/rst/languages/sv.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python + +""" +:Author: Adam Chodorowski +:Contact: chodorowski@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Swedish language mappings for language-dependent features of reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + 'observera': 'attention', + 'varning': 'caution', + 'fara': 'danger', + 'fel': 'error', + 'vgledning': 'hint', + 'viktigt': 'important', + 'notera': 'note', + 'tips': 'tip', + 'varning': 'warning', + 'frgor': 'questions', + 'frgor-och-svar': 'questions', # NOTE: A bit long, but recommended by + 'vanliga-frgor': 'questions', # NOTE: http://www.nada.kth.se/dataterm/ + 'meta': 'meta', + #'bildkarta': 'imagemap', # FIXME: Translation might be to literal. + 'bild': 'image', + 'figur': 'figure', + #'r': 'raw', # FIXME: Translation might be to literal. + 'innehll': 'contents', + #'fotnoter': 'footnotes', + #'citeringar': 'citations', + #'mne': 'topic', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""Swedish name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From cc938c6242269ac94acbba52e0938c9d83e5d5db Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 14:09:32 +0000 Subject: Ignore generated files. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@342 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/.cvsignore | 1 + docutils/languages/.cvsignore | 1 + docutils/parsers/.cvsignore | 1 + docutils/parsers/rst/.cvsignore | 1 + docutils/parsers/rst/directives/.cvsignore | 1 + docutils/parsers/rst/languages/.cvsignore | 1 + docutils/readers/.cvsignore | 1 + docutils/transforms/.cvsignore | 1 + docutils/writers/.cvsignore | 1 + 9 files changed, 9 insertions(+) create mode 100644 docutils/.cvsignore create mode 100644 docutils/languages/.cvsignore create mode 100644 docutils/parsers/.cvsignore create mode 100644 docutils/parsers/rst/.cvsignore create mode 100644 docutils/parsers/rst/directives/.cvsignore create mode 100644 docutils/parsers/rst/languages/.cvsignore create mode 100644 docutils/readers/.cvsignore create mode 100644 docutils/transforms/.cvsignore create mode 100644 docutils/writers/.cvsignore diff --git a/docutils/.cvsignore b/docutils/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/languages/.cvsignore b/docutils/languages/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/languages/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/parsers/.cvsignore b/docutils/parsers/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/parsers/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/parsers/rst/.cvsignore b/docutils/parsers/rst/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/parsers/rst/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/parsers/rst/directives/.cvsignore b/docutils/parsers/rst/directives/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/parsers/rst/directives/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/parsers/rst/languages/.cvsignore b/docutils/parsers/rst/languages/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/parsers/rst/languages/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/readers/.cvsignore b/docutils/readers/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/readers/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/transforms/.cvsignore b/docutils/transforms/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/transforms/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/docutils/writers/.cvsignore b/docutils/writers/.cvsignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/docutils/writers/.cvsignore @@ -0,0 +1 @@ +*.pyc -- cgit v1.2.1 From 7d645311ae75ddc22c06bda35cc29ebdbcffa14e Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 14:13:21 +0000 Subject: ignore test output git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@343 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/.cvsignore | 1 + 1 file changed, 1 insertion(+) diff --git a/test/.cvsignore b/test/.cvsignore index 0d20b6487..b8af75aec 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -1 +1,2 @@ *.pyc +alltests.out -- cgit v1.2.1 From 60b6bf17f1679fa9b4cfabf6deb32ee6bca8881f Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 20 Jul 2002 14:44:14 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@344 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 04191d2dc..b7b52c7f1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,3 +4,4 @@ recursive-include docs * recursive-include spec * recursive-include test * recursive-include tools * +recursive-exclude * .cvsignore *.pyc *~ -- cgit v1.2.1 From 239298234e1bb3013da7341ef4d78f5947e6eb91 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:29:27 +0000 Subject: Added ``Element.set_class()`` method (sets "class" attribute). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@346 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 77e4a2ce6..874659d99 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -466,6 +466,11 @@ class Element(Node): def copy(self): return self.__class__(**self.attributes) + def set_class(self, name): + """Add a new name to the "class" attribute.""" + self.attributes['class'] = (self.attributes.get('class', '') + ' ' + + name.lower()).strip() + class TextElement(Element): -- cgit v1.2.1 From 8580b0585c3d927f38e4c38098e9c7e982e2ba81 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:33:29 +0000 Subject: Added "en" (English) as a fallback language for directive names. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@347 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 89d273651..484714588 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -31,6 +31,8 @@ Where: __docformat__ = 'reStructuredText' +from docutils.parsers.rst.languages import en as _fallback_language_module + _directive_registry = { 'attention': ('admonitions', 'attention'), @@ -63,15 +65,24 @@ _modules = {} _directives = {} """Cache of imported directive functions.""" -def directive(directivename, languagemodule): +def directive(directive_name, language_module): """ Locate and return a directive function from its language-dependent name. + If not found in the current language, check English. """ - normname = directivename.lower() + normname = directive_name.lower() if _directives.has_key(normname): return _directives[normname] try: - canonicalname = languagemodule.directives[normname] + canonicalname = language_module.directives[normname] + except KeyError: + try: + # Try English as a fallback: + canonicalname = _fallback_language_module.directives[normname] + except KeyError: + # The canonical name should be an English name, but just in case: + canonicalname = normname + try: modulename, functionname = _directive_registry[canonicalname] except KeyError: return None -- cgit v1.2.1 From a2cb2365b8cb48ba8223356bacde635de0109c5e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:34:21 +0000 Subject: Mozilla workaround. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@348 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 5a50bc57c..618061649 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -186,6 +186,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): def visit_entry(self, node): self.entry += 1 if self.pep_table and self.entry == 2 and len(node) == 1: + node['class'] = 'num' p = node[0] if isinstance(p, nodes.paragraph) and len(p) == 1: text = p.astext() -- cgit v1.2.1 From 805a0f809700599f03b5df222a5e495428079e58 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:39:25 +0000 Subject: minimize HTML whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@349 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 74112d2c5..93e36bffb 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -772,7 +772,7 @@ References & Footnotes .. [#Zen] From `The Zen of Python (by Tim Peters)`__ (or just "``import this``" in Python) - __ http://www.python.org/doc/Humor.html#zen +__ http://www.python.org/doc/Humor.html#zen .. [#PEP-216] PEP 216, Docstring Format, Zadka (http://www.python.org/peps/pep-0216.html) -- cgit v1.2.1 From 6f03aeb4f23233eca8173b07f195560eef55fcec Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:40:35 +0000 Subject: Many changes to optimize vertical space: compact simple lists etc. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@350 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 126 ++++++++++++++++++++++++++++++++---------- tools/stylesheets/default.css | 28 +++++++--- tools/stylesheets/pep.css | 44 ++++++++++----- 3 files changed, 149 insertions(+), 49 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f9a30b1ce..9234463bb 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -86,6 +86,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.context = [] self.topic_class = '' self.colspecs = [] + self.compact_p = 1 + self.compact_simple = None def astext(self): return ''.join(self.head_prefix + self.head @@ -182,13 +184,29 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_block_quote(self, node): self.body.append('\n') - def visit_bullet_list(self, node): - if self.topic_class == 'contents': - self.body.append(self.starttag(node, 'ul', compact=None)) + def check_simple_list(self, node): + visitor = SimpleListChecker(self.document) + try: + node.walk(visitor) + except nodes.NodeFound: + return None else: - self.body.append(self.starttag(node, 'ul')) + return 1 + + def visit_bullet_list(self, node): + atts = {} + old_compact_simple = self.compact_simple + self.context.append((self.compact_simple, self.compact_p)) + self.compact_p = None + self.compact_simple = (self.compact_simple + or self.topic_class == 'contents' + or self.check_simple_list(node)) + if self.compact_simple and not old_compact_simple: + atts['class'] = 'simple' + self.body.append(self.starttag(node, 'ul', **atts)) def depart_bullet_list(self, node): + self.compact_simple, self.compact_p = self.context.pop() self.body.append('\n') def visit_caption(self, node): @@ -206,10 +224,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_citation(self, node): self.body.append(self.starttag(node, 'table', CLASS='citation', frame="void", rules="none")) - self.body.append('\n' + self.body.append('\n' '\n' '\n' - '\n') + '') self.footnote_backrefs(node) def depart_citation(self, node): @@ -289,7 +307,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_definition(self, node): self.body.append('\n') - self.body.append(self.starttag(node, 'dd')) + self.body.append(self.starttag(node, 'dd', '')) + if len(node) and isinstance(node[0], nodes.paragraph): + node[0].set_class('first') def depart_definition(self, node): self.body.append('\n') @@ -307,7 +327,7 @@ class HTMLTranslator(nodes.NodeVisitor): pass def visit_description(self, node): - self.body.append('\n') + self.body.append(self.starttag(node, 'td', '')) def depart_description(self, node): self.body.append('') @@ -361,10 +381,12 @@ class HTMLTranslator(nodes.NodeVisitor): atts['rowspan'] = node['morerows'] + 1 if node.has_key('morecols'): atts['colspan'] = node['morecols'] + 1 - self.body.append(self.starttag(node, tagname, **atts)) - self.context.append('' % tagname.lower()) + self.body.append(self.starttag(node, tagname, '', **atts)) + self.context.append('\n' % tagname.lower()) if len(node) == 0: # empty cell self.body.append(' ') + elif isinstance(node[0], nodes.paragraph): + node[0].set_class('first') def depart_entry(self, node): self.body.append(self.context.pop()) @@ -382,9 +404,18 @@ class HTMLTranslator(nodes.NodeVisitor): atts['class'] = node['enumtype'] # @@@ To do: prefix, suffix. How? Change prefix/suffix to a # single "format" attribute? Use CSS2? + old_compact_simple = self.compact_simple + self.context.append((self.compact_simple, self.compact_p)) + self.compact_p = None + self.compact_simple = (self.compact_simple + or self.topic_class == 'contents' + or self.check_simple_list(node)) + if self.compact_simple and not old_compact_simple: + atts['class'] = (atts.get('class', '') + ' simple').strip() self.body.append(self.starttag(node, 'ol', **atts)) def depart_enumerated_list(self, node): + self.compact_simple, self.compact_p = self.context.pop() self.body.append('

\n') def visit_error(self, node): @@ -410,6 +441,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_body(self, node): self.body.append(': ') self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) + if len(node) and isinstance(node[0], nodes.paragraph): + node[0].set_class('first') def depart_field_body(self, node): self.body.append('\n') @@ -453,28 +486,28 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_footnote(self, node): self.body.append(self.starttag(node, 'table', CLASS='footnote', frame="void", rules="none")) - self.body.append('\n' - '\n' + self.body.append('\n' '\n' - '\n') + '') self.footnote_backrefs(node) def footnote_backrefs(self, node): if node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: - self.body.append('' % backrefs[0]) self.context.append(('', '')) + self.context.append(('' % backrefs[0],)) else: i = 1 backlinks = [] for backref in backrefs: backlinks.append('%s' % (backref, i)) i += 1 - self.context.append(('', ('

(%s)

\n' - % ', '.join(backlinks)))) + self.context.append(('', '(%s) ' % ', '.join(backlinks))) + self.context.append(('',)) else: self.context.append(('', '')) + self.context.append(('',)) def depart_footnote(self, node): self.body.append('\n' @@ -534,11 +567,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_label(self, node): - self.body.append(self.starttag(node, 'p', '[', CLASS='label')) + self.body.append(self.starttag(node, 'td', '%s[' % self.context.pop(), + CLASS='label')) def depart_label(self, node): - self.body.append(']%s

\n' - '%s\n' % self.context.pop()) + self.body.append(']%s%s' % self.context.pop()) def visit_legend(self, node): self.body.append(self.starttag(node, 'div', CLASS='legend')) @@ -547,7 +580,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def visit_list_item(self, node): - self.body.append(self.starttag(node, 'li')) + self.body.append(self.starttag(node, 'li', '')) + if len(node) and isinstance(node[0], nodes.paragraph): + node[0].set_class('first') def depart_list_item(self, node): self.body.append('\n') @@ -599,12 +634,12 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.context.append('') self.body.append(self.starttag(node, 'td', **atts)) - self.body.append('

') - self.context.append(0) + self.body.append('') + self.context.append(0) # count number of options def depart_option_group(self, node): self.context.pop() - self.body.append('

\n') + self.body.append('\n') self.body.append(self.context.pop()) def visit_option_list(self, node): @@ -637,14 +672,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_docinfo_item() def visit_paragraph(self, node): - if not self.topic_class == 'contents': + # Omit

tags if this is an only child and optimizable. + if (self.compact_simple or + self.compact_p and (len(node.parent) == 1 or + len(node.parent) == 2 and + isinstance(node.parent[0], nodes.label))): + self.context.append('') + else: self.body.append(self.starttag(node, 'p', '')) + self.context.append('

\n') def depart_paragraph(self, node): - if self.topic_class == 'contents': - self.body.append('\n') - else: - self.body.append('

\n') + self.body.append(self.context.pop()) def visit_problematic(self, node): if node.hasattr('refid'): @@ -861,3 +900,34 @@ class HTMLTranslator(nodes.NodeVisitor): def unimplemented_visit(self, node): raise NotImplementedError('visiting unimplemented node type: %s' % node.__class__.__name__) + + +class SimpleListChecker(nodes.GenericNodeVisitor): + + """ + Raise `nodes.SkipNode` if non-simple list item is encountered. + + Here "simple" means a list item containing anything other than a single + paragraph, a simple list, or a paragraph followed by a simple list. + """ + + def default_visit(self, node): + raise nodes.NodeFound + + def visit_bullet_list(self, node): + pass + + def visit_enumerated_list(self, node): + pass + + def visit_list_item(self, node): + if len(node) <= 1 or (len(node) == 2 and + isinstance(node[0], nodes.paragraph) and + (isinstance(node[1], nodes.bullet_list) or + isinstance(node[1], nodes.enumerated_list))): + return + else: + raise nodes.NodeFound + + def visit_paragraph(self, node): + raise nodes.SkipNode diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index b5b2d148c..dc8881606 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -63,6 +63,10 @@ div.system-message p.system-message-title { div.topic { margin: 2em } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none ; + color: black } + h1.title { text-align: center } @@ -72,6 +76,9 @@ h2.subtitle { hr { width: 75% } +ol.simple, ul.simple { + margin-bottom: 1em } + ol.arabic { list-style: decimal } @@ -87,12 +94,10 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } -dd p:first-child { - margin-top: 0px } - -li p:first-child { - margin-top: 0px } - +/*dd p:first-child, li p:first-child, td p:first-child, th p:first-child { + margin-top: 0 ; + padding-top: 0 } +*/ p.caption { font-style: italic } @@ -100,6 +105,9 @@ p.credits { font-style: italic ; font-size: smaller } +p.first { + margin-top: 0 } + p.label { white-space: nowrap } @@ -132,7 +140,8 @@ span.problematic { color: red } table { - margin-top: 1em } + margin-top: 0.5em ; + margin-bottom: 0.5em } table.citation { border-left: solid thin gray ; @@ -145,6 +154,11 @@ table.footnote { border-left: solid thin black ; padding-left: 0.5ex } +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: baseline } + td.docinfo-name { font-weight: bold ; text-align: right } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index e84b7a7cf..53b67b303 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -10,7 +10,9 @@ Default cascading style sheet for the PEP HTML output of Docutils. .navigation { width: 100% ; - background: #99ccff } + background: #99ccff ; + margin-top: 0px ; + margin-bottom: 0px } .navigation .navicon { width: 150px ; @@ -20,10 +22,16 @@ Default cascading style sheet for the PEP HTML output of Docutils. padding-left: 1em ; text-align: left } +.navigation td, .navigation th { + padding-left: 0em ; + padding-right: 0em ; + vertical-align: middle } + .rfc2822 { margin-top: 0.5em ; - margin-left: 1em ; - margin-right: 1em } + margin-left: 0.5em ; + margin-right: 0.5em ; + margin-bottom: 0em } .rfc2822 div.field-body { text-align: left } @@ -42,17 +50,22 @@ a.footnote-reference { a.target { color: blue } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none ; + color: black } + body { margin: 0px ; margin-bottom: 1em ; padding: 0px } -col.num { - text-align: center } +td.num { + text-align: right } div.section { margin-left: 1em ; - margin-right: 1em } + margin-right: 1em ; + margin-bottom: 1.5em } div.abstract { margin: 2em 5em } @@ -135,6 +148,9 @@ h6 { .section hr { width: 75% } +ol, ul { + margin-bottom: 1em } + ol.arabic { list-style: decimal } @@ -150,10 +166,7 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } -dd p:first-child { - margin-top: 0px } - -li p:first-child { +dd p:first-child, li p:first-child, td p:first-child, th p:first-child { margin-top: 0px } p.caption { @@ -195,8 +208,11 @@ span.option-argument { span.problematic { color: red } -table.citation { - margin-bottom: 1em } +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } -table.footnote { - margin-bottom: 1em } +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: baseline } -- cgit v1.2.1 From 8e5edd1f37920b6904adb3993072d8f9b03d6951 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 23 Jul 2002 02:41:44 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@351 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 32ccba231..e5ccf6212 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -108,6 +108,7 @@ Specific: - 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 @@ -171,6 +172,9 @@ Specific: - 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. @@ -236,6 +240,7 @@ Specific: - Option lists: "" changed to "", ``option_argument`` "" changed to "". - Inline literals: "" changed to "". + - Many changes to optimize vertical space: compact simple lists etc. * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). -- cgit v1.2.1 From c838df7b5cd17daa4545f03e097791ae34679eb1 Mon Sep 17 00:00:00 2001 From: chodorowski Date: Tue, 23 Jul 2002 03:04:00 +0000 Subject: Escaped all swedish characters and changed all strings to be unicode strings (for consistency). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@352 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 58 ++++++++++++++++++------------------ docutils/parsers/rst/languages/sv.py | 44 +++++++++++++-------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index e70479359..67d37df00 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -17,38 +17,38 @@ from docutils import nodes labels = { - 'author': 'Frfattare', - 'authors': 'Frfattare', - 'organization': 'Organisation', - 'contact': 'Kontakt', - 'version': 'Version', - 'revision': 'Revision', - 'status': 'Status', - 'date': 'Datum', - 'copyright': 'Copyright', - 'abstract': 'Sammanfattning', - 'attention': 'Observera!', - 'caution': 'Varning!', - 'danger': 'FARA!', - 'error': 'Fel', - 'hint': 'Vgledning', - 'important': 'Viktigt', - 'note': 'Notera', - 'tip': 'Tips', - 'warning': 'Varning', - 'contents': 'Innehll'} + 'author': u'F\u00f6rfattare', + 'authors': u'F\u00f6rfattare', + 'organization': u'Organisation', + 'contact': u'Kontakt', + 'version': u'Version', + 'revision': u'Revision', + 'status': u'Status', + 'date': u'Datum', + 'copyright': u'Copyright', + 'abstract': u'Sammanfattning', + 'attention': u'Observera!', + 'caution': u'Varning!', + 'danger': u'FARA!', + 'error': u'Fel', + 'hint': u'V\u00e4gledning', + 'important': u'Viktigt', + 'note': u'Notera', + 'tip': u'Tips', + 'warning': u'Varning', + 'contents': u'Inneh\u00e5ll' } """Mapping of node class name to label text.""" bibliographic_fields = { - 'frfattare': nodes.authors, - 'organisation': nodes.organization, - 'kontakt': nodes.contact, - 'version': nodes.version, - 'revision': nodes.revision, - 'status': nodes.status, - 'datum': nodes.date, - 'copyright': nodes.copyright, - 'sammanfattning': nodes.topic} + u'f\u00f6rfattare': nodes.authors, + u'organisation': nodes.organization, + u'kontakt': nodes.contact, + u'version': nodes.version, + u'revision': nodes.revision, + u'status': nodes.status, + u'datum': nodes.date, + u'copyright': nodes.copyright, + u'sammanfattning': nodes.topic } """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index ad2454cb9..07e16a36c 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -14,26 +14,26 @@ __docformat__ = 'reStructuredText' directives = { - 'observera': 'attention', - 'varning': 'caution', - 'fara': 'danger', - 'fel': 'error', - 'vgledning': 'hint', - 'viktigt': 'important', - 'notera': 'note', - 'tips': 'tip', - 'varning': 'warning', - 'frgor': 'questions', - 'frgor-och-svar': 'questions', # NOTE: A bit long, but recommended by - 'vanliga-frgor': 'questions', # NOTE: http://www.nada.kth.se/dataterm/ - 'meta': 'meta', - #'bildkarta': 'imagemap', # FIXME: Translation might be to literal. - 'bild': 'image', - 'figur': 'figure', - #'r': 'raw', # FIXME: Translation might be to literal. - 'innehll': 'contents', - #'fotnoter': 'footnotes', - #'citeringar': 'citations', - #'mne': 'topic', - 'restructuredtext-test-directive': 'restructuredtext-test-directive'} + u'observera': 'attention', + u'varning': 'caution', + u'fara': 'danger', + u'fel': 'error', + u'v\u00e4gledning': 'hint', + u'viktigt': 'important', + u'notera': 'note', + u'tips': 'tip', + u'varning': 'warning', + u'fr\u00e5gor': 'questions', + u'fr\u00e5gor-och-svar': 'questions', # NOTE: A bit long, but recommended by + u'vanliga-fr\u00e5gor': 'questions', # NOTE: http://www.nada.kth.se/dataterm/ + u'meta': 'meta', + # u'bildkarta': 'imagemap', # FIXME: Translation might be to literal. + u'bild': 'image', + u'figur': 'figure', + # u'r\u00e5': 'raw', # FIXME: Translation might be to literal. + u'innehll': 'contents', + # u'fotnoter': 'footnotes', + # u'citeringar': 'citations', + # u'\u00e4mne': 'topic', + u'restructuredtext-test-directive': 'restructuredtext-test-directive' } """Swedish name to registered (in directives/__init__.py) directive name mapping.""" -- cgit v1.2.1 From e2befb2363ac2b741e4ef450d7cd20ba2e2f38e4 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:35:21 +0000 Subject: Added options to control backlinks from footnotes/citations and section headers (back to TOC). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@353 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docutils/frontend.py b/docutils/frontend.py index f0a4f8974..d6025e4a4 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -52,6 +52,25 @@ class OptionParser(optik.OptionParser): ('Do not include a "(View document source)" link.', ['--no-source-link'], {'action': 'store_false', 'dest': 'source_link'}), + ('Enable backlinks from section headers to table of contents ' + 'entries. This is the default.', + ['--toc-entry-backlinks'], + {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'entry', + 'default': 'entry'}), + ('Enable backlinks from section headers to the top of the table of ' + 'contents.', + ['--toc-top-backlinks'], + {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'top'}), + ('Disable backlinks to the table of contents.', + ['--no-toc-backlinks'], + {'dest': 'toc_backlinks', 'action': 'store_false'}), + ('Enable backlinks from footnotes and citations to their ' + 'references. This is the default.', + ['--footnote-backlinks'], + {'action': 'store_true', 'default': 1}), + ('Disable backlinks from footnotes and citations.', + ['--no-footnote-backlinks'], + {'dest': 'footnote_backlinks', 'action': 'store_false'}), ('Set verbosity threshold; report system messages at or higher than ' ' (by name or number: "info" or "1", warning/2, error/3, ' 'severe/4; also, "none" or "5"). Default is 2 (warning).', -- cgit v1.2.1 From a277893cdd0f8adca0cbac657f0724c4b61e6b0d Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:35:56 +0000 Subject: Added simple table. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@354 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 83 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index aa0d8f3ed..ea98e6788 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -20,7 +20,7 @@

http://docutils.sourceforge.net/docs/rst/quickref.html
Being a cheat-sheet for reStructuredText -
Version 0.8a of 2002-07-12 +
Version 0.9 of 2002-07-23

The full details may be found on the @@ -625,6 +625,10 @@ This means that something like:

(details?) +

There are two syntaxes for tables in reStructuredText. Grid + tables are complete but cumbersome to create. Simple tables are + easy to create but limited (no row spans, etc.).

+

@@ -634,19 +638,22 @@ This means that something like: +
-    +------------+------------+-----------+ -
    | Header 1   | Header 2   | Header 3  | -
    +============+============+===========+ -
    | body row 1 | column 2   | column 3  | -
    +------------+------------+-----------+ -
    | body row 2 | Cells may span columns.| -
    +------------+------------+-----------+ -
    | body row 3 | Cells may  | - Cells   | -
    +------------+ span rows. | - contain | -
    | body row 4 |            | - blocks. | -
    +------------+------------+-----------+ +

Grid table:

+ +

+------------+------------+-----------+ +
| Header 1   | Header 2   | Header 3  | +
+============+============+===========+ +
| body row 1 | column 2   | column 3  | +
+------------+------------+-----------+ +
| body row 2 | Cells may span columns.| +
+------------+------------+-----------+ +
| body row 3 | Cells may  | - Cells   | +
+------------+ span rows. | - contain | +
| body row 4 |            | - blocks. | +
+------------+------------+-----------+

- +

Grid table:

+
Header 1 Header 2 @@ -670,6 +677,56 @@ This means that something like:
body row 4
+
+

Simple table:

+ +

=====  =====  ====== +
   Inputs     Output +
------------  ------ +
  A      B    A or B +
=====  =====  ====== +
False  False  False +
True   False  True +
False  True   True +
True   True   True +
=====  =====  ======

+ +
+

Simple table:

+ + + + + + + + + + + + + + +
Inputs + Output +
A + B + A or B +
False + False + False +
True + False + True +
False + True + True +
True + True + True +
+

Transitions

-- cgit v1.2.1 From 09d88c2d27d9781fd35f1cec44633cf4acd7d9ba Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:36:58 +0000 Subject: In case language_module is None. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@355 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 484714588..74ff8830a 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -75,7 +75,7 @@ def directive(directive_name, language_module): return _directives[normname] try: canonicalname = language_module.directives[normname] - except KeyError: + except (KeyError, AttributeError): try: # Try English as a fallback: canonicalname = _fallback_language_module.directives[normname] -- cgit v1.2.1 From 9c1f254c9a15569eecdb31276a51628881f6a06f Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:37:44 +0000 Subject: Added "backlinks" attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@356 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 7b3d63697..d3bba86c5 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -19,8 +19,23 @@ from docutils.transforms import parts def unchanged(arg): return arg # unchanged! +def backlinks(arg): + try: + value = arg.lower().strip() + except AttributeError: + raise TypeError('must supply an argument; choose from "top", ' + '"entry", or "none"') + if value == 'none': + return None + elif value == 'top' or arg == 'entry': + return value + else: + raise ValueError( + '"%s" unknown; choose from "top", "entry", or "none"' % arg) + contents_attribute_spec = {'depth': int, 'local': unchanged, + 'backlinks': backlinks, 'qa': unchanged} def contents(match, type_name, data, state, state_machine, attributes): -- cgit v1.2.1 From 54a26a7452be9b2e0f5f0404d383e244fec5376a Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:39:23 +0000 Subject: Changed format of directve attribute error.. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@357 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 04a9ea605..cfb934e9d 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1598,7 +1598,7 @@ class Body(RSTState): except KeyError, detail: return 0, ('unknown attribute: "%s"' % detail), blank_finish except (ValueError, TypeError), detail: - return 0, ('invalid attribute value:\n%s' % detail), blank_finish + return 0, ('invalid attribute value: %s' % detail), blank_finish except utils.ExtensionAttributeError, detail: return 0, ('invalid attribute data: %s' % detail), blank_finish return 1, attributes, blank_finish -- cgit v1.2.1 From 0ef0fd6e65f2ac5221a125f6c2aa2e6d6340e8de Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:40:14 +0000 Subject: Support for optional TOC backlinks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@358 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index d109d3552..5c778fb12 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -49,19 +49,24 @@ class Contents(Transform): startnode = self.document if not title: title = nodes.title('', self.language.labels['contents']) + if title: + name = title.astext() + topic += title + else: + name = self.language.labels['contents'] + name = utils.normalize_name(name) + if not self.document.has_name(name): + topic['name'] = name + self.document.note_implicit_target(topic) + self.toc_id = topic['id'] + if self.startnode.details.has_key('backlinks'): + self.backlinks = self.startnode.details['backlinks'] + else: + self.backlinks = self.document.options.toc_backlinks contents = self.build_contents(startnode) if len(contents): - if title: - name = title.astext() - topic += title - else: - name = self.language.labels['contents'] topic += contents self.startnode.parent.replace(self.startnode, topic) - name = utils.normalize_name(name) - if not self.document.has_name(name): - topic['name'] = name - self.document.note_implicit_target(topic) else: self.startnode.parent.remove(self.startnode) @@ -83,7 +88,10 @@ class Contents(Transform): entry = nodes.paragraph('', '', reference) item = nodes.list_item('', entry) itemid = self.document.set_id(item) - title['refid'] = itemid + if self.backlinks == 'entry': + title['refid'] = itemid + elif self.backlinks == 'top': + title['refid'] = self.toc_id if level < depth: subsects = self.build_contents(section, level) item += subsects -- cgit v1.2.1 From 513862cec4707b0b5f1f54460052a23e36ba7ecb Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:42:01 +0000 Subject: Changed format of directive attribute error. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@359 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index c2418d91c..8b1d7ddf9 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -275,7 +275,7 @@ def assemble_attribute_dict(attlist, attspec): try: attributes[name] = convertor(value) except (ValueError, TypeError), detail: - raise detail.__class__('(attribute "%s", value "%s") %s' + raise detail.__class__('(attribute: "%s"; value: %r)\n%s' % (name, value, detail)) return attributes -- cgit v1.2.1 From 3036132b61ec33f0d9e7f70daa6e3a25b6ae9c60 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:43:14 +0000 Subject: Added support for optional footnote/citation backlinks. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@360 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9234463bb..0f205838d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -328,6 +328,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_description(self, node): self.body.append(self.starttag(node, 'td', '')) + if len(node) and isinstance(node[0], nodes.paragraph): + node[0].set_class('first') def depart_description(self, node): self.body.append('') @@ -492,7 +494,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.footnote_backrefs(node) def footnote_backrefs(self, node): - if node.hasattr('backrefs'): + if self.document.options.footnote_backlinks \ + and node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: self.context.append(('', '')) @@ -907,7 +910,7 @@ class SimpleListChecker(nodes.GenericNodeVisitor): """ Raise `nodes.SkipNode` if non-simple list item is encountered. - Here "simple" means a list item containing anything other than a single + Here "simple" means a list item containing nothing other than a single paragraph, a simple list, or a paragraph followed by a simple list. """ -- cgit v1.2.1 From a29e32f3d2999d91eba1444f59c809de7489fed9 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:44:44 +0000 Subject: Added cautions for anonymous hyperlink use. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@361 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index abf85b19c..74e8cf3c8 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1676,12 +1676,14 @@ Anonymous Hyperlinks The `World Wide Web Consortium`_ recommends in its `HTML Techniques for Web Content Accessibility Guidelines`_ that authors should -"clearly identify the target of each link." Hyperlink references +"clearly identify the target of each link." Hyperlink references should be as verbose as possible, but duplicating a verbose hyperlink name in the target is onerous and error-prone. Anonymous hyperlinks are designed to allow convenient verbose hyperlink references, and are analogous to `Auto-Numbered Footnotes`_. They are particularly useful -in short or one-off documents. +in short or one-off documents. However, this feature is easily abused +and can result in unreadable plaintext and/or unmaintainable +documents. Caution is advised. Anonymous `hyperlink references`_ are specified with two underscores instead of one:: @@ -1703,7 +1705,10 @@ to its target. Instead, the order of anonymous hyperlink references and targets within the document is significant: the first anonymous reference will link to the first anonymous target. The number of anonymous hyperlink references in a document must match the number of -anonymous targets. +anonymous targets. For readability, it is recommended that targets be +kept close to references. Take care when editing text containing +anonymous references; adding, removing, and rearranging references +require attention to the order of corresponding targets. Directives -- cgit v1.2.1 From 9aff0d96c5f7e0fff2b9df8cc522d922534753dd Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:45:41 +0000 Subject: Added "backlinks" attribute to "contents" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@362 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index d39f488c3..039e7fd0c 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -212,6 +212,9 @@ The following attributes are recognized: Generate a local table of contents. Entries will only include subsections of the section in which the directive is given. If no explicit title is given, the table of contents will not be titled. +``backlinks`` : "entry" or "top" or "none" + Generate links from section headers back to the table of contents + entries, the table of contents itself, or generate no backlinks. Footnotes -- cgit v1.2.1 From 28df6f89902b7c24bd945c5857982d0ebfb7506b Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:47:56 +0000 Subject: German language mappings; added to project. Thanks to Gunnar Schwant for the translations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@363 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/de.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docutils/languages/de.py diff --git a/docutils/languages/de.py b/docutils/languages/de.py new file mode 100644 index 000000000..8c512dc14 --- /dev/null +++ b/docutils/languages/de.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python + +""" +:Authors: David Goodger; Gunnar Schwant +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +German language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes + + +labels = { + 'author': 'Autor', + 'authors': 'Autoren', + 'organization': 'Organisation', + 'contact': 'Kontakt', + 'version': 'Version', + 'revision': 'Revision', + 'status': 'Status', + 'date': 'Datum', + 'copyright': 'Copyright', + 'abstract': 'Zusammenfassung', + 'attention': 'Achtung!', + 'caution': 'Vorsicht!', + 'danger': '!GEFAHR!', + 'error': 'Fehler', + 'hint': 'Hinweis', + 'important': 'Wichtig', + 'note': 'Bemerkung', + 'tip': 'Tipp', + 'warning': 'Warnung', + 'contents': 'Inhalt'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'autor': nodes.author, + 'autoren': nodes.authors, + 'organisation': nodes.organization, + 'kontakt': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'datum': nodes.date, + 'copyright': nodes.copyright, + 'zusammenfassung': nodes.topic} +"""Field name (lowcased) to node class name mapping for bibliographic fields +(field_list).""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" -- cgit v1.2.1 From 18fba0d32c5d883296ddb64ee8ad6dc9fa1ddcd2 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 24 Jul 2002 01:51:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@364 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 28 ++++++++++-- docs/dev/rst/alternatives.txt | 4 +- docs/dev/todo.txt | 7 --- .../test_rst/test_directives/test_contents.py | 36 ++++++++++++++- .../test_rst/test_directives/test_images.py | 8 ++-- test/test_transforms/test_contents.py | 52 +++++++++++++++++++++- tools/stylesheets/default.css | 4 -- 7 files changed, 115 insertions(+), 24 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e5ccf6212..3c4b93d4e 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -23,9 +23,9 @@ and related projects: Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis - Rudd, Ollie Rutherfurd, Ueli Schlaepfer, tav, Bob Tolbert, - Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, - Ka-Ping Yee, Moshe Zadka + Rudd, Ollie Rutherfurd, Ueli Schlaepfer, Gunnar Schwant, tav, Bob + Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward + Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -113,7 +113,7 @@ Specific: * 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/OptionParser.py: Added to project. Combined from the Optik package, with no modifications. This module will probably eventually take over from optik.py. Not used at present. @@ -140,6 +140,12 @@ Specific: warning_level -> report_level; error_level -> halt_level. - Moved ``utils.id()`` to ``nodes.make_id()``. +* docutils/languages/de.py: German mappings; added to project. Thanks + to Gunnar Schwant for the translations. + +* docutils/languages/sv.py: Swedish mappings; added to project by Adam + Chodorowski. + * docutils/parsers/rst/states.py: - Added underscores to improve many awkward names. @@ -181,6 +187,11 @@ Specific: * 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. @@ -203,6 +214,7 @@ Specific: - 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. @@ -241,6 +253,9 @@ Specific: "" changed to "". - Inline literals: "" changed to "". - 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. * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). @@ -293,6 +308,10 @@ Specific: - 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. @@ -309,6 +328,7 @@ Specific: - 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. * test: Made test modules standalone (subdirectories became packages). diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 92681bb2e..e241ed557 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1543,7 +1543,9 @@ A new type of "inline external hyperlink" has been proposed. Advantages and disadvantages are similar to those in (2). Readability is still an issue, but the syntax is a bit less - heavyweight (reduced line noise). + heavyweight (reduced line noise). Backquotes are required, even + for one-word references; the target URL is included within the + reference text, forcing a phrase context. Problem: how to refer to a title like "HTML Anchors: " (which ends with an HTML/SGML/XML tag)? We could either require more diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 2d244ab0c..8b273ce73 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -111,10 +111,6 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -- Add a command-line option & directive attribute to control TOC - backlinks: no TOC backlinks, backlinks to TOC entries, or backlinks - to TOC itself only. - Specification ------------- @@ -628,9 +624,6 @@ Front-Ends conflicts) to splitting common and component-specific options apart. -- Allow multiple option groups per component (thus enabling component - subclasses to easily incorporate their superclass' options). - - Parameterize help text & defaults somehow? Perhaps a callback? Or initialize ``cmdline_options`` in ``__init__``? diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 43b13c4f7..976acdd41 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -115,6 +115,7 @@ totest['contents'] = [ .. contents:: Table of Contents :local: :depth: 2 + :backlinks: none """, """\ @@ -123,6 +124,7 @@ totest['contents'] = [ .transform: docutils.transforms.parts.Contents .stage: 'last reader' .details: + backlinks: None depth: 2 local: None title: @@ -138,8 +140,8 @@ totest['contents'] = [ Error in "contents" directive attributes at line 1: - invalid attribute value: - (attribute "depth", value "two") invalid literal for int(): two. + invalid attribute value: (attribute: "depth"; value: 'two') + invalid literal for int(): two. .. contents:: :depth: two @@ -158,6 +160,36 @@ totest['contents'] = [ .. contents:: :width: 2 """], +["""\ +.. contents:: + :backlinks: no way! +""", +"""\ + + + + Error in "contents" directive attributes at line 1: + invalid attribute value: (attribute: "backlinks"; value: 'no way!') + "no way!" unknown; choose from "top", "entry", or "none". + + .. contents:: + :backlinks: no way! +"""], +["""\ +.. contents:: + :backlinks: +""", +"""\ + + + + Error in "contents" directive attributes at line 1: + invalid attribute value: (attribute: "backlinks"; value: None) + must supply an argument; choose from "top", "entry", or "none". + + .. contents:: + :backlinks: +"""], ] diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index bdaeb08e1..66047591d 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -133,8 +133,8 @@ totest['images'] = [ Error in "image" directive attributes at line 1: - invalid attribute value: - (attribute "scale", value "None") object can't be converted to int. + invalid attribute value: (attribute: "scale"; value: None) + object can't be converted to int. .. image:: picture.png :scale: @@ -203,8 +203,8 @@ totest['images'] = [ Error in "image" directive attributes at line 1: - invalid attribute value: - (attribute "scale", value "fifty") invalid literal for int(): fifty. + invalid attribute value: (attribute: "scale"; value: 'fifty') + invalid literal for int(): fifty. .. image:: picture.png :scale: fifty diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 4ac93ef68..5b416a82d 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -298,14 +298,38 @@ Paragraph. """, """\ - + - + Contents Test duplicate name "Contents". +
+ + Contents + <paragraph> + Paragraph. +"""], +["""\ +.. contents:: + :backlinks: top + +Contents +-------- +Paragraph. +""", +"""\ +<document> + <topic class="contents" id="id1"> + <title> + Contents + <bullet_list> + <list_item id="id2"> + <paragraph> + <reference refid="contents"> + Contents <section id="contents" name="contents"> <title refid="id1"> Contents @@ -313,6 +337,30 @@ Paragraph. Paragraph. """], ["""\ +.. contents:: + :backlinks: none + +Contents +-------- +Paragraph. +""", +"""\ +<document> + <topic class="contents" id="id1"> + <title> + Contents + <bullet_list> + <list_item id="id2"> + <paragraph> + <reference refid="contents"> + Contents + <section id="contents" name="contents"> + <title> + Contents + <paragraph> + Paragraph. +"""], +["""\ .. contents:: Degenerate case, no table of contents generated. diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index dc8881606..a9bd01a18 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -94,10 +94,6 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } -/*dd p:first-child, li p:first-child, td p:first-child, th p:first-child { - margin-top: 0 ; - padding-top: 0 } -*/ p.caption { font-style: italic } -- cgit v1.2.1 From 299249be5abfef3d4d12afbc4152465b5573f406 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:42:59 +0000 Subject: "Docutils Front-End Tools" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@365 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 698 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 docs/user/tools.txt diff --git a/docs/user/tools.txt b/docs/user/tools.txt new file mode 100644 index 000000000..923b17a0d --- /dev/null +++ b/docs/user/tools.txt @@ -0,0 +1,698 @@ +========================== + + Docutils Front-End Tools + +========================== + + + +:Author: David Goodger + +:Contact: goodger@users.sourceforge.net + +:Revision: $Revision$ + +:Date: $Date$ + + + +Once the Docutils package is unpacked, you will discover a "``tools``" + +directory containing several front ends for common Docutils + +processing. Most front ends combine a Docutils "Reader" (which knows + +how to interpret a file in context) with a "Writer" (which knows how + +to generate a specific data format) + + + +Each tool has a "``--help``" option which lists the `command-line + +options`_ and arguments it supports. Processing can also be + +customized with `configuration files`_. + + + + + +.. contents:: + + + + + +html.py + +======= + + + +:Reader: Standalone + +:Parser: reStructuredText + +:Writer: HTML + + + +The ``html.py`` front end reads standalone reStructuredText source + +files and produces HTML 4 (XHTML 1) output. It inserts a link to a + +cascading stylesheet (``.css`` file), ``default.css`` unless specified + +by a "--stylesheet" command-line option or in a configuration file. + +The ``tools/default.css`` stylesheet is provided for basic use. + + + + + +pep.py + +====== + + + +:Reader: PEP + +:Parser: reStructuredText + +:Writer: PEP/HTML + + + +``pep.py`` reads a new-style PEP (marked up with reStructuredText) and + +produces HTML. It requires a template file and a stylesheet. By + +default, it makes use of a ``pep-html-template`` file and a + +``default.css`` stylesheet in the current directory, but these can be + +overridden by command-line options or configuration files. The + +``tools/stylesheets/pep.css`` stylesheet is intended specifically for + +PEP use. + + + +The ``docutils.conf`` `configuration file`_ in the "``spec``" + +directory of Docutils contains a default setup for use in processing + +the PEP files there (``spec/pep-*.txt``) into HTML. It specifies + +defaults of ``tools/pep-html-template`` and + +``tools/stylesheets/pep.css``. + + + + + +pep2html.py + +=========== + + + +:Reader: PEP + +:Parser: reStructuredText + +:Writer: PEP/HTML + + + +``pep2html.py`` is a modified version of the original script by + +Fredrik Lundh, with support for Docutils added. It reads the + +beginning of a PEP text file to determine the format (old-style + +indented or new-style reStructuredText) and processes accordingly. + +Since it does not use the Docutils front end mechanism (the common + +command-line options are not supported), it must be configured using + +`configuration files`_. + + + + + +docutils-xml.py + +=============== + + + +:Reader: Standalone + +:Parser: reStructuredText + +:Writer: XML (Docutils native) + + + +The ``docutils-xml.py`` front end produces Docutils-native XML output. + +This can be transformed with standard XML tools such as XSLT + +processors into arbitrary final forms. + + + + + +publish.py + +========== + + + +:Reader: Standalone + +:Parser: reStructuredText + +:Writer: Pseudo-XML + + + +``publish.py`` is used for debugging the Docutils Reader -> Transform + +-> Writer pipeline. It produces a compact pretty-printed + +"pseudo-XML", where nesting is indicated by indentation (no end-tags). + +External attributes for all elements are output, and internal + +attributes for any leftover "pending" elements are also given. + + + + + +quicktest.py + +============ + + + +:Reader: N/A + +:Parser: reStructuredText + +:Writer: N/A + + + +The ``quicktest.py`` tool is used for testing the reStructuredText + +parser. It does not use the Docutils Reader/Writer mechanism. + +Rather, it does its own I/O and calls the parser directly. No + +transforms are applied to the parsed document. Various forms output + +are possible: + + + +- Pretty-printed pseudo-XML + +- Test data (Python list of input and pseudo-XML output strings; + + useful for creating new test cases) + +- Pretty-printed native XML + +- Raw native XML (with or without a stylesheet reference) + + + + + +Customization + +============= + + + +Command-Line Options + +-------------------- + + + +Each front-end tool supports command-line options for one-off + +customization. For persistent customization, use `configuration + +files`_. + + + +Use the "--help" option on each of the front ends to list the + +command-line options it supports. Command-line options and their + +corresponding configuration file entry names are listed in + +`Configuration File Entries`_ below. + + + + + +.. _configuration file: + + + +Configuration Files + +------------------- + + + +Configuration files are used for persistent customization; they can be + +set once and take effect every time you use a front-end tool. + + + +By default, Docutils checks three places for configuration files, in + +the following order: + + + +1. ``/etc/docutils.conf``: This is a system-wide configuration file, + + applicable to all Docutils processing on the system. + + + +2. ``./docutils.conf``: This is a project-specific configuration file, + + located in the current directory. The Docutils front end has to be + + executed from the directory containing this configuration file for + + it to take effect. The project-specific configuration file + + overrides the system-wide file. + + + +3. ``~/.docutils``: This is a user-specific configuration file, + + located in the user's home directory. This file overrides both the + + system-wide and project-specific configuration files. + + + +If more than one configuration file is found, all will be read but + +later entries will override earlier ones. For example, a "stylesheet" + +entry in a user-specific configuration file will override a + +system-wide entry. + + + +Configuration files use the standard ConfigParser.py_ Python_ module. + +From its documentation: + + + + The configuration file consists of sections, lead by a "[section]" + + header and followed by "name: value" entries, with continuations + + in the style of `RFC 822`_; "name=value" is also accepted. Note + + that leading whitespace is removed from values. The optional + + values can contain format strings which refer to other values in + + the same section, or values in a special DEFAULT section. + + Additional defaults can be provided upon initialization and + + retrieval. Lines beginning with "#" or ";" are ignored and may be + + used to provide comments. + + + +Docutils only uses an "[options]" section; all other sections will be + +ignored. + + + +Configuration entry names correspond to internal option attributes. + +Underscores ("_") and hyphens ("-") can be used interchangably in + +entry names. The correspondence between entry names and command-line + +options is listed in `Configuration File Entries`_ below. + + + +.. _ConfigParser.py: + + http://www.python.org/doc/current/lib/module-ConfigParser.html + +.. _Python: http://www.python.org/ + +.. _RFC 822: http://www.rfc-editor.org/rfc/rfc822.txt + + + + + +Configuration File Entries + +-------------------------- + + + +The entry names listed below may be specified in `configuration + +files`_ (hyphens may be used in place of underscores). Some knowledge + +of Python_ is assumed for some attributes. + + + +==================== ================================================ + +Entry Name Description and Command-Line Options + +==================== ================================================ + +datestamp Include a time/datestamp in the document footer. + + Contains a format string for ``time.strftime``. + + + + Default: None. + + + + ``--date, -d, --time, -t, --no-datestamp`` + + + +debug Report debug-level system messages. + + + + Default: don't (None). + + + + ``--debug, --no-debug`` + + + +dump_internals Hidden option: At the end of processing, print + + out all internal attributes of the document + + (``document.__dict__``). + + + + Default: don't (None). + + + + ``--dump-internals`` + + + +footnote_backlinks Enable or disable backlinks from footnotes and + + citations to their references. + + + + Default: enabled (1). + + + + ``--footnote-backlinks, --no-footnote-backlinks`` + + + +generator Include a "Generated by Docutils" credit and + + link in the document footer. + + + + Default: off (None). + + + + ``--generator, -g, --no-generator`` + + + +halt_level Set the threshold at or above which system + + messages are converted to exceptions, halting + + execution immediately. + + + + Default: severe (4). + + + + ``--halt, --strict`` + + + +indents XML-specific: Generate XML with indents and + + newlines. + + + + Default: None. + + + + ``--indents`` + + + +input_encoding Default: auto-detect (None). + + + + ``--input-encoding, -i`` + + + +language_code Default: English ("en"). + + + + ``--language, -l`` + + + +newlines XML-specific: Generate XML with newlines before + + and after tags. + + + + Default: None. + + + + ``--newlines`` + + + +no_random PEP/HTML-specific hidden option: Workaround for + + platforms which core-dump on "``import + + random``". + + + + Default: random enabled (None). + + + + ``--no-random`` + + + +output_encoding Default: UTF-8. + + + + ``--output-encoding, -o`` + + + +pep_home PEP/HTML-specific: Home URL prefix for PEPs. + + + + Default: current directory ("."). + + + + ``--pep-home`` + + + +pep_stylesheet PEP/HTML-specific: Overrides HTML stylesheet. + + + + Default: None. + + + + ``--pep-stylesheet`` + + + +pep_template PEP/HTML-specific: PEP template file. + + + + Default: "pep-html-template". + + + + ``--pep-template`` + + + +python_home PEP/HTML-specific: Python's home URL. + + + + Default: parent directory (".."). + + + + ``--python-home`` + + + +report_level Set verbosity threshold at or above which system + + messages are reported. + + + + Default: warning (2). + + + + ``--report, -r, --verbose`` + + + +source_link Include a "View document source" link in the + + document footer. + + + + Default: don't (None). + + + + ``--source-link, --no-source-link`` + + + +stylesheet HTML-specific. + + + + Default: "default.css". + + + + ``--stylesheet`` + + + +toc_backlinks Enable backlinks from section titles to table of + + contents entries ("entry"), to the top of the + + TOC ("top"), or disable ("none"). + + + + Default: "entry". + + + + ``--toc-entry-backlinks, --toc-top-backlinks, + + --no-toc-backlinks`` + + + +warning_stream Send the output of system messages (warnings) to + + a file. + + + + Default: stderr (None). + + + + ``--warnings`` + +==================== ================================================ + + + + + +.. + + Local Variables: + + mode: indented-text + + indent-tabs-mode: nil + + sentence-end-double-space: t + + fill-column: 70 + + End: + -- cgit v1.2.1 From 15f41ca47d032c33376f939059faf9eb82ac3f51 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:46:28 +0000 Subject: Added default usage message and description. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@366 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 5f2af0be3..eb6f35d20 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -136,18 +136,23 @@ class Publisher: self.process_command_line(argv, usage, description, option_spec) document = self.reader.read(self.source, self.parser, self.options) output = self.writer.write(document, self.destination) - if self.options.dump_internal_document_attributes: + if self.options.dump_internals: from pprint import pformat print >>sys.stderr, pformat(document.__dict__) return output +default_usage = '%prog [options] [<source> [<destination>]]' +default_description = ('Reads from <source> (default is stdin) and writes to ' + '<destination> (default is stdout).') + def publish(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', - argv=None, usage=None, description=None, option_spec=None): + argv=None, usage=default_usage, description=default_description, + option_spec=None): """ - A convenience function for file I/O front-ends; set up & run a + A convenience function for file I/O front ends; set up & run a `Publisher`. """ pub = Publisher(reader, parser, writer) -- cgit v1.2.1 From 8773019e39e7199f06b0bd263b778a74ffb86a61 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:47:58 +0000 Subject: docstrings & option descriptions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@367 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index d6025e4a4..759e11472 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -7,7 +7,7 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -Command-line and common processing for Docutils front-ends. +Command-line and common processing for Docutils front-end tools. """ __docformat__ = 'reStructuredText' @@ -32,7 +32,7 @@ class OptionParser(optik.OptionParser): cmdline_options = ( 'General Docutils Options', None, - (('Include a "Generated by Docutils" credit with a link, at the end ' + (('Include a "Generated by Docutils" credit and link at the end ' 'of the document.', ['--generator', '-g'], {'action': 'store_true'}), ('Do not include a generator credit.', @@ -47,9 +47,9 @@ class OptionParser(optik.OptionParser): ('Do not include a datestamp of any kind.', ['--no-datestamp'], {'action': 'store_const', 'const': None, 'dest': 'datestamp'}), - ('Include a "View document source." link.', + ('Include a "View document source" link.', ['--source-link', '-s'], {'action': 'store_true'}), - ('Do not include a "(View document source)" link.', + ('Do not include a "View document source" link.', ['--no-source-link'], {'action': 'store_false', 'dest': 'source_link'}), ('Enable backlinks from section headers to table of contents ' @@ -109,15 +109,14 @@ class OptionParser(optik.OptionParser): ['--help', '-h'], {'action': 'help'}), # Hidden options, for development use only: (optik.SUPPRESS_HELP, - ['--dump-internal-document-attributes'], + ['--dump-internals'], {'action': 'store_true'}),)) - """Command-line option specifications, common to all Docutils front-ends. - One or more sets of option group title, description, and a - list/tuple of tuples: ``('help text', [list of option strings], - {keyword arguments})``. Group title and/or description may be - `None`; no group title implies no group, just a list of single - options. Option specs from Docutils components are also used (see - `populate_from_components()`).""" + """Command-line option specifications, common to all Docutils front ends. + One or more sets of option group title, description, and a list/tuple of + tuples: ``('help text', [list of option strings], {keyword arguments})``. + Group title and/or description may be `None`; no group title implies no + group, just a list of single options. Option specs from Docutils + components are also used (see `populate_from_components()`).""" version_template = '%%prog (Docutils %s)' % docutils.__version__ -- cgit v1.2.1 From 659ceac33a3aa10d234d7eaf8e4f4adc2778df99 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:49:17 +0000 Subject: one last 8-bit char; cleanup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@368 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/sv.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 07e16a36c..2d45a5222 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -24,16 +24,18 @@ directives = { u'tips': 'tip', u'varning': 'warning', u'fr\u00e5gor': 'questions', - u'fr\u00e5gor-och-svar': 'questions', # NOTE: A bit long, but recommended by - u'vanliga-fr\u00e5gor': 'questions', # NOTE: http://www.nada.kth.se/dataterm/ + # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: + u'fr\u00e5gor-och-svar': 'questions', + u'vanliga-fr\u00e5gor': 'questions', u'meta': 'meta', - # u'bildkarta': 'imagemap', # FIXME: Translation might be to literal. + # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. u'bild': 'image', u'figur': 'figure', - # u'r\u00e5': 'raw', # FIXME: Translation might be to literal. - u'innehll': 'contents', + # u'r\u00e5': 'raw', # FIXME: Translation might be too literal. + u'inneh\u00e5ll': 'contents', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', # u'\u00e4mne': 'topic', u'restructuredtext-test-directive': 'restructuredtext-test-directive' } -"""Swedish name to registered (in directives/__init__.py) directive name mapping.""" +"""Swedish name to registered (in directives/__init__.py) directive name +mapping.""" -- cgit v1.2.1 From 8d07f5fac59043b0af54a372a3ffbc4ed10f6cf3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:49:57 +0000 Subject: Simple tables bug fix. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@369 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 51beb6b97..d304445c8 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -426,6 +426,9 @@ class SimpleTableParser(TableParser): if end < 0: end = len(line) cols.append((begin, end)) + if self.columns: + # Allow for an unbounded rightmost column: + cols[-1] = (cols[-1][0], self.columns[-1][1]) return cols def init_row(self, colspec, offset): -- cgit v1.2.1 From 880c53928e14b1c38276722cb82a60e1c6dd10f8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:52:07 +0000 Subject: updates & improvements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@370 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 11 +++++++---- tools/stylesheets/pep.css | 15 +++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index a9bd01a18..8d880c7cb 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -15,6 +15,13 @@ a.footnote-reference { a.target { color: blue } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + div.abstract { margin: 2em 5em } @@ -63,10 +70,6 @@ div.system-message p.system-message-title { div.topic { margin: 2em } -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { - text-decoration: none ; - color: black } - h1.title { text-align: center } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 53b67b303..3a41e6b58 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -59,8 +59,8 @@ body { margin-bottom: 1em ; padding: 0px } -td.num { - text-align: right } +dd { + margin-bottom: 0.5em } div.section { margin-left: 1em ; @@ -148,7 +148,7 @@ h6 { .section hr { width: 75% } -ol, ul { +ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { @@ -166,9 +166,6 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } -dd p:first-child, li p:first-child, td p:first-child, th p:first-child { - margin-top: 0px } - p.caption { font-style: italic } @@ -176,6 +173,9 @@ p.credits { font-style: italic ; font-size: smaller } +p.first { + margin-top: 0 } + p.label { white-space: nowrap } @@ -212,6 +212,9 @@ table { margin-top: 0.5em ; margin-bottom: 0.5em } +td.num { + text-align: right } + td, th { padding-left: 0.5em ; padding-right: 0.5em ; -- cgit v1.2.1 From c1cdf743e8823711597a7a0ed47822af56c030e2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:55:51 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@371 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 +++--- README.txt | 10 ++++---- docs/dev/todo.txt | 22 ++++++++-------- docs/peps/pep-0258.txt | 2 +- docs/ref/rst/restructuredtext.txt | 11 ++++---- test/test_parsers/test_rst/test_tables.py | 42 ++++++++++++++++++++++++++----- tools/docutils-xml.py | 11 ++++---- tools/html.py | 11 ++++---- tools/pep.py | 9 ++++--- tools/publish.py | 11 ++++---- 10 files changed, 85 insertions(+), 52 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 3c4b93d4e..50649e807 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -265,6 +265,8 @@ Specific: * 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". @@ -349,11 +351,11 @@ Specific: * tools: - - Updated html.py and publish.py front-ends to use the new + - 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-ends. + - Added ``locale.setlocale()`` calls to front-end tools. * tools/default.css: @@ -361,7 +363,7 @@ Specific: * tools/docutils-xml.py: Added to project. -* tools/pep.py: Added to project; PEP to HTML front-end. +* tools/pep.py: Added to project; PEP to HTML front-end tool. * tools/pep-html-template: Added to project. diff --git a/README.txt b/README.txt index 911595512..011e7f11f 100644 --- a/README.txt +++ b/README.txt @@ -135,11 +135,11 @@ not appear. Usage ===== -Start with the html.py and publish.py front-ends from the unpacked -"tools" subdirectory. Both 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-ends for details on options and -arguments. +Start with the html.py and publish.py front-end tools from the +unpacked "tools" subdirectory. Both 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. The package modules are continually growing and evolving. The ``docutils.statemachine`` module is usable independently. It contains diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 8b273ce73..a0b445f26 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -45,6 +45,11 @@ Bugs to underline with "===" (I just did). The parser should produce a warning in such cases. +- The parser doesn't know anything about double-width characters such + as Chinese hanza & Japanese kanji/kana. Also, it's dependent on + whitespace and punctuation as markup delimiters, which may not be + applicable in these languages. + General ------- @@ -69,7 +74,7 @@ General - User docs. - - How to use the front-ends (docs/tools.txt). + - How to use the front-end tools (docs/tools.txt). - Configuration file syntax & recognized entries. @@ -301,9 +306,6 @@ __ rst/alternatives.html#or-not-to-do first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. -- The parser doesn't know anything about double-width characters such - as Chinese hanza & Japanese kanji/kana. - Directives `````````` @@ -582,8 +584,8 @@ HTML Writer iframe, img, map. -Front-Ends ----------- +Front-End Tools +--------------- - Common and component-specific options must not conflict. Reserve short options for the core, and restrict components to long @@ -596,7 +598,7 @@ Front-Ends Perhaps have different types of front ends: a) _`Fully qualified`: Reader and Writer are hard-coded into the - front-end (e.g. ``pep2html [options]``, ``pysource2pdf + front end (e.g. ``pep2html [options]``, ``pysource2pdf [options]``). b) _`Partially qualified`: Reader is hard-coded, and the Writer is @@ -607,7 +609,7 @@ Front-Ends c) _`Unqualified`: Reader and Writer are specified as subcommands (e.g. ``publish pep html [options]``, ``publish pysource pdf - [options]``). A single front-end would be sufficient, but + [options]``). A single front end would be sufficient, but probably only useful for testing purposes. d) _`Dynamic`: Reader and/or Writer are specified by options, with @@ -619,7 +621,7 @@ Front-Ends Allow common options before subcommands, as in CVS? Or group all options together? In the case of the `fully qualified`_ - front-ends, all the options will have to be grouped together + front ends, all the options will have to be grouped together anyway, so there's no advantage (we can't use it to avoid conflicts) to splitting common and component-specific options apart. @@ -872,7 +874,7 @@ structure is recommended:: ... test/ # Test suite. ... - tools/ # For front-ends etc. + tools/ # For front ends etc. ... setup.py # Use Distutils to install the component # code and tools/ files into the right diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index a66feeb95..905aae688 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -322,7 +322,7 @@ Specification convenience function "publish()". See `Publisher`_ above. - Module "docutils.frontend" provides command-line and option - processing for Docutils front-ends. + processing for Docutils front-end tools. - Module "docutils.io" provides a uniform API for low-level input and output. diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 74e8cf3c8..4c56bd25d 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -795,11 +795,12 @@ The syntax for field arguments may be extended in the future. For example, quoted phrases may be treated as a single argument, and direct support for the "name=value" syntax may be added. -Standard RFC822 headers cannot be used for this construct because they -are ambiguous. A word followed by a colon at the beginning of a line -is common in written text. However, in well-defined contexts such as -when a field list invariably occurs at the beginning of a document -(PEPs and email messages), standard RFC822 headers could be used. +Standard RFC822_ headers cannot be used for this construct because +they are ambiguous. A word followed by a colon at the beginning of a +line is common in written text. However, in well-defined contexts +such as when a field list invariably occurs at the beginning of a +document (PEPs and email messages), standard RFC822 headers could be +used. Syntax diagram (simplified):: diff --git a/test/test_parsers/test_rst/test_tables.py b/test/test_parsers/test_rst/test_tables.py index e74c7cfb5..2b45cd527 100755 --- a/test/test_parsers/test_rst/test_tables.py +++ b/test/test_parsers/test_rst/test_tables.py @@ -642,11 +642,13 @@ two rows, and a column span. 1 A table with three rows, -- ------------------------ 2 and three columns. -3 First and last rows +3 First and third rows contain column spans. - This last row is a multi-line row, and overflows to the right. -== ======================== + This row is a multi-line row, and overflows to the right. +-- ------------------------ +4 One last row. +== =========== =========== """, """\ <document> @@ -654,7 +656,7 @@ two rows, and a column span. <tgroup cols="3"> <colspec colwidth="2"> <colspec colwidth="11"> - <colspec colwidth="49"> + <colspec colwidth="44"> <tbody> <row> <entry> @@ -679,10 +681,20 @@ two rows, and a column span. 3 <entry morecols="1"> <paragraph> - First and last rows + First and third rows contain column spans. <paragraph> - This last row is a multi-line row, and overflows to the right. + This row is a multi-line row, and overflows to the right. + <row> + <entry> + <paragraph> + 4 + <entry> + <paragraph> + One last + <entry> + <paragraph> + row. """], ["""\ ======= ========= ======== @@ -949,6 +961,24 @@ with empty cells <paragraph> cells. """], +["""\ +============== ====== +A simple table this text extends to the right +cell 3 the bottom border below is too long +============== ======== +""", +"""\ +<document> + <system_message level="3" type="ERROR"> + <paragraph> + Malformed table at line 1; formatting as a literal block. + Bottom/header table border does not match top border. + <literal_block> + ============== ====== + A simple table this text extends to the right + cell 3 the bottom border below is too long + ============== ======== +"""], ] diff --git a/tools/docutils-xml.py b/tools/docutils-xml.py index 9269376bf..72f72ca86 100755 --- a/tools/docutils-xml.py +++ b/tools/docutils-xml.py @@ -7,17 +7,16 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher, producing Docutils XML. +A minimal front end to the Docutils Publisher, producing Docutils XML. """ import locale locale.setlocale(locale.LC_ALL, '') -from docutils.core import publish +from docutils.core import publish, default_description -usage = '%prog [options] [source [destination]]' -description = ('Generate Docutils XML from standalone reStructuredText ' - 'sources.') +description = ('Generates Docutils-native XML from standalone ' + 'reStructuredText sources. ' + default_description) -publish(writer_name='xml', usage=usage, description=description) +publish(writer_name='xml', description=description) diff --git a/tools/html.py b/tools/html.py index c1c29b2b6..a79aefca8 100755 --- a/tools/html.py +++ b/tools/html.py @@ -7,17 +7,16 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher, producing HTML. +A minimal front end to the Docutils Publisher, producing HTML. """ import locale locale.setlocale(locale.LC_ALL, '') -from docutils.core import publish +from docutils.core import publish, default_description -usage = '%prog [options] [source [destination]]' -description = ('Generate HTML documents from standalone reStructuredText ' - 'sources.') +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) -publish(writer_name='html', usage=usage, description=description) +publish(writer_name='html', description=description) diff --git a/tools/pep.py b/tools/pep.py index acaab10c4..837221495 100755 --- a/tools/pep.py +++ b/tools/pep.py @@ -7,16 +7,17 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher, producing HTML from PEP +A minimal front end to the Docutils Publisher, producing HTML from PEP (Python Enhancement Proposal) documents. """ import locale locale.setlocale(locale.LC_ALL, '') -from docutils.core import publish +from docutils.core import publish, default_description -usage = 'usage:\n %prog [options] [source [destination]]' +description = ('Generates (X)HTML from reStructuredText-format PEP files. ' + + default_description) -publish(reader_name='pep', writer_name='pep_html', usage=usage) +publish(reader_name='pep', writer_name='pep_html', description=description) diff --git a/tools/publish.py b/tools/publish.py index 6e814ea67..edd643b04 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -7,17 +7,16 @@ :Date: $Date$ :Copyright: This module has been placed in the public domain. -A minimal front-end to the Docutils Publisher, producing pseudo-XML. +A minimal front end to the Docutils Publisher, producing pseudo-XML. """ import locale locale.setlocale(locale.LC_ALL, '') -from docutils.core import publish +from docutils.core import publish, default_description -usage = '%prog [options] [source [destination]]' -description = ('Generate pseudo-XML from standalone reStructuredText sources ' - '(for testing purposes).') +description = ('Generates pseudo-XML from standalone reStructuredText ' + 'sources (for testing purposes). ' + default_description) -publish(usage=usage, description=description) +publish(description=description) -- cgit v1.2.1 From 6d5cb7fba39d36ceb10a35aea035f9b65c4da179 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 01:56:16 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@372 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 50649e807..ae64f6604 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -77,6 +77,7 @@ Specific: - 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 -- cgit v1.2.1 From 6b905e0d6511b550d563f0f7c79dd09a2ccdcb14 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Jul 2002 02:02:54 +0000 Subject: removed extra lines git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@373 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 349 ---------------------------------------------------- 1 file changed, 349 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 923b17a0d..cf3e092d7 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -1,698 +1,349 @@ ========================== - Docutils Front-End Tools - ========================== - - :Author: David Goodger - :Contact: goodger@users.sourceforge.net - :Revision: $Revision$ - :Date: $Date$ - - Once the Docutils package is unpacked, you will discover a "``tools``" - directory containing several front ends for common Docutils - processing. Most front ends combine a Docutils "Reader" (which knows - how to interpret a file in context) with a "Writer" (which knows how - to generate a specific data format) - - Each tool has a "``--help``" option which lists the `command-line - options`_ and arguments it supports. Processing can also be - customized with `configuration files`_. - - - .. contents:: - - - html.py - ======= - - :Reader: Standalone - :Parser: reStructuredText - :Writer: HTML - - The ``html.py`` front end reads standalone reStructuredText source - files and produces HTML 4 (XHTML 1) output. It inserts a link to a - cascading stylesheet (``.css`` file), ``default.css`` unless specified - by a "--stylesheet" command-line option or in a configuration file. - The ``tools/default.css`` stylesheet is provided for basic use. - - - pep.py - ====== - - :Reader: PEP - :Parser: reStructuredText - :Writer: PEP/HTML - - ``pep.py`` reads a new-style PEP (marked up with reStructuredText) and - produces HTML. It requires a template file and a stylesheet. By - default, it makes use of a ``pep-html-template`` file and a - ``default.css`` stylesheet in the current directory, but these can be - overridden by command-line options or configuration files. The - ``tools/stylesheets/pep.css`` stylesheet is intended specifically for - PEP use. - - The ``docutils.conf`` `configuration file`_ in the "``spec``" - directory of Docutils contains a default setup for use in processing - the PEP files there (``spec/pep-*.txt``) into HTML. It specifies - defaults of ``tools/pep-html-template`` and - ``tools/stylesheets/pep.css``. - - - pep2html.py - =========== - - :Reader: PEP - :Parser: reStructuredText - :Writer: PEP/HTML - - ``pep2html.py`` is a modified version of the original script by - Fredrik Lundh, with support for Docutils added. It reads the - beginning of a PEP text file to determine the format (old-style - indented or new-style reStructuredText) and processes accordingly. - Since it does not use the Docutils front end mechanism (the common - command-line options are not supported), it must be configured using - `configuration files`_. - - - docutils-xml.py - =============== - - :Reader: Standalone - :Parser: reStructuredText - :Writer: XML (Docutils native) - - The ``docutils-xml.py`` front end produces Docutils-native XML output. - This can be transformed with standard XML tools such as XSLT - processors into arbitrary final forms. - - - publish.py - ========== - - :Reader: Standalone - :Parser: reStructuredText - :Writer: Pseudo-XML - - ``publish.py`` is used for debugging the Docutils Reader -> Transform - -> Writer pipeline. It produces a compact pretty-printed - "pseudo-XML", where nesting is indicated by indentation (no end-tags). - External attributes for all elements are output, and internal - attributes for any leftover "pending" elements are also given. - - - quicktest.py - ============ - - :Reader: N/A - :Parser: reStructuredText - :Writer: N/A - - The ``quicktest.py`` tool is used for testing the reStructuredText - parser. It does not use the Docutils Reader/Writer mechanism. - Rather, it does its own I/O and calls the parser directly. No - transforms are applied to the parsed document. Various forms output - are possible: - - - Pretty-printed pseudo-XML - - Test data (Python list of input and pseudo-XML output strings; - useful for creating new test cases) - - Pretty-printed native XML - - Raw native XML (with or without a stylesheet reference) - - - Customization - ============= - - Command-Line Options - -------------------- - - Each front-end tool supports command-line options for one-off - customization. For persistent customization, use `configuration - files`_. - - Use the "--help" option on each of the front ends to list the - command-line options it supports. Command-line options and their - corresponding configuration file entry names are listed in - `Configuration File Entries`_ below. - - - .. _configuration file: - - Configuration Files - ------------------- - - Configuration files are used for persistent customization; they can be - set once and take effect every time you use a front-end tool. - - By default, Docutils checks three places for configuration files, in - the following order: - - 1. ``/etc/docutils.conf``: This is a system-wide configuration file, - applicable to all Docutils processing on the system. - - 2. ``./docutils.conf``: This is a project-specific configuration file, - located in the current directory. The Docutils front end has to be - executed from the directory containing this configuration file for - it to take effect. The project-specific configuration file - overrides the system-wide file. - - 3. ``~/.docutils``: This is a user-specific configuration file, - located in the user's home directory. This file overrides both the - system-wide and project-specific configuration files. - - If more than one configuration file is found, all will be read but - later entries will override earlier ones. For example, a "stylesheet" - entry in a user-specific configuration file will override a - system-wide entry. - - Configuration files use the standard ConfigParser.py_ Python_ module. - From its documentation: - - The configuration file consists of sections, lead by a "[section]" - header and followed by "name: value" entries, with continuations - in the style of `RFC 822`_; "name=value" is also accepted. Note - that leading whitespace is removed from values. The optional - values can contain format strings which refer to other values in - the same section, or values in a special DEFAULT section. - Additional defaults can be provided upon initialization and - retrieval. Lines beginning with "#" or ";" are ignored and may be - used to provide comments. - - Docutils only uses an "[options]" section; all other sections will be - ignored. - - Configuration entry names correspond to internal option attributes. - Underscores ("_") and hyphens ("-") can be used interchangably in - entry names. The correspondence between entry names and command-line - options is listed in `Configuration File Entries`_ below. - - .. _ConfigParser.py: - http://www.python.org/doc/current/lib/module-ConfigParser.html - .. _Python: http://www.python.org/ - .. _RFC 822: http://www.rfc-editor.org/rfc/rfc822.txt - - - Configuration File Entries - -------------------------- - - The entry names listed below may be specified in `configuration - files`_ (hyphens may be used in place of underscores). Some knowledge - of Python_ is assumed for some attributes. - - ==================== ================================================ - Entry Name Description and Command-Line Options - ==================== ================================================ - datestamp Include a time/datestamp in the document footer. - Contains a format string for ``time.strftime``. - - Default: None. - - ``--date, -d, --time, -t, --no-datestamp`` - - debug Report debug-level system messages. - - Default: don't (None). - - ``--debug, --no-debug`` - - dump_internals Hidden option: At the end of processing, print - out all internal attributes of the document - (``document.__dict__``). - - Default: don't (None). - - ``--dump-internals`` - - footnote_backlinks Enable or disable backlinks from footnotes and - citations to their references. - - Default: enabled (1). - - ``--footnote-backlinks, --no-footnote-backlinks`` - - generator Include a "Generated by Docutils" credit and - link in the document footer. - - Default: off (None). - - ``--generator, -g, --no-generator`` - - halt_level Set the threshold at or above which system - messages are converted to exceptions, halting - execution immediately. - - Default: severe (4). - - ``--halt, --strict`` - - indents XML-specific: Generate XML with indents and - newlines. - - Default: None. - - ``--indents`` - - input_encoding Default: auto-detect (None). - - ``--input-encoding, -i`` - - language_code Default: English ("en"). - - ``--language, -l`` - - newlines XML-specific: Generate XML with newlines before - and after tags. - - Default: None. - - ``--newlines`` - - no_random PEP/HTML-specific hidden option: Workaround for - platforms which core-dump on "``import - random``". - - Default: random enabled (None). - - ``--no-random`` - - output_encoding Default: UTF-8. - - ``--output-encoding, -o`` - - pep_home PEP/HTML-specific: Home URL prefix for PEPs. - - Default: current directory ("."). - - ``--pep-home`` - - pep_stylesheet PEP/HTML-specific: Overrides HTML stylesheet. - - Default: None. - - ``--pep-stylesheet`` - - pep_template PEP/HTML-specific: PEP template file. - - Default: "pep-html-template". - - ``--pep-template`` - - python_home PEP/HTML-specific: Python's home URL. - - Default: parent directory (".."). - - ``--python-home`` - - report_level Set verbosity threshold at or above which system - messages are reported. - - Default: warning (2). - - ``--report, -r, --verbose`` - - source_link Include a "View document source" link in the - document footer. - - Default: don't (None). - - ``--source-link, --no-source-link`` - - stylesheet HTML-specific. - - Default: "default.css". - - ``--stylesheet`` - - toc_backlinks Enable backlinks from section titles to table of - contents entries ("entry"), to the top of the - TOC ("top"), or disable ("none"). - - Default: "entry". - - ``--toc-entry-backlinks, --toc-top-backlinks, - --no-toc-backlinks`` - - warning_stream Send the output of system messages (warnings) to - a file. - - Default: stderr (None). - - ``--warnings`` - ==================== ================================================ - - - .. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: - -- cgit v1.2.1 From 371e8d963cd1a0872b25b3d1521b507f5a1bb741 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:41:19 +0000 Subject: elaborated; added usage & stylesheet examples; redid table git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@375 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 255 +++++++++++++++++++++++++++++----------------------- 1 file changed, 144 insertions(+), 111 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index cf3e092d7..f0b183125 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -9,13 +9,23 @@ Once the Docutils package is unpacked, you will discover a "``tools``" directory containing several front ends for common Docutils -processing. Most front ends combine a Docutils "Reader" (which knows -how to interpret a file in context) with a "Writer" (which knows how -to generate a specific data format) +processing. Most Docutils front ends combine a specific "Reader" +(which knows how to interpret a file in context), a "Parser" (which +understands the syntax of the text), and a "Writer" (which knows how +to generate a specific data format). Most front ends have common +options and the same command-line usage pattern:: -Each tool has a "``--help``" option which lists the `command-line -options`_ and arguments it supports. Processing can also be -customized with `configuration files`_. + toolname [options] [<source> [<destination]] + +The sole exception is pep2html.py_. See html.py_ for concrete +examples. Each tool has a "``--help``" option which lists the +`command-line options`_ and arguments it supports. Processing can +also be customized with `configuration files`_. + +The two arguments, "source" and "destination", are optional. If only +one argument (source) is specified, the standard output (stdout) is +used for the destination. If no arguments are specified, the standard +input (stdin) is used for the source as well. .. contents:: @@ -29,10 +39,50 @@ html.py :Writer: HTML The ``html.py`` front end reads standalone reStructuredText source -files and produces HTML 4 (XHTML 1) output. It inserts a link to a -cascading stylesheet (``.css`` file), ``default.css`` unless specified -by a "--stylesheet" command-line option or in a configuration file. -The ``tools/default.css`` stylesheet is provided for basic use. +files and produces HTML 4 (XHTML 1) output compatible with modern +browsers. For example, to process a reStructuredText file +"``test.txt``" into HTML:: + + html.py test.txt test.html + +In fact, there *is* a "``test.txt``" file in the "``tools``" +directory. It contains "at least one example of each reStructuredText +construct", including intentional errors. Use it to put the system +through its paces and compare input to output. + +Now open the "``test.html``" file in your favorite browser to see the +results. To get a footer with a link to the source file, date & time +of processing, and links to the Docutils projects, add some options:: + + html.py -stg test.txt test.html + + +Stylesheets +----------- + +``html.py`` inserts into the generated HTML a link to a cascading +stylesheet, defaulting to "``default.css``" (override with a +"``--stylesheet``" command-line option or with a configuration file). +The "``tools/default.css``" stylesheet is provided for basic use. To +experiment with styles, rather than editing the default stylesheet +(which will be updated as the project evolves), it is recommended to +use the "``@import``" statement to create a "wrapper" stylesheet. For +example, a "``my.css``" stylesheet could contain the following:: + + @import url(default.css); + + h1, h2, h3, h4, h5, h6, p.topic-title { + font-family: sans-serif } + +Generate HTML with the following command:: + + html.py -stg --stylesheet my.css test.txt test.html + +When viewed in a browser, the new "wrapper" stylesheet will change the +typeface family of titles to "sans serif", typically Helvetica or +Arial. Other styles will not be affected. Styles in wrapper +stylesheets override styles in imported stylesheets, enabling +incremental experimentation. pep.py @@ -44,17 +94,18 @@ pep.py ``pep.py`` reads a new-style PEP (marked up with reStructuredText) and produces HTML. It requires a template file and a stylesheet. By -default, it makes use of a ``pep-html-template`` file and a -``default.css`` stylesheet in the current directory, but these can be -overridden by command-line options or configuration files. The -``tools/stylesheets/pep.css`` stylesheet is intended specifically for -PEP use. +default, it makes use of a "``pep-html-template``" file and a +"``default.css``" stylesheet in the current directory, but these can +be overridden by command-line options or configuration files. The +"``tools/stylesheets/pep.css``" stylesheet is intended specifically +for PEP use. -The ``docutils.conf`` `configuration file`_ in the "``spec``" +The "``docutils.conf``" `configuration file`_ in the "``spec``" directory of Docutils contains a default setup for use in processing -the PEP files there (``spec/pep-*.txt``) into HTML. It specifies -defaults of ``tools/pep-html-template`` and -``tools/stylesheets/pep.css``. +the PEP files there (``spec/pep-*.txt``) into HTML. It specifies a +default template (``tools/pep-html-template``) and a default +stylesheet (``tools/stylesheets/pep.css``). See Stylesheets_ above +for more information. pep2html.py @@ -70,7 +121,12 @@ beginning of a PEP text file to determine the format (old-style indented or new-style reStructuredText) and processes accordingly. Since it does not use the Docutils front end mechanism (the common command-line options are not supported), it must be configured using -`configuration files`_. +`configuration files`_. The template and stylesheet requirements of +``pep2html.py`` are the same as those of `pep.py`_ above. + +Arguments to ``pep2html.py`` may be a list of PEP numbers or .txt +files. If no arguments are given, all files of the form +"``pep-*.txt``" are processed. docutils-xml.py @@ -107,12 +163,12 @@ quicktest.py :Writer: N/A The ``quicktest.py`` tool is used for testing the reStructuredText -parser. It does not use the Docutils Reader/Writer mechanism. -Rather, it does its own I/O and calls the parser directly. No -transforms are applied to the parsed document. Various forms output -are possible: +parser. It does not use a Docutils Reader or Writer or the standard +Docutils command-line options. Rather, it does its own I/O and calls +the parser directly. No transforms are applied to the parsed +document. Various forms output are possible: -- Pretty-printed pseudo-XML +- Pretty-printed pseudo-XML (default) - Test data (Python list of input and pseudo-XML output strings; useful for creating new test cases) - Pretty-printed native XML @@ -195,148 +251,125 @@ Configuration File Entries -------------------------- The entry names listed below may be specified in `configuration -files`_ (hyphens may be used in place of underscores). Some knowledge -of Python_ is assumed for some attributes. +files`_. Hyphens may be used in place of underscores in entry names. +Some knowledge of Python_ is assumed for some attributes. ==================== ================================================ -Entry Name Description and Command-Line Options +Config Entry Name Description ==================== ================================================ datestamp Include a time/datestamp in the document footer. Contains a format string for ``time.strftime``. - Default: None. - - ``--date, -d, --time, -t, --no-datestamp`` - + Default: None. Options: ``--date, -d, --time, + -t, --no-datestamp``. +-------------------- ------------------------------------------------ debug Report debug-level system messages. - Default: don't (None). - - ``--debug, --no-debug`` - + Default: don't (None). Options: ``--debug, + --no-debug``. +-------------------- ------------------------------------------------ dump_internals Hidden option: At the end of processing, print out all internal attributes of the document (``document.__dict__``). - Default: don't (None). - - ``--dump-internals`` - + Default: don't (None). Options: + ``--dump-internals``. +-------------------- ------------------------------------------------ footnote_backlinks Enable or disable backlinks from footnotes and citations to their references. - Default: enabled (1). - - ``--footnote-backlinks, --no-footnote-backlinks`` - + Default: enabled (1). Options: + ``--footnote-backlinks, + --no-footnote-backlinks``. +-------------------- ------------------------------------------------ generator Include a "Generated by Docutils" credit and link in the document footer. - Default: off (None). - - ``--generator, -g, --no-generator`` - + Default: off (None). Options: ``--generator, + -g, --no-generator``. +-------------------- ------------------------------------------------ halt_level Set the threshold at or above which system messages are converted to exceptions, halting execution immediately. - Default: severe (4). - - ``--halt, --strict`` - + Default: severe (4). Options: ``--halt, + --strict``. +-------------------- ------------------------------------------------ indents XML-specific: Generate XML with indents and newlines. - Default: None. - - ``--indents`` - -input_encoding Default: auto-detect (None). - - ``--input-encoding, -i`` - -language_code Default: English ("en"). - - ``--language, -l`` - + Default: None. Options: ``--indents``. +-------------------- ------------------------------------------------ +input_encoding Default: auto-detect (None). Options: + ``--input-encoding, -i``. +-------------------- ------------------------------------------------ +language_code Default: English ("en"). Options: ``--language, + -l``. +-------------------- ------------------------------------------------ newlines XML-specific: Generate XML with newlines before and after tags. - Default: None. - - ``--newlines`` - + Default: None. Options: ``--newlines``. +-------------------- ------------------------------------------------ no_random PEP/HTML-specific hidden option: Workaround for platforms which core-dump on "``import random``". - Default: random enabled (None). - - ``--no-random`` - -output_encoding Default: UTF-8. - - ``--output-encoding, -o`` - + Default: random enabled (None). Options: + ``--no-random``. +-------------------- ------------------------------------------------ +output_encoding Default: UTF-8. Options: ``--output-encoding, + -o``. +-------------------- ------------------------------------------------ pep_home PEP/HTML-specific: Home URL prefix for PEPs. - Default: current directory ("."). - - ``--pep-home`` - + Default: current directory ("."). Options: + ``--pep-home``. +-------------------- ------------------------------------------------ pep_stylesheet PEP/HTML-specific: Overrides HTML stylesheet. - Default: None. - - ``--pep-stylesheet`` - + Default: None. Options: ``--pep-stylesheet``. +-------------------- ------------------------------------------------ pep_template PEP/HTML-specific: PEP template file. - Default: "pep-html-template". - - ``--pep-template`` - + Default: "pep-html-template". Options: + ``--pep-template``. +-------------------- ------------------------------------------------ python_home PEP/HTML-specific: Python's home URL. - Default: parent directory (".."). - - ``--python-home`` - + Default: parent directory (".."). Options: + ``--python-home``. +-------------------- ------------------------------------------------ report_level Set verbosity threshold at or above which system messages are reported. - Default: warning (2). - - ``--report, -r, --verbose`` - + Default: warning (2). Options: ``--report, -r, + --verbose``. +-------------------- ------------------------------------------------ source_link Include a "View document source" link in the document footer. - Default: don't (None). - - ``--source-link, --no-source-link`` - + Default: don't (None). Options: + ``--source-link, --no-source-link``. +-------------------- ------------------------------------------------ stylesheet HTML-specific. - Default: "default.css". - - ``--stylesheet`` - + Default: "default.css". Options: + ``--stylesheet``. +-------------------- ------------------------------------------------ toc_backlinks Enable backlinks from section titles to table of contents entries ("entry"), to the top of the TOC ("top"), or disable ("none"). - Default: "entry". - + Default: "entry". Options: ``--toc-entry-backlinks, --toc-top-backlinks, - --no-toc-backlinks`` - + --no-toc-backlinks``. +-------------------- ------------------------------------------------ warning_stream Send the output of system messages (warnings) to a file. - Default: stderr (None). - - ``--warnings`` + Default: stderr (None). Options: + ``--warnings``. ==================== ================================================ -- cgit v1.2.1 From a1713e3ba0b936004190f616c62f2189e0953b59 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:42:23 +0000 Subject: Added "Dedication" bibliographic field mappings. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@376 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/en.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/languages/en.py b/docutils/languages/en.py index 5b97dadb7..8488a902b 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -26,6 +26,7 @@ labels = { 'status': 'Status', 'date': 'Date', 'copyright': 'Copyright', + 'dedication': 'Dedication', 'abstract': 'Abstract', 'attention': 'Attention!', 'caution': 'Caution!', @@ -49,6 +50,7 @@ bibliographic_fields = { 'status': nodes.status, 'date': nodes.date, 'copyright': nodes.copyright, + 'dedication': nodes.topic, 'abstract': nodes.topic} """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" -- cgit v1.2.1 From 674653b218bfaa9ebe3f73f28b7dc1c744e1ab54 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:45:39 +0000 Subject: Added support for "Dedication" and generic bibliographic fields. (Not tested yet.) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@377 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 54 +++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index f61e828a1..1586bec5a 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -131,10 +131,11 @@ class DocTitle(Transform): subtitle[:] = subsection[0][:] document = self.document document[:] = (document[:1] # document title - + [subtitle] - + document[1:index] # everything that was in the document - # before the section - + subsection[1:]) # everything that was in the subsection + + [subtitle] + # everything that was before the section: + + document[1:index] + # everything that was in the subsection: + + subsection[1:]) return 1 def candidate_index(self): @@ -164,8 +165,9 @@ class DocInfo(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 the - abstract, which becomes a "topic" element after "docinfo"). + 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:: @@ -234,19 +236,16 @@ class DocInfo(Transform): if isinstance(candidate, nodes.field_list): biblioindex = document.first_child_not_matching_class( nodes.Titular) - nodelist, remainder = self.extract_bibliographic(candidate) - if remainder: - document[index] = remainder - else: - del document[index] + nodelist = self.transform_bibliographic(candidate) + del document[index] # untransformed field list (candidate) document[biblioindex:biblioindex] = nodelist return def extract_bibliographic(self, field_list): docinfo = nodes.docinfo() - remainder = [] bibliofields = self.language.bibliographic_fields - abstract = None + labels = self.language.labels + topics = {'dedication': None, 'abstract': None} for field in field_list: try: name = field[0][0].astext() @@ -265,29 +264,25 @@ class DocInfo(Transform): if issubclass(biblioclass, nodes.authors): self.extract_authors(field, name, docinfo) elif issubclass(biblioclass, nodes.topic): - if abstract: + if topics[normedname]: field[-1] += self.document.reporter.warning( - 'There can only be one abstract.') + 'There can only be one "%s" field.' % name) raise TransformError - title = nodes.title( - name, self.language.labels['abstract']) - abstract = nodes.topic('', title, CLASS='abstract', - *field[1].children) + title = nodes.title(name, labels[normedname]) + topics[normedname] = biblioclass( + '', title, CLASS='normedname', *field[1].children) else: docinfo.append(biblioclass('', *field[1].children)) except TransformError: - remainder.append(field) + docinfo.append(field) continue nodelist = [] if len(docinfo) != 0: nodelist.append(docinfo) - if abstract: - nodelist.append(abstract) - if remainder: - field_list[:] = remainder - else: - field_list = None - return nodelist, field_list + 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: @@ -303,9 +298,8 @@ class DocInfo(Transform): 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) + 'Cannot extract bibliographic field "%s" containing ' + 'anything other than a single paragraph.' % name) return None return 1 -- cgit v1.2.1 From 6b056f9e44a429f6f1f6641e37dc383a02a97d42 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:48:12 +0000 Subject: Added support for generic bibliographic fields. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@378 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/docutils.dtd | 1 + docutils/writers/html4css1.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 80e54b084..5d6ec6ad6 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -103,6 +103,7 @@ resolve to either an internal or external reference. <!ENTITY % bibliographic.elements " author | authors | organization | contact | version | revision | status | date | copyright + | field %additional.bibliographic.elements; "> <!ENTITY % additional.structural.elements ""> diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0f205838d..0903a7b59 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -88,6 +88,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.colspecs = [] self.compact_p = 1 self.compact_simple = None + self.in_docinfo = None def astext(self): return ''.join(self.head_prefix + self.head @@ -340,15 +341,17 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('<col class="docinfo-name" />\n' '<col class="docinfo-content" />\n' '<tbody valign="top">\n') + self.in_docinfo = 1 def depart_docinfo(self, node): self.body.append('</tbody>\n</table>\n') + self.in_docinfo = None def visit_docinfo_item(self, node, name): self.head.append('<meta name="%s" content="%s" />\n' % (name, self.attval(node.astext()))) self.body.append(self.starttag(node, 'tr', '')) - self.body.append('<td class="docinfo-name">%s:</td><td>\n' + self.body.append('<td class="docinfo-name">%s: </td><td>\n' % self.language.labels[name]) def depart_docinfo_item(self): @@ -427,7 +430,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_field(self, node): - self.body.append(self.starttag(node, 'tr', CLASS='field')) + self.body.append(self.starttag(node, 'tr', '', CLASS='field')) def depart_field(self, node): self.body.append('</tr>\n') @@ -460,7 +463,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</tbody>\n</table>\n') def visit_field_name(self, node): - self.body.append(self.starttag(node, 'td', '', CLASS='field-name')) + if self.in_docinfo: + class_name = 'docinfo-name' + else: + class_name = 'field-name' + self.body.append(self.starttag(node, 'td', '', CLASS=class_name)) def depart_field_name(self, node): """ -- cgit v1.2.1 From 08050d45bb78052da7109b32b46e29f8ef9f5021 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:50:20 +0000 Subject: Added "Dedication" and generic bibliographic fields. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@379 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 49 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 4c56bd25d..0e0941226 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -754,7 +754,7 @@ DTD elements: field_list, field, field_name, field_argument, field_body. Field lists are most often used as part of an extension syntax, such -as attributes for directives_, or database-like fields meant for +as attributes for directives_, or database-like records meant for further processing. They are not intended to be an alternative to definition lists. Applications of reStructuredText may recognize field names and transform fields or field bodies in certain contexts. @@ -815,7 +815,7 @@ Bibliographic Fields ```````````````````` DTD elements: docinfo, author, authors, organization, contact, -version, status, date, copyright, topic. +version, status, date, copyright, field, topic. When a field list is the first non-comment element in a document (after the document title, if there is one), it may have certain @@ -823,15 +823,15 @@ specific fields transformed to document bibliographic data. This bibliographic data corresponds to the front matter of a book, such as the title page and copyright page. -Certain field names (listed below) are recognized and transformed to -the corresponding DTD elements, most becoming child elements of the -"docinfo" element. No ordering is required of these fields, although -they may be rearranged to fit the document structure, as noted. -Unless otherwise indicated in the list below, each of the -bibliographic elements' field bodies may contain a single paragraph -only. Field bodies may be checked for `RCS keywords`_ and cleaned up. -Any unrecognized fields will remain in a generic field list in the -document body. +Certain registered field names (listed below) are recognized and +transformed to the corresponding DTD elements, most becoming child +elements of the "docinfo" element. No ordering is required of these +fields, although they may be rearranged to fit the document structure, +as noted. Unless otherwise indicated below, each of the bibliographic +elements' field bodies may contain a single paragraph only. Field +bodies may be checked for `RCS keywords`_ and cleaned up. Any +unrecognized fields will remain as generic fields in the docinfo +element. The registered bibliographic field names and their corresponding DTD elements are as follows: @@ -844,6 +844,7 @@ elements are as follows: - "Status": status. - "Date": date. - "Copyright": copyright. +- "Dedication": topic. - "Abstract": topic. The "Authors" field may contain either: a single paragraph consisting @@ -856,14 +857,17 @@ single name is interpreted as an "Author". If a single name contains a comma, end it with a semicolon to disambiguate: ":Authors: Doe, Jane;". -The "Abstract" field may contain arbitrary body elements. Only one -abstract is allowed. The abstract becomes a topic element with title -"Abstract" (or language equivalent) immediately following the docinfo -element. +The "Dedication" and "Abstract" fields may contain arbitrary body +elements. Only one of each is allowed. They become topic elements +with "Dedication" or "Abstract" titles (or language equivalents) +immediately following the docinfo element. -This field-name-to-element mapping can be extended, or replaced for -other languages. See the `DocInfo transform`_ implementation -documentation for details. +This field-name-to-element mapping can be replaced for other +languages. See the `DocInfo transform`_ implementation documentation +for details. + +Unregistered/generic fields may contain one or more paragraphs or +arbitrary body elements. RCS Keywords @@ -1277,8 +1281,13 @@ column. In that case, that line of text is parsed as a continuation line. For this reason, cells in the first column of new rows (*not* continuation lines) *must* contain some text; blank cells would lead to a misinterpretation. An empty comment ("..") is sufficient and -will be omitted from the processed output. Also, cells in the first -column are limited to one line of text. +will be omitted from the processed output. Also, this mechanism +limits cells in the first column to only one line of text. Use `grid +tables`_ if this limitation is unacceptable. + +Underlines of '-' may also be used to visually separate rows, even if +there are no column spans. This is especially useful in long tables, +where rows are many lines long. Blank lines are permitted within simple tables. Their interpretation depends on the context. Blank lines *between* rows are ignored. -- cgit v1.2.1 From f03140adb17f496124ff185331d2ab204eccb4fa Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:52:46 +0000 Subject: Added a second command-line argument (output file); cleaned up. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@380 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/quicktest.py | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/tools/quicktest.py b/tools/quicktest.py index 9517b95cc..133cfc815 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -26,9 +26,11 @@ quicktest.py: quickly test the restructuredtext parser. Usage:: - quicktest.py [options] [filename] + quicktest.py [options] [<source> [<destination>]] -``filename`` is the name of the file to use as input (default is stdin). +``source`` is the name of the file to use as input (default is stdin). +``destination`` is the name of the file to create as output (default is +stdout). Options: """ @@ -38,8 +40,8 @@ options = [('pretty', 'p', ('test', 't', 'output test-ready data (input & expected output, ' 'ready to be copied to a parser test module)'), ('rawxml', 'r', 'output raw XML'), - ('styledxml=', 's', 'output raw XML with XSL style sheet reference ' - '(filename supplied in the option argument)'), + ('styledxml=', 's', 'output raw XML with XSL style sheet ' + 'reference (filename supplied in the option argument)'), ('xml', 'x', 'output pretty XML (indented)'), ('attributes', '', 'dump document attributes after processing'), ('debug', 'd', 'debug mode (lots of output)'), @@ -74,8 +76,8 @@ def _styledxml(input, document, optargs): docnode = document.asdom().childNodes[0] return '%s\n%s\n%s' % ( '<?xml version="1.0" encoding="ISO-8859-1"?>', - '<?xml-stylesheet type="text/xsl" href="%s"?>' % optargs['styledxml'], - docnode.toxml()) + '<?xml-stylesheet type="text/xsl" href="%s"?>' + % optargs['styledxml'], docnode.toxml()) def _prettyxml(input, document, optargs): return document.asdom().toprettyxml(' ', '\n') @@ -96,7 +98,7 @@ def _test(input, document, optargs): def escape(text): """ - Return `text` in a form compatible with triple-double-quoted Python strings. + Return `text` in triple-double-quoted Python string form. """ text = text.replace('\\', '\\\\') # escape backslashes text = text.replace('"""', '""\\"') # break up triple-double-quotes @@ -154,33 +156,36 @@ def posixGetArgs(argv): optargs['debug'] = 1 else: raise getopt.GetoptError, "getopt should have saved us!" - if len(args) > 1: - print "Only one file at a time, thanks." + if len(args) > 2: + print 'Maximum 2 arguments allowed.' usage() sys.exit(1) - if len(args) == 1: - inputFile = open(args[0]) - else: - inputFile = sys.stdin - return inputFile, outputFormat, optargs + inputFile = sys.stdin + outputFile = sys.stdout + if args: + inputFile = open(args.pop(0)) + if args: + outputFile = open(args.pop(0), 'w') + return inputFile, outputFile, outputFormat, optargs def macGetArgs(): import EasyDialogs EasyDialogs.Message("""\ -In the following window, please: +Use the next dialog to build a command line: -1. Choose an output format from the "Option" list. -2. Click "Add" (if you don't, the default format will - be "pretty"). -3. Click "Add existing file..." and choose an input file. -4. Click "OK".""") +1. Choose an output format from the [Option] list +2. Click [Add] +3. Choose an input file: [Add existing file...] +4. Save the output: [Add new file...] +5. [OK]""") optionlist = [(longopt, description) for (longopt, shortopt, description) in options] - argv = EasyDialogs.GetArgv(optionlist=optionlist, addnewfile=0, addfolder=0) + argv = EasyDialogs.GetArgv(optionlist=optionlist, addfolder=0) return posixGetArgs(argv) def main(): - inputFile, outputFormat, optargs = getArgs() # process cmdline arguments + # process cmdline arguments: + inputFile, outputFile, outputFormat, optargs = getArgs() options = OptionParser().get_default_values() options.debug = optargs['debug'] parser = Parser() @@ -188,7 +193,7 @@ def main(): document = new_document(options) parser.parse(input, document) output = format(outputFormat, input, document, optargs) - print output, + outputFile.write(output) if optargs['attributes']: import pprint pprint.pprint(document.__dict__) -- cgit v1.2.1 From fe85dac3bdde0869b81347eca18a300a881940e8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:54:33 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@381 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 19 +++++++++++++++---- README.txt | 36 ++++++++++++++++-------------------- docs/dev/todo.txt | 23 +++++++++++++---------- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ae64f6604..90b313259 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -144,6 +144,9 @@ Specific: * 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. @@ -204,9 +207,11 @@ Specific: * 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. +* 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. @@ -257,6 +262,7 @@ Specific: - 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. * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). @@ -281,6 +287,7 @@ Specific: - 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". @@ -332,6 +339,7 @@ Specific: - 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). @@ -371,7 +379,10 @@ Specific: * 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. +* 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. diff --git a/README.txt b/README.txt index 011e7f11f..d1bc3b5de 100644 --- a/README.txt +++ b/README.txt @@ -41,25 +41,20 @@ Project Files & Directories * docutils: The project source directory, installed as a Python package. -* docs: The project user documentation directory. The docs/rst - directory contains reStructuredText user docs. +* docs: The project user documentation directory. Contains the + following documents: + + - docs/tools.txt: Docutils Front-End Tools + - docs/rst/quickstart.txt: A ReStructuredText Primer + - docs/rst/quickref.html: Quick reStructuredText (HTML only) * spec: The project specification directory. Contains PEPs (Python Enhancement Proposals), XML DTDs (document type definitions), and - other documents. The spec/rst directory contains the + other documents. The ``spec/rst`` directory contains the reStructuredText specification. -* tools: Directory for standalone scripts that use reStructuredText. - - - quicktest.py: Input reStructuredText, output pretty-printed - pseudo-XML and various other forms. - - - publish.py: A minimal example of a complete Docutils system, using - the "standalone" reader and "pformat" writer. - - - html.py: Read standalone reStructuredText documents and write - HTML4/CSS1. Uses the default.css stylesheet (but can be - overridden). +* tools: Directory for Docutils front-end tools. See docs/tools.txt + for documentation. * test: Unit tests; ``test/alltests.py`` runs all the tests. Not required to use the software, but very useful if you're planning to @@ -69,8 +64,8 @@ Project Files & Directories Installation ============ -The first step is to expand the .tar.gz or .tgz archive. It contains -a distutils setup file "setup.py". OS-specific installation +The first step is to expand the ``.tar.gz`` or ``.tgz`` archive. It +contains a distutils setup file "setup.py". OS-specific installation instructions follow. GNU/Linux, Unix, MacOS X, etc. @@ -109,8 +104,8 @@ Windows If your system is set up to run Python when you double-click on .py files, you can run install.py to do the same as the above. -MacOS ------ +MacOS 8/9 +--------- 1. Open the folder containing the expanded archive. @@ -139,11 +134,12 @@ Start with the html.py and publish.py front-end tools from the unpacked "tools" subdirectory. Both 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. +on options and arguments. See ``docs/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). +extensive inline documentation (in reStructuredText format of course). Contributions are welcome! diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a0b445f26..e53f96215 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -116,6 +116,15 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? +- Get the "--source-link" option (or a variation) to produce relative + links, like in this case:: + + cd tools + html.py -s ../spec/rst/problems.txt ../spec/rst/problems.html + + The source link should refer to "problems.txt" (relative to + "problems.html"), not "../spec/rst/problems.txt" which it does now. + Specification ------------- @@ -567,16 +576,6 @@ HTML Writer - @@@ Construct a _`templating system`, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. -- If a list's items contain single paragraphs only, omit the <P> tags? - Recursively? (if item == list whose items are single paragraphs - only...) Optional, with "--compact-lists" and "--no-compact-lists"? - Should only simple lists be compacted, or should the first paragraph - of all list items lack a <p> (perhaps "--compact-all-lists" and - "--compact-simple-lists")? - - Tried it. Twice. Not easy. If you're interested, email me for a - copy of the patches. - - Add more support for <link> elements, especially for navigation bars. @@ -629,6 +628,10 @@ Front-End Tools - Parameterize help text & defaults somehow? Perhaps a callback? Or initialize ``cmdline_options`` in ``__init__``? +- Write a tool (perhaps ``html-all.py`` or ``htmldocs.py``) which + generates .html from all the .txt files in the project. It could + even be run by setup.py as a final step! + Project Policies ================ -- cgit v1.2.1 From 2a12c4edb207059ea690a10f90be2aa1d5b09f32 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 03:55:25 +0000 Subject: bug squashed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@382 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 1586bec5a..1e8c988cd 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -236,7 +236,7 @@ class DocInfo(Transform): if isinstance(candidate, nodes.field_list): biblioindex = document.first_child_not_matching_class( nodes.Titular) - nodelist = self.transform_bibliographic(candidate) + nodelist = self.extract_bibliographic(candidate) del document[index] # untransformed field list (candidate) document[biblioindex:biblioindex] = nodelist return -- cgit v1.2.1 From e94353235397c0d258a15cff63802e210fc5ddd9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 04:23:56 +0000 Subject: bug fixes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@383 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 1e8c988cd..3a3cc6e5f 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -270,7 +270,7 @@ class DocInfo(Transform): raise TransformError title = nodes.title(name, labels[normedname]) topics[normedname] = biblioclass( - '', title, CLASS='normedname', *field[1].children) + '', title, CLASS=normedname, *field[1].children) else: docinfo.append(biblioclass('', *field[1].children)) except TransformError: -- cgit v1.2.1 From d9458f36b0b34f9582d360a7342825f04c87d7ae Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 04:24:50 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@384 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms/test_docinfo.py | 51 +++++++++++++++++------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index a734bfd3b..9c74cbfed 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -46,6 +46,14 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ 1 <date> 2001-08-11 + <field> + <field_name> + Parameter + <field_argument> + i + <field_body> + <paragraph> + integer <topic class="abstract"> <title> Abstract @@ -55,15 +63,6 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ It is automatically moved to the end of the other bibliographic elements. <comment> Bibliographic element extraction. - <field_list> - <field> - <field_name> - Parameter - <field_argument> - i - <field_body> - <paragraph> - integer """], ["""\ .. Bibliographic element extraction. @@ -86,16 +85,6 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ me@my.org <version> 1 - <date> - 2001-08-11 - <topic class="abstract"> - <title> - Abstract - <paragraph> - Abstract 1. - <comment> - Bibliographic element extraction. - <field_list> <field> <field_name> Abstract @@ -104,7 +93,9 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ Abstract 2 (should generate a warning). <system_message level="2" type="WARNING"> <paragraph> - There can only be one abstract. + There can only be one "Abstract" field. + <date> + 2001-08-11 <field> <field_name> Parameter @@ -113,6 +104,13 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <field_body> <paragraph> integer + <topic class="abstract"> + <title> + Abstract + <paragraph> + Abstract 1. + <comment> + Bibliographic element extraction. """], ["""\ :Author: - must be a paragraph @@ -127,12 +125,6 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ """\ <document> <docinfo> - <status> - a \n\ - <emphasis> - simple - paragraph - <field_list> <field> <field_name> Author @@ -144,6 +136,11 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <system_message level="2" type="WARNING"> <paragraph> Cannot extract bibliographic field "Author" containing anything other than a single paragraph. + <status> + a \n\ + <emphasis> + simple + paragraph <field> <field_name> Date @@ -245,7 +242,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ """, """\ <document> - <field_list> + <docinfo> <field> <field_name> Authors -- cgit v1.2.1 From 983fbe0421320e73abaf91159e3eac91db386a2e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 04:33:42 +0000 Subject: Added a style for dedications. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@385 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 8d880c7cb..495188af2 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -47,6 +47,15 @@ div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + div.figure { margin-left: 2em } -- cgit v1.2.1 From f9911cad64b1b288d54f2b021baef80d0b07c5f6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 04:55:34 +0000 Subject: vertical whitespace optimization docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@386 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0903a7b59..52e739145 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -56,6 +56,44 @@ class Writer(writers.Writer): class HTMLTranslator(nodes.NodeVisitor): + """ + This HTML writer has been optimized to produce visually compact + HTML (less vertical whitespace). HTML's mixed content models + allow list items to contain "<li><p>body elements</p></li>" or + "<li>just text</li>" or even "<li>text<p>and body + elements</p>combined</li>", each with different effects. It would + be best to stick with strict body elements in list items, but they + affect vertical spacing in browsers (although they really + shouldn't). + + Here is an outline of the optimization: + + - Check for and omit <p> tags in "simple" lists: list items + contain either a single paragraph, a nested simple list, or a + paragraph followed by a nested simple list. This means that + this list can be compact: + + - Item 1. + - Item 2. + + But this list cannot be compact: + + - Item 1. + + This second paragraph forces space between list items. + + - Item 2. + + - In non-list contexts, omit <p> tags on a paragraph if that + paragraph is the only child of its parent (footnotes & citations + are allowed a label first). + + - Regardless of the above, in definitions, table cells, field + bodies, option descriptions, and list items, mark the first + child with 'class="first"' if it is a paragraph. The stylesheet + sets the top margin to 0 for these paragraphs. + """ + xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' doctype = '<!DOCTYPE html' \ ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' \ -- cgit v1.2.1 From 07501dc56f11f966a74871ecc01a12af19d0cc25 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 04:56:06 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@387 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 90b313259..702797496 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -369,6 +369,7 @@ Specific: * tools/default.css: - Added support for ``header`` and ``footer`` elements. + - Added styles for "Dedication" topics (biblio fields). * tools/docutils-xml.py: Added to project. -- cgit v1.2.1 From 7e7572ebbb3def8f25b4108c56c10cbf75abe073 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 05:06:06 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@388 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0287.txt | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 93e36bffb..a076b61ce 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -55,11 +55,11 @@ to produce complex documents, and extensible so that there are few limits. Of course, to write reStructuredText documents some prior knowledge is required. -The reStructuredText parser is available now. The Docutils project is -at the point where standalone reStructuredText documents can be -converted to HTML; other output format writers will become available -over time. Work is progressing on a Python source "Reader" which will -implement auto-documentation from docstrings. Authors of existing +The reStructuredText parser is available now. Standalone +reStructuredText documents and PEPs can be converted to HTML; other +output format writers will become available over time. Work is +progressing on a Python source "Reader" which will implement +auto-documentation from docstrings. Authors of existing auto-documentation tools are encouraged to integrate the reStructuredText parser into their projects, or better yet, to join forces to produce a world-class toolset for the Python standard @@ -140,7 +140,8 @@ a) Keep the existing PEP section structure constructs (one-line b) Replace the PEP section structure constructs with the reStructuredText syntax. Section headers will require underlines, subsections will be supported out of the box, and body text need - not be indented (except for block quotes). + not be indented (except for block quotes). This strategy is + recommended, and has already been implemented. Support for RFC 2822 headers has been added to the reStructuredText parser for PEPs (unambiguous given a specific context: the first @@ -622,18 +623,18 @@ Questions & Answers 6. The existing pep2html.py script converts the existing PEP format to HTML. How will the new-format PEPs be converted to HTML? - One of the deliverables of the Docutils_ project will be a new - version of pep2html.py with integrated reStructuredText parsing. - The Docutils project will support PEPs with a "PEP Reader" - component, including all functionality currently in pep2html.py - (auto-recognition of PEP & RFC references). + A new version of pep2html.py with integrated reStructuredText + parsing has been completed. The Docutils project supports PEPs + with a "PEP Reader" component, including all functionality + currently in pep2html.py (auto-recognition of PEP & RFC references, + email masking, etc.). 7. Who's going to convert the existing PEPs to reStructuredText? PEP authors or volunteers may convert existing PEPs if they like, but there is no requirement to do so. The reStructuredText-based PEPs will coexist with the old PEP standard. The pep2html.py - mentioned in answer 6 will process both old and new standards. + mentioned in answer 6 processes both old and new standards. 8. Why use reStructuredText for README and other ancillary files? -- cgit v1.2.1 From 69f25103de91c8f4747c791d0e17656e84175eca Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 14:53:16 +0000 Subject: Identify backrefs. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@389 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 52e739145..63773ed30 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -544,12 +544,14 @@ class HTMLTranslator(nodes.NodeVisitor): backrefs = node['backrefs'] if len(backrefs) == 1: self.context.append(('</a>', '')) - self.context.append(('<a href="#%s">' % backrefs[0],)) + self.context.append(('<a class="fn-backref" href="#%s">' + % backrefs[0],)) else: i = 1 backlinks = [] for backref in backrefs: - backlinks.append('<a href="#%s">%s</a>' % (backref, i)) + backlinks.append('<a class="fn-backref" href="#%s">%s</a>' + % (backref, i)) i += 1 self.context.append(('', '(%s) ' % ', '.join(backlinks))) self.context.append(('',)) @@ -912,7 +914,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.starttag(node, 'h%s' % self.section_level, '')) context = '' if node.hasattr('refid'): - self.body.append('<a href="#%s">' % node['refid']) + self.body.append('<a class="toc-backref" href="#%s">' + % node['refid']) context = '</a>' self.context.append('%s</h%s>\n' % (context, self.section_level)) -- cgit v1.2.1 From ee4147188574574db105b733162e3ce6c854555e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 14:56:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@390 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 ++----- docs/peps/pep-0287.txt | 4 +++- tools/stylesheets/default.css | 2 +- tools/stylesheets/pep.css | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 702797496..51c56ab5d 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -82,7 +82,7 @@ Specific: * 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. + processing (installed locally as docutils/optik.py). * docutils/io.py: Added to project; uniform API for a variety of input output mechanisms. @@ -115,10 +115,6 @@ Specific: package, with added option groups and other modifications. The use of this module is probably only temporary. -* docutils/OptionParser.py: Added to project. Combined from the Optik - package, with no modifications. This module will probably - eventually take over from optik.py. Not used at present. - * docutils/statemachine.py: - Added ``runtime_init`` method to ``StateMachine`` and ``State``. @@ -263,6 +259,7 @@ Specific: and footnote/citation backlinks. - Added support for optional footnote/citation backlinks. - Added support for generic bibliographic fields. + - Identify backrefs. * docutils/writers/pep_html.py: Added to project; HTML Writer for PEPs (subclass of ``html4css1.Writer``). diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index a076b61ce..346a3f2a7 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -548,6 +548,8 @@ Questions & Answers This PEP proposes adding frungible doodads [1] to the core. It extends PEP 9876 [2] via the BCA [3] mechanism. + ... + References and Footnotes [1] http://www.example.org/ @@ -641,7 +643,7 @@ Questions & Answers The reasoning given for PEPs in answer 4 above also applies to README and other ancillary files. By adopting a standard markup, these files can be converted to attractive cross-referenced HTML - and put up on python.org. Developers of Python projects can also + and put up on python.org. Developers of other projects can also take advantage of this facility for their own documentation. 9. Won't the superficial similarity to existing markup conventions diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 495188af2..a7842ed3c 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -15,7 +15,7 @@ a.footnote-reference { a.target { color: blue } -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { +a.toc-backref { text-decoration: none ; color: black } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 3a41e6b58..601872253 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -50,7 +50,7 @@ a.footnote-reference { a.target { color: blue } -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { +a.toc-backref { text-decoration: none ; color: black } -- cgit v1.2.1 From 61d204ba2bacd28ca39307302970bda873e053d8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 15:07:53 +0000 Subject: Footer fiddling. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@391 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 63773ed30..2110c4424 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -525,7 +525,8 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footer(self, node): start = self.context.pop() - footer = ([self.starttag(node, 'div', CLASS='footer'), '<hr />\n'] + footer = (['<hr class="footer"/>\n', + self.starttag(node, 'div', CLASS='footer')] + self.body[start:] + ['</div>\n']) self.body_suffix[:0] = footer del self.body[start:] -- cgit v1.2.1 From 1cc7535a35c2fc5cd335e6c91aad7226f47ddb24 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 15:08:43 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@392 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 601872253..a38cb1d61 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -98,7 +98,7 @@ div.figure { div.footer, div.header { font-size: smaller } -div.footer p { +div.footer { margin-left: 1em ; margin-right: 1em } -- cgit v1.2.1 From 087383956c0c5aba2337ab961e66b3ef18e2445f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 15:49:37 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@393 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 759e11472..f9e2b7880 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -20,7 +20,13 @@ from docutils import optik class OptionParser(optik.OptionParser): """ - Parser for command-line and library use. The `cmdline_options` specification here and in other Docutils components are merged + Parser for command-line and library use. The `cmdline_options` + specification here and in other Docutils components are merged to + build the set of command-line options for this process. + + Common options (defined below) and component-specific options must + not conflict. Short options are reserved for common options, and + components are restrict to using long options. """ threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split() -- cgit v1.2.1 From c32cc0f4c2155740d72c24cd5ff5d01d6e7c15bb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 15:51:02 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@394 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e53f96215..07d9c95cf 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -73,10 +73,6 @@ General - Howto: Directives - User docs. - - - How to use the front-end tools (docs/tools.txt). - - - Configuration file syntax & recognized entries. - Refactor @@ -143,12 +139,20 @@ Specification - Rework PEP 257, separating style from spec from tools, wrt Docutils? See Doc-SIG from 2001-06-19/20. -- Add layout component to framework? Or part of the writer? - - Once doctree.txt is fleshed out, how about breaking (most of) it up and putting it into nodes.py as docstrings? +PySource Reader +--------------- + +- Analyze Tony Ibbs' PySource code. + +- Analyze Doug Hellman's HappyDoc project. + +- Take the best ideas and integrate them into Docutils 0.3. + + reStructuredText Parser ----------------------- @@ -586,10 +590,6 @@ HTML Writer Front-End Tools --------------- -- Common and component-specific options must not conflict. Reserve - short options for the core, and restrict components to long - options? - - What about if we don't know which Reader and/or Writer we are going to use? If the Reader/Writer is specified on the command-line? (Will this ever happen?) @@ -628,9 +628,10 @@ Front-End Tools - Parameterize help text & defaults somehow? Perhaps a callback? Or initialize ``cmdline_options`` in ``__init__``? -- Write a tool (perhaps ``html-all.py`` or ``htmldocs.py``) which +- Write a tool (perhaps ``htmldocs.py`` or ``buildhtml.py``) which generates .html from all the .txt files in the project. It could - even be run by setup.py as a final step! + even be run by setup.py as a final step! Once PySource is there, + it can build .html from .py as well. Project Policies -- cgit v1.2.1 From 0fde6c336dc365cf31b5c0caf2087642a8af7c9d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Jul 2002 16:06:12 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@395 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 16 ++++++++-------- docs/dev/todo.txt | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 51c56ab5d..b47fa665b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -18,14 +18,14 @@ suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: Aahz, David Ascher, Fred Bremmer, Simon Budig, Adam Chodorowski, - Fred Drake, Dethe Elza, Jim Fulton, Peter Funk, Engelbert Gruber, - Simon Hefti, Doug Hellmann, Juergen Hermann, Tony Ibbs, Alan - Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre - Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, - Michel Pelletier, Sam Penrose, Tim Peters, Mark Pilgrim, Tavis - Rudd, Ollie Rutherfurd, Ueli Schlaepfer, Gunnar Schwant, tav, Bob - Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward - Welbourne, Ka-Ping Yee, Moshe Zadka + Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter Funk, + Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen Hermann, + Tony Ibbs, Alan Jaffray, Richard Jones, Garth Kidd, Daniel + Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken + Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, + Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli Schlaepfer, + Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van + Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 07d9c95cf..4dc22943c 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -148,7 +148,7 @@ PySource Reader - Analyze Tony Ibbs' PySource code. -- Analyze Doug Hellman's HappyDoc project. +- Analyze Doug Hellmann's HappyDoc project. - Take the best ideas and integrate them into Docutils 0.3. -- cgit v1.2.1 From fe66cb1cd619d5abd815be4b235b116cd3c43807 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 15:35:28 +0000 Subject: Added ``relative_uri(source, target)``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@396 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docutils/utils.py b/docutils/utils.py index 8b1d7ddf9..44a537667 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -13,6 +13,8 @@ Miscellaneous utilities for the documentation utilities. __docformat__ = 'reStructuredText' import sys +import os +import os.path from types import StringType, UnicodeType from docutils import ApplicationError, DataError from docutils import frontend, nodes @@ -347,3 +349,24 @@ def clean_rcs_keywords(paragraph, keyword_substitutions): if match: textnode.data = pattern.sub(substitution, textnode.data) return + +def relative_uri(source, target): + """ + Build and return a URI to `target`, relative to `source`. + + If there is no common prefix, return the absolute path to `target`. + """ + source_parts = os.path.abspath(source).split(os.sep) + target_parts = os.path.abspath(target).split(os.sep) + if source_parts[:2] != target_parts[:2]: + # Nothing in common between paths. Return absolute path. + return '/'.join(target_parts) + source_parts.reverse() + target_parts.reverse() + while source_parts[-1] == target_parts[-1]: + # Remove path components in common: + source_parts.pop() + target_parts.pop() + target_parts.reverse() + parts = ['..'] * (len(source_parts) - 1) + target_parts + return '/'.join(parts) -- cgit v1.2.1 From 52307a7656fe38d3f35126a9bd90170e4fd10912 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:20:00 +0000 Subject: Source & destination paths now returned inside option values object. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@397 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 7 ++++--- tools/pep2html.py | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index eb6f35d20..80344a793 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -120,10 +120,11 @@ class Publisher: option_spec, **defaults) if argv is None: argv = sys.argv[1:] - self.options, source, destination = option_parser.parse_args(argv) - self.source = self.source_class(self.options, source_path=source) + self.options = option_parser.parse_args(argv) + self.source = self.source_class(self.options, + source_path=self.options.source) self.destination = self.destination_class( - self.options, destination_path=destination) + self.options, destination_path=self.options.destination) def publish(self, argv=None, usage=None, description=None, option_spec=None): diff --git a/tools/pep2html.py b/tools/pep2html.py index d5d3221d0..49d925b37 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -273,7 +273,8 @@ def fix_rst_pep(infile, outfile): pub.set_reader(reader_name='pep', parser_name='restructuredtext', parser=None) pub.set_writer(writer_name='pep_html') - options = pub.set_options(generator=1, datestamp='%Y-%m-%d %H:%M UTC') + options = pub.set_options(source=infile.name, destination=outfile.name, + generator=1, datestamp='%Y-%m-%d %H:%M UTC') pub.source = io.FileIO(options, source=infile, source_path=infile.name) pub.destination = io.FileIO(options, destination=outfile, destination_path=outfile.name) -- cgit v1.2.1 From 00721f31c013181f753ed200b3fa0414f143f780 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:38:04 +0000 Subject: - Added ``store_multiple()`` option callback. - Added "--source-url" option. - Return source & destination path in option values object. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@398 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index f9e2b7880..f2be2d46a 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -17,6 +17,19 @@ import docutils from docutils import optik +def store_multiple(option, opt, value, parser, *args, **kwargs): + """ + Store multiple values in `parser.values`. (Option callback.) + + Store `None` for each attribute named in `args`, and store the value for + each key (attribute name) in `kwargs`. + """ + for attribute in args: + setattr(parser.values, attribute, None) + for key, value in kwargs.items(): + setattr(parser.values, key, value) + + class OptionParser(optik.OptionParser): """ @@ -53,11 +66,15 @@ class OptionParser(optik.OptionParser): ('Do not include a datestamp of any kind.', ['--no-datestamp'], {'action': 'store_const', 'const': None, 'dest': 'datestamp'}), - ('Include a "View document source" link.', + ('Include a "View document source" link (relative to destination).', ['--source-link', '-s'], {'action': 'store_true'}), + ('Use the supplied <url> for a "View document source" link; ' + 'implies --source-link.', + ['--source-url'], {'metavar': '<url>'}), ('Do not include a "View document source" link.', - ['--no-source-link'], {'action': 'store_false', - 'dest': 'source_link'}), + ['--no-source-link'], + {'action': 'callback', 'callback': store_multiple, + 'callback_args': ('source_link', 'source_url')}), ('Enable backlinks from section headers to table of contents ' 'entries. This is the default.', ['--toc-entry-backlinks'], @@ -158,8 +175,8 @@ class OptionParser(optik.OptionParser): def check_values(self, values, args): values.report_level = self.check_threshold(values.report_level) values.halt_level = self.check_threshold(values.halt_level) - source, destination = self.check_args(args) - return values, source, destination + values.source, values.destination = self.check_args(args) + return values def check_threshold(self, level): try: -- cgit v1.2.1 From dccdd3a5cb8b4a36c1d3e2aa5518efc58c00e055 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:39:57 +0000 Subject: Added "source", "destination", and "source_url" option attributes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@399 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index f0b183125..c56a7dda0 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -268,6 +268,10 @@ debug Report debug-level system messages. Default: don't (None). Options: ``--debug, --no-debug``. -------------------- ------------------------------------------------ +destination Path to output destination, set from positional + arguments. Default: stdout (None). No + command-line options. +-------------------- ------------------------------------------------ dump_internals Hidden option: At the end of processing, print out all internal attributes of the document (``document.__dict__``). @@ -346,12 +350,23 @@ report_level Set verbosity threshold at or above which system Default: warning (2). Options: ``--report, -r, --verbose``. -------------------- ------------------------------------------------ +source Path to input source, set from positional + arguments. Default: stdin (None). No + command-line options. +-------------------- ------------------------------------------------ source_link Include a "View document source" link in the - document footer. + document footer. URL will be relative to the + destination. Default: don't (None). Options: ``--source-link, --no-source-link``. -------------------- ------------------------------------------------ +source_url Use the supplied URL for a "View document + source" link. + + Default: None. Options: ``--source-uri, + --no-source-link``. +-------------------- ------------------------------------------------ stylesheet HTML-specific. Default: "default.css". Options: -- cgit v1.2.1 From efd006184800e755c1baef8b7fc5790bf301bb96 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:45:16 +0000 Subject: Changed "Decorations" transform to produce relative source links. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@400 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index e4ad65b48..9e58679bf 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -57,10 +57,15 @@ class Decorations(Transform): options = self.document.options if options.generator or options.datestamp or options.source_link: text = [] - if options.source_link and self.document.hasattr('source'): + if options.source_link and options.source or options.source_uri: + if options.source_uri: + source = options.source_uri + else: + source = utils.relative_uri(options.destination, + options.source) text.extend([ nodes.reference('', 'View document source', - refuri=self.document['source']), + refuri=source), nodes.Text('. ')]) if options.datestamp: datestamp = time.strftime(options.datestamp, time.gmtime()) -- cgit v1.2.1 From ae2521dfb7014eca7ac0d421c3a8f8658e1f0553 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:46:16 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@401 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/dev/todo.txt | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index b47fa665b..bc3e7f27b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -136,6 +136,7 @@ Specific: - Changed names of Reporter's thresholds: warning_level -> report_level; error_level -> halt_level. - Moved ``utils.id()`` to ``nodes.make_id()``. + - Added ``relative_uri(source, target)``. * docutils/languages/de.py: German mappings; added to project. Thanks to Gunnar Schwant for the translations. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4dc22943c..0ba2e863f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -112,15 +112,6 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -- Get the "--source-link" option (or a variation) to produce relative - links, like in this case:: - - cd tools - html.py -s ../spec/rst/problems.txt ../spec/rst/problems.html - - The source link should refer to "problems.txt" (relative to - "problems.html"), not "../spec/rst/problems.txt" which it does now. - Specification ------------- -- cgit v1.2.1 From ef63f320763f423632642e4b2aeb2b9570d4eedf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:49:48 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@402 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 9e58679bf..004923887 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -55,9 +55,10 @@ class Decorations(Transform): # @@@ Text is hard-coded for now. # Should be made dynamic (language-dependent). options = self.document.options - if options.generator or options.datestamp or options.source_link: + if options.generator or options.datestamp or options.source_link \ + or options.source_url: text = [] - if options.source_link and options.source or options.source_uri: + if options.source_link and options.source or options.source_url: if options.source_uri: source = options.source_uri else: -- cgit v1.2.1 From e13eaad4a71d8536f52ca0445ee27b9b4e214eec Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 17:51:05 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@403 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 004923887..bc5a1bb74 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -59,8 +59,8 @@ class Decorations(Transform): or options.source_url: text = [] if options.source_link and options.source or options.source_url: - if options.source_uri: - source = options.source_uri + if options.source_url: + source = options.source_url else: source = utils.relative_uri(options.destination, options.source) -- cgit v1.2.1 From c7021872c6b1e32f2c2443b715b8809a094997ee Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 18:36:34 +0000 Subject: Relative URLs for stylesheet links. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@405 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 12 +++++++----- docutils/writers/pep_html.py | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2110c4424..283edcac3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -108,14 +108,16 @@ class HTMLTranslator(nodes.NodeVisitor): def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - self.language = languages.get_language(document.options.language_code) + options = document.options + self.language = languages.get_language(options.language_code) self.head_prefix = [ - self.xml_declaration % document.options.output_encoding, + self.xml_declaration % options.output_encoding, self.doctype, - self.html_head % document.options.language_code, - self.content_type % document.options.output_encoding, + self.html_head % options.language_code, + self.content_type % options.output_encoding, self.generator, - self.stylesheet_link % document.options.stylesheet] + self.stylesheet_link % utils.relative_uri(options.destination, + options.stylesheet)] self.head = [] self.body_prefix = ['</head>\n<body>\n'] self.body = [] diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 2a0c273ea..9aff8d062 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -53,6 +53,7 @@ class Writer(html4css1.Writer): stylesheet = options.pep_stylesheet if stylesheet is None: stylesheet = options.stylesheet + stylesheet = utils.relative_uri(options.destination, stylesheet) pyhome = options.python_home pephome = options.pep_home if pyhome == '..': -- cgit v1.2.1 From 6e912150d2857fd9067754fbfb9d319f1f7b59c0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 18:40:19 +0000 Subject: omission git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@406 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- docutils/writers/pep_html.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 283edcac3..d1a8fda04 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -21,7 +21,7 @@ import sys import time import re from types import ListType -from docutils import writers, nodes, languages +from docutils import nodes, utils, writers, languages class Writer(writers.Writer): diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 9aff8d062..61689fd59 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -15,7 +15,7 @@ __docformat__ = 'reStructuredText' import sys #import random -from docutils import nodes, optik +from docutils import nodes, optik, utils from docutils.writers import html4css1 -- cgit v1.2.1 From 9d05481bb58063c956fc9c9bf910ee4ef7956b14 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 18:51:20 +0000 Subject: Moved from spec/ to tools/, since that's where processing is done now. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@407 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tools/docutils.conf diff --git a/tools/docutils.conf b/tools/docutils.conf new file mode 100644 index 000000000..5d53f9b7d --- /dev/null +++ b/tools/docutils.conf @@ -0,0 +1,6 @@ +[options] + +# These entries affect reStructuredText-style PEPs: +pep-stylesheet: stylesheets/pep.css +python-home: http://www.python.org +no-random: 1 -- cgit v1.2.1 From 0e1aadf8cc6ace83cb42ca97d89fa9d1649ad396 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 19:37:58 +0000 Subject: Added ``read_config_file()`` option callback & "--config" option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@408 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docutils/frontend.py b/docutils/frontend.py index f2be2d46a..100027497 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -29,6 +29,16 @@ def store_multiple(option, opt, value, parser, *args, **kwargs): for key, value in kwargs.items(): setattr(parser.values, key, value) +def read_config_file(option, opt, value, parser): + """ + Read a configuration file during option processing. (Option callback.) + """ + config = ConfigParser() + config.read(value) + if config.has_section('options'): + for entry in config.options('options'): + setattr(parser.values, entry, config.get('options', entry)) + class OptionParser(optik.OptionParser): @@ -126,6 +136,9 @@ class OptionParser(optik.OptionParser): ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': '<name>'}), + ('Read this configuration <file>.', + ['--config'], {'metavar': '<file>', 'type': 'string', + 'action': 'callback', 'callback': read_config_file}) ("Show this program's version number and exit.", ['--version'], {'action': 'version'}), ('Show this help message and exit.', -- cgit v1.2.1 From 22cd52f0533d812aa24cdc92226e148adf9d168e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 19:55:59 +0000 Subject: Made footer options persistent. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@410 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/docutils.conf b/tools/docutils.conf index 5d53f9b7d..88838eac6 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -1,5 +1,10 @@ [options] +# These entries affect all processing: +source-link: 1 +datestamp: %%Y-%%m-%%d %%H:%%M UTC +generator: 1 + # These entries affect reStructuredText-style PEPs: pep-stylesheet: stylesheets/pep.css python-home: http://www.python.org -- cgit v1.2.1 From fad349b8d9dac2aea4e20397ff4ff74143247622 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 19:58:29 +0000 Subject: comma git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@411 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 100027497..d841a3774 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -138,7 +138,7 @@ class OptionParser(optik.OptionParser): 'metavar': '<name>'}), ('Read this configuration <file>.', ['--config'], {'metavar': '<file>', 'type': 'string', - 'action': 'callback', 'callback': read_config_file}) + 'action': 'callback', 'callback': read_config_file}), ("Show this program's version number and exit.", ['--version'], {'action': 'version'}), ('Show this help message and exit.', -- cgit v1.2.1 From 77eae9bf49c5f60bd96f133b02499dc6034f25d0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Jul 2002 20:00:56 +0000 Subject: Single "%" is OK git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@412 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docutils.conf b/tools/docutils.conf index 88838eac6..26ddddb5c 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -2,7 +2,7 @@ # These entries affect all processing: source-link: 1 -datestamp: %%Y-%%m-%%d %%H:%%M UTC +datestamp: %Y-%m-%d %H:%M UTC generator: 1 # These entries affect reStructuredText-style PEPs: -- cgit v1.2.1 From dc4065c13ec599e83c726a55d343a2b63969bef3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 29 Jul 2002 02:21:01 +0000 Subject: Added "config" option attribute. Minor improvements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@415 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 54 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index c56a7dda0..58a0f0adb 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -199,8 +199,8 @@ Configuration Files Configuration files are used for persistent customization; they can be set once and take effect every time you use a front-end tool. -By default, Docutils checks three places for configuration files, in -the following order: +By default, Docutils checks the following places for configuration +files, in the following order: 1. ``/etc/docutils.conf``: This is a system-wide configuration file, applicable to all Docutils processing on the system. @@ -208,13 +208,17 @@ the following order: 2. ``./docutils.conf``: This is a project-specific configuration file, located in the current directory. The Docutils front end has to be executed from the directory containing this configuration file for - it to take effect. The project-specific configuration file - overrides the system-wide file. + it to take effect (note that this may have nothing to do with the + location of the source files). The project-specific configuration + file overrides the system-wide file. 3. ``~/.docutils``: This is a user-specific configuration file, located in the user's home directory. This file overrides both the system-wide and project-specific configuration files. +4. A configuration file may be explicitly specified with the + "--config" command-line option. + If more than one configuration file is found, all will be read but later entries will override earlier ones. For example, a "stylesheet" entry in a user-specific configuration file will override a @@ -257,6 +261,12 @@ Some knowledge of Python_ is assumed for some attributes. ==================== ================================================ Config Entry Name Description ==================== ================================================ +config Path to a configuration file to read (if it + exists). Settings may override defaults and + earlier settings. + + Default: None. Options: ``--config``. +-------------------- ------------------------------------------------ datestamp Include a time/datestamp in the document footer. Contains a format string for ``time.strftime``. @@ -292,9 +302,9 @@ generator Include a "Generated by Docutils" credit and Default: off (None). Options: ``--generator, -g, --no-generator``. -------------------- ------------------------------------------------ -halt_level Set the threshold at or above which system - messages are converted to exceptions, halting - execution immediately. +halt_level The threshold at or above which system messages + are converted to exceptions, halting execution + immediately. Default: severe (4). Options: ``--halt, --strict``. @@ -302,18 +312,21 @@ halt_level Set the threshold at or above which system indents XML-specific: Generate XML with indents and newlines. - Default: None. Options: ``--indents``. + Default: don't (None). Options: ``--indents``. -------------------- ------------------------------------------------ input_encoding Default: auto-detect (None). Options: ``--input-encoding, -i``. -------------------- ------------------------------------------------ -language_code Default: English ("en"). Options: ``--language, +language_code `ISO 639`_ 2-letter language code (3-letter + codes used only if no 2-letter code exists). + + Default: English ("en"). Options: ``--language, -l``. -------------------- ------------------------------------------------ newlines XML-specific: Generate XML with newlines before and after tags. - Default: None. Options: ``--newlines``. + Default: don't (None). Options: ``--newlines``. -------------------- ------------------------------------------------ no_random PEP/HTML-specific hidden option: Workaround for platforms which core-dump on "``import @@ -330,7 +343,8 @@ pep_home PEP/HTML-specific: Home URL prefix for PEPs. Default: current directory ("."). Options: ``--pep-home``. -------------------- ------------------------------------------------ -pep_stylesheet PEP/HTML-specific: Overrides HTML stylesheet. +pep_stylesheet PEP/HTML-specific: path to CSS stylesheet. + Overrides HTML stylesheet (``--stylesheet``). Default: None. Options: ``--pep-stylesheet``. -------------------- ------------------------------------------------ @@ -344,7 +358,7 @@ python_home PEP/HTML-specific: Python's home URL. Default: parent directory (".."). Options: ``--python-home``. -------------------- ------------------------------------------------ -report_level Set verbosity threshold at or above which system +report_level Verbosity threshold at or above which system messages are reported. Default: warning (2). Options: ``--report, -r, @@ -361,13 +375,13 @@ source_link Include a "View document source" link in the Default: don't (None). Options: ``--source-link, --no-source-link``. -------------------- ------------------------------------------------ -source_url Use the supplied URL for a "View document - source" link. +source_url An explicit URL for a "View document source" + link. - Default: None. Options: ``--source-uri, - --no-source-link``. + Default: compute if source_link (None). + Options: ``--source-uri, --no-source-link``. -------------------- ------------------------------------------------ -stylesheet HTML-specific. +stylesheet HTML-specific: path to CSS stylesheet. Default: "default.css". Options: ``--stylesheet``. @@ -380,13 +394,15 @@ toc_backlinks Enable backlinks from section titles to table of ``--toc-entry-backlinks, --toc-top-backlinks, --no-toc-backlinks``. -------------------- ------------------------------------------------ -warning_stream Send the output of system messages (warnings) to - a file. +warning_stream Path to a file for the output of system messages + (warnings). Default: stderr (None). Options: ``--warnings``. ==================== ================================================ +.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html + .. Local Variables: -- cgit v1.2.1 From 01e9aa4defd064eaaf678dcf0c2e92185689988d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 29 Jul 2002 02:24:13 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@416 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index bc3e7f27b..0cb20e777 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -261,6 +261,7 @@ Specific: - 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``). @@ -277,9 +278,6 @@ Specific: - Changed the title to "The Docutils Document Tree". - Added "Hyperlink Bookkeeping" section. -* spec/docutils.conf: Added to project. Not a spec itself, but a - configuration file for Docutils processing of the specs. - * spec/docutils.dtd: - Added ``decoration``, ``header``, and ``footer`` elements. @@ -369,6 +367,8 @@ Specific: - 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. -- cgit v1.2.1 From 05bb28bde7fb0af0e406ddc493b590d0c1135304 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:31:26 +0000 Subject: Added ``buildhtml.py`` & "recurse" setting; added "For Internal Use Only" division of table; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@417 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 117 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 31 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 58a0f0adb..6ae309fff 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -9,17 +9,18 @@ Once the Docutils package is unpacked, you will discover a "``tools``" directory containing several front ends for common Docutils -processing. Most Docutils front ends combine a specific "Reader" -(which knows how to interpret a file in context), a "Parser" (which +processing. Rather than a single all-purpose program, Docutils has +many small front ends, each specialized for a specific "Reader" (which +knows how to interpret a file in context), a "Parser" (which understands the syntax of the text), and a "Writer" (which knows how to generate a specific data format). Most front ends have common options and the same command-line usage pattern:: toolname [options] [<source> [<destination]] -The sole exception is pep2html.py_. See html.py_ for concrete -examples. Each tool has a "``--help``" option which lists the -`command-line options`_ and arguments it supports. Processing can +The exceptions are buildhtml.py_ and pep2html.py_. See html.py_ for +concrete examples. Each tool has a "``--help``" option which lists +the `command-line options`_ and arguments it supports. Processing can also be customized with `configuration files`_. The two arguments, "source" and "destination", are optional. If only @@ -31,6 +32,36 @@ input (stdin) is used for the source as well. .. contents:: +buildhtml.py +============ + +:Readers: Standalone, PEP +:Parser: reStructuredText +:Writers: HTML, PEP/HTML + +Use ``buildhtml.py`` to generate .html from all the .txt files +(including PEPs) in each <directory> given, and their subdirectories +too. (Use the ``--local`` option to skip subdirectories.) + +Usage:: + + buildhtml.py [options] [<directory> ...] + +After unpacking the Docutils package, the following commands will +build all the HTML documents: + + cd docutils + tools/buildhtml.py --config=tools/docutils.conf + +The current directory (and all subdirectories) is chosen by default if +no directory is named. Incomplete files (such as spec/doctree.txt) +may generate system messages; use the ``--quiet`` option to suppress +all warnings. The ``--config`` option ensures that the correct +stylesheets, templates, and settings are in place. Command-line +options may be used to override config file settings or replace them +altogether. + + html.py ======= @@ -262,8 +293,14 @@ Some knowledge of Python_ is assumed for some attributes. Config Entry Name Description ==================== ================================================ config Path to a configuration file to read (if it - exists). Settings may override defaults and - earlier settings. + exists) [#pwd]. Settings may override defaults + and earlier settings. This is only effective as + a command-line option; setting it in a config + file has no effect. + + Filesystem path settings contained within the + config file will be interpreted relative to the + config file's location. Default: None. Options: ``--config``. -------------------- ------------------------------------------------ @@ -278,13 +315,9 @@ debug Report debug-level system messages. Default: don't (None). Options: ``--debug, --no-debug``. -------------------- ------------------------------------------------ -destination Path to output destination, set from positional - arguments. Default: stdout (None). No - command-line options. --------------------- ------------------------------------------------ -dump_internals Hidden option: At the end of processing, print - out all internal attributes of the document - (``document.__dict__``). +dump_internals (Hidden option.) At the end of processing, + print out all internal attributes of the + document (``document.__dict__``). Default: don't (None). Options: ``--dump-internals``. @@ -309,7 +342,7 @@ halt_level The threshold at or above which system messages Default: severe (4). Options: ``--halt, --strict``. -------------------- ------------------------------------------------ -indents XML-specific: Generate XML with indents and +indents (XML Writer.) Generate XML with indents and newlines. Default: don't (None). Options: ``--indents``. @@ -323,13 +356,13 @@ language_code `ISO 639`_ 2-letter language code (3-letter Default: English ("en"). Options: ``--language, -l``. -------------------- ------------------------------------------------ -newlines XML-specific: Generate XML with newlines before +newlines (XML Writer.) Generate XML with newlines before and after tags. Default: don't (None). Options: ``--newlines``. -------------------- ------------------------------------------------ -no_random PEP/HTML-specific hidden option: Workaround for - platforms which core-dump on "``import +no_random (PEP/HTML Writer; hidden option.) Workaround + for platforms which core-dump on "``import random``". Default: random enabled (None). Options: @@ -338,36 +371,40 @@ no_random PEP/HTML-specific hidden option: Workaround for output_encoding Default: UTF-8. Options: ``--output-encoding, -o``. -------------------- ------------------------------------------------ -pep_home PEP/HTML-specific: Home URL prefix for PEPs. +pep_home (PEP/HTML Writer.) Home URL prefix for PEPs. Default: current directory ("."). Options: ``--pep-home``. -------------------- ------------------------------------------------ -pep_stylesheet PEP/HTML-specific: path to CSS stylesheet. - Overrides HTML stylesheet (``--stylesheet``). +pep_stylesheet (PEP/HTML Writer.) Path to CSS stylesheet + [#pwd]. Overrides HTML stylesheet + (``--stylesheet``). Default: None. Options: ``--pep-stylesheet``. -------------------- ------------------------------------------------ -pep_template PEP/HTML-specific: PEP template file. +pep_template (PEP/HTML Writer.) Path to PEP template file + [#pwd]. - Default: "pep-html-template". Options: - ``--pep-template``. + Default: "pep-html-template" (in current + directory). Options: ``--pep-template``. -------------------- ------------------------------------------------ -python_home PEP/HTML-specific: Python's home URL. +python_home (PEP/HTML Writer.) Python's home URL. Default: parent directory (".."). Options: ``--python-home``. -------------------- ------------------------------------------------ +recurse (``buildhtml.py`` front end.) Recursively scan + subdirectories. + + Default: recurse (1). Options: ``--recurse, + --local``. +-------------------- ------------------------------------------------ report_level Verbosity threshold at or above which system messages are reported. Default: warning (2). Options: ``--report, -r, --verbose``. -------------------- ------------------------------------------------ -source Path to input source, set from positional - arguments. Default: stdin (None). No - command-line options. --------------------- ------------------------------------------------ source_link Include a "View document source" link in the document footer. URL will be relative to the destination. @@ -381,7 +418,7 @@ source_url An explicit URL for a "View document source" Default: compute if source_link (None). Options: ``--source-uri, --no-source-link``. -------------------- ------------------------------------------------ -stylesheet HTML-specific: path to CSS stylesheet. +stylesheet (HTML Writer.) Path to CSS stylesheet [#pwd]. Default: "default.css". Options: ``--stylesheet``. @@ -395,14 +432,32 @@ toc_backlinks Enable backlinks from section titles to table of --no-toc-backlinks``. -------------------- ------------------------------------------------ warning_stream Path to a file for the output of system messages - (warnings). + (warnings) [#pwd]. Default: stderr (None). Options: ``--warnings``. + +For Internal Use Only (setting these in a config file has no effect) +---------------------------------------------------------------------- +_directories (``buildhtml.py`` front end.) List of paths to + source directories, set from positional + arguments. Default: current working directory + (None). No command-line options. +-------------------- ------------------------------------------------ +_destination Path to output destination, set from positional + arguments. Default: stdout (None). No + command-line options. +-------------------- ------------------------------------------------ +_source Path to input source, set from positional + arguments. Default: stdin (None). No + command-line options. ==================== ================================================ .. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html +.. [#pwd] Path relative to the working directory of the process at + launch. + .. Local Variables: -- cgit v1.2.1 From 542dc656827c94acf719e1d942053787b5752b0a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:31:49 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@418 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 52a9e500b..ba75a4427 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -73,8 +73,8 @@ class Component: """Names for this component. Override in subclasses.""" cmdline_options = () - """Command-line option specification. A list/tuple of tuples: - ``('help text', [list of option strings], {keyword arguments})``.""" + """Command-line option specification. + See `docutils.frontend.OptionParser`.""" def supports(self, format): """ -- cgit v1.2.1 From acd9230bd930f072e3857c81da4a8e138957b379 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:33:11 +0000 Subject: Updated config file & command-line processing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@419 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 80344a793..9e836c6be 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -17,9 +17,8 @@ custom component objects first, and pass *them* to __docformat__ = 'reStructuredText' import sys -import os.path from docutils import Component -from docutils import readers, parsers, writers, io +from docutils import frontend, io, readers, parsers, writers from docutils.frontend import OptionParser, ConfigParser @@ -29,12 +28,6 @@ class Publisher: A facade encapsulating the high-level logic of a Docutils system. """ - config_files = ('/etc/docutils.conf', # system-wide - './docutils.conf', # project-specific - os.path.expanduser('~/.docutils')) # user-specific - """Docutils configuration files, using ConfigParser syntax (section - 'options'). Later files override earlier ones.""" - def __init__(self, reader=None, parser=None, writer=None, source=None, source_class=io.FileIO, destination=None, destination_class=io.FileIO, @@ -84,10 +77,10 @@ class Publisher: def setup_option_parser(self, usage=None, description=None, option_spec=None, **defaults): config = ConfigParser() - config.read(self.config_files) - if config.has_section('options'): - for option in config.options('options'): - defaults[option] = config.get('options', option) + config.read_standard_files() + config_options = config.get_section('options') + frontend.make_paths_absolute(config_options) + defaults.update(config_options) option_parser = OptionParser( components=(option_spec, self.reader, self.parser, self.writer), usage=usage, description=description) @@ -121,10 +114,12 @@ class Publisher: if argv is None: argv = sys.argv[1:] self.options = option_parser.parse_args(argv) + + def set_io(self): self.source = self.source_class(self.options, - source_path=self.options.source) + source_path=self.options._source) self.destination = self.destination_class( - self.options, destination_path=self.options.destination) + self.options, destination_path=self.options._destination) def publish(self, argv=None, usage=None, description=None, option_spec=None): @@ -135,6 +130,7 @@ class Publisher: """ if self.options is None: self.process_command_line(argv, usage, description, option_spec) + self.set_io() document = self.reader.read(self.source, self.parser, self.options) output = self.writer.write(document, self.destination) if self.options.dump_internals: -- cgit v1.2.1 From 3442dc02845bbf4569ddfa838bf1ea13449346fc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:38:04 +0000 Subject: Added "--quiet" option. Path-related settings now made absolute, improving batch flexibility. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@420 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index d841a3774..be31637de 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -8,13 +8,22 @@ :Copyright: This module has been placed in the public domain. Command-line and common processing for Docutils front-end tools. + +Exports the following classes: + +- `OptionParser`: Standard Docutils command-line processing. +- `Values`: Option values; objects are simple structs (``object.attribute``). +- `ConfigParser`: Standard Docutils config file processing. """ __docformat__ = 'reStructuredText' +import os +import os.path import ConfigParser as CP import docutils from docutils import optik +from docutils.optik import Values def store_multiple(option, opt, value, parser, *args, **kwargs): @@ -33,11 +42,25 @@ def read_config_file(option, opt, value, parser): """ Read a configuration file during option processing. (Option callback.) """ - config = ConfigParser() - config.read(value) - if config.has_section('options'): - for entry in config.options('options'): - setattr(parser.values, entry, config.get('options', entry)) + config_parser = ConfigParser() + config_parser.read(value) + settings = config_parser.get_section('options') + make_paths_absolute(settings, os.path.dirname(value)) + parser.values.__dict__.update(settings) + +relative_path_options = ('warning_stream', 'stylesheet', 'pep_stylesheet', + 'pep_template') + +def make_paths_absolute(dictionary, base_path=None): + """ + Interpret filesystem path settings relative to the `base_path` given. + """ + if base_path is None: + base_path = os.getcwd() + for option in relative_path_options: + if dictionary.has_key(option) and dictionary[option]: + dictionary[option] = os.path.normpath( + os.path.join(base_path, dictionary[option])) class OptionParser(optik.OptionParser): @@ -113,6 +136,9 @@ class OptionParser(optik.OptionParser): '"--report=info".)', ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', 'dest': 'report_level'}), + ('Don't report any system messages. (Same as "--report=none".)', + ['--quiet', '-q'], {'action': 'store_const', 'const': 'none', + 'dest': 'report_level'}), ('Set the threshold (<level>) at or above which system messages are ' 'converted to exceptions, halting execution immediately. Levels ' 'as in --report. Default is 4 (severe).', @@ -136,7 +162,7 @@ class OptionParser(optik.OptionParser): ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': '<name>'}), - ('Read this configuration <file>.', + ('Read configuration options from <file>, if it exists.', ['--config'], {'metavar': '<file>', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), ("Show this program's version number and exit.", @@ -186,9 +212,12 @@ class OptionParser(optik.OptionParser): i += 3 def check_values(self, values, args): - values.report_level = self.check_threshold(values.report_level) - values.halt_level = self.check_threshold(values.halt_level) - values.source, values.destination = self.check_args(args) + if hasattr(values, 'report_level'): + values.report_level = self.check_threshold(values.report_level) + if hasattr(values, 'halt_level'): + values.halt_level = self.check_threshold(values.halt_level) + values._source, values._destination = self.check_args(args) + make_paths_absolute(values.__dict__, os.getcwd()) return values def check_threshold(self, level): @@ -213,8 +242,62 @@ class OptionParser(optik.OptionParser): class ConfigParser(CP.ConfigParser): + standard_config_files = ( + '/etc/docutils.conf', # system-wide + './docutils.conf', # project-specific + os.path.expanduser('~/.docutils')) # user-specific + """Docutils configuration files, using ConfigParser syntax (section + 'options'). Later files override earlier ones.""" + + def read_standard_files(self): + self.read(self.standard_config_files) + def optionxform(self, optionstr): """ Transform '-' to '_' so the cmdline form of option names can be used. """ return optionstr.lower().replace('-', '_') + + def get_section(self, section, raw=0, vars=None): + """ + Return a given section as a dictionary (empty if the section + doesn't exist). + + All % interpolations are expanded in the return values, based on the + defaults passed into the constructor, unless the optional argument + `raw` is true. Additional substitutions may be provided using the + `vars` argument, which must be a dictionary whose contents overrides + any pre-existing defaults. + + The section DEFAULT is special. + """ + try: + sectdict = self._ConfigParser__sections[section].copy() + except KeyError: + sectdict = {} + d = self._ConfigParser__defaults.copy() + d.update(sectdict) + # Update with the entry specific variables + if vars: + d.update(vars) + if raw: + return sectdict + # do the string interpolation + for option in sectdict.keys(): + rawval = sectdict[option] + value = rawval # Make it a pretty variable name + depth = 0 + while depth < 10: # Loop through this until it's done + depth += 1 + if value.find("%(") >= 0: + try: + value = value % d + except KeyError, key: + raise CP.InterpolationError(key, option, section, + rawval) + else: + break + if value.find("%(") >= 0: + raise CP.InterpolationDepthError(option, section, rawval) + sectdict[option] = value + return sectdict -- cgit v1.2.1 From 49be7aa3488ab501b6993dff09b6552d707ced82 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:38:33 +0000 Subject: Added "--quiet". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@421 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 6ae309fff..bd496bebe 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -403,7 +403,7 @@ report_level Verbosity threshold at or above which system messages are reported. Default: warning (2). Options: ``--report, -r, - --verbose``. + --verbose, --quiet, -q``. -------------------- ------------------------------------------------ source_link Include a "View document source" link in the document footer. URL will be relative to the -- cgit v1.2.1 From c3dd163385425e7e2df847faef58c3bdb22d19a4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:39:19 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@422 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index 44a537667..c8a0be2ba 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -363,7 +363,8 @@ def relative_uri(source, target): return '/'.join(target_parts) source_parts.reverse() target_parts.reverse() - while source_parts[-1] == target_parts[-1]: + while (source_parts and target_parts + and source_parts[-1] == target_parts[-1]): # Remove path components in common: source_parts.pop() target_parts.pop() -- cgit v1.2.1 From 777adc1e1ebbcef09ddf6c07ed2e2c7ab607a334 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:41:46 +0000 Subject: updated for improved front-end handling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@423 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/docutils.conf b/tools/docutils.conf index 26ddddb5c..4dfabae6e 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -5,7 +5,11 @@ source-link: 1 datestamp: %Y-%m-%d %H:%M UTC generator: 1 +# These entries affect HTML output: +stylesheet: default.css + # These entries affect reStructuredText-style PEPs: +pep-template: pep-html-template pep-stylesheet: stylesheets/pep.css python-home: http://www.python.org no-random: 1 -- cgit v1.2.1 From 9e2088dd544b377896ec7c893212cd6f0aa6422d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:42:43 +0000 Subject: made importable (for RST PEP handling) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@424 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 49d925b37..c4b52d47b 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -267,14 +267,21 @@ def fixfile(infile, outfile): print >> outfile, '</html>' +docutils_options = None + def fix_rst_pep(infile, outfile): from docutils import core, io pub = core.Publisher() pub.set_reader(reader_name='pep', parser_name='restructuredtext', parser=None) pub.set_writer(writer_name='pep_html') - options = pub.set_options(source=infile.name, destination=outfile.name, - generator=1, datestamp='%Y-%m-%d %H:%M UTC') + if docutils_options: + options = docutils_options + pub.options = options + else: + options = pub.set_options() + options._source = infile.name + options._destination = outfile.name pub.source = io.FileIO(options, source=infile, source_path=infile.name) pub.destination = io.FileIO(options, destination=outfile, destination_path=outfile.name) @@ -287,8 +294,8 @@ def check_rst_pep(infile): """ Check if `infile` is a reStructuredText PEP. Return 1 for yes, 0 for no. - If the result is indeterminate, return None. Reset `infile` to the - beginning. + If the result is indeterminate, return None. When the check is complete, + rewind `infile` to the beginning. """ result = None underline_match = underline.match -- cgit v1.2.1 From 60e5c1371c60c00dc4c76d684f263021a703c3a7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:49:12 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@425 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- COPYING.txt | 9 ++++----- HISTORY.txt | 3 +++ README.txt | 42 +++++++++++++++++++++++++++++++++++----- docs/dev/todo.txt | 5 ----- docs/peps/pep-0258.txt | 4 ++-- docutils/transforms/universal.py | 6 +++--- docutils/writers/html4css1.py | 2 +- docutils/writers/pep_html.py | 2 +- 8 files changed, 51 insertions(+), 22 deletions(-) diff --git a/COPYING.txt b/COPYING.txt index e74ff96ee..883e6836b 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -9,11 +9,10 @@ Most of the files included in this project are in the public domain, and therefore have no license requirement and no restrictions on -copying or usage. The two exceptions are: +copying or usage. The exceptions are: -- docutils/optik.py & OptionParser.py, copyright Gregory P. Ward, - licensed under the BSD license (which can be found in the source - code of optik.py). +- docutils/optik.py, copyright Gregory P. Ward, licensed under the BSD + license (which can be found in the module's source code). - docutils/roman.py, copyright by Mark Pilgrim, licensed under the `Python 2.1.1 license`_. @@ -31,7 +30,7 @@ license are OSI-approved_ and GPL-compatible_. Although complicated by multiple owners and lots of legalese, the Python license basically lets you copy, use, modify, and redistribute files as long as you keep the copyright attribution intact, note any changes you make, and don't -use the owner's name in vain. +use the owner's name in vain. The BSD license is similar. .. _Python 2.1.1 license: http://www.python.org/2.1.1/license.html .. _Python 2.2 license: http://www.python.org/2.2/license.html diff --git a/HISTORY.txt b/HISTORY.txt index 0cb20e777..33ceda451 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -362,6 +362,9 @@ Specific: 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. diff --git a/README.txt b/README.txt index d1bc3b5de..3644ec313 100644 --- a/README.txt +++ b/README.txt @@ -15,6 +15,30 @@ experimental; APIs are subject to change at any time. .. contents:: +Releases & Snapshots +==================== + +Putting together an official "Release" of Docutils is a significant +effort, so it isn't done that often. In the meantime, the CVS +snapshots always contain the latest code and documentation, usually +updated within an hour of changes being committed to the repository, +and usually bug-free: + +- Snapshot of Docutils code, tests, documentation, and + specifications: http://docutils.sf.net/docutils-snapshot.tgz + +- Snapshot of the Sandbox (experimental, contributed code): + http://docutils.sf.net/docutils-sandbox-snapshot.tgz + +- `Snapshot of web files` (the files that generate the web site): + http://docutils.sf.net/docutils-web-snapshot.tgz + +To keep up to date on the latest developments, download fresh copies +of the snapshots regularly. New functionality is being added weekly, +sometimes daily. (There's also the CVS repository, and a mailing list +for CVS messages. See the web site for details; address above.) + + Requirements ============ @@ -130,11 +154,17 @@ not appear. Usage ===== -Start with the html.py and publish.py front-end tools from the -unpacked "tools" subdirectory. Both 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 ``docs/tools.txt`` for full +After unpacking the Docutils package, the following commands will +generate HTML for all included documentation:: + + cd docutils # or "docutils-X.Y" for official releases + tools/buildhtml.py --config=tools/docutils.conf + +There are many front-end tools in the unpacked "tools" subdirectory. +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/tools.txt``) for full documentation. The package modules are continually growing and evolving. The @@ -143,6 +173,8 @@ extensive inline documentation (in reStructuredText format of course). Contributions are welcome! +.. _Docutils Front-End Tools: http://docutils.sf.net/docs/tools.html + .. Local Variables: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 0ba2e863f..009da9801 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -619,11 +619,6 @@ Front-End Tools - Parameterize help text & defaults somehow? Perhaps a callback? Or initialize ``cmdline_options`` in ``__init__``? -- Write a tool (perhaps ``htmldocs.py`` or ``buildhtml.py``) which - generates .html from all the .txt files in the project. It could - even be run by setup.py as a final step! Once PySource is there, - it can build .html from .py as well. - Project Policies ================ diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 905aae688..9912e92ec 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -415,9 +415,9 @@ Specification Front-End Tools =============== - @@@ To be determined. + See `Docutils Front-End Tools`_. - @@@ Document tools & summarize their command-line interfaces. + .. _Docutils Front-End Tools: http://docutils.sf.net/docs/tools.html Document Tree diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index bc5a1bb74..dc4a97fb1 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -58,12 +58,12 @@ class Decorations(Transform): if options.generator or options.datestamp or options.source_link \ or options.source_url: text = [] - if options.source_link and options.source or options.source_url: + if options.source_link and options._source or options.source_url: if options.source_url: source = options.source_url else: - source = utils.relative_uri(options.destination, - options.source) + source = utils.relative_uri(options._destination, + options._source) text.extend([ nodes.reference('', 'View document source', refuri=source), diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d1a8fda04..78e5803a4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -116,7 +116,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.html_head % options.language_code, self.content_type % options.output_encoding, self.generator, - self.stylesheet_link % utils.relative_uri(options.destination, + self.stylesheet_link % utils.relative_uri(options._destination, options.stylesheet)] self.head = [] self.body_prefix = ['</head>\n<body>\n'] diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 61689fd59..af1a84dd5 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -53,7 +53,7 @@ class Writer(html4css1.Writer): stylesheet = options.pep_stylesheet if stylesheet is None: stylesheet = options.stylesheet - stylesheet = utils.relative_uri(options.destination, stylesheet) + stylesheet = utils.relative_uri(options._destination, stylesheet) pyhome = options.python_home pephome = options.pep_home if pyhome == '..': -- cgit v1.2.1 From b2f915ec237d6c11b15261ae4e0b70baf2bb53bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 01:54:01 +0000 Subject: Added to project; batch-generates .html from all the .txt files in directories and subdirectories. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@426 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 tools/buildhtml.py diff --git a/tools/buildhtml.py b/tools/buildhtml.py new file mode 100755 index 000000000..310790899 --- /dev/null +++ b/tools/buildhtml.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python + +""" +Generates .html from all the .txt files in a directory. + +Ordinary .txt files are understood to be standalone reStructuredText. +Files named ``pep-*.txt`` are interpreted as PEPs (either old-style or +new reStructuredText PEPs). +""" +# Once PySource is here, build .html from .py as well. + +__docformat__ = 'reStructuredText' + + +import sys +import os +import os.path +import copy +from docutils import core, frontend, io +from docutils.parsers import rst +from docutils.readers import pep +from docutils.writers import pep_html +import pep2html + + +usage = '%prog [options] [<directory> ...]' +description = ('Generates .html from all the .txt files (including PEPs) ' + 'in each <directory> (default is the current directory).') + + +class OptionSpec: + + """ + Command-line options for the ``buildhtml.py`` front end. + """ + + # Can't be included in OptionParser below because we don't want to + # override the base class. + cmdline_options = ( + 'Build-HTML Options', + None, + (('Recursively scan subdirectories for files to process. This is ' + 'the default.', + ['--recurse'], {'action': 'store_true', 'default': 1}), + ('Do not scan subdirectories for files to process.', + ['--local'], {'dest': 'recurse', 'action': 'store_false'}),)) + + +class OptionParser(frontend.OptionParser): + + """ + Command-line option processing for the ``buildhtml.py`` front end. + """ + + def check_values(self, values, args): + frontend.OptionParser.check_values(self, values, args) + values._source = None + return values + + def check_args(self, args): + source = destination = None + if args: + self.values._directories = args + else: + self.values._directories = [os.getcwd()] + return source, destination + + +class Builder: + + def run(self, directory=None, recurse=1): + self.process_command_line() + initial_options = self.get_options() + recurse = recurse and initial_options.recurse + self.setup_html_publisher() + if directory: + self.directories = [directory] + elif self.cmdline_options._directories: + self.directories = self.cmdline_options._directories + else: + self.directories = [os.getcwd()] + for directory in self.directories: + os.path.walk(directory, self.visit, recurse) + + def visit(self, recurse, directory, names): + print >>sys.stderr, '/// Processing directory:', directory + sys.stderr.flush() + options = self.get_options(directory) + peps_found = 0 + for name in names: + if name.endswith('.txt'): + if name.startswith('pep-'): + peps_found = 1 + else: + self.process_txt(directory, name, options) + if peps_found: + self.process_peps(options, directory) + if not recurse: + del names[:] + + def process_txt(self, directory, name, options): + options._source = os.path.normpath(os.path.join(directory, name)) + options._destination = options._source[:-4]+'.html' + self.pub.options = options + print >>sys.stderr, ' ::: Processing .txt:', name + sys.stderr.flush() + self.pub.source = io.FileIO(options, source_path=options._source) + self.pub.destination = io.FileIO( + options, destination_path=options._destination) + self.pub.publish() + + def process_peps(self, options, directory): + old_directory = os.getcwd() + os.chdir(directory) + print >>sys.stderr, ' ::: Processing PEPs:' + sys.stderr.flush() + pep2html.docutils_options = options + pep2html.main() + os.chdir(old_directory) + + def process_command_line(self): + option_parser = OptionParser( + components=(OptionSpec, pep.Reader, rst.Parser, pep_html.Writer), + usage=usage, description=description) + self.option_defaults = option_parser.get_default_values() + config_parser = frontend.ConfigParser() + config_parser.read_standard_files() + self.config_settings = config_parser.get_section('options') + frontend.make_paths_absolute(self.config_settings) + self.cmdline_options = option_parser.parse_args( + values=frontend.Values()) # no defaults + # Clear out the command-line options so pep2html doesn't see them: + del sys.argv[1:] + + def get_options(self, directory=None): + """ + Return an option values object, from multiple sources. + + Copy the option defaults, overlay the startup config file settings, + then the local config file settings, then the command-line options. + Assumes the current directory has been set. + """ + options = copy.deepcopy(self.option_defaults) + options.__dict__.update(self.config_settings) + if directory: + config_parser = frontend.ConfigParser() + config_parser.read(os.path.join(directory, 'docutils.conf')) + local_config = config_parser.get_section('options') + frontend.make_paths_absolute(local_config, directory) + options.__dict__.update(local_config) + options.__dict__.update(self.cmdline_options.__dict__) + return options + + def setup_html_publisher(self): + pub = core.Publisher() + pub.set_reader(reader_name='standalone', + parser_name='restructuredtext', parser=None) + pub.set_writer(writer_name='html') + self.pub = pub + + +if __name__ == "__main__": + Builder().run() -- cgit v1.2.1 -- cgit v1.2.1 From e07795fb06abccd594d7553cc8d7c6daf7f199c4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 02:13:22 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@428 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index be31637de..148a3b894 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -136,7 +136,7 @@ class OptionParser(optik.OptionParser): '"--report=info".)', ['--verbose', '-v'], {'action': 'store_const', 'const': 'info', 'dest': 'report_level'}), - ('Don't report any system messages. (Same as "--report=none".)', + ('Do not report any system messages. (Same as "--report=none".)', ['--quiet', '-q'], {'action': 'store_const', 'const': 'none', 'dest': 'report_level'}), ('Set the threshold (<level>) at or above which system messages are ' -- cgit v1.2.1 From e8d4289000e3ab952b2e465f462b89deed93bbdb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 02:21:49 +0000 Subject: be gone! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@429 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 163 ----------------------------------------------------- 1 file changed, 163 deletions(-) delete mode 100755 tools/buildhtml.py diff --git a/tools/buildhtml.py b/tools/buildhtml.py deleted file mode 100755 index 310790899..000000000 --- a/tools/buildhtml.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python - -""" -Generates .html from all the .txt files in a directory. - -Ordinary .txt files are understood to be standalone reStructuredText. -Files named ``pep-*.txt`` are interpreted as PEPs (either old-style or -new reStructuredText PEPs). -""" -# Once PySource is here, build .html from .py as well. - -__docformat__ = 'reStructuredText' - - -import sys -import os -import os.path -import copy -from docutils import core, frontend, io -from docutils.parsers import rst -from docutils.readers import pep -from docutils.writers import pep_html -import pep2html - - -usage = '%prog [options] [<directory> ...]' -description = ('Generates .html from all the .txt files (including PEPs) ' - 'in each <directory> (default is the current directory).') - - -class OptionSpec: - - """ - Command-line options for the ``buildhtml.py`` front end. - """ - - # Can't be included in OptionParser below because we don't want to - # override the base class. - cmdline_options = ( - 'Build-HTML Options', - None, - (('Recursively scan subdirectories for files to process. This is ' - 'the default.', - ['--recurse'], {'action': 'store_true', 'default': 1}), - ('Do not scan subdirectories for files to process.', - ['--local'], {'dest': 'recurse', 'action': 'store_false'}),)) - - -class OptionParser(frontend.OptionParser): - - """ - Command-line option processing for the ``buildhtml.py`` front end. - """ - - def check_values(self, values, args): - frontend.OptionParser.check_values(self, values, args) - values._source = None - return values - - def check_args(self, args): - source = destination = None - if args: - self.values._directories = args - else: - self.values._directories = [os.getcwd()] - return source, destination - - -class Builder: - - def run(self, directory=None, recurse=1): - self.process_command_line() - initial_options = self.get_options() - recurse = recurse and initial_options.recurse - self.setup_html_publisher() - if directory: - self.directories = [directory] - elif self.cmdline_options._directories: - self.directories = self.cmdline_options._directories - else: - self.directories = [os.getcwd()] - for directory in self.directories: - os.path.walk(directory, self.visit, recurse) - - def visit(self, recurse, directory, names): - print >>sys.stderr, '/// Processing directory:', directory - sys.stderr.flush() - options = self.get_options(directory) - peps_found = 0 - for name in names: - if name.endswith('.txt'): - if name.startswith('pep-'): - peps_found = 1 - else: - self.process_txt(directory, name, options) - if peps_found: - self.process_peps(options, directory) - if not recurse: - del names[:] - - def process_txt(self, directory, name, options): - options._source = os.path.normpath(os.path.join(directory, name)) - options._destination = options._source[:-4]+'.html' - self.pub.options = options - print >>sys.stderr, ' ::: Processing .txt:', name - sys.stderr.flush() - self.pub.source = io.FileIO(options, source_path=options._source) - self.pub.destination = io.FileIO( - options, destination_path=options._destination) - self.pub.publish() - - def process_peps(self, options, directory): - old_directory = os.getcwd() - os.chdir(directory) - print >>sys.stderr, ' ::: Processing PEPs:' - sys.stderr.flush() - pep2html.docutils_options = options - pep2html.main() - os.chdir(old_directory) - - def process_command_line(self): - option_parser = OptionParser( - components=(OptionSpec, pep.Reader, rst.Parser, pep_html.Writer), - usage=usage, description=description) - self.option_defaults = option_parser.get_default_values() - config_parser = frontend.ConfigParser() - config_parser.read_standard_files() - self.config_settings = config_parser.get_section('options') - frontend.make_paths_absolute(self.config_settings) - self.cmdline_options = option_parser.parse_args( - values=frontend.Values()) # no defaults - # Clear out the command-line options so pep2html doesn't see them: - del sys.argv[1:] - - def get_options(self, directory=None): - """ - Return an option values object, from multiple sources. - - Copy the option defaults, overlay the startup config file settings, - then the local config file settings, then the command-line options. - Assumes the current directory has been set. - """ - options = copy.deepcopy(self.option_defaults) - options.__dict__.update(self.config_settings) - if directory: - config_parser = frontend.ConfigParser() - config_parser.read(os.path.join(directory, 'docutils.conf')) - local_config = config_parser.get_section('options') - frontend.make_paths_absolute(local_config, directory) - options.__dict__.update(local_config) - options.__dict__.update(self.cmdline_options.__dict__) - return options - - def setup_html_publisher(self): - pub = core.Publisher() - pub.set_reader(reader_name='standalone', - parser_name='restructuredtext', parser=None) - pub.set_writer(writer_name='html') - self.pub = pub - - -if __name__ == "__main__": - Builder().run() -- cgit v1.2.1 From 8225e8771b884608aed60523eef8daa2981927e5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 31 Jul 2002 02:24:34 +0000 Subject: give up git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@430 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 tools/buildhtml.py diff --git a/tools/buildhtml.py b/tools/buildhtml.py new file mode 100755 index 000000000..310790899 --- /dev/null +++ b/tools/buildhtml.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python + +""" +Generates .html from all the .txt files in a directory. + +Ordinary .txt files are understood to be standalone reStructuredText. +Files named ``pep-*.txt`` are interpreted as PEPs (either old-style or +new reStructuredText PEPs). +""" +# Once PySource is here, build .html from .py as well. + +__docformat__ = 'reStructuredText' + + +import sys +import os +import os.path +import copy +from docutils import core, frontend, io +from docutils.parsers import rst +from docutils.readers import pep +from docutils.writers import pep_html +import pep2html + + +usage = '%prog [options] [<directory> ...]' +description = ('Generates .html from all the .txt files (including PEPs) ' + 'in each <directory> (default is the current directory).') + + +class OptionSpec: + + """ + Command-line options for the ``buildhtml.py`` front end. + """ + + # Can't be included in OptionParser below because we don't want to + # override the base class. + cmdline_options = ( + 'Build-HTML Options', + None, + (('Recursively scan subdirectories for files to process. This is ' + 'the default.', + ['--recurse'], {'action': 'store_true', 'default': 1}), + ('Do not scan subdirectories for files to process.', + ['--local'], {'dest': 'recurse', 'action': 'store_false'}),)) + + +class OptionParser(frontend.OptionParser): + + """ + Command-line option processing for the ``buildhtml.py`` front end. + """ + + def check_values(self, values, args): + frontend.OptionParser.check_values(self, values, args) + values._source = None + return values + + def check_args(self, args): + source = destination = None + if args: + self.values._directories = args + else: + self.values._directories = [os.getcwd()] + return source, destination + + +class Builder: + + def run(self, directory=None, recurse=1): + self.process_command_line() + initial_options = self.get_options() + recurse = recurse and initial_options.recurse + self.setup_html_publisher() + if directory: + self.directories = [directory] + elif self.cmdline_options._directories: + self.directories = self.cmdline_options._directories + else: + self.directories = [os.getcwd()] + for directory in self.directories: + os.path.walk(directory, self.visit, recurse) + + def visit(self, recurse, directory, names): + print >>sys.stderr, '/// Processing directory:', directory + sys.stderr.flush() + options = self.get_options(directory) + peps_found = 0 + for name in names: + if name.endswith('.txt'): + if name.startswith('pep-'): + peps_found = 1 + else: + self.process_txt(directory, name, options) + if peps_found: + self.process_peps(options, directory) + if not recurse: + del names[:] + + def process_txt(self, directory, name, options): + options._source = os.path.normpath(os.path.join(directory, name)) + options._destination = options._source[:-4]+'.html' + self.pub.options = options + print >>sys.stderr, ' ::: Processing .txt:', name + sys.stderr.flush() + self.pub.source = io.FileIO(options, source_path=options._source) + self.pub.destination = io.FileIO( + options, destination_path=options._destination) + self.pub.publish() + + def process_peps(self, options, directory): + old_directory = os.getcwd() + os.chdir(directory) + print >>sys.stderr, ' ::: Processing PEPs:' + sys.stderr.flush() + pep2html.docutils_options = options + pep2html.main() + os.chdir(old_directory) + + def process_command_line(self): + option_parser = OptionParser( + components=(OptionSpec, pep.Reader, rst.Parser, pep_html.Writer), + usage=usage, description=description) + self.option_defaults = option_parser.get_default_values() + config_parser = frontend.ConfigParser() + config_parser.read_standard_files() + self.config_settings = config_parser.get_section('options') + frontend.make_paths_absolute(self.config_settings) + self.cmdline_options = option_parser.parse_args( + values=frontend.Values()) # no defaults + # Clear out the command-line options so pep2html doesn't see them: + del sys.argv[1:] + + def get_options(self, directory=None): + """ + Return an option values object, from multiple sources. + + Copy the option defaults, overlay the startup config file settings, + then the local config file settings, then the command-line options. + Assumes the current directory has been set. + """ + options = copy.deepcopy(self.option_defaults) + options.__dict__.update(self.config_settings) + if directory: + config_parser = frontend.ConfigParser() + config_parser.read(os.path.join(directory, 'docutils.conf')) + local_config = config_parser.get_section('options') + frontend.make_paths_absolute(local_config, directory) + options.__dict__.update(local_config) + options.__dict__.update(self.cmdline_options.__dict__) + return options + + def setup_html_publisher(self): + pub = core.Publisher() + pub.set_reader(reader_name='standalone', + parser_name='restructuredtext', parser=None) + pub.set_writer(writer_name='html') + self.pub = pub + + +if __name__ == "__main__": + Builder().run() -- cgit v1.2.1 From a0f7c8dbee178f8426ad60a251134cff94f2b99b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 1 Aug 2002 00:07:43 +0000 Subject: docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@431 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docutils/io.py b/docutils/io.py index 265e49851..00285c21d 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -55,6 +55,11 @@ class IO: """ Decode a string, `data`, heuristically. Raise UnicodeError if unsuccessful. + + The client application should call ``locale.setlocale`` at the + beginning of processing:: + + locale.setlocale(locale.LC_ALL, '') """ encodings = [self.options.input_encoding, 'utf-8'] try: -- cgit v1.2.1 From 1822e231995b5aacc2511922f1fe4b7c46ff2de5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 1 Aug 2002 00:15:21 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@433 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- README.txt | 12 +++++++++--- docs/dev/todo.txt | 37 +++++++++++++++++++++++++------------ docs/peps/pep-0287.txt | 23 ++++++++++++----------- docs/ref/rst/directives.txt | 10 ++++++++++ docs/user/tools.txt | 26 +++++++++++++++++--------- setup.py | 4 ++-- 7 files changed, 76 insertions(+), 38 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 33ceda451..6af5b203e 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -34,7 +34,7 @@ hard cash :-).) Hopefully I haven't forgotten anyone or misspelled any names; apologies (and please let me know!) if I have. -Changes Since 0.1 +Release 0.2 (2002-07-31) ======================== General: diff --git a/README.txt b/README.txt index 3644ec313..fe0ccb550 100644 --- a/README.txt +++ b/README.txt @@ -154,10 +154,16 @@ not appear. Usage ===== -After unpacking the Docutils package, the following commands will -generate HTML for all included documentation:: +After unpacking the Docutils package, the following shell commands +will generate HTML for all included documentation:: - cd docutils # or "docutils-X.Y" for official releases + cd docutils/tools + buildhtml.py .. + +For official releases, the directory may be called "docutils-X.Y", +where "X.Y" is the release version. Alternatively:: + + cd docutils tools/buildhtml.py --config=tools/docutils.conf There are many front-end tools in the unpacked "tools" subdirectory. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 009da9801..62412811a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -79,7 +79,7 @@ General - Rename methods & variables according to the `coding conventions`_ below. - - The name->id conversion and hyperlink resolution code needs to be + - The name-to-id conversion and hyperlink resolution code needs to be checked for correctness and refactored. I'm afraid it's a bit of a spaghetti mess now. @@ -95,11 +95,11 @@ General avoid importing top-level modules if the module name is not in docutils/readers. Potential nastiness.) -- Perhaps store a name->id mapping file? This could be stored +- Perhaps store a name-to-id mapping file? This could be stored permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) -- Need a Unicode -> HTML entities codec for HTML writer? +- Need a Unicode to HTML entities codec for HTML writer? - Fix tests to run standalone. I.e., allow:: @@ -168,13 +168,13 @@ __ rst/alternatives.html#or-not-to-do - Add _`character processing`? For example: - - ``--`` -> em-dash (or ``--`` -> en-dash, and ``---`` -> em-dash). + - ``--`` to em-dash (or ``--`` to en-dash, and ``---`` to em-dash). (Look for pre-existing conventions.) - Convert quotes to curly quote entities. (Essentially impossible for HTML? Unnecessary for TeX. An output issue?) - Various forms of ``:-)`` to smiley icons. - - ``"\ "`` ->  . - - Escaped newlines -> <BR>. + - ``"\ "`` to  . + - Escaped newlines to <BR>. - Escaped period or quote as a disappearing catalyst to allow character-level inline markup? - Others? @@ -297,8 +297,9 @@ __ rst/alternatives.html#or-not-to-do "docutils feedback"). - Generalize the "literal block" construct to allow blocks with a - per-line quoting to avoid indentation? For example, an email reply - quoting the original:: + per-line quoting to avoid indentation? For example, in this email + reply quoting the original, the block quoted with "``>``" (and + prefaced by "``::``") would be treated as a literal block:: John Doe wrote:: @@ -306,10 +307,18 @@ __ rst/alternatives.html#or-not-to-do > > Why didn't I think of that? + You just did! ;-) + The literal block would have to be a continuous text block (the first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. +- Decide whether or not to implement Simon Budig's "inline external + targets" syntax idea, and if so, how (pragma directive or full-blown + addition to the spec & parser). + +- Add support for pragma (syntax-altering) directives. + Directives `````````` @@ -593,9 +602,11 @@ Front-End Tools b) _`Partially qualified`: Reader is hard-coded, and the Writer is specified a sub-command (e.g. ``pep2 html [options]``, - ``pysource2 pdf [options]``). The Writer is known before - option processing happens, allowing the OptionParser to be - built dynamically. + ``pysource2 pdf [options]``). The Writer is known before option + processing happens, allowing the OptionParser to be built + dynamically. Alternatively, the Writer could be hard-coded and + the Reader specified as a sub-command (e.g. ``htmlfrom pep + [options]``). c) _`Unqualified`: Reader and Writer are specified as subcommands (e.g. ``publish pep html [options]``, ``publish pysource pdf @@ -617,7 +628,9 @@ Front-End Tools apart. - Parameterize help text & defaults somehow? Perhaps a callback? Or - initialize ``cmdline_options`` in ``__init__``? + initialize ``cmdline_options`` in ``__init__`` or ``init_options``? + +- Disable common options that don't apply? Project Policies diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 346a3f2a7..c03cf9007 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -55,15 +55,15 @@ to produce complex documents, and extensible so that there are few limits. Of course, to write reStructuredText documents some prior knowledge is required. -The reStructuredText parser is available now. Standalone -reStructuredText documents and PEPs can be converted to HTML; other -output format writers will become available over time. Work is -progressing on a Python source "Reader" which will implement -auto-documentation from docstrings. Authors of existing -auto-documentation tools are encouraged to integrate the -reStructuredText parser into their projects, or better yet, to join -forces to produce a world-class toolset for the Python standard -library. +The reStructuredText parser is available now, part of the Docutils_ +project. Standalone reStructuredText documents and PEPs can be +converted to HTML; other output format writers are being worked on and +will become available over time. Work is progressing on a Python +source "Reader" which will implement auto-documentation from +docstrings. Authors of existing auto-documentation tools are +encouraged to integrate the reStructuredText parser into their +projects, or better yet, to join forces to produce a world-class +toolset for the Python standard library. Tools will become available in the near future, which will allow programmers to generate HTML for online help, XML for multiple @@ -140,8 +140,9 @@ a) Keep the existing PEP section structure constructs (one-line b) Replace the PEP section structure constructs with the reStructuredText syntax. Section headers will require underlines, subsections will be supported out of the box, and body text need - not be indented (except for block quotes). This strategy is - recommended, and has already been implemented. + not be indented (except for block quotes). + +Strategy (b) is recommended, and its implementation is complete. Support for RFC 2822 headers has been added to the reStructuredText parser for PEPs (unambiguous given a specific context: the first diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 039e7fd0c..8011eb3c5 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -220,6 +220,8 @@ The following attributes are recognized: Footnotes ========= +**NOT IMPLEMENTED YET** + DTD elements: pending, topic. @@@ @@ -228,6 +230,8 @@ DTD elements: pending, topic. Citations ========= +**NOT IMPLEMENTED YET** + DTD elements: pending, topic. @@@ @@ -236,6 +240,8 @@ DTD elements: pending, topic. Topic ===== +**NOT IMPLEMENTED YET** + DTD element: topic. @@@ @@ -303,6 +309,8 @@ HTML equivalent:: Imagemap ======== +**NOT IMPLEMENTED YET** + Non-standard element: imagemap. @@ -313,6 +321,8 @@ Non-standard element: imagemap. Raw Data Pass-Through ===================== +**NOT IMPLEMENTED YET** + DTD element: pending. Directive block: the directive data is interpreted as an output format diff --git a/docs/user/tools.txt b/docs/user/tools.txt index bd496bebe..cc52c6a66 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -47,8 +47,14 @@ Usage:: buildhtml.py [options] [<directory> ...] -After unpacking the Docutils package, the following commands will -build all the HTML documents: +After unpacking the Docutils package, the following shell commands +will generate HTML for all included documentation:: + + cd docutils/tools + buildhtml.py .. + +For official releases, the directory may be called "docutils-X.Y", +where "X.Y" is the release version. Alternatively:: cd docutils tools/buildhtml.py --config=tools/docutils.conf @@ -57,9 +63,9 @@ The current directory (and all subdirectories) is chosen by default if no directory is named. Incomplete files (such as spec/doctree.txt) may generate system messages; use the ``--quiet`` option to suppress all warnings. The ``--config`` option ensures that the correct -stylesheets, templates, and settings are in place. Command-line -options may be used to override config file settings or replace them -altogether. +stylesheets, templates, and settings are in place (``./docutils.conf`` +is picked up automatically). Command-line options may be used to +override config file settings or replace them altogether. html.py @@ -247,14 +253,15 @@ files, in the following order: located in the user's home directory. This file overrides both the system-wide and project-specific configuration files. -4. A configuration file may be explicitly specified with the - "--config" command-line option. - If more than one configuration file is found, all will be read but later entries will override earlier ones. For example, a "stylesheet" entry in a user-specific configuration file will override a system-wide entry. +In addition, a configuration file may be explicitly specified with the +"--config" command-line option. This configuration file is read after +the three implicit ones listed above. + Configuration files use the standard ConfigParser.py_ Python_ module. From its documentation: @@ -300,7 +307,8 @@ config Path to a configuration file to read (if it Filesystem path settings contained within the config file will be interpreted relative to the - config file's location. + config file's location (*not* relative to the + current working directory). Default: None. Options: ``--config``. -------------------- ------------------------------------------------ diff --git a/setup.py b/setup.py index ef42fdfd2..06393c568 100755 --- a/setup.py +++ b/setup.py @@ -9,10 +9,10 @@ def do_setup(): description = 'Python Documentation Utilities', #long_description = '', url = 'http://docutils.sourceforge.net/', - version = '0.1+', + version = '0.2', author = 'David Goodger', author_email = 'goodger@users.sourceforge.net', - license = 'public domain, Python (see COPYING.txt)', + license = 'public domain, Python, BSD (see COPYING.txt)', packages = ['docutils', 'docutils.readers', 'docutils.writers', 'docutils.transforms', 'docutils.languages', 'docutils.parsers', 'docutils.parsers.rst', -- cgit v1.2.1 From 2460b80464a4fed030ed23de250da15235c2f606 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 1 Aug 2002 00:23:26 +0000 Subject: oops git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@434 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index cc52c6a66..35c5d2e98 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -300,7 +300,7 @@ Some knowledge of Python_ is assumed for some attributes. Config Entry Name Description ==================== ================================================ config Path to a configuration file to read (if it - exists) [#pwd]. Settings may override defaults + exists) [#pwd]_. Settings may override defaults and earlier settings. This is only effective as a command-line option; setting it in a config file has no effect. @@ -385,13 +385,13 @@ pep_home (PEP/HTML Writer.) Home URL prefix for PEPs. ``--pep-home``. -------------------- ------------------------------------------------ pep_stylesheet (PEP/HTML Writer.) Path to CSS stylesheet - [#pwd]. Overrides HTML stylesheet + [#pwd]_. Overrides HTML stylesheet (``--stylesheet``). Default: None. Options: ``--pep-stylesheet``. -------------------- ------------------------------------------------ pep_template (PEP/HTML Writer.) Path to PEP template file - [#pwd]. + [#pwd]_. Default: "pep-html-template" (in current directory). Options: ``--pep-template``. @@ -426,7 +426,7 @@ source_url An explicit URL for a "View document source" Default: compute if source_link (None). Options: ``--source-uri, --no-source-link``. -------------------- ------------------------------------------------ -stylesheet (HTML Writer.) Path to CSS stylesheet [#pwd]. +stylesheet (HTML Writer.) Path to CSS stylesheet [#pwd]_. Default: "default.css". Options: ``--stylesheet``. @@ -440,7 +440,7 @@ toc_backlinks Enable backlinks from section titles to table of --no-toc-backlinks``. -------------------- ------------------------------------------------ warning_stream Path to a file for the output of system messages - (warnings) [#pwd]. + (warnings) [#pwd]_. Default: stderr (None). Options: ``--warnings``. -- cgit v1.2.1 From 2a5a926315c1ef3dfe6c0a62329da715f0ba4a01 Mon Sep 17 00:00:00 2001 From: chodorowski <chodorowski@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 1 Aug 2002 10:01:18 +0000 Subject: Added translation for "dedication". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@436 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 67d37df00..f2019c16e 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -26,6 +26,7 @@ labels = { 'status': u'Status', 'date': u'Datum', 'copyright': u'Copyright', + 'dedication': u'Dedikation', 'abstract': u'Sammanfattning', 'attention': u'Observera!', 'caution': u'Varning!', @@ -48,6 +49,7 @@ bibliographic_fields = { u'status': nodes.status, u'datum': nodes.date, u'copyright': nodes.copyright, + u'dedikation': nodes.topic, u'sammanfattning': nodes.topic } """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" -- cgit v1.2.1 From e3645352686aa984895833ad4c300e570c506ee8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 2 Aug 2002 03:27:50 +0000 Subject: Made ``argv`` a parameter to ``main()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@437 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index c4b52d47b..b03a6019a 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -397,16 +397,19 @@ def browse_remote(pep): webbrowser.open(url) -def main(): +def main(argv=None): # defaults update = 0 username = '' verbose = 1 browse = 0 + if argv is None: + argv = sys.argv[1:] + try: opts, args = getopt.getopt( - sys.argv[1:], 'bihqu:', + argv, 'bihqu:', ['browse', 'install', 'help', 'quiet', 'user=']) except getopt.error, msg: usage(1, msg) -- cgit v1.2.1 From 7991633913061d37950de322af8b9367f26e6fdc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 2 Aug 2002 03:30:22 +0000 Subject: Added "--silent" option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@438 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tools/buildhtml.py b/tools/buildhtml.py index 310790899..97b1bf000 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -43,7 +43,9 @@ class OptionSpec: 'the default.', ['--recurse'], {'action': 'store_true', 'default': 1}), ('Do not scan subdirectories for files to process.', - ['--local'], {'dest': 'recurse', 'action': 'store_false'}),)) + ['--local'], {'dest': 'recurse', 'action': 'store_false'}), + ('Work silently (no progress messages). Independent of "--quiet".', + ['--silent'], {'action': 'store_true'}),)) class OptionParser(frontend.OptionParser): @@ -83,9 +85,10 @@ class Builder: os.path.walk(directory, self.visit, recurse) def visit(self, recurse, directory, names): - print >>sys.stderr, '/// Processing directory:', directory - sys.stderr.flush() options = self.get_options(directory) + if not options.silent: + print >>sys.stderr, '/// Processing directory:', directory + sys.stderr.flush() peps_found = 0 for name in names: if name.endswith('.txt'): @@ -102,8 +105,9 @@ class Builder: options._source = os.path.normpath(os.path.join(directory, name)) options._destination = options._source[:-4]+'.html' self.pub.options = options - print >>sys.stderr, ' ::: Processing .txt:', name - sys.stderr.flush() + if not options.silent: + print >>sys.stderr, ' ::: Processing .txt:', name + sys.stderr.flush() self.pub.source = io.FileIO(options, source_path=options._source) self.pub.destination = io.FileIO( options, destination_path=options._destination) @@ -112,10 +116,14 @@ class Builder: def process_peps(self, options, directory): old_directory = os.getcwd() os.chdir(directory) - print >>sys.stderr, ' ::: Processing PEPs:' - sys.stderr.flush() + if options.silent: + argv = ['-q'] + else: + print >>sys.stderr, ' ::: Processing PEPs:' + sys.stderr.flush() + argv = [] pep2html.docutils_options = options - pep2html.main() + pep2html.main(argv) os.chdir(old_directory) def process_command_line(self): @@ -129,8 +137,6 @@ class Builder: frontend.make_paths_absolute(self.config_settings) self.cmdline_options = option_parser.parse_args( values=frontend.Values()) # no defaults - # Clear out the command-line options so pep2html doesn't see them: - del sys.argv[1:] def get_options(self, directory=None): """ -- cgit v1.2.1 From 7f748ab02632f42643865c7d021e8845e677ed3e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 2 Aug 2002 03:32:12 +0000 Subject: Added "silent" setting for ``buildhtml.py``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@440 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 35c5d2e98..f58a7a62d 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -413,6 +413,13 @@ report_level Verbosity threshold at or above which system Default: warning (2). Options: ``--report, -r, --verbose, --quiet, -q``. -------------------- ------------------------------------------------ +silent (``buildhtml.py`` front end.) Work silently (no + progress messages). Independent of + "report_level". + + Default: show progress (None). Options: + ``--silent``. +-------------------- ------------------------------------------------ source_link Include a "View document source" link in the document footer. URL will be relative to the destination. @@ -445,7 +452,7 @@ warning_stream Path to a file for the output of system messages Default: stderr (None). Options: ``--warnings``. -For Internal Use Only (setting these in a config file has no effect) +**For Internal Use Only** (setting these in a config file has no effect) ---------------------------------------------------------------------- _directories (``buildhtml.py`` front end.) List of paths to source directories, set from positional -- cgit v1.2.1 From 415ea7d3b8d5217275984c80b475d4cf2da5b00d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 2 Aug 2002 03:34:18 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@441 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 16 ++++++++++++++++ README.txt | 3 ++- docs/dev/todo.txt | 21 +++++++++++++++++++-- docutils/__init__.py | 2 +- setup.py | 2 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6af5b203e..af3a66198 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -34,6 +34,22 @@ hard cash :-).) Hopefully I haven't forgotten anyone or misspelled any names; apologies (and please let me know!) if I have. +Changes Since 0.2 +======================== + +* docs/tools.txt: + + - Added "silent" setting for ``buildhtml.py``. + +* tools/buildhtml.py: + + - Added "--silent" option. + +* tools/pep2html.py: + + - Made ``argv`` a parameter to ``main()``. + + Release 0.2 (2002-07-31) ======================== diff --git a/README.txt b/README.txt index fe0ccb550..d77600ffc 100644 --- a/README.txt +++ b/README.txt @@ -36,7 +36,8 @@ and usually bug-free: To keep up to date on the latest developments, download fresh copies of the snapshots regularly. New functionality is being added weekly, sometimes daily. (There's also the CVS repository, and a mailing list -for CVS messages. See the web site for details; address above.) +for CVS messages. See the web site [address above] or spec/notes.txt +for details.) Requirements diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 62412811a..24be32a61 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -314,8 +314,11 @@ __ rst/alternatives.html#or-not-to-do non-alphanumeric non-whitespace character. - Decide whether or not to implement Simon Budig's "inline external - targets" syntax idea, and if so, how (pragma directive or full-blown - addition to the spec & parser). + targets" syntax idea, and if so, how: + + - regular directive affecting its indented text block + - pragma directive affecting the entire document + - or a full-blown addition to the spec & parser - Add support for pragma (syntax-altering) directives. @@ -883,6 +886,20 @@ structure is recommended:: # code and tools/ files into the right # places in Docutils. + +Release Checklist +================= + +* Edit the version number in the following files: + + + docutils: + + - setup.py + - HISTORY.txt + - docutils/__init__.py + + + web: index.txt + .. Local Variables: diff --git a/docutils/__init__.py b/docutils/__init__.py index ba75a4427..d2b58ae0e 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -56,7 +56,7 @@ Subpackages: """ __docformat__ = 'reStructuredText' -__version__ = '0.1+' +__version__ = '0.2+' class ApplicationError(StandardError): pass diff --git a/setup.py b/setup.py index 06393c568..636619bb6 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ def do_setup(): description = 'Python Documentation Utilities', #long_description = '', url = 'http://docutils.sourceforge.net/', - version = '0.2', + version = '0.2+', author = 'David Goodger', author_email = 'goodger@users.sourceforge.net', license = 'public domain, Python, BSD (see COPYING.txt)', -- cgit v1.2.1 From a411812a5ace3c65515654456a2cf329b4119e44 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 3 Aug 2002 15:43:50 +0000 Subject: - "name" attributes only on these tags: a, applet, form, frame, iframe, img, map. - Add "name" attribute to <a> in section titles for Netscape 4 support (bug report: Pearu Peterson). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@442 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 78e5803a4..2412a1b5c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -105,6 +105,8 @@ class HTMLTranslator(nodes.NodeVisitor): generator = '<meta name="generator" content="Docutils: ' \ 'http://docutils.sourceforge.net/">\n' stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' + named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, + 'img': 1, 'map': 1} def __init__(self, document): nodes.NodeVisitor.__init__(self, document) @@ -153,6 +155,7 @@ class HTMLTranslator(nodes.NodeVisitor): Construct and return a start tag given a node (id & class attributes are extracted), tag name, and optional attributes. """ + tagname = tagname.lower() atts = {} for (name, value) in attributes.items(): atts[name.lower()] = value @@ -163,11 +166,11 @@ class HTMLTranslator(nodes.NodeVisitor): for att in ('id',): # node attribute overrides if node.has_key(att): atts[att] = node[att] - if atts.has_key('id'): + if atts.has_key('id') and self.named_tags.has_key(tagname): atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() attlist.sort() - parts = [tagname.lower()] + parts = [tagname] for name, value in attlist: if value is None: # boolean attribute # According to the HTML spec, ``<element boolean>`` is good, @@ -915,12 +918,12 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.body.append( self.starttag(node, 'h%s' % self.section_level, '')) - context = '' + atts = {'name': node.parent['id']} if node.hasattr('refid'): - self.body.append('<a class="toc-backref" href="#%s">' - % node['refid']) - context = '</a>' - self.context.append('%s</h%s>\n' % (context, self.section_level)) + atts['class'] = 'toc-backref' + atts['href'] = '#' + node['refid'] + self.body.append(self.starttag({}, 'a', '', **atts) + self.context.append('</a></h%s>\n' % (self.section_level)) def depart_title(self, node): self.body.append(self.context.pop()) -- cgit v1.2.1 From ddcb0e28d9953527e67dd6c57ff1c2cfda4db40f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 3 Aug 2002 15:46:05 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@443 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2412a1b5c..8dca22daf 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -922,7 +922,7 @@ class HTMLTranslator(nodes.NodeVisitor): if node.hasattr('refid'): atts['class'] = 'toc-backref' atts['href'] = '#' + node['refid'] - self.body.append(self.starttag({}, 'a', '', **atts) + self.body.append(self.starttag({}, 'a', '', **atts)) self.context.append('</a></h%s>\n' % (self.section_level)) def depart_title(self, node): -- cgit v1.2.1 From 90b5fbc2436e55d24b306af0f63239513ca01700 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 3 Aug 2002 15:52:34 +0000 Subject: Sometimes a <section> doesn't have an ID ("Docutils System Messages"). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@444 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8dca22daf..8c620d79d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -918,7 +918,9 @@ class HTMLTranslator(nodes.NodeVisitor): else: self.body.append( self.starttag(node, 'h%s' % self.section_level, '')) - atts = {'name': node.parent['id']} + atts = {} + if node.parent.hasattr('id'): + atts['name'] = node.parent['id'] if node.hasattr('refid'): atts['class'] = 'toc-backref' atts['href'] = '#' + node['refid'] -- cgit v1.2.1 From b581b58ae8e7da7de63a48df9bd31f4b95e377a6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 3 Aug 2002 17:57:22 +0000 Subject: - Moved the "id" attribute from TOC list items to the references (``Contents.build_contents()``). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@445 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 5c778fb12..8b835f276 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -85,11 +85,11 @@ class Contents(Transform): entrytext = self.copy_and_filter(title) reference = nodes.reference('', '', refid=section['id'], *entrytext) + ref_id = self.document.set_id(reference) entry = nodes.paragraph('', '', reference) item = nodes.list_item('', entry) - itemid = self.document.set_id(item) if self.backlinks == 'entry': - title['refid'] = itemid + title['refid'] = ref_id elif self.backlinks == 'top': title['refid'] = self.toc_id if level < depth: -- cgit v1.2.1 From ae13869ee63c7ae64140e871af20b91000495388 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 3 Aug 2002 18:02:03 +0000 Subject: Fixed targets (names) on footnotes, citations, and topic titles (for Netscape 4). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@446 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8c620d79d..ee804e5cc 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -549,9 +549,9 @@ class HTMLTranslator(nodes.NodeVisitor): and node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: - self.context.append(('</a>', '')) - self.context.append(('<a class="fn-backref" href="#%s">' - % backrefs[0],)) + self.context.append('') + self.context.append('<a class="fn-backref" href="#%s" ' + 'name="%s">' % (backrefs[0], node['id'])) else: i = 1 backlinks = [] @@ -559,11 +559,11 @@ class HTMLTranslator(nodes.NodeVisitor): backlinks.append('<a class="fn-backref" href="#%s">%s</a>' % (backref, i)) i += 1 - self.context.append(('', '(%s) ' % ', '.join(backlinks))) - self.context.append(('',)) + self.context.append('(%s) ' % ', '.join(backlinks)) + self.context.append('<a name="%s">' % node['id']) else: - self.context.append(('', '')) - self.context.append(('',)) + self.context.append('') + self.context.append('<a name="%s">' % node['id']) def depart_footnote(self, node): self.body.append('</td></tr>\n' @@ -627,7 +627,7 @@ class HTMLTranslator(nodes.NodeVisitor): CLASS='label')) def depart_label(self, node): - self.body.append(']%s</td><td>%s' % self.context.pop()) + self.body.append(']</a></td><td>%s' % self.context.pop()) def visit_legend(self, node): self.body.append(self.starttag(node, 'div', CLASS='legend')) @@ -908,7 +908,12 @@ class HTMLTranslator(nodes.NodeVisitor): if isinstance(node.parent, nodes.topic): self.body.append( self.starttag(node, 'p', '', CLASS='topic-title')) - self.context.append('</p>\n') + if node.parent.hasattr('id'): + self.body.append( + self.starttag({}, 'a', '', name=node.parent['id'])) + self.context.append('</a></p>\n') + else: + self.context.append('</p>\n') elif self.section_level == 0: # document title self.head.append('<title>%s\n' -- cgit v1.2.1 From 3bbb14e798d82df66f5927610f4846c802e7719d Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 18:35:01 +0000 Subject: Fixed targets (names) on problematic and system_message (for Netscape 4). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@447 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ee804e5cc..b12e628e3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -743,7 +743,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_problematic(self, node): if node.hasattr('refid'): - self.body.append('' % node['refid']) + self.body.append('' % (node['refid'], + node['id'])) self.context.append('') else: self.context.append('') @@ -820,24 +821,28 @@ class HTMLTranslator(nodes.NodeVisitor): raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) self.body.append('

') + attr = {} + a_end = '' + backref_text = '' + if node.hasattr('id'): + attr['name'] = node['id'] if node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: - self.body.append('%s ' - '(level %s system message)

\n' - % (backrefs[0], node['type'], node['level'])) + attr['href'] = '#' + backrefs[0] else: i = 1 backlinks = [] for backref in backrefs: backlinks.append('%s' % (backref, i)) i += 1 - self.body.append('%s (%s; level %s system message)

\n' - % (node['type'], ', '.join(backlinks), - node['level'])) - else: - self.body.append('%s (level %s system message)

\n' - % (node['type'], node['level'])) + backref_text = '%s; ' % ', '.join(backlinks) + if attr: + self.body.append(self.starttag({}, 'a', attr, '')) + a_end = '' + self.body.append('%s%s (%slevel %s system message)

\n' + % (node['type'], a_end, backref_text, + node['level'])) def depart_system_message(self, node): self.body.append('\n') -- cgit v1.2.1 From 9262e52a8ffdd20c02f27f329483a9fd3ce9a6b6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 18:39:38 +0000 Subject: buglet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@448 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b12e628e3..1c0eade3e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -838,7 +838,7 @@ class HTMLTranslator(nodes.NodeVisitor): i += 1 backref_text = '%s; ' % ', '.join(backlinks) if attr: - self.body.append(self.starttag({}, 'a', attr, '')) + self.body.append(self.starttag({}, 'a', '', attr)) a_end = '' self.body.append('%s%s (%slevel %s system message)

\n' % (node['type'], a_end, backref_text, -- cgit v1.2.1 From 33ab19e98898244b41e4a442fee68713a5c8a00e Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 18:42:10 +0000 Subject: buglet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@449 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1c0eade3e..2a9773a56 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -838,7 +838,7 @@ class HTMLTranslator(nodes.NodeVisitor): i += 1 backref_text = '%s; ' % ', '.join(backlinks) if attr: - self.body.append(self.starttag({}, 'a', '', attr)) + self.body.append(self.starttag({}, 'a', '', **attr)) a_end = '' self.body.append('%s%s (%slevel %s system message)

\n' % (node['type'], a_end, backref_text, -- cgit v1.2.1 From 8a3f3452d5f1810da1d6fe284baf1e98edc6e974 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 19:14:40 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@450 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 21 ++++++++++++++++++--- docs/dev/todo.txt | 3 --- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index af3a66198..f514764c6 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -23,9 +23,10 @@ and related projects: Tony Ibbs, Alan Jaffray, Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, - Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli Schlaepfer, - Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van - Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Pearu Peterson, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli + Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, + Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, + Moshe Zadka Thank you! @@ -37,6 +38,20 @@ any names; apologies (and please let me know!) if I have. Changes Since 0.2 ======================== +* docutils/transforms/parts.py: + + - Moved the "id" attribute from TOC list items to the references + (``Contents.build_contents()``). + +* docutils/writers/html4css1.py: + + - "name" attributes only on these tags: a, applet, form, frame, + iframe, img, map. + - Add "name" attribute to 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). + * docs/tools.txt: - Added "silent" setting for ``buildhtml.py``. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 24be32a61..e4d0cc69f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -586,9 +586,6 @@ HTML Writer - Add more support for elements, especially for navigation bars. -- "name" attributes only on these tags: a, applet, form, frame, - iframe, img, map. - Front-End Tools --------------- -- cgit v1.2.1 From 7a5a460f62ecc8141af024aa01bc6612d8301ed8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 20:21:37 +0000 Subject: Changed field names from "" to "". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@451 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2a9773a56..de25de2fc 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -394,7 +394,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.head.append('\n' % (name, self.attval(node.astext()))) self.body.append(self.starttag(node, 'tr', '')) - self.body.append('%s: \n' + self.body.append('%s: \n' % self.language.labels[name]) def depart_docinfo_item(self): @@ -487,7 +487,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_field_body(self, node): - self.body.append(': ') + self.body.append(': ') self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) if len(node) and isinstance(node[0], nodes.paragraph): node[0].set_class('first') @@ -510,7 +510,7 @@ class HTMLTranslator(nodes.NodeVisitor): class_name = 'docinfo-name' else: class_name = 'field-name' - self.body.append(self.starttag(node, 'td', '', CLASS=class_name)) + self.body.append(self.starttag(node, 'th', '', CLASS=class_name)) def depart_field_name(self, node): """ -- cgit v1.2.1 From 3876764b213354e4a6e86017ca3fc7d12fadf235 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Aug 2002 20:23:00 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@452 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + tools/stylesheets/default.css | 4 ++-- tools/stylesheets/pep.css | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index f514764c6..39fc5cada 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -51,6 +51,7 @@ Changes Since 0.2 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 "" to "". * docs/tools.txt: diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index a7842ed3c..d1dd52155 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -167,9 +167,9 @@ td, th { padding-right: 0.5em ; vertical-align: baseline } -td.docinfo-name { +th.docinfo-name { font-weight: bold ; text-align: right } -td.field-name { +th.field-name { font-weight: bold } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index a38cb1d61..0af6d129d 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -36,7 +36,7 @@ Default cascading style sheet for the PEP HTML output of Docutils. .rfc2822 div.field-body { text-align: left } -.rfc2822 td.field-name { +.rfc2822 th.field-name { text-align: right ; font-family: sans-serif ; padding-right: 0.5em ; @@ -219,3 +219,6 @@ td, th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: baseline } + +th.field-name { + font-weight: bold } -- cgit v1.2.1 From a55a4fb8cf2a716bfecabe1e292fa945a4d3b06a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Aug 2002 04:10:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@453 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 0af6d129d..8c6a2424f 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -33,10 +33,10 @@ Default cascading style sheet for the PEP HTML output of Docutils. margin-right: 0.5em ; margin-bottom: 0em } -.rfc2822 div.field-body { +.rfc2822 td { text-align: left } -.rfc2822 th.field-name { +.rfc2822 th { text-align: right ; font-family: sans-serif ; padding-right: 0.5em ; -- cgit v1.2.1 From 9ce4ad12cb84b65e8c52697119ed2fce6dc3babe Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Aug 2002 20:04:20 +0000 Subject: Merged changes from Python's revision 1.39. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@454 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index b03a6019a..9952087d2 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -31,6 +31,8 @@ Options: The optional argument `peps' is a list of either pep numbers or .txt files. """ +# Requires Python 2.2 + import sys import os import re @@ -40,6 +42,7 @@ import getopt import errno import random import time +from email.Utils import parseaddr PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' @@ -64,6 +67,7 @@ fixpat = re.compile("((http|ftp):[-_a-zA-Z0-9/.+~:?#$=&,]+)|(pep-\d+(.txt)?)|" EMPTYSTRING = '' SPACE = ' ' +COMMASPACE = ', ' @@ -180,19 +184,20 @@ def fixfile(infile, outfile): for k, v in header: if k.lower() in ('author', 'discussions-to'): mailtos = [] - for addr in v.split(): - if '@' in addr: + for part in re.split(',\s*', v): + if '@' in part: + realname, addr = parseaddr(part) if k.lower() == 'discussions-to': m = linkemail(addr, pep) else: m = fixemail(addr, pep) - mailtos.append(m) - elif addr.startswith('http:'): + mailtos.append('%s <%s>' % (realname, m)) + elif part.startswith('http:'): mailtos.append( - '%s' % (addr, addr)) + '%s' % (part, part)) else: - mailtos.append(addr) - v = SPACE.join(mailtos) + mailtos.append(part) + v = COMMASPACE.join(mailtos) elif k.lower() in ('replaces', 'replaced-by'): otherpeps = '' for otherpep in v.split(): -- cgit v1.2.1 From 6e9d13e192d14bb626255e5a06dbcfed07122564 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 4 Aug 2002 21:08:35 +0000 Subject: docstring update git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@455 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 74ff8830a..025405029 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -27,6 +27,12 @@ Where: element the directive produces. Currently, only an "alt" attribute is passed by substitution definitions (value: the substitution name), which may by used by an embedded image directive. + +Directive functions return a tuple of two values: + +- a list of nodes which will be inserted into the document tree at the point + where the directive was encountered (can be an empty list), and +- a boolean: true iff the directive block finished at a blank line. """ __docformat__ = 'reStructuredText' -- cgit v1.2.1 From 88a5dd42dc5c2a6b77c637700f963e2624932529 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 5 Aug 2002 16:50:17 +0000 Subject: Added ``mask_email()`` function, updating to pep2html.py's functionality. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@456 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 57 +++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 618061649..ec8cc91fe 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -84,17 +84,12 @@ class Headers(Transform): para = body[0] if name == 'author': for node in para: - if isinstance(node, nodes.reference) \ - and node.has_key('refuri') \ - and node['refuri'].startswith('mailto:'): - replacement = node.astext().replace('@', ' at ') - node.parent.replace(node, nodes.Text(replacement)) + if isinstance(node, nodes.reference): + node.parent.replace(node, mask_email(node)) elif name == 'discussions-to': for node in para: - if isinstance(node, nodes.reference) \ - and node.has_key('refuri') \ - and node['refuri'].startswith('mailto:'): - node['refuri'] += '?subject=PEP%%20%s' % pep + if isinstance(node, nodes.reference): + node.parent.replace(node, mask_email(node, pep)) elif name in ('replaces', 'replaced-by'): newbody = [] space = nodes.Text(' ') @@ -144,28 +139,19 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): """ Perform the special processing needed by PEP 0: - - For all email-address references 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` and addresses in the - "Discussions-To" field). + - Mask email addresses. - Link PEP numbers in the second column of 4-column tables to the PEPs themselves. """ - non_masked_addresses = ('peps@python.org', - 'python-list@python.org', - 'python-dev@python.org') pep_url = Headers.pep_url def unknown_visit(self, node): pass def visit_reference(self, node): - if node.hasattr('refuri') and node['refuri'].startswith('mailto:') \ - and node['refuri'][8:] not in self.non_masked_addresses: - replacement = node.astext().replace('@', ' at ') - node.parent.replace(node, nodes.Text(replacement)) + node.parent.replace(node, mask_email(node)) def visit_field_list(self, node): if node.hasattr('class') and node['class'] == 'rfc2822': @@ -196,3 +182,34 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): 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 -- cgit v1.2.1 From 6d62cbfd975dd9cc39eca06f70e9a23daba93150 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 5 Aug 2002 16:51:03 +0000 Subject: Added "@" to "@" encoding to thwart address harvesters. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@457 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index de25de2fc..63b51fb48 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -143,6 +143,7 @@ class HTMLTranslator(nodes.NodeVisitor): text = text.replace("<", "<") text = text.replace('"', """) text = text.replace(">", ">") + text = text.replace("@", "@") # may thwart some address harvesters return text def attval(self, text, -- cgit v1.2.1 From c0b162dca2a7e9a61d57ad46aa444b025a1e650b Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 5 Aug 2002 16:55:05 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@458 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 +++++ docs/dev/todo.txt | 68 +++++++++++++++++++++++++++++++++++++++++++++++--- docs/peps/pep-0287.txt | 3 ++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 39fc5cada..96973b4f9 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -43,6 +43,11 @@ Changes Since 0.2 - Moved the "id" attribute from TOC list items to the references (``Contents.build_contents()``). +* docutils/transforms/peps.py: + + - Added ``mask_email()`` function, updating to pep2html.py's + functionality. + * docutils/writers/html4css1.py: - "name" attributes only on these tags: a, applet, form, frame, @@ -52,6 +57,7 @@ Changes Since 0.2 - Fixed targets (names) on footnote, citation, topic title, problematic, and system_message nodes (for Netscape 4). - Changed field names from "" to "". + - Added "@" to "@" encoding to thwart address harvesters. * docs/tools.txt: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e4d0cc69f..8814a4524 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -50,6 +50,10 @@ Bugs whitespace and punctuation as markup delimiters, which may not be applicable in these languages. +- Text like "``--an-option``" can get wrapped badly in HTML browsers, + like "``--\nan-option``". Should inline literals prevent soft + linebreaks? Allow breaks at whitespace or not at all? + General ------- @@ -341,8 +345,6 @@ Directives - _`parts.citations`: See `Footnote & Citation Gathering`_. - - _`parts.topic` (maybe "body.topic") - - _`parts.sectnum` (section numbering; add support to .contents; could be cmdline option also) @@ -381,6 +383,8 @@ Directives problem similar to the first problem listed for misc.encoding_, although to a lesser degree. + - _`body.topic` + - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) @@ -490,7 +494,65 @@ Directives - _`body.example`: Examples; suggested by Simon Hefti. Semantics as per Docbook's "example"; admonition-style, numbered, reference, - with a caption/title. (Maybe "admonitions.example"?) + with a caption/title. + + - _`body.index`: Index targets. + + Were I writing a book with an index, I guess I'd need two + different kinds of index tags: inline/implicit and + out-of-line/explicit. For example:: + + In this `paragraph`:index:, several words are being + `marked`:index: inline as implicit `index`:index: + entries. + + .. index:: markup + .. index:: syntax + + The explicit index directives above would refer to + this paragraph. + + The words "paragraph", "marked", and "index" would become index + entries pointing at the words in the first paragraph. The index + entries appear verbatim in the text. (Don't worry about the ugly + ":index:" part; if indexing is the only application of interpreted + text in your documents, it can be implicit and omitted.) The two + directives provide manual indexing, where the index entry words + ("markup" and "syntax") do not appear in the main text. We could + combine the two directives into one:: + + .. index:: markup; syntax + + Semicolons instead of commas because commas could *be* part of the + index entry, like:: + + .. index:: van Rossum, Guido + + Sometimes index entries have multiple levels. Given:: + + .. index:: statement syntax: expression statements + + In a hypothetical index, combined with other entries, it might + look like this:: + + statement syntax + expression statements ..... 56 + assignment ................ 57 + simple statements ......... 58 + compound statements ....... 60 + + Inline multi-level index targets could be done too. Something + like:: + + When dealing with `expression statements `, + we must remember ... + + The opposite sense could also be possible:: + + When dealing with `index entries <:multi-level>`, there are + many permutations to consider. + + Also "see / see also" index entries. - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index c03cf9007..16f143e9b 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -2,10 +2,11 @@ PEP: 287 Title: reStructuredText Docstring Format Version: $Revision$ Last-Modified: $Date$ -Author: goodger@users.sourceforge.net (David Goodger) +Author: David Goodger Discussions-To: doc-sig@python.org Status: Draft Type: Informational +Content-Type: text/x-rst Created: 25-Mar-2002 Post-History: 02-Apr-2002 Replaces: 216 -- cgit v1.2.1 From e9989ec41dc36cbef0e6e199ce65d786965643bc Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 5 Aug 2002 19:51:20 +0000 Subject: Added support for "Content-Type:" header & arbitrary PEP formats. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@459 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 126 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 9952087d2..28cfd9a0b 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -44,6 +44,11 @@ import random import time from email.Utils import parseaddr +try: + import docutils +except ImportError: + docutils = None + PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' @@ -128,8 +133,9 @@ def linkemail(address, pepno): % (parts[0], parts[1], pepno, parts[0], parts[1])) -def fixfile(infile, outfile): - basename = os.path.basename(infile.name) +def fixfile(inpath, input_lines, outfile): + basename = os.path.basename(inpath) + infile = iter(input_lines) # convert plain text pep to minimal XHTML markup print >> outfile, DTD print >> outfile, '' @@ -139,7 +145,10 @@ def fixfile(infile, outfile): pep = "" title = "" while 1: - line = infile.readline() + try: + line = infile.next() + except StopIteration: + break if not line.strip(): break if line[0].strip(): @@ -202,13 +211,13 @@ def fixfile(infile, outfile): otherpeps = '' for otherpep in v.split(): otherpep = int(otherpep) - otherpeps += '%i ' % (otherpep, + otherpeps += '%i ' % (otherpep, otherpep) v = otherpeps elif k.lower() in ('last-modified',): url = PEPCVSURL % int(pep) date = v or time.strftime('%d-%b-%Y', - time.localtime(os.stat(infile.name)[8])) + time.localtime(os.stat(inpath)[8])) v = '%s ' % (url, cgi.escape(date)) else: v = cgi.escape(v) @@ -220,8 +229,9 @@ def fixfile(infile, outfile): print >> outfile, '
' need_pre = 1 while 1: - line = infile.readline() - if not line: + try: + line = infile.next() + except StopIteration: break if line[0] == '\f': continue @@ -260,7 +270,7 @@ def fixfile(infile, outfile): print >> outfile, re.sub( parts[-1], url, line, 1), continue - line = fixpat.sub(lambda x, c=infile.name: fixanchor(c, x), line) + line = fixpat.sub(lambda x, c=inpath: fixanchor(c, x), line) if need_pre: print >> outfile, '
'
                 need_pre = 0
@@ -273,8 +283,10 @@ def fixfile(infile, outfile):
 
 
 docutils_options = None
+"""Option value object used by Docutils.  Can be set by the client application
+when this module is imported."""
 
-def fix_rst_pep(infile, outfile):
+def fix_rst_pep(inpath, input_lines, outfile):
     from docutils import core, io
     pub = core.Publisher()
     pub.set_reader(reader_name='pep', parser_name='restructuredtext',
@@ -285,48 +297,36 @@ def fix_rst_pep(infile, outfile):
         pub.options = options
     else:
         options = pub.set_options()
-    options._source = infile.name
+    options._source = inpath
     options._destination = outfile.name
-    pub.source = io.FileIO(options, source=infile, source_path=infile.name)
-    pub.destination = io.FileIO(options, destination=outfile,
-                                destination_path=outfile.name)
+    pub.source = io.StringIO(
+        options, source=''.join(input_lines), source_path=inpath)
+    pub.destination = io.FileIO(
+        options, destination=outfile, destination_path=outfile.name)
     pub.publish()
 
 
-underline = re.compile('[!-/:-@[-`{-~]{4,}$')
-
-def check_rst_pep(infile):
+def get_pep_type(input_lines):
     """
-    Check if `infile` is a reStructuredText PEP.  Return 1 for yes, 0 for no.
-
-    If the result is indeterminate, return None.  When the check is complete,
-    rewind `infile` to the beginning.
+    Return the Content-Type of the input.  "text/plain" is the default.
+    Return ``None`` if the input is not a PEP.
     """
-    result = None
-    underline_match = underline.match
-    # Find the end of the RFC 2822 header (first blank line):
-    while 1:
-        line = infile.readline().strip()
+    pep_type = None
+    for line in input_lines:
+        line = line.rstrip().lower()
         if not line:
+            # End of the RFC 2822 header (first blank line).
             break
-    # Determine if the PEP is old-style or new (reStructuredText):
-    while result is None:
-        line = infile.readline()
-        if not line:
+        elif line.startswith('content-type: '):
+            pep_type = line.split()[1]
             break
-        line = line.rstrip()
-        if len(line.lstrip()) < len(line):
-            # Indented section; this is an old-style PEP.
-            result = 0
-        elif underline_match(line):
-            # Matched a section header underline;
-            # this is a reStructuredText PEP.
-            result = 1
-    infile.seek(0)
-    return result
+        elif line.startswith('pep: '):
+            # Default PEP type, used if no explicit content-type specified:
+            pep_type = 'text/plain'
+    return pep_type
 
 
-def open_files(inpath, outpath):
+def get_input_lines(inpath):
     try:
         infile = open(inpath)
     except IOError, e:
@@ -334,14 +334,10 @@ def open_files(inpath, outpath):
         print >> sys.stderr, 'Error: Skipping missing PEP file:', e.filename
         sys.stderr.flush()
         return None, None
-    outfile = open(outpath, "w")
-    return infile, outfile
-
-def close_files(infile, outfile):
+    lines = infile.readlines()
     infile.close()
-    outfile.close()
-    os.chmod(outfile.name, 0664)
-    
+    return lines
+
 
 def find_pep(pep_str):
     """Find the .txt file indicated by a cmd line argument"""
@@ -350,18 +346,35 @@ def find_pep(pep_str):
     num = int(pep_str)
     return "pep-%04d.txt" % num
 
+PEP_TYPE_DISPATCH = {'text/plain': fixfile,
+                     'text/x-rst': fix_rst_pep}
+
 def make_html(inpath, verbose=0):
+    input_lines = get_input_lines(inpath)
+    pep_type = get_pep_type(input_lines)
+    if pep_type is None:
+        print >> sys.stderr, 'Error: Input file %s is not a PEP.' % inpath
+        sys.stdout.flush()
+        return None
+    elif not PEP_TYPE_DISPATCH.has_key(pep_type):
+        print >> sys.stderr, ('Error: Unknown PEP type for input file %s: %s'
+                              % (inpath, pep_type))
+        sys.stdout.flush()
+        return None
+    elif pep_type == 'text/x-rst' and not docutils:
+        print >> sys.stderr, ('Error: Docutils not present for "%s" PEP file '
+                              '%s.  See README.txt for installation.'
+                              % (pep_type, inpath))
+        sys.stdout.flush()
+        return None
     outpath = os.path.splitext(inpath)[0] + ".html"
     if verbose:
-        print inpath, "->", outpath
+        print inpath, "(%s)" % pep_type, "->", outpath
         sys.stdout.flush()
-    infile, outfile = open_files(inpath, outpath)
-    if infile is not None:
-        if check_rst_pep(infile):
-            fix_rst_pep(infile, outfile)
-        else:
-            fixfile(infile, outfile)
-        close_files(infile, outfile)
+    outfile = open(outpath, "w")
+    PEP_TYPE_DISPATCH[pep_type](inpath, input_lines, outfile)
+    outfile.close()
+    os.chmod(outfile.name, 0664)
     return outpath
 
 def push_pep(htmlfiles, txtfiles, username, verbose):
@@ -438,7 +451,8 @@ def main(argv=None):
             file = find_pep(pep)
             peptxt.append(file)
             newfile = make_html(file, verbose=verbose)
-            html.append(newfile)
+            if newfile:
+                html.append(newfile)
             if browse and not update:
                 browse_file(pep)
     else:
-- 
cgit v1.2.1


From 496d5c948fad38875e737c9b20ae8ddabf34d1b8 Mon Sep 17 00:00:00 2001
From: goodger 
Date: Mon, 5 Aug 2002 19:52:39 +0000
Subject: updated

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@460 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 HISTORY.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/HISTORY.txt b/HISTORY.txt
index 96973b4f9..e0ce636aa 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -70,6 +70,7 @@ Changes Since 0.2
 * tools/pep2html.py:
 
   - Made ``argv`` a parameter to ``main()``.
+  - Added support for "Content-Type:" header & arbitrary PEP formats.
 
 
 Release 0.2 (2002-07-31)
-- 
cgit v1.2.1


From 5db282bc4ae30b9d4a53010c7e1a231ba1bbcbc9 Mon Sep 17 00:00:00 2001
From: goodger 
Date: Tue, 6 Aug 2002 03:58:55 +0000
Subject: updated

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@461 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docs/dev/todo.txt      | 34 ++++++++++++++++++++++++++++++++--
 docs/peps/pep-0287.txt |  9 ++++++++-
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt
index 8814a4524..737e4533e 100644
--- a/docs/dev/todo.txt
+++ b/docs/dev/todo.txt
@@ -54,6 +54,27 @@ Bugs
   like "``--\nan-option``".  Should inline literals prevent soft
   linebreaks?  Allow breaks at whitespace or not at all?
 
+- @@@ This shouldn't be recognized as a list item::
+
+      A. Einstein was a really
+      smart dude.
+
+  The only problem is, what about this? ::
+
+      A. Einstein was a really smart dude.
+
+  This should definitely be a list::
+
+      A. Einstein was a really smart dude.
+      B. So was Carl Sagan.
+
+  Time to put more smarts into the list item recognition code, or
+  just document it as a corner case and require escapes?  E.g.::
+
+      \A. Einstein was a really smart dude.
+
+  (Bug report by Jeremy Hylton.)
+
 
 General
 -------
@@ -116,6 +137,12 @@ General
 - Perhaps the ``Component.supports`` method should deal with
   individual features ("meta" etc.) instead of formats ("html" etc.)?
 
+- @@@ Add references to the user docs: bugs to the SF bug tracker,
+  questions to the mailing lists.
+
+- @@@ Add a transform to remove body-level targets from the doctree,
+  as the first stage of optimization.
+
 
 Specification
 -------------
@@ -383,7 +410,7 @@ Directives
     problem similar to the first problem listed for misc.encoding_,
     although to a lesser degree.
 
-  - _`body.topic`
+  - @@@ _`body.topic`
 
   - _`body.qa` (directive a.k.a. "faq", "questions"): Questions &
     Answers.  Implement as a generic two-column marked list?  As a
@@ -642,12 +669,15 @@ Index
 HTML Writer
 -----------
 
-- @@@ Construct a _`templating system`, as in ht2html/yaptu, using
+- @@ Construct a _`templating system`, as in ht2html/yaptu, using
   directives and substitutions for dynamic stuff.
 
 - Add more support for  elements, especially for navigation
   bars.
 
+- @@@ Add ```` around chunks of text in inline
+  literals, and a "whitespace: pre" style to the stylesheet. 
+
 
 Front-End Tools
 ---------------
diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt
index 16f143e9b..95f11d59c 100644
--- a/docs/peps/pep-0287.txt
+++ b/docs/peps/pep-0287.txt
@@ -3,7 +3,7 @@ Title: reStructuredText Docstring Format
 Version: $Revision$
 Last-Modified: $Date$
 Author: David Goodger 
-Discussions-To: doc-sig@python.org
+Discussions-To: 
 Status: Draft
 Type: Informational
 Content-Type: text/x-rst
@@ -56,6 +56,13 @@ to produce complex documents, and extensible so that there are few
 limits.  Of course, to write reStructuredText documents some prior
 knowledge is required.
 
+The markup offers functionality and expressivity, while maintaining
+easy readability in the source text.  The processed form (HTML etc.)
+makes it all accessible to readers: inline live hyperlinks; live links
+to and from footnotes; automatic tables of contents (with live
+links!); tables; images for diagrams etc.; pleasant, readable styled
+text.
+
 The reStructuredText parser is available now, part of the Docutils_
 project.  Standalone reStructuredText documents and PEPs can be
 converted to HTML; other output format writers are being worked on and
-- 
cgit v1.2.1


From 1b900859f33ba50de9fcef9a07417edfe033922f Mon Sep 17 00:00:00 2001
From: goodger 
Date: Wed, 7 Aug 2002 01:05:41 +0000
Subject:   - Added "Invisible" element category class.   - Changed
 ``Node.walk()`` & ``.walkabout()`` to permit more tree     modification
 during a traversal.

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@462 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docutils/nodes.py | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/docutils/nodes.py b/docutils/nodes.py
index 874659d99..c863c8ef5 100644
--- a/docutils/nodes.py
+++ b/docutils/nodes.py
@@ -66,8 +66,11 @@ class Node:
         `walkabout()` method is similar, except it also calls ``depart_...``
         methods before exiting each node.)
 
-        This tree traversal doesn't handle arbitrary in-place tree
-        modifications.  Replacing one element with one element is OK.
+        This tree traversal supports limited in-place tree
+        modifications.  Replacing one node with one or more nodes is
+        OK, as is removing an element.  However, if the node removed
+        or replaced occurs after the current node, the old node will
+        still be traversed, and any new nodes will not.
 
         Within ``visit_...`` methods (and ``depart_...`` methods for
         `walkabout()`), `TreePruningException` subclasses may be raised
@@ -87,8 +90,8 @@ class Node:
             pass
         children = self.get_children()
         try:
-            for i in range(len(children)):
-                children[i].walk(visitor)
+            for child in children[:]:
+                child.walk(visitor)
         except SkipSiblings:
             pass
 
@@ -115,8 +118,8 @@ class Node:
                 call_depart = 0
             children = self.get_children()
             try:
-                for i in range(len(children)):
-                    children[i].walkabout(visitor)
+                for child in children[:]:
+                    child.walkabout(visitor)
             except SkipSiblings:
                 pass
         except SkipChildren:
@@ -538,6 +541,9 @@ class Admonition(Body): pass
 class Special(Body):
     """Special internal body elements."""
 
+class Invisible:
+    """Internal elements that don't appear in output."""
+
 class Part: pass
 
 class Inline: pass
@@ -928,9 +934,9 @@ class note(Admonition, Element): pass
 class tip(Admonition, Element): pass
 class hint(Admonition, Element): pass
 class warning(Admonition, Element): pass
-class comment(Special, PreBibliographic, TextElement): pass
-class substitution_definition(Special, TextElement): pass
-class target(Special, Inline, TextElement, Targetable): pass
+class comment(Special, Invisible, PreBibliographic, TextElement): pass
+class substitution_definition(Special, Invisible, TextElement): pass
+class target(Special, Invisible, Inline, TextElement, Targetable): pass
 class footnote(General, Element, Labeled, BackLinkable): pass
 class citation(General, Element, Labeled, BackLinkable): pass
 class label(Part, TextElement): pass
@@ -959,7 +965,7 @@ class system_message(Special, PreBibliographic, Element, BackLinkable):
                                Element.astext(self))
 
 
-class pending(Special, PreBibliographic, Element):
+class pending(Special, Invisible, PreBibliographic, Element):
 
     """
     The "pending" element is used to encapsulate a pending operation: the
-- 
cgit v1.2.1


From 66dca2559e93fca4d221305e15099438b00ddc5a Mon Sep 17 00:00:00 2001
From: goodger 
Date: Wed, 7 Aug 2002 01:06:41 +0000
Subject: Added to project.  Contains the "topic" directive.

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@463 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docutils/parsers/rst/directives/body.py | 47 +++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 docutils/parsers/rst/directives/body.py

diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py
new file mode 100644
index 000000000..3cdc1d382
--- /dev/null
+++ b/docutils/parsers/rst/directives/body.py
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+
+"""
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:Revision: $Revision$
+:Date: $Date$
+:Copyright: This module has been placed in the public domain.
+
+Directives for additional body elements.
+"""
+
+__docformat__ = 'reStructuredText'
+
+from docutils import nodes
+
+
+def topic(match, type_name, data, state, state_machine, attributes):
+    lineno = state_machine.abs_line_number()
+    initial_offset = state_machine.line_offset
+    indented, indent, line_offset, blank_finish \
+          = state_machine.get_first_known_indented(match.end())
+    blocktext = '\n'.join(state_machine.input_lines[
+        initial_offset : line_offset + len(indented)])
+    if not state_machine.match_titles:
+        error = state_machine.reporter.error(
+              'Topics may not be nested within body elements (line %s).'
+              % lineno, '', nodes.literal_block(blocktext, blocktext))
+        return [error], blank_finish
+    if not indented:
+        return [], blank_finish
+    title_text = indented.pop(0)
+    textnodes, messages = state.inline_text(title_text, lineno)
+    title = nodes.title(title_text, '', *textnodes)
+    if indented:
+        if indented[0].strip():
+            warning = state_machine.reporter.warning(
+                'The second line of a topic block must be blank (line %s).'
+                % (lineno + 1 + line_offset - initial_offset), '')
+            messages.append(warning)
+        text = '\n'.join(indented)
+    else:
+        text = ''
+    topic_node = nodes.topic(text, title, *messages)
+    if text:
+        state.nested_parse(indented, line_offset, topic_node)
+    return [topic_node], blank_finish
-- 
cgit v1.2.1


From cb4fb1612a6ffa1ef09177bb72043d48139aba94 Mon Sep 17 00:00:00 2001
From: goodger 
Date: Wed, 7 Aug 2002 01:07:18 +0000
Subject: bugfix

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@464 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docutils/readers/pep.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py
index a4dc17cf1..c926723b8 100644
--- a/docutils/readers/pep.py
+++ b/docutils/readers/pep.py
@@ -69,7 +69,7 @@ class Inliner(rst.states.Inliner):
             rfcnum = int(match.group('rfcnum'))
             ref = self.rfc_url % rfcnum
         else:
-            raise MarkupMismatch
+            raise rst.states.MarkupMismatch
         unescaped = rst.states.unescape(text, 0)
         return [nodes.reference(rst.states.unescape(text, 1), unescaped,
                                 refuri=ref)]
-- 
cgit v1.2.1


From 1ca64904a318386d094f5e14b78e4da1db2944ab Mon Sep 17 00:00:00 2001
From: goodger 
Date: Wed, 7 Aug 2002 01:08:29 +0000
Subject: Linked "Content-Type: text/x-rst" to PEP 12.  Added support for
 "Requires:" header.

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@465 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docutils/transforms/peps.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py
index ec8cc91fe..edc9ed382 100644
--- a/docutils/transforms/peps.py
+++ b/docutils/transforms/peps.py
@@ -90,10 +90,10 @@ class Headers(Transform):
                 for node in para:
                     if isinstance(node, nodes.reference):
                         node.parent.replace(node, mask_email(node, pep))
-            elif name in ('replaces', 'replaced-by'):
+            elif name in ('replaces', 'replaced-by', 'requires'):
                 newbody = []
                 space = nodes.Text(' ')
-                for refpep in body.astext().split():
+                for refpep in re.split(',?\s+', body.astext()):
                     pepno = int(refpep)
                     newbody.append(nodes.reference(
                           refpep, refpep, refuri=self.pep_url % pepno))
@@ -104,6 +104,10 @@ class Headers(Transform):
                 date = para.astext()
                 uri = self.pep_cvs_url % int(pep)
                 para[:] = [nodes.reference('', date, refuri=uri)]
+            elif name == 'content-type':
+                pep_type = para.astext()
+                uri = 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)
 
-- 
cgit v1.2.1


From a7adc99cd85872704146a67073f508518f08cadd Mon Sep 17 00:00:00 2001
From: goodger 
Date: Wed, 7 Aug 2002 01:09:40 +0000
Subject:   - Improved the vertical whitespace optimization; ignore "invisible"
     nodes (targets, comments, etc.).   - Improved inline literals with
 ```` around chunks     of text and `` `` for runs of
 spaces.

git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@466 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
---
 docutils/writers/html4css1.py | 49 +++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py
index 63b51fb48..f1861a7f3 100644
--- a/docutils/writers/html4css1.py
+++ b/docutils/writers/html4css1.py
@@ -72,22 +72,22 @@ class HTMLTranslator(nodes.NodeVisitor):
       contain either a single paragraph, a nested simple list, or a
       paragraph followed by a nested simple list.  This means that
       this list can be compact:
-    
+
           - Item 1.
           - Item 2.
-    
+
       But this list cannot be compact:
-    
+
           - Item 1.
-    
+
             This second paragraph forces space between list items.
-    
+
           - Item 2.
-    
+
     - In non-list contexts, omit 

tags on a paragraph if that paragraph is the only child of its parent (footnotes & citations are allowed a label first). - + - Regardless of the above, in definitions, table cells, field bodies, option descriptions, and list items, mark the first child with 'class="first"' if it is a paragraph. The stylesheet @@ -107,6 +107,7 @@ class HTMLTranslator(nodes.NodeVisitor): stylesheet_link = '\n' named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, 'img': 1, 'map': 1} + words_and_spaces = re.compile(r'\S+| +|\n') def __init__(self, document): nodes.NodeVisitor.__init__(self, document) @@ -230,6 +231,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n') def check_simple_list(self, node): + """Check for a simple list that can be rendered compactly.""" visitor = SimpleListChecker(self.document) try: node.walk(visitor) @@ -646,9 +648,16 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_literal(self, node): self.body.append(self.starttag(node, 'tt', '', CLASS='literal')) - - def depart_literal(self, node): + text = node.astext() + for token in self.words_and_spaces.findall(text): + if token in ('\n', ' '): + self.body.append(token) + elif token.strip(): + self.body.append('%s' % token) + else: + self.body.append(' ' * (len(token) - 1) + ' ') self.body.append('') + raise nodes.SkipNode def visit_literal_block(self, node): self.body.append(self.starttag(node, 'pre', suffix='', @@ -991,13 +1000,27 @@ class SimpleListChecker(nodes.GenericNodeVisitor): pass def visit_list_item(self, node): - if len(node) <= 1 or (len(node) == 2 and - isinstance(node[0], nodes.paragraph) and - (isinstance(node[1], nodes.bullet_list) or - isinstance(node[1], nodes.enumerated_list))): + children = [] + for child in node.get_children(): + if not isinstance(child, nodes.Invisible): + children.append(child) + if (children and isinstance(children[0], nodes.paragraph) + and (isinstance(children[-1], nodes.bullet_list) + or isinstance(children[-1], nodes.enumerated_list))): + children.pop() + if len(children) <= 1: return else: raise nodes.NodeFound def visit_paragraph(self, node): raise nodes.SkipNode + + def invisible_visit(self, node): + """Invisible nodes should be ignored.""" + pass + + visit_comment = invisible_visit + visit_substitution_definition = invisible_visit + visit_target = invisible_visit + visit_pending = invisible_visit -- cgit v1.2.1 From a83a3af1132c11079e108f60f7d1ed8c7b76b2ed Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Aug 2002 01:11:08 +0000 Subject: Converted to reStructuredText & updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@467 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0256.txt | 385 +++++++------- docs/peps/pep-0258.txt | 1316 ++++++++++++++++++++++++------------------------ 2 files changed, 860 insertions(+), 841 deletions(-) diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index 7f438a8d8..017ba3b01 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -2,290 +2,301 @@ PEP: 256 Title: Docstring Processing System Framework Version: $Revision$ Last-Modified: $Date$ -Author: goodger@users.sourceforge.net (David Goodger) -Discussions-To: doc-sig@python.org +Author: David Goodger +Discussions-To: Status: Draft Type: Standards Track +Content-Type: text/x-rst Created: 01-Jun-2001 Post-History: 13-Jun-2001 Abstract +======== - Python lends itself to inline documentation. With its built-in - docstring syntax, a limited form of Literate Programming [1]_ is - easy to do in Python. However, there are no satisfactory standard - tools for extracting and processing Python docstrings. The lack - of a standard toolset is a significant gap in Python's - infrastructure; this PEP aims to fill the gap. +Python lends itself to inline documentation. With its built-in +docstring syntax, a limited form of `Literate Programming`_ is easy to +do in Python. However, there are no satisfactory standard tools for +extracting and processing Python docstrings. The lack of a standard +toolset is a significant gap in Python's infrastructure; this PEP aims +to fill the gap. - The issues surrounding docstring processing have been contentious - and difficult to resolve. This PEP proposes a generic Docstring - Processing System (DPS) framework, which separates out the - components (program and conceptual), enabling the resolution of - individual issues either through consensus (one solution) or - through divergence (many). It promotes standard interfaces which - will allow a variety of plug-in components (input context readers, - markup parsers, and output format writers) to be used. +The issues surrounding docstring processing have been contentious and +difficult to resolve. This PEP proposes a generic Docstring +Processing System (DPS) framework, which separates out the components +(program and conceptual), enabling the resolution of individual issues +either through consensus (one solution) or through divergence (many). +It promotes standard interfaces which will allow a variety of plug-in +components (input context readers, markup parsers, and output format +writers) to be used. - The concepts of a DPS framework are presented independently of - implementation details. +The concepts of a DPS framework are presented independently of +implementation details. Roadmap to the Doctring PEPs +============================ - There are many aspects to docstring processing. The "Docstring - PEPs" have broken up the issues in order to deal with each of them - in isolation, or as close as possible. The individual aspects and - associated PEPs are as follows: +There are many aspects to docstring processing. The "Docstring PEPs" +have broken up the issues in order to deal with each of them in +isolation, or as close as possible. The individual aspects and +associated PEPs are as follows: - * Docstring syntax. PEP 287, reStructuredText Docstring Format, - proposes a syntax for Python docstrings, PEPs, and other uses. +* Docstring syntax. PEP 287, "reStructuredText Docstring Format" + [#PEP-287]_, proposes a syntax for Python docstrings, PEPs, and + other uses. - * Docstring semantics consist of at least two aspects: +* Docstring semantics consist of at least two aspects: - - Conventions: the high-level structure of docstrings. Dealt - with in PEP 257, Docstring Conventions. + - Conventions: the high-level structure of docstrings. Dealt with + in PEP 257, "Docstring Conventions" [#PEP-257]_. - - Methodology: rules for the informational content of - docstrings. Not addressed. + - Methodology: rules for the informational content of docstrings. + Not addressed. - * Processing mechanisms. This PEP outlines the high-level issues - and specification of an abstract docstring processing system - (DPS). PEP 258, Docutils Design Specification, is an overview - of the design and implementation of one DPS under development. +* Processing mechanisms. This PEP (PEP 256) outlines the high-level + issues and specification of an abstract docstring processing system + (DPS). PEP 258, "Docutils Design Specification" [#PEP-258]_, is an + overview of the design and implementation of one DPS under + development. - * Output styles: developers want the documentation generated from - their source code to look good, and there are many different - ideas about what that means. PEP 258 touches on "Stylist - Transforms". This aspect of docstring processing has yet to be - fully explored. +* Output styles: developers want the documentation generated from + their source code to look good, and there are many different ideas + about what that means. PEP 258 touches on "Stylist Transforms". + This aspect of docstring processing has yet to be fully explored. - By separating out the issues, we can form consensus more easily - (smaller fights ;-), and accept divergence more readily. +By separating out the issues, we can form consensus more easily +(smaller fights ;-), and accept divergence more readily. Rationale +========= - There are standard inline documentation systems for some other - languages. For example, Perl has POD [2]_ and Java has Javadoc - [3]_, but neither of these mesh with the Pythonic way. POD syntax - is very explicit, but takes after Perl in terms of readability. - Javadoc is HTML-centric; except for '@field' tags, raw HTML is - used for markup. There are also general tools such as Autoduck - [4]_ and Web (Tangle & Weave) [5]_, useful for multiple languages. +There are standard inline documentation systems for some other +languages. For example, Perl has POD_ ("Plain Old Documentation") and +Java has Javadoc_, but neither of these mesh with the Pythonic way. +POD syntax is very explicit, but takes after Perl in terms of +readability. Javadoc is HTML-centric; except for "``@field``" tags, +raw HTML is used for markup. There are also general tools such as +Autoduck_ and Web_ (Tangle & Weave), useful for multiple languages. - There have been many attempts to write auto-documentation systems - for Python (not an exhaustive list): +There have been many attempts to write auto-documentation systems +for Python (not an exhaustive list): - - Marc-Andre Lemburg's doc.py [6]_ +- Marc-Andre Lemburg's doc.py_ - - Daniel Larsson's pythondoc & gendoc [7]_ +- Daniel Larsson's pythondoc_ & gendoc_ - - Doug Hellmann's HappyDoc [8]_ +- Doug Hellmann's HappyDoc_ - - Laurence Tratt's Crystal [9]_ +- Laurence Tratt's Crystal_ - - Ka-Ping Yee's htmldoc & pydoc [10]_ (pydoc.py is now part of the - Python standard library; see below) +- Ka-Ping Yee's pydoc_ (pydoc.py is now part of the Python standard + library; see below) - - Tony Ibbs' docutils [11]_ +- Tony Ibbs' docutils_ (Tony has donated this name to the `Docutils + project`_) - - Edward Loper's STminus formalization and related efforts [12]_ +- Edward Loper's STminus_ formalization and related efforts - These systems, each with different goals, have had varying degrees - of success. A problem with many of the above systems was - over-ambition combined with inflexibility. They provided a - self-contained set of components: a docstring extraction system, a - markup parser, an internal processing system and one or more - output format writers with a fixed style. Inevitably, one or more - aspects of each system had serious shortcomings, and they were not - easily extended or modified, preventing them from being adopted as - standard tools. +These systems, each with different goals, have had varying degrees of +success. A problem with many of the above systems was over-ambition +combined with inflexibility. They provided a self-contained set of +components: a docstring extraction system, a markup parser, an +internal processing system and one or more output format writers with +a fixed style. Inevitably, one or more aspects of each system had +serious shortcomings, and they were not easily extended or modified, +preventing them from being adopted as standard tools. - It has become clear (to this author, at least) that the "all or - nothing" approach cannot succeed, since no monolithic - self-contained system could possibly be agreed upon by all - interested parties. A modular component approach designed for - extension, where components may be multiply implemented, may be - the only chance for success. Standard inter-component APIs will - make the DPS components comprehensible without requiring detailed - knowledge of the whole, lowering the barrier for contributions, - and ultimately resulting in a rich and varied system. +It has become clear (to this author, at least) that the "all or +nothing" approach cannot succeed, since no monolithic self-contained +system could possibly be agreed upon by all interested parties. A +modular component approach designed for extension, where components +may be multiply implemented, may be the only chance for success. +Standard inter-component APIs will make the DPS components +comprehensible without requiring detailed knowledge of the whole, +lowering the barrier for contributions, and ultimately resulting in a +rich and varied system. - Each of the components of a docstring processing system should be - developed independently. A 'best of breed' system should be - chosen, either merged from existing systems, and/or developed - anew. This system should be included in Python's standard - library. +Each of the components of a docstring processing system should be +developed independently. A "best of breed" system should be chosen, +either merged from existing systems, and/or developed anew. This +system should be included in Python's standard library. PyDoc & Other Existing Systems - - PyDoc became part of the Python standard library as of release - 2.1. It extracts and displays docstrings from within the Python - interactive interpreter, from the shell command line, and from a - GUI window into a web browser (HTML). Although a very useful - tool, PyDoc has several deficiencies, including: - - - In the case of the GUI/HTML, except for some heuristic - hyperlinking of identifier names, no formatting of the - docstrings is done. They are presented within

- tags to avoid unwanted line wrapping. Unfortunately, the result - is not attractive. - - - PyDoc extracts docstrings and structural information (class - identifiers, method signatures, etc.) from imported module - objects. There are security issues involved with importing - untrusted code. Also, information from the source is lost when - importing, such as comments, "additional docstrings" (string - literals in non-docstring contexts; see PEP 258 [13]_), and the - order of definitions. - - The functionality proposed in this PEP could be added to or used - by PyDoc when serving HTML pages. The proposed docstring - processing system's functionality is much more than PyDoc needs in - its current form. Either an independent tool will be developed - (which PyDoc may or may not use), or PyDoc could be expanded to - encompass this functionality and *become* the docstring processing - system (or one such system). That decision is beyond the scope of - this PEP. - - Similarly for other existing docstring processing systems, their - authors may or may not choose compatibility with this framework. - However, if this framework is accepted and adopted as the Python - standard, compatibility will become an important consideration in - these systems' future. +------------------------------ + +PyDoc became part of the Python standard library as of release 2.1. +It extracts and displays docstrings from within the Python interactive +interpreter, from the shell command line, and from a GUI window into a +web browser (HTML). Although a very useful tool, PyDoc has several +deficiencies, including: + +- In the case of the GUI/HTML, except for some heuristic hyperlinking + of identifier names, no formatting of the docstrings is done. They + are presented within ``

`` tags to avoid unwanted line + wrapping. Unfortunately, the result is not attractive. + +- PyDoc extracts docstrings and structural information (class + identifiers, method signatures, etc.) from imported module objects. + There are security issues involved with importing untrusted code. + Also, information from the source is lost when importing, such as + comments, "additional docstrings" (string literals in non-docstring + contexts; see PEP 258 [#PEP-258]_), and the order of definitions. + +The functionality proposed in this PEP could be added to or used by +PyDoc when serving HTML pages. The proposed docstring processing +system's functionality is much more than PyDoc needs in its current +form. Either an independent tool will be developed (which PyDoc may +or may not use), or PyDoc could be expanded to encompass this +functionality and *become* the docstring processing system (or one +such system). That decision is beyond the scope of this PEP. + +Similarly for other existing docstring processing systems, their +authors may or may not choose compatibility with this framework. +However, if this framework is accepted and adopted as the Python +standard, compatibility will become an important consideration in +these systems' future. Specification +============= - The docstring processing system framework consists of components, - as follows:: +The docstring processing system framework is broken up as follows: - 1. Docstring conventions. Documents issues such as: +1. Docstring conventions. Documents issues such as: - - What should be documented where. + - What should be documented where. - - First line is a one-line synopsis. + - First line is a one-line synopsis. - PEP 257, Docstring Conventions [14]_, documents some of these - issues. + PEP 257 [#PEP-257]_ documents some of these issues. - 2. Docstring processing system design specification. Documents - issues such as: +2. Docstring processing system design specification. Documents + issues such as: - - High-level spec: what a DPS does. + - High-level spec: what a DPS does. - - Command-line interface for executable script. + - Command-line interface for executable script. - - System Python API. + - System Python API. - - Docstring extraction rules. + - Docstring extraction rules. - - Readers, which encapsulate the input context . + - Readers, which encapsulate the input context . - - Parsers. + - Parsers. - - Document tree: the intermediate internal data structure. The - output of the Parser and Reader, and the input to the Writer - all share the same data structure. + - Document tree: the intermediate internal data structure. The + output of the Parser and Reader, and the input to the Writer all + share the same data structure. - - Transforms, which modify the document tree. + - Transforms, which modify the document tree. - - Writers for output formats. + - Writers for output formats. - - Distributors, which handle output management (one file, many - files, or objects in memory). + - Distributors, which handle output management (one file, many + files, or objects in memory). - These issues are applicable to any docstring processing system - implementation. PEP 258, Docutils Design Specification [13 ]_, - documents these issues. + These issues are applicable to any docstring processing system + implementation. PEP 258 [#PEP-258]_ documents these issues. - 3. Docstring processing system implementation. +3. Docstring processing system implementation. - 4. Input markup specifications: docstring syntax. PEP 287, - reStructuredText Docstring Format [15]_, proposes a standard - syntax. +4. Input markup specifications: docstring syntax. PEP 287 [#PEP-287]_ + proposes a standard syntax. - 5. Input parser implementations. +5. Input parser implementations. - 6. Input context readers ("modes": Python source code, PEP, - standalone text file, email, etc.) and implementations. +6. Input context readers ("modes": Python source code, PEP, standalone + text file, email, etc.) and implementations. - 7. Stylists: certain input context readers may have associated - stylists which allow for a variety of output document styles. +7. Stylists: certain input context readers may have associated + stylists which allow for a variety of output document styles. - 8. Output formats (HTML, XML, TeX, DocBook, info, etc.) and writer - implementations. +8. Output formats (HTML, XML, TeX, DocBook, info, etc.) and writer + implementations. - Components 1, 2/3, and 4/5 are the subject of individual companion - PEPs. If there is another implementation of the framework or - syntax/parser, additional PEPs may be required. Multiple - implementations of each of components 6 and 7 will be required; - the PEP mechanism may be overkill for these components. +Components 1, 2/3/5, and 4 are the subject of individual companion +PEPs. If there is another implementation of the framework or +syntax/parser, additional PEPs may be required. Multiple +implementations of each of components 6 and 7 will be required; the +PEP mechanism may be overkill for these components. Project Web Site +================ - A SourceForge project has been set up for this work at - http://docutils.sourceforge.net/. +A SourceForge project has been set up for this work at +http://docutils.sourceforge.net/. References and Footnotes +======================== + +.. [#PEP-287] PEP 287, reStructuredText Docstring Format, Goodger + + http://www.python.org/peps/pep-0287.html + +.. [#PEP-257] PEP 257, Docstring Conventions, Goodger, Van Rossum + + http://www.python.org/peps/pep-0257.html - [1] http://www.literateprogramming.com/ +.. [#PEP-258] PEP 258, Docutils Design Specification, Goodger - [2] Perl "Plain Old Documentation" - http://www.perldoc.com/perl5.6/pod/perlpod.html + http://www.python.org/peps/pep-0258.html - [3] http://java.sun.com/j2se/javadoc/ +.. _Literate Programming: http://www.literateprogramming.com/ - [4] http://www.helpmaster.com/hlp-developmentaids-autoduck.htm +.. _POD: http://www.perldoc.com/perl5.6/pod/perlpod.html - [5] http://www-cs-faculty.stanford.edu/~knuth/cweb.html +.. _Javadoc: http://java.sun.com/j2se/javadoc/ - [6] http://www.lemburg.com/files/python/SoftwareDescriptions.html#doc.py +.. _Autoduck: + http://www.helpmaster.com/hlp-developmentaids-autoduck.htm - [7] http://starship.python.net/crew/danilo/pythondoc/ +.. _Web: http://www-cs-faculty.stanford.edu/~knuth/cweb.html - [8] http://happydoc.sourceforge.net/ +.. _doc.py: + http://www.lemburg.com/files/python/SoftwareDescriptions.html#doc.py - [9] http://www.btinternet.com/~tratt/comp/python/crystal/ +.. _pythondoc: +.. _gendoc: http://starship.python.net/crew/danilo/pythondoc/ - [10] http://www.python.org/doc/current/lib/module-pydoc.html +.. _HappyDoc: http://happydoc.sourceforge.net/ - [11] http://homepage.ntlworld.com/tibsnjoan/docutils/ +.. _Crystal: http://www.btinternet.com/~tratt/comp/python/crystal/ - [12] http://www.cis.upenn.edu/~edloper/pydoc/ +.. _pydoc: http://www.python.org/doc/current/lib/module-pydoc.html - [13] PEP 258, Docutils Design Specification, Goodger - http://www.python.org/peps/pep-0258.html +.. _docutils: http://homepage.ntlworld.com/tibsnjoan/docutils/ - [14] PEP 257, Docstring Conventions, Goodger, Van Rossum - http://www.python.org/peps/pep-0257.html +.. _Docutils project: http://docutils.sourceforge.net/ - [15] PEP 287, reStructuredText Docstring Format, Goodger - http://www.python.org/peps/pep-0287.html +.. _STMinus: http://www.cis.upenn.edu/~edloper/pydoc/ - [16] http://www.python.org/sigs/doc-sig/ +.. _Python Doc-SIG: http://www.python.org/sigs/doc-sig/ Copyright +========= - This document has been placed in the public domain. +This document has been placed in the public domain. Acknowledgements +================ - This document borrows ideas from the archives of the Python - Doc-SIG [16]_. Thanks to all members past & present. +This document borrows ideas from the archives of the `Python +Doc-SIG`_. Thanks to all members past & present. -Local Variables: -mode: indented-text -indent-tabs-mode: nil -fill-column: 70 -sentence-end-double-space: t -End: +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 9912e92ec..7f3038116 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -2,923 +2,931 @@ PEP: 258 Title: Docutils Design Specification Version: $Revision$ Last-Modified: $Date$ -Author: goodger@users.sourceforge.net (David Goodger) -Discussions-To: doc-sig@python.org +Author: David Goodger +Discussions-To: Status: Draft Type: Standards Track +Content-Type: text/x-rst Requires: 256, 257 Created: 31-May-2001 Post-History: 13-Jun-2001 -Abstract - - This PEP documents design issues and implementation details for - Docutils, a Python Docstring Processing System (DPS). The - rationale and high-level concepts of a DPS are documented in PEP - 256, "Docstring Processing System Framework" [1]. Also see PEP - 256 for a "Roadmap to the Doctring PEPs". - - Docutils is being designed modularly so that any of its components - can be replaced easily. In addition, Docutils is not limited to - the processing of Python docstrings; it processes standalone - documents as well, in several contexts. - - No changes to the core Python language are required by this PEP. - Its deliverables consist of a package for the standard library and - its documentation. - - -Specification - - Docutils Project Model - ====================== - - :: - - +--------------------------+ - | Docutils: | - | docutils.core.Publisher, | - | docutils.core.publish() | - +--------------------------+ - / \ - / \ - 1,3,5,7 / \ 8,10 - +--------+ +--------+ - | READER | =========================> | WRITER | - +--------+ +--------+ - / || \ / \ - / || \ / \ - 2 / 4 || \ 6 9 / \ 11 - +-----+ +--------+ +-------------+ +------------+ +-----+ - | I/O | | PARSER |...| reader | | writer | | I/O | - +-----+ +--------+ | transforms | | transforms | +-----+ - | | | | - | - docinfo | | - system | - | - titles | | messages | - | - linking | | - final | - | - lookups | | checks | - | - reader- | | - writer- | - | specific | | specific | - | - parser- | | - etc. | - | specific | +------------+ - | - layout | - | (stylist) | - | - etc. | - +-------------+ +========== + Abstract +========== + +This PEP documents design issues and implementation details for +Docutils, a Python Docstring Processing System (DPS). The rationale +and high-level concepts of a DPS are documented in PEP 256, "Docstring +Processing System Framework" [#PEP-256]_. Also see PEP 256 for a +"Roadmap to the Doctring PEPs". + +Docutils is being designed modularly so that any of its components can +be replaced easily. In addition, Docutils is not limited to the +processing of Python docstrings; it processes standalone documents as +well, in several contexts. + +No changes to the core Python language are required by this PEP. Its +deliverables consist of a package for the standard library and its +documentation. + + +=============== + Specification +=============== + +Docutils Project Model +====================== + +:: + + +--------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish() | + +--------------------------+ + / \ + / \ + 1,3,5,7 / \ 8,10 + +--------+ +--------+ + | READER | =========================> | WRITER | + +--------+ +--------+ + / || \ / \ + / || \ / \ + 2 / 4 || \ 6 9 / \ 11 + +-----+ +--------+ +-------------+ +------------+ +-----+ + | I/O | | PARSER |...| reader | | writer | | I/O | + +-----+ +--------+ | transforms | | transforms | +-----+ + | | | | + | - docinfo | | - system | + | - titles | | messages | + | - linking | | - final | + | - lookups | | checks | + | - reader- | | - writer- | + | specific | | specific | + | - parser- | | - etc. | + | specific | +------------+ + | - layout | + | (stylist) | + | - etc. | + +-------------+ - The numbers indicate the path a document's data takes through the - code. Double-width lines between reader & parser and between - reader & writer indicate that data sent along these paths should - be standard (pure & unextended) Docutils doc trees. Single-width - lines signify that internal tree extensions or completely - unrelated representations are possible, but they must be supported - at both ends. +The numbers indicate the path a document's data takes through the +code. Double-width lines between reader & parser and between reader & +writer indicate that data sent along these paths should be standard +(pure & unextended) Docutils doc trees. Single-width lines signify +that internal tree extensions or completely unrelated representations +are possible, but they must be supported at both ends. - Publisher - --------- +Publisher +--------- - The "docutils.core" module contains a "Publisher" facade class and - "publish" convenience function. Publisher encapsulates the - high-level logic of a Docutils system. The Publisher.publish() - method first calls its Reader, which reads data from its source - I/O, parses and transforms the data, and returns it. - Publisher.publish() then passes the resulting document tree to its - Writer, which further transforms the document before translating - it to the final output format and writing the formatted data to - its destination I/O. +The ``docutils.core`` module contains a "Publisher" facade class and +"publish" convenience function. Publisher encapsulates the high-level +logic of a Docutils system. The ``Publisher.publish()`` method first +calls its Reader, which reads data from its source I/O, parses and +transforms the data, and returns it. ``Publisher.publish()`` then +passes the resulting document tree to its Writer, which further +transforms the document before translating it to the final output +format and writing the formatted data to its destination I/O. - Calling the "publish" function (or instantiating a "Publisher" - object) with component names will result in default behavior. For - custom behavior (setting component options), create custom - component objects first, and pass *them* to publish/Publisher. +Calling the "publish" function (or instantiating a "Publisher" object) +with component names will result in default behavior. For custom +behavior (setting component options), create custom component objects +first, and pass *them* to publish/Publisher. - Readers - ------- +Readers +------- - Readers understand the input context (where the data is coming - from), send the whole input or discrete "chunks" to the parser, - and provide the context to bind the chunks together back into a - cohesive whole. Using transforms_, Readers also resolve - references, footnote numbers, interpreted text processing, and - anything else that requires context-sensitive computation. +Readers understand the input context (where the data is coming from), +send the whole input or discrete "chunks" to the parser, and provide +the context to bind the chunks together back into a cohesive whole. +Using transforms_, Readers also resolve references, footnote numbers, +interpreted text processing, and anything else that requires +context-sensitive computation. - Each reader is a module or package exporting a "Reader" class with - a "read" method. The base "Reader" class can be found in the - docutils/readers/__init__.py module. +Each reader is a module or package exporting a "Reader" class with a +"read" method. The base "Reader" class can be found in the +``docutils/readers/__init__.py`` module. - Most Readers will have to be told what parser to use. So far (see - the list of examples below), only the Python Source Reader - (PySource; still incomplete) will be able to determine the parser - on its own. +Most Readers will have to be told what parser to use. So far (see the +list of examples below), only the Python Source Reader ("PySource"; +still incomplete) will be able to determine the parser on its own. - Responsibilities: +Responsibilities: - - Get input text from the source I/O. +- Get input text from the source I/O. - - Pass the input text to the parser, along with a fresh doctree - root. +- Pass the input text to the parser, along with a fresh doctree root. - - Run transforms over the doctree(s). +- Run transforms over the doctree(s). - Examples: +Examples: - - Standalone (Raw/Plain): Just read a text file and process it. - The reader needs to be told which parser to use. +- Standalone (Raw/Plain): Just read a text file and process it. + The reader needs to be told which parser to use. - The "Standalone Reader" has been implemented in - docutils/readers/standalone.py. + The "Standalone Reader" has been implemented in module + ``docutils.readers.standalone``. - - Python Source: See `Python Source Reader`_ below. This Reader - is currently in development in the Docutils sandbox. +- Python Source: See `Python Source Reader`_ below. This Reader is + currently in development in the Docutils sandbox. - - Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. +- Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. - - PEP: RFC-822 headers, "PEP xxxx" and "RFC xxxx" conversion to - URIs. Either interpret PEPs' indented sections or convert - existing PEPs to reStructuredText (or both?). +- PEP: RFC-822 headers, "PEP xxxx" and "RFC xxxx" conversion to URIs. + Either interpret PEPs' indented sections or convert existing PEPs to + reStructuredText (or both?). - The "PEP Reader" is being implemented in - docutils/readers/pep.py. + The "PEP Reader" is being implemented in module + ``docutils.readers.pep``. - - Wiki: Global reference lookups of "wiki links" incorporated into - transforms. (CamelCase only or unrestricted?) Lazy - indentation? +- Wiki: Global reference lookups of "wiki links" incorporated into + transforms. (CamelCase only or unrestricted?) Lazy + indentation? - - Web Page: As standalone, but recognize meta fields as meta tags. - Support for templates of some sort? (After , before - ?) +- Web Page: As standalone, but recognize meta fields as meta tags. + Support for templates of some sort? (After ````, before + ````?) - - FAQ: Structured "question & answer(s)" constructs. +- FAQ: Structured "question & answer(s)" constructs. - - Compound document: Merge chapters into a book. Master TOC file? +- Compound document: Merge chapters into a book. Master TOC file? - Parsers - ------- +Parsers +------- - Parsers analyze their input and produce a Docutils `document - tree`_. They don't know or care anything about the source or - destination of the data. +Parsers analyze their input and produce a Docutils `document tree`_. +They don't know or care anything about the source or destination of +the data. - Each input parser is a module or package exporting a "Parser" - class with a "parse" method. The base "Parser" class can be found - in the docutils/parsers/__init__.py module. +Each input parser is a module or package exporting a "Parser" class +with a "parse" method. The base "Parser" class can be found in the +``docutils/parsers/__init__.py`` module. - Responsibilities: Given raw input text and a doctree root node, - populate the doctree by parsing the input text. +Responsibilities: Given raw input text and a doctree root node, +populate the doctree by parsing the input text. - Example: The only parser implemented so far is for the - reStructuredText markup. It is implemented in the - docutils/parsers/rst/ package. +Example: The only parser implemented so far is for the +reStructuredText markup. It is implemented in the +``docutils/parsers/rst/`` package. - Transforms - ---------- +Transforms +---------- - Transforms change the document tree from one form to another, add - to the tree, or prune it. Transforms are run by Reader and Writer - objects. Some transforms are Reader-specific, some are - Parser-specific, and others are Writer-specific. The choice and - order of transforms is specified in the Reader and Writer objects. +Transforms change the document tree from one form to another, add to +the tree, or prune it. Transforms are run by Reader and Writer +objects. Some transforms are Reader-specific, some are +Parser-specific, and others are Writer-specific. The choice and order +of transforms is specified in the Reader and Writer objects. - Each transform is a class in a module in the docutils/transforms - package, a subclass of docutils.tranforms.Transform. +Each transform is a class in a module in the ``docutils/transforms/`` +package, a subclass of docutils.tranforms.Transform. - Responsibilities: +Responsibilities: - - Modify a doctree in-place, either purely transforming one - structure into another, or adding new structures based on the - doctree and/or external data. +- Modify a doctree in-place, either purely transforming one structure + into another, or adding new structures based on the doctree and/or + external data. - Examples (in the docutils/transforms/ package): +Examples (in the ``docutils/transforms/`` package): - - frontmatter.DocInfo: Conversion of document metadata - (bibliographic information). +- frontmatter.DocInfo: Conversion of document metadata (bibliographic + information). - - references.Hyperlinks: Resolution of hyperlinks. +- references.Hyperlinks: Resolution of hyperlinks. - - parts.Contents: Generates a table of contents for a document. +- parts.Contents: Generates a table of contents for a document. - - document.Merger: Combining multiple populated doctrees into one - (not yet implemented or fully understood). +- document.Merger: Combining multiple populated doctrees into one (not + yet implemented or fully understood). - - document.Splitter: Splits a document into a tree-structure of - subdocuments, perhaps by section. It will have to transform - references appropriately. (Neither implemented not remotely - understood.) +- document.Splitter: Splits a document into a tree-structure of + subdocuments, perhaps by section. It will have to transform + references appropriately. (Neither implemented not remotely + understood.) - - universal.Pending: Handles transforms that must be executed at - specific stages of processing. +- universal.Pending: Handles transforms that must be executed at + specific stages of processing. - - components.Filter: Includes or excludes elements which depend on - a specific Docutils component (triggered by the - universal.Pending transform). +- components.Filter: Includes or excludes elements which depend on a + specific Docutils component (triggered by the universal.Pending + transform). - Writers - ------- +Writers +------- - Writers produce the final output (HTML, XML, TeX, etc.). Writers - translate the internal document tree structure into the final data - format, possibly running Writer-specific transforms_ first. +Writers produce the final output (HTML, XML, TeX, etc.). Writers +translate the internal document tree structure into the final data +format, possibly running Writer-specific transforms_ first. - Each writer is a module or package exporting a "Writer" class with - a "write" method. The base "Writer" class can be found in the - docutils/writers/__init__.py module. +Each writer is a module or package exporting a "Writer" class with a +"write" method. The base "Writer" class can be found in the +``docutils/writers/__init__.py`` module. - Responsibilities: +Responsibilities: - - Run transforms over the doctree(s). +- Run transforms over the doctree(s). - - Translate doctree(s) into specific output formats. +- Translate doctree(s) into specific output formats. - - Transform references into format-native forms. + - Transform references into format-native forms. - - Write the translated output to the destination I/O. +- Write the translated output to the destination I/O. - Examples: +Examples: - - XML: Various forms, such as: +- XML: Various forms, such as: - - DocBook (being implemented in the Docutils sandbox). + - DocBook (being implemented in the Docutils sandbox). - - Raw doctree XML (accessible via "doctree.asdom().toxml()"; no - Writer component implemented yet). + - Raw doctree XML (accessible via "``doctree.asdom().toxml()``"; no + Writer component implemented yet). - - HTML (XHTML implemented as docutils/writers/html4css1.py). +- HTML (XHTML implemented as ``docutils.writers.html4css1``). - - PDF (a ReportLabs interface is being developed in the Docutils - sandbox). +- PDF (a ReportLabs interface is being developed in the Docutils + sandbox). - - TeX +- TeX - - Docutils-native pseudo-XML (implemented as - docutils/writers/pseudoxml.py, used for testing). +- Docutils-native pseudo-XML (implemented as + ``docutils.writers.pseudoxml``, used for testing). - - Plain text +- Plain text - - reStructuredText? +- reStructuredText? - I/O - --- +Input/Output +------------ - I/O classes provide a uniform API for low-level input and output. - Subclasses will exist for a variety of input/output mechanisms. +I/O classes provide a uniform API for low-level input and output. +Subclasses will exist for a variety of input/output mechanisms. - I/O classes are currently in the preliminary stages; there's a lot - of work yet to be done. Issues: +I/O classes are currently in the preliminary stages; there's a lot of +work yet to be done. Issues: - - Looking at the list of writers, it seems that only HTML would - require anything other than monolithic output. Perhaps "Writer" - variants, one for each output distribution type? +- Looking at the list of writers, it seems that only HTML would + require anything other than monolithic output. Perhaps "Writer" + variants, one for each output distribution type? - - How to represent a multi-file document (files & directories) in - the API? +- How to represent a multi-file document (files & directories) in the + API? - Responsibilities: +Responsibilities: - - Read data from the input source and/or write data to the output - destination. +- Read data from the input source and/or write data to the output + destination. - Examples of input sources: +Examples of input sources: - - A single file on disk or a stream (implemented as - docutils.io.FileIO). +- A single file on disk or a stream (implemented as + ``docutils.io.FileIO``). - - Multiple files on disk (MultiFileIO?). +- Multiple files on disk (``MultiFileIO``?). - - Python source files: modules and packages. +- Python source files: modules and packages. - - Python strings, as received from a client application - (implemented as docutils.io.StringIO). +- Python strings, as received from a client application + (implemented as ``docutils.io.StringIO``). - Examples of output destinations: +Examples of output destinations: - - A single file on disk or a stream (implemented as - docutils.io.FileIO). +- A single file on disk or a stream (implemented as + ``docutils.io.FileIO``). - - A tree of directories and files on disk. +- A tree of directories and files on disk. - - A Python string, returned to a client application (implemented - as docutils.io.StringIO). +- A Python string, returned to a client application (implemented as + ``docutils.io.StringIO``). - - A single tree-shaped data structure in memory. +- A single tree-shaped data structure in memory. - - Some other set of data structures in memory. +- Some other set of data structures in memory. - Docutils Package Structure - ========================== +Docutils Package Structure +========================== - - Package "docutils". +- Package "docutils". - - Class "Component" is a base class for Docutils components. + - Class "Component" is a base class for Docutils components. - - Module "docutils.core" contains facade class "Publisher" and - convenience function "publish()". See `Publisher`_ above. + - Module "docutils.core" contains facade class "Publisher" and + convenience function "publish()". See `Publisher`_ above. - - Module "docutils.frontend" provides command-line and option - processing for Docutils front-end tools. + - Module "docutils.frontend" provides command-line and option + processing for Docutils front-end tools. - - Module "docutils.io" provides a uniform API for low-level - input and output. + - Module "docutils.io" provides a uniform API for low-level input + and output. See `Input/Output`_ above. - - Module "docutils.nodes" contains the Docutils document tree - element class library plus Visitor pattern base classes. See - `Document Tree`_ below. + - Module "docutils.nodes" contains the Docutils document tree + element class library plus Visitor pattern base classes. See + `Document Tree`_ below. - - Module "docutils.optik" provides option parsing and - command-line help; from Greg Ward's http://optik.sf.net/ - project, included for convenience. + - Module "docutils.optik" provides option parsing and command-line + help; from Greg Ward's http://optik.sf.net/ project, included for + convenience. - - Module "docutils.roman" contains Roman numeral conversion - routines. + - Module "docutils.roman" contains Roman numeral conversion + routines. - - Module "docutils.statemachine" contains a finite state machine - specialized for regular-expression-based text filters. The - reStructuredText parser implementation is based on this - module. + - Module "docutils.statemachine" contains a finite state machine + specialized for regular-expression-based text filters. The + reStructuredText parser implementation is based on this module. - - Module "docutils.urischemes" contains a mapping of known URI - schemes ("http", "ftp", "mail", etc.). + - Module "docutils.urischemes" contains a mapping of known URI + schemes ("http", "ftp", "mail", etc.). - - Module "docutils.utils" contains utility functions and - classes, including a logger class ("Reporter"; see `Error - Handling`_ below). + - Module "docutils.utils" contains utility functions and classes, + including a logger class ("Reporter"; see `Error Handling`_ + below). - - Package "docutils.parsers": markup parsers_. + - Package "docutils.parsers": markup parsers_. - - Function "get_parser_class(parser_name)" returns a parser - module by name. Class "Parser" is the base class of - specific parsers. (docutils/parsers/__init__.py) + - Function "get_parser_class(parser_name)" returns a parser module + by name. Class "Parser" is the base class of specific parsers. + (``docutils/parsers/__init__.py``) - - Package "docutils.parsers.rst": the reStructuredText parser. + - Package "docutils.parsers.rst": the reStructuredText parser. - - Alternate markup parsers may be added. + - Alternate markup parsers may be added. - - Package "docutils.readers": context-aware input readers. + See `Parsers`_ above. - - Function "get_reader_class(reader_name)" returns a reader - module by name or alias. Class "Reader" is the base class - of specific readers. (docutils/readers/__init__.py) + - Package "docutils.readers": context-aware input readers. - - Module "docutils.readers.standalone" reads independent - document files. + - Function "get_reader_class(reader_name)" returns a reader module + by name or alias. Class "Reader" is the base class of specific + readers. (``docutils/readers/__init__.py``) - - Module "docutils.readers.pep" reads PEPs (Python Enhancement - Proposals). + - Module "docutils.readers.standalone" reads independent document + files. - - Readers to be added for: Python source code (structure & - docstrings), PEPs, email, FAQ, and perhaps Wiki and others. + - Module "docutils.readers.pep" reads PEPs (Python Enhancement + Proposals). - - Package "docutils.writers": output format writers. + - Readers to be added for: Python source code (structure & + docstrings), PEPs, email, FAQ, and perhaps Wiki and others. - - Function "get_writer_class(writer_name)" returns a writer - module by name. Class "Writer" is the base class of - specific writers. (docutils/writers/__init__.py) + See `Readers`_ above. - - Module "docutils.writers.pseudoxml" is a simple internal - document tree writer; it writes indented pseudo-XML. + - Package "docutils.writers": output format writers. - - Module "docutils.writers.html4css1" is a simple HyperText - Markup Language document tree writer for HTML 4.01 and CSS1. + - Function "get_writer_class(writer_name)" returns a writer module + by name. Class "Writer" is the base class of specific writers. + (``docutils/writers/__init__.py``) - - Writers to be added: HTML 3.2 or 4.01-loose, XML (various - forms, such as DocBook and the raw internal doctree), PDF, - TeX, plaintext, reStructuredText, and perhaps others. + - Module "docutils.writers.pseudoxml" is a simple internal + document tree writer; it writes indented pseudo-XML. - - Package "docutils.transforms": tree transform classes. + - Module "docutils.writers.html4css1" is a simple HyperText Markup + Language document tree writer for HTML 4.01 and CSS1. - - Class "Transform" is the base class of specific transforms; - see `Transform API`_ below. - (docutils/transforms/__init__.py) + - Writers to be added: HTML 3.2 or 4.01-loose, XML (various forms, + such as DocBook and the raw internal doctree), PDF, TeX, + plaintext, reStructuredText, and perhaps others. - - Each module contains related transform classes. + See `Writers`_ above. - - Package "docutils.languages": Language modules contain - language-dependent strings and mappings. They are named for - their language identifier (as defined in `Choice of Docstring - Format`_ above), converting dashes to underscores. + - Package "docutils.transforms": tree transform classes. - - Function "get_language(language_code)", returns matching - language module. (docutils/languages/__init__.py) + - Class "Transform" is the base class of specific transforms. + (``docutils/transforms/__init__.py``) - - Module "docutils.languages.en" (English). + - Each module contains related transform classes. - - Other languages to be added. + See `Transforms`_ above. + - Package "docutils.languages": Language modules contain + language-dependent strings and mappings. They are named for their + language identifier (as defined in `Choice of Docstring Format`_ + above), converting dashes to underscores. - Front-End Tools - =============== + - Function "get_language(language_code)", returns matching + language module. (``docutils/languages/__init__.py``) - See `Docutils Front-End Tools`_. + - Module "docutils.languages.en" (English). - .. _Docutils Front-End Tools: http://docutils.sf.net/docs/tools.html + - Other languages to be added. - Document Tree - ============= +Front-End Tools +=============== - A single intermediate data structure is used internally by - Docutils, in the interfaces between components; it is defined in - the docutils.nodes module. It is not required that this data - structure be used *internally* by any of the components, just - *between* components. +See `Docutils Front-End Tools`_. - Custom node types are allowed, providing that either (A) a - transform converts them to standard Docutils nodes before they - reach the Writer proper, or (B) the custom node is explicitly - supported by certain Writers, and is wrapped in a filtered - "pending" node. An example of condition A is the `Python Source - Reader`_ (see below), where a "stylist" transform converts custom - nodes. The HTML tag is an example of condition B; it is - supported by the HTML Writer but not by others. The - reStructuredText ".. meta::" directive creates a "pending" node, - which contains knowledge that the embedded "meta" node can only be - handled by HTML-compatible writers. The "pending" node is - resolved by the "transforms.components.Filter" transform, which - checks that the calling writer supports HTML; if it doesn't, the - "meta" node is removed from the document. +.. _Docutils Front-End Tools: http://docutils.sf.net/docs/tools.html - The document tree data structure is similar to a DOM tree, but - with specific node names (classes) instead of DOM's generic nodes. - The schema is documented in an XML DTD (eXtensible Markup Language - Document Type Definition), which comes in two parts: - - the Docutils Generic DTD, docutils.dtd [2], and +Document Tree +============= - - the OASIS Exchange Table Model, soextbl.dtd [3]. +A single intermediate data structure is used internally by Docutils, +in the interfaces between components; it is defined in the +docutils.nodes module. It is not required that this data structure be +used *internally* by any of the components, just *between* components. - The DTD defines a rich set of elements, suitable for many input - and output formats. The DTD retains all information necessary to - reconstruct the original input text, or a reasonable facsimile - thereof. +Custom node types are allowed, provided that either (a) a transform +converts them to standard Docutils nodes before they reach the Writer +proper, or (b) the custom node is explicitly supported by certain +Writers, and is wrapped in a filtered "pending" node. An example of +condition A is the `Python Source Reader`_ (see below), where a +"stylist" transform converts custom nodes. The HTML ```` tag is +an example of condition B; it is supported by the HTML Writer but not +by others. The reStructuredText "meta" directive creates a "pending" +node, which contains knowledge that the embedded "meta" node can only +be handled by HTML-compatible writers. The "pending" node is resolved +by the "transforms.components.Filter" transform, which checks that the +calling writer supports HTML; if it doesn't, the "meta" node is +removed from the document. - See "The Docutils Document Tree" [4] for details (incomplete). +The document tree data structure is similar to a DOM tree, but with +specific node names (classes) instead of DOM's generic nodes. The +schema is documented in an XML DTD (eXtensible Markup Language +Document Type Definition), which comes in two parts: +- the Docutils Generic DTD, docutils.dtd_, and - Error Handling - ============== +- the OASIS Exchange Table Model, soextbl.dtd_. - When the parser encounters an error in markup, it inserts a system - message (DTD element "system_message"). There are five levels of - system messages: +The DTD defines a rich set of elements, suitable for many input and +output formats. The DTD retains all information necessary to +reconstruct the original input text, or a reasonable facsimile +thereof. - - Level-0, "DEBUG": an internal reporting issue. There is no - effect on the processing. Level-0 system messages are - handled separately from the others. +See `The Docutils Document Tree`_ for details (incomplete). - - Level-1, "INFO": a minor issue that can be ignored. There is - little or no effect on the processing. Typically level-1 system - messages are not reported. - - Level-2, "WARNING": an issue that should be addressed. If - ignored, there may be minor problems with the output. Typically - level-2 system messages are reported but do not halt processing +Error Handling +============== - - Level-3, "ERROR": a major issue that should be addressed. If - ignored, the output will contain unpredictable errors. - Typically level-3 system messages are reported but do not halt - processing +When the parser encounters an error in markup, it inserts a system +message (DTD element "system_message"). There are five levels of +system messages: - - Level-4, "SEVERE": a critical error that must be addressed. - Typically level-4 system messages are turned into exceptions - which halt processing. If ignored, the output will contain - severe errors. +- Level-0, "DEBUG": an internal reporting issue. There is no effect + on the processing. Level-0 system messages are handled separately + from the others. - Although the initial message levels were devised independently, - they have a strong correspondence to VMS error condition severity - levels [5]; the names in quotes for levels 1 through 4 were - borrowed from VMS. Error handling has since been influenced by - the log4j project [6]. +- Level-1, "INFO": a minor issue that can be ignored. There is little + or no effect on the processing. Typically level-1 system messages + are not reported. +- Level-2, "WARNING": an issue that should be addressed. If ignored, + there may be minor problems with the output. Typically level-2 + system messages are reported but do not halt processing - Python Source Reader - ==================== +- Level-3, "ERROR": a major issue that should be addressed. If + ignored, the output will contain unpredictable errors. Typically + level-3 system messages are reported but do not halt processing - The Python Source Reader ("PySource") is the Docutils component - that reads Python source files, extracts docstrings in context, - then parses, links, and assembles the docstrings into a cohesive - whole. It is a major and non-trivial component, currently under - experimental development in the Docutils sandbox. High-level - design issues are presented here. +- Level-4, "SEVERE": a critical error that must be addressed. + Typically level-4 system messages are turned into exceptions which + halt processing. If ignored, the output will contain severe errors. +Although the initial message levels were devised independently, they +have a strong correspondence to `VMS error condition severity +levels`_; the names in quotes for levels 1 through 4 were borrowed +from VMS. Error handling has since been influenced by the `log4j +project`_. - Processing Model - ---------------- - This model will evolve over time, incorporating experience and - discoveries. +Python Source Reader +==================== - 1. The PySource Reader uses an I/O class to read in some Python - packages and modules, into a tree of strings. +The Python Source Reader ("PySource") is the Docutils component that +reads Python source files, extracts docstrings in context, then +parses, links, and assembles the docstrings into a cohesive whole. It +is a major and non-trivial component, currently under experimental +development in the Docutils sandbox. High-level design issues are +presented here. - 2. The Python modules are parsed, converting the tree of strings - into a tree of abstract syntax trees. - 3. The abstract syntax trees are converted into an internal - representation of the packages/modules. Docstrings are - extracted, as well as code structure details. See `AST - Mining`_ below. Namespaces are constructed for lookup in step - 6. +Processing Model +---------------- - 4. One at a time, the docstrings are parsed, producing standard - Docutils doctrees. +This model will evolve over time, incorporating experience and +discoveries. - 5. PySource assembles all the individual docstrings' doctrees into - a Python-specific custom Docutils tree parallelling the - package/module/class structure; this is a custom - Reader-specific internal representation (see the Docutils - Python Source DTD [7]). Namespaces must be merged: Python - identifiers, hyperlink targets. +1. The PySource Reader uses an I/O class to read in some Python + packages and modules, into a tree of strings. - 6. Cross-references from docstrings (interpreted text) to Python - identifiers are resolved according to the Python namespace - lookup rules. See `Identifier Cross-References`_ below. +2. The Python modules are parsed, converting the tree of strings into + a tree of abstract syntax trees. - 7. A "Stylist" transform is applied to the custom doctree, custom - nodes are rendered using standard nodes as primitives, and a - standard document tree is emitted. See `Stylist Transforms`_ - below. +3. The abstract syntax trees are converted into an internal + representation of the packages/modules. Docstrings are extracted, + as well as code structure details. See `AST Mining`_ below. + Namespaces are constructed for lookup in step 6. - 8. Other transforms are applied to the standard doctree. +4. One at a time, the docstrings are parsed, producing standard + Docutils doctrees. - 9. The standard doctree is sent to a Writer, which translates the - document into a concrete format (HTML, PDF, etc.). +5. PySource assembles all the individual docstrings' doctrees into a + Python-specific custom Docutils tree parallelling the + package/module/class structure; this is a custom Reader-specific + internal representation (see the `Docutils Python Source DTD`_). + Namespaces must be merged: Python identifiers, hyperlink targets. - 10. The Writer uses an I/O class to write the resulting data to - its destination (disk file, directories and files, etc.). +6. Cross-references from docstrings (interpreted text) to Python + identifiers are resolved according to the Python namespace lookup + rules. See `Identifier Cross-References`_ below. +7. A "Stylist" transform is applied to the custom doctree, custom + nodes are rendered using standard nodes as primitives, and a + standard document tree is emitted. See `Stylist Transforms`_ + below. - AST Mining - ---------- +8. Other transforms are applied to the standard doctree. - Abstract Syntax Tree mining code will be written that scans a - parsed Python module, and returns an ordered tree containing the - names, docstrings (including attribute and additional docstrings; - see below), and additional info (in parentheses below) of all of - the following objects: +9. The standard doctree is sent to a Writer, which translates the + document into a concrete format (HTML, PDF, etc.). - - packages - - modules - - module attributes (+ initial values) - - classes (+ inheritance) - - class attributes (+ initial values) - - instance attributes (+ initial values) - - methods (+ parameters & defaults) - - functions (+ parameters & defaults) +10. The Writer uses an I/O class to write the resulting data to its + destination (disk file, directories and files, etc.). - (Extract comments too? For example, comments at the start of a - module would be a good place for bibliographic field lists.) - In order to evaluate interpreted text cross-references, namespaces - for each of the above will also be required. +AST Mining +---------- - See python-dev/docstring-develop thread "AST mining", started on - 2001-08-14. +Abstract Syntax Tree mining code will be written that scans a parsed +Python module, and returns an ordered tree containing the names, +docstrings (including attribute and additional docstrings; see below), +and additional info (in parentheses below) of all of the following +objects: +- packages +- modules +- module attributes (+ initial values) +- classes (+ inheritance) +- class attributes (+ initial values) +- instance attributes (+ initial values) +- methods (+ parameters & defaults) +- functions (+ parameters & defaults) - Docstring Extraction Rules - -------------------------- +(Extract comments too? For example, comments at the start of a module +would be a good place for bibliographic field lists.) - 1. What to examine: +In order to evaluate interpreted text cross-references, namespaces for +each of the above will also be required. - a) If the "__all__" variable is present in the module being - documented, only identifiers listed in "__all__" are - examined for docstrings. +See python-dev/docstring-develop thread "AST mining", started on +2001-08-14. - b) In the absense of "__all__", all identifiers are examined, - except those whose names are private (names begin with "_" - but don't begin and end with "__"). - c) 1a and 1b can be overridden by a parameter or command-line - option. +Docstring Extraction Rules +-------------------------- - 2. Where: +1. What to examine: - Docstrings are string literal expressions, and are recognized - in the following places within Python modules: + a) If the "``__all__``" variable is present in the module being + documented, only identifiers listed in "``__all__``" are + examined for docstrings. - a) At the beginning of a module, function definition, class - definition, or method definition, after any comments. This - is the standard for Python __doc__ attributes. + b) In the absense of "``__all__``", all identifiers are examined, + except those whose names are private (names begin with "_" but + don't begin and end with "__"). - b) Immediately following a simple assignment at the top level - of a module, class definition, or __init__ method - definition, after any comments. See "Attribute Docstrings" - below. + c) 1a and 1b can be overridden by a parameter or command-line + option. - c) Additional string literals found immediately after the - docstrings in (a) and (b) will be recognized, extracted, and - concatenated. See "Additional Docstrings" below. +2. Where: - d) @@@ 2.2-style "properties" with attribute docstrings? + Docstrings are string literal expressions, and are recognized in + the following places within Python modules: - 3. How: + a) At the beginning of a module, function definition, class + definition, or method definition, after any comments. This is + the standard for Python ``__doc__`` attributes. - Whenever possible, Python modules should be parsed by Docutils, - not imported. There are several reasons: + b) Immediately following a simple assignment at the top level of a + module, class definition, or ``__init__`` method definition, + after any comments. See "Attribute Docstrings" below. - - Importing untrusted code is inherently insecure. + c) Additional string literals found immediately after the + docstrings in (a) and (b) will be recognized, extracted, and + concatenated. See "Additional Docstrings" below. - - Information from the source is lost when using introspection - to examine an imported module, such as comments and the order - of definitions. + d) @@@ 2.2-style "properties" with attribute docstrings? - - Docstrings are to be recognized in places where the bytecode - compiler ignores string literal expressions (2b and 2c - above), meaning importing the module will lose these - docstrings. +3. How: - Of course, standard Python parsing tools such as the "parser" - library module should be used. + Whenever possible, Python modules should be parsed by Docutils, not + imported. There are several reasons: - When the Python source code for a module is not available - (i.e. only the .pyc file exists) or for C extension modules, to - access docstrings the module can only be imported, and any - limitations must be lived with. + - Importing untrusted code is inherently insecure. - Since attribute docstrings and additional docstrings are ignored - by the Python bytecode compiler, no namespace pollution or runtime - bloat will result from their use. They are not assigned to - __doc__ or to any other attribute. The initial parsing of a - module may take a slight performance hit. + - Information from the source is lost when using introspection to + examine an imported module, such as comments and the order of + definitions. + - Docstrings are to be recognized in places where the bytecode + compiler ignores string literal expressions (2b and 2c above), + meaning importing the module will lose these docstrings. - Attribute Docstrings - ```````````````````` + Of course, standard Python parsing tools such as the "parser" + library module should be used. - (This is a simplified version of PEP 224 [8] by Marc-Andre - Lemberg.) + When the Python source code for a module is not available + (i.e. only the ``.pyc`` file exists) or for C extension modules, to + access docstrings the module can only be imported, and any + limitations must be lived with. - A string literal immediately following an assignment statement is - interpreted by the docstring extration machinery as the docstring - of the target of the assignment statement, under the following - conditions: +Since attribute docstrings and additional docstrings are ignored by +the Python bytecode compiler, no namespace pollution or runtime bloat +will result from their use. They are not assigned to ``__doc__`` or +to any other attribute. The initial parsing of a module may take a +slight performance hit. - 1. The assignment must be in one of the following contexts: - a) At the top level of a module (i.e., not nested inside a - compound statement such as a loop or conditional): a module - attribute. +Attribute Docstrings +'''''''''''''''''''' - b) At the top level of a class definition: a class attribute. +(This is a simplified version of PEP 224 [#PEP-224]_.) - c) At the top level of the "__init__" method definition of a - class: an instance attribute. +A string literal immediately following an assignment statement is +interpreted by the docstring extration machinery as the docstring of +the target of the assignment statement, under the following +conditions: - Since each of the above contexts are at the top level (i.e., in - the outermost suite of a definition), it may be necessary to - place dummy assignments for attributes assigned conditionally - or in a loop. +1. The assignment must be in one of the following contexts: - 2. The assignment must be to a single target, not to a list or a - tuple of targets. + a) At the top level of a module (i.e., not nested inside a compound + statement such as a loop or conditional): a module attribute. - 3. The form of the target: + b) At the top level of a class definition: a class attribute. - a) For contexts 1a and 1b above, the target must be a simple - identifier (not a dotted identifier, a subscripted - expression, or a sliced expression). + c) At the top level of the "``__init__``" method definition of a + class: an instance attribute. - b) For context 1c above, the target must be of the form - "self.attrib", where "self" matches the "__init__" method's - first parameter (the instance parameter) and "attrib" is a - simple indentifier as in 3a. + Since each of the above contexts are at the top level (i.e., in the + outermost suite of a definition), it may be necessary to place + dummy assignments for attributes assigned conditionally or in a + loop. - Blank lines may be used after attribute docstrings to emphasize - the connection between the assignment and the docstring. +2. The assignment must be to a single target, not to a list or a tuple + of targets. - Examples:: +3. The form of the target: - g = 'module attribute (module-global variable)' - """This is g's docstring.""" + a) For contexts 1a and 1b above, the target must be a simple + identifier (not a dotted identifier, a subscripted expression, + or a sliced expression). - class AClass: + b) For context 1c above, the target must be of the form + "``self.attrib``", where "``self``" matches the "``__init__``" + method's first parameter (the instance parameter) and "attrib" + is a simple indentifier as in 3a. - c = 'class attribute' - """This is AClass.c's docstring.""" +Blank lines may be used after attribute docstrings to emphasize the +connection between the assignment and the docstring. - def __init__(self): - self.i = 'instance attribute' - """This is self.i's docstring.""" +Examples:: + g = 'module attribute (module-global variable)' + """This is g's docstring.""" - Additional Docstrings - ````````````````````` + class AClass: - (This idea was adapted from PEP 216, Docstring Format [9], by - Moshe Zadka.) + c = 'class attribute' + """This is AClass.c's docstring.""" - Many programmers would like to make extensive use of docstrings - for API documentation. However, docstrings do take up space in - the running program, so some of these programmers are reluctant to - "bloat up" their code. Also, not all API documentation is - applicable to interactive environments, where __doc__ would be - displayed. + def __init__(self): + self.i = 'instance attribute' + """This is self.i's docstring.""" - The docstring processing system's extraction tools will - concatenate all string literal expressions which appear at the - beginning of a definition or after a simple assignment. Only the - first strings in definitions will be available as __doc__, and can - be used for brief usage text suitable for interactive sessions; - subsequent string literals and all attribute docstrings are - ignored by the Python bytecode compiler and may contain more - extensive API information. - Example:: +Additional Docstrings +''''''''''''''''''''' - def function(arg): - """This is __doc__, function's docstring.""" - """ - This is an additional docstring, ignored by the bytecode - compiler, but extracted by the Docutils. - """ - pass - - Issue: This breaks "from __future__ import" statements in Python - 2.1 for multiple module docstrings. The Python Reference Manual - specifies: - - A future statement must appear near the top of the module. - The only lines that can appear before a future statement are: - - * the module docstring (if any), - * comments, - * blank lines, and - * other future statements. - - Resolution? +(This idea was adapted from PEP 216 [#PEP-216]_.) - 1. Should we search for docstrings after a __future__ statement? - Very ugly. +Many programmers would like to make extensive use of docstrings for +API documentation. However, docstrings do take up space in the +running program, so some of these programmers are reluctant to "bloat +up" their code. Also, not all API documentation is applicable to +interactive environments, where ``__doc__`` would be displayed. - 2. Redefine __future__ statements to allow multiple preceeding - string literals? +The docstring processing system's extraction tools will concatenate +all string literal expressions which appear at the beginning of a +definition or after a simple assignment. Only the first strings in +definitions will be available as ``__doc__``, and can be used for +brief usage text suitable for interactive sessions; subsequent string +literals and all attribute docstrings are ignored by the Python +bytecode compiler and may contain more extensive API information. - 3. Or should we not even worry about this? There shouldn't be - __future__ statements in production code, after all. Will - modules with __future__ statements simply have to put up with - the single-docstring limitation? +Example:: + def function(arg): + """This is __doc__, function's docstring.""" + """ + This is an additional docstring, ignored by the bytecode + compiler, but extracted by the Docutils. + """ + pass - Choice of Docstring Format - -------------------------- +.. topic:: Issue: ``from __future__ import`` - Rather than force everyone to use a single docstring format, - multiple input formats are allowed by the processing system. A - special variable, __docformat__, may appear at the top level of a - module before any function or class definitions. Over time or - through decree, a standard format or set of formats should emerge. + This would break "``from __future__ import``" statements introduced + in Python 2.1 for multiple module docstrings (main docstring plus + additional docstring(s)). The Python Reference Manual specifies: + + A future statement must appear near the top of the module. The + only lines that can appear before a future statement are: + + * the module docstring (if any), + * comments, + * blank lines, and + * other future statements. + + Resolution? + + 1. Should we search for docstrings after a ``__future__`` + statement? Very ugly. - The __docformat__ variable is a string containing the name of the - format being used, a case-insensitive string matching the input - parser's module or package name (i.e., the same name as required - to "import" the module or package), or a registered alias. If no - __docformat__ is specified, the default format is "plaintext" for - now; this may be changed to the standard format once determined. + 2. Redefine ``__future__`` statements to allow multiple preceeding + string literals? - The __docformat__ string may contain an optional second field, - separated from the format name (first field) by a single space: a - case-insensitive language identifier as defined in RFC 1766 [10]. - A typical language identifier consists of a 2-letter language code - from ISO 639 [11] (3-letter codes used only if no 2-letter code - exists; RFC 1766 is currently being revised to allow 3-letter - codes). If no language identifier is specified, the default is - "en" for English. The language identifier is passed to the parser - and can be used for language-dependent markup features. + 3. Or should we not even worry about this? There probably + shouldn't be ``__future__`` statements in production code, after + all. Will modules with ``__future__`` statements simply have to + put up with the single-docstring limitation? - Identifier Cross-References - --------------------------- +Choice of Docstring Format +-------------------------- - In Python docstrings, interpreted text is used to classify and - mark up program identifiers, such as the names of variables, - functions, classes, and modules. If the identifier alone is - given, its role is inferred implicitly according to the Python - namespace lookup rules. For functions and methods (even when - dynamically assigned), parentheses ('()') may be included:: - - This function uses `another()` to do its work. +Rather than force everyone to use a single docstring format, multiple +input formats are allowed by the processing system. A special +variable, ``__docformat__``, may appear at the top level of a module +before any function or class definitions. Over time or through +decree, a standard format or set of formats should emerge. + +The ``__docformat__`` variable is a string containing the name of the +format being used, a case-insensitive string matching the input +parser's module or package name (i.e., the same name as required to +"import" the module or package), or a registered alias. If no +``__docformat__`` is specified, the default format is "plaintext" for +now; this may be changed to the standard format once determined. + +The ``__docformat__`` string may contain an optional second field, +separated from the format name (first field) by a single space: a +case-insensitive language identifier as defined in RFC 1766. A +typical language identifier consists of a 2-letter language code from +`ISO 639`_ (3-letter codes used only if no 2-letter code exists; RFC +1766 is currently being revised to allow 3-letter codes). If no +language identifier is specified, the default is "en" for English. +The language identifier is passed to the parser and can be used for +language-dependent markup features. + + +Identifier Cross-References +--------------------------- + +In Python docstrings, interpreted text is used to classify and mark up +program identifiers, such as the names of variables, functions, +classes, and modules. If the identifier alone is given, its role is +inferred implicitly according to the Python namespace lookup rules. +For functions and methods (even when dynamically assigned), +parentheses ('()') may be included:: + + This function uses `another()` to do its work. + +For class, instance and module attributes, dotted identifiers are used +when necessary. For example (using reStructuredText markup):: + + class Keeper(Storer): + + """ + Extend `Storer`. Class attribute `instances` keeps track + of the number of `Keeper` objects instantiated. + """ + + instances = 0 + """How many `Keeper` objects are there?""" + + def __init__(self): + """ + Extend `Storer.__init__()` to keep track of instances. - For class, instance and module attributes, dotted identifiers are - used when necessary. For example (using reStructuredText - markup):: + Keep count in `self.instances`, data in `self.data`. + """ + Storer.__init__(self) + self.instances += 1 - class Keeper(Storer): + self.data = [] + """Store data in a list, most recent last.""" + def storedata(self, data): """ - Extend `Storer`. Class attribute `instances` keeps track - of the number of `Keeper` objects instantiated. + Extend `Storer.storedata()`; append new `data` to a + list (in `self.data`). """ + self.data = data - instances = 0 - """How many `Keeper` objects are there?""" - - def __init__(self): - """ - Extend `Storer.__init__()` to keep track of instances. - - Keep count in `self.instances`, data in `self.data`. - """ - Storer.__init__(self) - self.instances += 1 - - self.data = [] - """Store data in a list, most recent last.""" +Each of the identifiers quoted with backquotes ("`") will become +references to the definitions of the identifiers themselves. - def storedata(self, data): - """ - Extend `Storer.storedata()`; append new `data` to a - list (in `self.data`). - """ - self.data = data - Each of the identifiers quoted with backquotes ("`") will become - references to the definitions of the identifiers themselves. +Stylist Transforms +------------------ +Stylist transforms are specialized transforms specific to a Reader. +The PySource Reader doesn't have to make any decisions as to style; it +just produces a logically constructed document tree, parsed and +linked, including custom node types. Stylist transforms understand +the custom nodes created by the Reader and convert them into standard +Docutils nodes. - Stylist Transforms - ------------------ +Multiple Stylist transforms may be implemented and one can be chosen +at runtime (through a "--style" or "--stylist" command-line option). +Each Stylist transform implements a different layout or style; thus +the name. They decouple the context-understanding part of the Reader +from the layout-generating part of processing, resulting in a more +flexible and robust system. This also serves to "separate style from +content", the SGML/XML ideal. - Stylist transforms are specialized transforms specific to a - Reader. The PySource Reader doesn't have to make any decisions as - to style; it just produces a logically constructed document tree, - parsed and linked, including custom node types. Stylist - transforms understand the custom nodes created by the Reader and - convert them into standard Docutils nodes. +By keeping the piece of code that does the styling small and modular, +it becomes much easier for people to roll their own styles. The +"barrier to entry" is too high with existing tools; extracting the +stylist code will lower the barrier considerably. - Multiple Stylist transforms may be implemented and one can be - chosen at runtime (through a "--style" or "--stylist" command-line - option). Each Stylist transform implements a different layout or - style; thus the name. They decouple the context-understanding - part of the Reader from the layout-generating part of processing, - resulting in a more flexible and robust system. This also serves - to "separate style from content", the SGML/XML ideal. - By keeping the piece of code that does the styling small and - modular, it becomes much easier for people to roll their own - styles. The "barrier to entry" is too high with existing tools; - extracting the stylist code will lower the barrier considerably. +========================== + References and Footnotes +========================== +.. [#PEP-256] PEP 256, Docstring Processing System Framework, Goodger -References and Footnotes + http://www.python.org/peps/pep-0256.html - [1] PEP 256, Docstring Processing System Framework, Goodger - http://www.python.org/peps/pep-0256.html +.. [#PEP-224] PEP 224, Attribute Docstrings, Lemburg - [2] http://docutils.sourceforge.net/spec/docutils.dtd + http://www.python.org/peps/pep-0224.html - [3] http://docutils.sourceforge.net/spec/soextblx.dtd +.. [#PEP-216] PEP 216, Docstring Format, Zadka - [4] http://docutils.sourceforge.net/spec/doctree.txt + http://www.python.org/peps/pep-0216.html - [5] http://www.openvms.compaq.com:8000/73final/5841/ - 5841pro_027.html#error_cond_severity +.. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd - [6] http://jakarta.apache.org/log4j/ +.. _soextbl.dtd: http://docutils.sourceforge.net/spec/soextblx.dtd - [7] http://docutils.sourceforge.net/spec/pysource.dtd +.. _The Docutils Document Tree: + http://docutils.sourceforge.net/spec/doctree.txt - [8] PEP 224, Attribute Docstrings, Lemburg - http://www.python.org/peps/pep-0224.html +.. _VMS error condition severity levels: + http://www.openvms.compaq.com:8000/73final/5841/841pro_027.html + #error_cond_severity - [9] PEP 216, Docstring Format, Zadka - http://www.python.org/peps/pep-0216.html +.. _log4j project: http://jakarta.apache.org/log4j/ - [10] http://www.rfc-editor.org/rfc/rfc1766.txt +.. _Docutils Python Source DTD: + http://docutils.sourceforge.net/spec/pysource.dtd - [11] http://lcweb.loc.gov/standards/iso639-2/englangn.html +.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html - [12] http://www.python.org/sigs/doc-sig/ +.. _Python Doc-SIG: http://www.python.org/sigs/doc-sig/ -Project Web Site +================== + Project Web Site +================== - A SourceForge project has been set up for this work at - http://docutils.sourceforge.net/. +A SourceForge project has been set up for this work at +http://docutils.sourceforge.net/. -Copyright +=========== + Copyright +=========== - This document has been placed in the public domain. +This document has been placed in the public domain. -Acknowledgements +================== + Acknowledgements +================== - This document borrows ideas from the archives of the Python - Doc-SIG [12]. Thanks to all members past & present. +This document borrows ideas from the archives of the `Python +Doc-SIG`_. Thanks to all members past & present. -Local Variables: -mode: indented-text -indent-tabs-mode: nil -fill-column: 70 -sentence-end-double-space: t -End: +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: -- cgit v1.2.1 From 550b619ded6ea003676ceacebaed30b27fb81061 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Aug 2002 01:11:40 +0000 Subject: Added "topic" directive docs. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@468 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 8011eb3c5..205d3843a 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -157,6 +157,34 @@ legend. To specify a legend without a caption, use an empty comment ("..") in place of the caption. +--------------- + Body Elements +--------------- + +Topic +===== + +DTD element: topic. + +Directive block: directive data and all following indented lines are +collected. The first line is interpreted as the topic title; the +second line must be blank. All subsequent lines are the topic body, +interpreted as body elements. + +A topic is like a block quote with a title, or a self-contained +section with no subsections. Use the "topic" directive to indicate a +self-contained idea that is separate from the flow of the document. +Topics may occur anywhere a section or transition may occur. Body +elements (including topics) may not contain nested topics. For +example:: + + topic:: Topic Title + + Subsequent indented lines comprise + the body of the topic, and are + interpreted as body elements. + + ---------------- Document Parts ---------------- -- cgit v1.2.1 From 43396c99e65920bfc0219d8d4e731c6542cd1cce Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Aug 2002 01:12:51 +0000 Subject: Disambiguated comments. Updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@469 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 0e0941226..c94e03ffb 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -6,7 +6,7 @@ :Revision: $Revision$ :Date: $Date$ -reStructuredText_ is plain text that uses simple and intuitive +reStructuredText_ is plaintext that uses simple and intuitive constructs to indicate the structure of a document. These constructs are equally easy to read in raw and processed forms. This document is itself an example of reStructuredText (raw, if you are reading the @@ -28,8 +28,7 @@ reStructuredText markup by example. A complete specification is given in the `Syntax Details`_ section. `Literal blocks`_ (in which no markup processing is done) are used for -examples throughout this document, to illustrate the plain text -markup. +examples throughout this document, to illustrate the plaintext markup. .. contents:: @@ -324,7 +323,7 @@ the field names):: Escaping Mechanism ================== -The character set universally available to plain text documents, 7-bit +The character set universally available to plaintext documents, 7-bit ASCII, is limited. No matter what characters are used for markup, they will already have multiple meanings in written text. Therefore markup characters *will* sometimes appear in text **without being @@ -1335,7 +1334,7 @@ required between explicit markup blocks and other elements, but are optional between explicit markup blocks where unambiguous. The explicit markup syntax is used for footnotes, citations, hyperlink -targets, directives, and comments. +targets, directives, substitution definitions, and comments. Footnotes @@ -1927,8 +1926,8 @@ Styles [#]_ The style name may be meaningful in the context of some particular output format (CSS class name for HTML output, LaTeX style name - for LaTeX, etc), or may be ignored for other output formats (often - for plain text). + for LaTeX, etc), or may be ignored for other output formats (such + as plaintext). .. @@@ This needs to be rethought & rewritten or removed: @@ -2006,8 +2005,20 @@ be processed as a comment element. No further processing is done on the comment block text; a comment contains a single "text blob". Depending on the output formatter, comments may be removed from the processed output. The only restriction on comments is that they not -use the same syntax as directives, footnotes, citations, or hyperlink -targets. +use the same syntax as any of the other explicit markup constructs: +substitution definitions, directives, footnotes, citations, or +hyperlink targets. To ensure that none of the other explicit markup +constructs is recognized, leave the ".." on a line by itself:: + + .. This is a comment + .. + _so: is this! + .. + [and] this! + .. + this:: too! + .. + |even| this:: ! A explicit markup start followed by a blank line and nothing else (apart from whitespace) is an "empty comment". It serves to terminate -- cgit v1.2.1 From c3a7c82de29b32306d082fdf5b20ccc24ce55023 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Aug 2002 01:17:10 +0000 Subject: Tests for the "topic" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@470 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/test_topics.py | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 test/test_parsers/test_rst/test_directives/test_topics.py diff --git a/test/test_parsers/test_rst/test_directives/test_topics.py b/test/test_parsers/test_rst/test_directives/test_topics.py new file mode 100644 index 000000000..000f98799 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_topics.py @@ -0,0 +1,149 @@ +#! /usr/bin/env python + +""" +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Tests for the "topic" directive. +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['topics'] = [ +["""\ +.. topic:: +""", +"""\ + +"""], +["""\ +.. topic:: Title +""", +"""\ + + + + Title +"""], +["""\ +.. topic:: Title + + Body. +""", +"""\ +<document> + <topic> + <title> + Title + <paragraph> + Body. +"""], +["""\ +.. topic:: + + Title + + Body. +""", +"""\ +<document> + <topic> + <title> + Title + <paragraph> + Body. +"""], +["""\ +.. topic:: Title + Body. +""", +"""\ +<document> + <topic> + <title> + Title + <system_message level="2" type="WARNING"> + <paragraph> + The second line of a topic block must be blank (line 2). + <paragraph> + Body. +"""], +["""\ +.. topic:: + + Title + Body. +""", +"""\ +<document> + <topic> + <title> + Title + <system_message level="2" type="WARNING"> + <paragraph> + The second line of a topic block must be blank (line 4). + <paragraph> + Body. +"""], +["""\ +.. topic:: Title + + .. topic:: Nested + + Body. +""", +"""\ +<document> + <topic> + <title> + Title + <system_message level="3" type="ERROR"> + <paragraph> + Topics may not be nested within body elements (line 2). + <literal_block> + .. topic:: Nested + \n\ + Body. +"""], +["""\ +.. topic:: Title + + .. topic:: Nested + + Body. + More. +""", +"""\ +<document> + <topic> + <title> + Title + <system_message level="3" type="ERROR"> + <paragraph> + Topics may not be nested within body elements (line 2). + <literal_block> + .. topic:: Nested + \n\ + Body. + <system_message level="2" type="WARNING"> + <paragraph> + Explicit markup ends without a blank line; unexpected unindent at line 5. + <paragraph> + More. +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 60e31f05a8a0edd5eca8ea046c3ff6a98e46e581 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 7 Aug 2002 01:20:34 +0000 Subject: Fixed nested section margins. Added style for chunks of inline literals. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@471 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 8c6a2424f..818c4cd20 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -67,6 +67,11 @@ div.section { margin-right: 1em ; margin-bottom: 1.5em } +div.section div.section { + margin-left: 0em ; + margin-right: 0em ; + margin-top: 1.5em } + div.abstract { margin: 2em 5em } @@ -205,6 +210,9 @@ span.interpreted { span.option-argument { font-style: italic } +span.pre { + white-space: pre } + span.problematic { color: red } -- cgit v1.2.1 From f5b6a9b7a5bd51366e4878b953bb7cf42b5f1a6e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 7 Aug 2002 01:20:52 +0000 Subject: Added style for chunks of inline literals. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@472 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index d1dd52155..6f4cde5b4 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -144,6 +144,9 @@ span.interpreted { span.option-argument { font-style: italic } +span.pre { + white-space: pre } + span.problematic { color: red } -- cgit v1.2.1 From 9eb27da5f41ace80bb1ecd48f6cc5839cd96b6e7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 7 Aug 2002 01:22:54 +0000 Subject: Linked "Content-Type: text/plain" to PEP 9. Updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@473 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 28cfd9a0b..42328ae9c 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -207,9 +207,9 @@ def fixfile(inpath, input_lines, outfile): else: mailtos.append(part) v = COMMASPACE.join(mailtos) - elif k.lower() in ('replaces', 'replaced-by'): + elif k.lower() in ('replaces', 'replaced-by', 'requires'): otherpeps = '' - for otherpep in v.split(): + for otherpep in re.split(',?\s+', v): otherpep = int(otherpep) otherpeps += '<a href="pep-%04d.html">%i</a> ' % (otherpep, otherpep) @@ -219,6 +219,10 @@ def fixfile(inpath, input_lines, outfile): date = v or time.strftime('%d-%b-%Y', time.localtime(os.stat(inpath)[8])) v = '<a href="%s">%s</a> ' % (url, cgi.escape(date)) + elif k.lower() in ('content-type',): + url = PEPURL % 9 + pep_type = v or 'text/plain' + v = '<a href="%s">%s</a> ' % (url, cgi.escape(pep_type)) else: v = cgi.escape(v) print >> outfile, ' <tr><th>%s: </th><td>%s</td></tr>' \ @@ -318,7 +322,7 @@ def get_pep_type(input_lines): # End of the RFC 2822 header (first blank line). break elif line.startswith('content-type: '): - pep_type = line.split()[1] + pep_type = line.split()[1] or 'text/plain' break elif line.startswith('pep: '): # Default PEP type, used if no explicit content-type specified: @@ -334,7 +338,7 @@ def get_input_lines(inpath): print >> sys.stderr, 'Error: Skipping missing PEP file:', e.filename sys.stderr.flush() return None, None - lines = infile.readlines() + lines = infile.read().splitlines(1) # handles x-platform line endings infile.close() return lines -- cgit v1.2.1 From 1981123ec5a63f9d98ee3b8d8433e7d1cab3b021 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 7 Aug 2002 01:25:26 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@474 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 36 ++++++++++++++ docs/dev/todo.txt | 8 ---- docs/peps/pep-0287.txt | 28 +++++------ docutils/parsers/rst/directives/__init__.py | 4 +- docutils/parsers/rst/languages/en.py | 8 ++-- test/test_parsers/test_rst/test_comments.py | 60 +++++++++++++++++++++++ test/test_parsers/test_rst/test_paragraphs.py | 10 ++++ test/test_transforms/test_contents.py | 68 +++++++++++++-------------- 8 files changed, 160 insertions(+), 62 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e0ce636aa..0669ad00f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -38,6 +38,15 @@ any names; apologies (and please let me know!) if I have. Changes Since 0.2 ======================== +* docutils/nodes.py: + + - Added "Invisible" element category class. + - Changed ``Node.walk()`` & ``.walkabout()`` to permit more tree + modification during a traversal. + +* docutils/parsers/rst/directives/body.py: Added to project. Contains + the "topic" directive. + * docutils/transforms/parts.py: - Moved the "id" attribute from TOC list items to the references @@ -47,6 +56,7 @@ Changes Since 0.2 - Added ``mask_email()`` function, updating to pep2html.py's functionality. + - Linked "Content-Type: text/x-rst" to PEP 12. * docutils/writers/html4css1.py: @@ -58,19 +68,45 @@ Changes Since 0.2 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. * docs/tools.txt: - Added "silent" setting for ``buildhtml.py``. +* spec/pep-0256.txt: Converted to reStructuredText & updated. + +* spec/pep-0258.txt: Converted to reStructuredText & updated. + +* spec/rst/directives.txt: + + - Added the "topic" directive. + +* spec/rst/reStructuredText.txt: + + - Disambiguated comments (just add a newline after the "::"). + * tools/buildhtml.py: - Added "--silent" option. +* tools/default.css: + + - Added style for chunks of inline literals. + * 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. + +* tools/stylesheets/pep.css: + + - Fixed nested section margins. + - Added style for chunks of inline literals. Release 0.2 (2002-07-31) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 737e4533e..7649fb083 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -140,9 +140,6 @@ General - @@@ Add references to the user docs: bugs to the SF bug tracker, questions to the mailing lists. -- @@@ Add a transform to remove body-level targets from the doctree, - as the first stage of optimization. - Specification ------------- @@ -410,8 +407,6 @@ Directives problem similar to the first problem listed for misc.encoding_, although to a lesser degree. - - @@@ _`body.topic` - - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) @@ -675,9 +670,6 @@ HTML Writer - Add more support for <link> elements, especially for navigation bars. -- @@@ Add ``<span class="pre">`` around chunks of text in inline - literals, and a "whitespace: pre" style to the stylesheet. - Front-End Tools --------------- diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 95f11d59c..4b4ed4e44 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -727,6 +727,20 @@ Questions & Answers References & Footnotes ====================== +.. [#PEP-1] PEP 1, PEP Guidelines, Warsaw, Hylton + (http://www.python.org/peps/pep-0001.html) + +.. [#PEP-9] PEP 9, Sample PEP Template, Warsaw + (http://www.python.org/peps/pep-0009.html) + +.. [#Zen] From `The Zen of Python (by Tim Peters)`__ (or just + "``import this``" in Python) + +__ http://www.python.org/doc/Humor.html#zen + +.. [#PEP-216] PEP 216, Docstring Format, Zadka + (http://www.python.org/peps/pep-0216.html) + .. _reStructuredText markup: http://docutils.sourceforge.net/spec/rst.html .. _Doc-SIG: http://www.python.org/sigs/doc-sig/ @@ -775,20 +789,6 @@ References & Footnotes .. _Docutils: http://docutils.sourceforge.net/ -.. [#PEP-1] PEP 1, PEP Guidelines, Warsaw, Hylton - (http://www.python.org/peps/pep-0001.html) - -.. [#PEP-9] PEP 9, Sample PEP Template, Warsaw - (http://www.python.org/peps/pep-0009.html) - -.. [#Zen] From `The Zen of Python (by Tim Peters)`__ (or just - "``import this``" in Python) - -__ http://www.python.org/doc/Humor.html#zen - -.. [#PEP-216] PEP 216, Docstring Format, Zadka - (http://www.python.org/peps/pep-0216.html) - Copyright ========= diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 025405029..ada409a79 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -50,13 +50,13 @@ _directive_registry = { 'tip': ('admonitions', 'tip'), 'hint': ('admonitions', 'hint'), 'warning': ('admonitions', 'warning'), - 'questions': ('body', 'question_list'), + 'topic': ('body', 'topic'), + #'questions': ('body', 'question_list'), 'image': ('images', 'image'), 'figure': ('images', 'figure'), 'contents': ('parts', 'contents'), #'footnotes': ('parts', 'footnotes'), #'citations': ('parts', 'citations'), - #'topic': ('parts', 'topic'), 'meta': ('html', 'meta'), #'imagemap': ('html', 'imagemap'), #'raw': ('misc', 'raw'), diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 370c34d12..0ccba3952 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -24,9 +24,10 @@ directives = { 'note': 'note', 'tip': 'tip', 'warning': 'warning', - 'questions': 'questions', - 'qa': 'questions', - 'faq': 'questions', + 'topic': 'topic', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', 'meta': 'meta', #'imagemap': 'imagemap', 'image': 'image', @@ -35,7 +36,6 @@ directives = { 'contents': 'contents', #'footnotes': 'footnotes', #'citations': 'citations', - #'topic': 'topic', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English name to registered (in directives/__init__.py) directive name mapping.""" diff --git a/test/test_parsers/test_rst/test_comments.py b/test/test_parsers/test_rst/test_comments.py index 73d83dc7d..1b5961c13 100755 --- a/test/test_parsers/test_rst/test_comments.py +++ b/test/test_parsers/test_rst/test_comments.py @@ -126,6 +126,66 @@ Paragraph. Paragraph. """], ["""\ +.. + comment:: + +The extra newline before the comment text prevents +the parser from recognizing a directive. +""", +"""\ +<document> + <comment> + comment:: + <paragraph> + The extra newline before the comment text prevents + the parser from recognizing a directive. +"""], +["""\ +.. + _comment: http://example.org + +The extra newline before the comment text prevents +the parser from recognizing a hyperlink target. +""", +"""\ +<document> + <comment> + _comment: http://example.org + <paragraph> + The extra newline before the comment text prevents + the parser from recognizing a hyperlink target. +"""], +["""\ +.. + [comment] Not a citation. + +The extra newline before the comment text prevents +the parser from recognizing a citation. +""", +"""\ +<document> + <comment> + [comment] Not a citation. + <paragraph> + The extra newline before the comment text prevents + the parser from recognizing a citation. +"""], +["""\ +.. + |comment| image:: bogus.png + +The extra newline before the comment text prevents +the parser from recognizing a substitution definition. +""", +"""\ +<document> + <comment> + |comment| image:: bogus.png + <paragraph> + The extra newline before the comment text prevents + the parser from recognizing a substitution definition. +"""], +["""\ .. Next is an empty comment, which serves to end this comment and prevents the following block quote being swallowed up. diff --git a/test/test_parsers/test_rst/test_paragraphs.py b/test/test_parsers/test_rst/test_paragraphs.py index d1f3a324a..296562cab 100755 --- a/test/test_parsers/test_rst/test_paragraphs.py +++ b/test/test_parsers/test_rst/test_paragraphs.py @@ -72,6 +72,16 @@ Line 3. Line 2. Line 3. """], +["""\ +A. Einstein was a really +smart dude. +""", +"""\ +<document> + <paragraph> + A. Einstein was a really + smart dude. +"""], ] if __name__ == '__main__': diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 5b416a82d..9b6b70106 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -51,23 +51,23 @@ Paragraph 4. <title> Contents <bullet_list> - <list_item id="id1"> + <list_item> <paragraph> - <reference refid="title-1"> + <reference id="id1" refid="title-1"> Title 1 <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="title-2"> + <reference id="id2" refid="title-2"> Title 2 <bullet_list> - <list_item id="id3"> + <list_item> <paragraph> - <reference refid="title-3"> + <reference id="id3" refid="title-3"> Title 3 - <list_item id="id4"> + <list_item> <paragraph> - <reference refid="title-4"> + <reference id="id4" refid="title-4"> Title 4 <section id="title-1" name="title 1"> <title refid="id1"> @@ -107,14 +107,14 @@ Paragraph 2. <title> Table of Contents <bullet_list> - <list_item id="id1"> + <list_item> <paragraph> - <reference refid="title-1"> + <reference id="id1" refid="title-1"> Title 1 <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="title-2"> + <reference id="id2" refid="title-2"> Title 2 <section id="title-1" name="title 1"> <title refid="id1"> @@ -146,13 +146,13 @@ Paragraph 2. <title> There's an image in Title 2 <bullet_list> - <list_item id="id1"> + <list_item> <paragraph> - <reference refid="title-1"> + <reference id="id1" refid="title-1"> Title 1 - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="title-2"> + <reference id="id2" refid="title-2"> Title 2 <section id="title-1" name="title 1"> <title refid="id1"> @@ -193,18 +193,18 @@ Paragraph 4. <title> Contents <bullet_list> - <list_item id="id1"> + <list_item> <paragraph> - <reference refid="title-1"> + <reference id="id1" refid="title-1"> Title 1 <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="title-2"> + <reference id="id2" refid="title-2"> Title 2 - <list_item id="id3"> + <list_item> <paragraph> - <reference refid="title-4"> + <reference id="id3" refid="title-4"> Title 4 <section id="title-1" name="title 1"> <title refid="id1"> @@ -255,18 +255,18 @@ Paragraph 4. Title 1 <topic class="contents" id="contents" name="contents"> <bullet_list> - <list_item id="id1"> + <list_item> <paragraph> - <reference refid="title-2"> + <reference id="id1" refid="title-2"> Title 2 <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="title-3"> + <reference id="id2" refid="title-3"> Title 3 - <list_item id="id3"> + <list_item> <paragraph> - <reference refid="title-4"> + <reference id="id3" refid="title-4"> Title 4 <paragraph> Paragraph 1. @@ -300,9 +300,9 @@ Paragraph. <document> <topic class="contents" id="id1"> <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="contents"> + <reference id="id2" refid="contents"> Contents <paragraph> Test duplicate name "Contents". @@ -326,9 +326,9 @@ Paragraph. <title> Contents <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="contents"> + <reference id="id2" refid="contents"> Contents <section id="contents" name="contents"> <title refid="id1"> @@ -350,9 +350,9 @@ Paragraph. <title> Contents <bullet_list> - <list_item id="id2"> + <list_item> <paragraph> - <reference refid="contents"> + <reference id="id2" refid="contents"> Contents <section id="contents" name="contents"> <title> -- cgit v1.2.1 From a83aaa90155115647d0bb2728003e61a7dc8248c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 7 Aug 2002 02:05:13 +0000 Subject: encode inline literals for HTML git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@475 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f1861a7f3..c3de6df2c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -653,7 +653,8 @@ class HTMLTranslator(nodes.NodeVisitor): if token in ('\n', ' '): self.body.append(token) elif token.strip(): - self.body.append('<span class="pre">%s</span>' % token) + self.body.append('<span class="pre">%s</span>' + % self.encode(token)) else: self.body.append(' ' * (len(token) - 1) + ' ') self.body.append('</tt>') -- cgit v1.2.1 From 21b6680682069491ad6ece14fbc099bdc913a148 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 8 Aug 2002 00:20:18 +0000 Subject: - Added a "Getting Help" section. - Added a style to make section header backlinks more subtle. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@476 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 93 ++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index ea98e6788..e32073cb7 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -3,6 +3,10 @@ <head> <title>Quick reStructuredText + + @@ -20,10 +24,10 @@

http://docutils.sourceforge.net/docs/rst/quickref.html
Being a cheat-sheet for reStructuredText -
Version 0.9 of 2002-07-23 +
Version 0.10 of 2002-08-07 -

The full details may be found on the +

The full details of the markup may be found on the reStructuredText page. This document is just intended as a reminder. @@ -64,9 +68,11 @@

  • Directives
  • Substitution References and Definitions
  • Comments
  • +
  • Getting Help
  • -

    Inline Markup

    +

    Inline Markup

    (details?) @@ -180,7 +186,8 @@ markup delimiter characters, but that doesn't count because nothing is processed). -

    Escaping with Bashslashes

    +

    Escaping with Bashslashes

    (details?) @@ -228,7 +235,8 @@ escape with "" -

    Section Structure

    +

    Section Structure

    (details?) @@ -261,7 +269,8 @@ are "= - ` : ' " ~ ^ _ * + # < >". -

    Paragraphs

    +

    Paragraphs

    (details?) @@ -288,7 +297,8 @@ -

    Bullet Lists

    +

    Bullet Lists

    (details?) @@ -325,7 +335,8 @@ item and after the last, but is optional between items. -

    Enumerated Lists

    +

    Enumerated Lists

    (details?) @@ -360,7 +371,8 @@ -

    Definition Lists

    +

    Definition Lists

    (details?) @@ -400,7 +412,8 @@ -

    Field Lists

    +

    Field Lists

    (details?) @@ -433,7 +446,8 @@ -

    Option Lists

    +

    Option Lists

    (details?) @@ -480,7 +494,8 @@

    There must be at least two spaces between the option and the description. -

    Literal Blocks

    +

    Literal Blocks

    (details?) @@ -558,7 +573,8 @@ This means that something like:

    is possible. -

    Block Quotes

    +

    Block Quotes

    (details?) @@ -586,7 +602,8 @@ This means that something like: -

    Doctest Blocks

    +

    Doctest Blocks

    (details?) @@ -621,7 +638,8 @@ This means that something like: interactive Python session, then executes all such sessions to verify they still work exactly as shown." (From the doctest docs.) -

    Tables

    +

    Tables

    (details?) @@ -729,7 +747,8 @@ This means that something like: -

    Transitions

    +

    Transitions

    (details?) @@ -769,7 +788,8 @@ A transition marker is a horizontal line gap spanning one or more lines, marking text divisions or signaling changes in subject, time, point of view, or emphasis. -

    Footnotes

    +

    Footnotes

    (details?) @@ -861,7 +881,8 @@ A transition marker is a horizontal line same relative order. Similarly for auto-symbol footnotes ("[*]_"). -

    Citations

    +

    Citations

    (details?) @@ -913,11 +934,13 @@ A transition marker is a horizontal line -

    Hyperlink Targets

    +

    Hyperlink Targets

    (details?) -

    External Hyperlink Targets

    +

    External Hyperlink Targets

    @@ -955,7 +978,8 @@ A transition marker is a horizontal line printed documents, where the link needs to be presented explicitly, for example as a footnote. -

    Internal Hyperlink Targets

    +

    Internal Hyperlink Targets

    @@ -990,7 +1014,8 @@ A transition marker is a horizontal line
    -

    Indirect Hyperlink Targets

    +

    Indirect Hyperlink Targets

    (details?) @@ -1025,7 +1050,8 @@ A transition marker is a horizontal line target. In the text, a double-underscore suffix is used to indicate an anonymous hyperlink reference. -

    Implicit Hyperlink Targets

    +

    Implicit Hyperlink Targets

    (details?) @@ -1051,7 +1077,8 @@ A transition marker is a horizontal line targets, too. -

    Directives

    +

    Directives

    (details?) @@ -1072,7 +1099,8 @@ A transition marker is a horizontal line

    ball1 -

    Substitution References and Definitions

    +

    Substitution References and Definitions

    (details?) @@ -1102,7 +1130,8 @@ dispose of medical waste. -

    Comments

    +

    Comments

    (details?) @@ -1139,6 +1168,18 @@ dispose of medical waste. +

    Getting Help

    + +

    Users who have questions or need assistance with Docutils or + reStructuredText should post a + message to the Docutils-Users mailing list. The Docutils project web + site has more information. +


    Authors: -- cgit v1.2.1 From 3d2f2e74848b639f85b0e64ead6ec78a6e67b20e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:21:15 +0000 Subject: - Added a table of contents. - Added feedback information. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@477 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickstart.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index e2bda81fd..c335ac97a 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -4,6 +4,9 @@ A ReStructuredText Primer :Author: Richard Jones :Version: $Revision$ +.. contents:: + + The text below contains links that look like "(quickref__)". These are relative links that point to the `Quick reStructuredText`_ user reference. If these links don't work, please refer to the `master @@ -328,8 +331,17 @@ but there are a lot more to explore. The `Quick reStructuredText`_ user reference is a good place to go next. For complete details, the `reStructuredText Markup Specification`_ is the place to go [#]_. -.. _reStructuredText Markup Specification: - ../../spec/rst/reStructuredText.html +Users who have questions or need assistance with Docutils or +reStructuredText should `post a message`_ to the `Docutils-Users +mailing list`_. The `Docutils project web site`_ has more +information. .. [#] If that relative link doesn't work, try the master document: http://docutils.sourceforge.net/spec/rst/reStructuredText.html. + +.. _reStructuredText Markup Specification: + ../../spec/rst/reStructuredText.html +.. _post a message: mailto:docutils-users@lists.sourceforge.net +.. _Docutils-Users mailing list: + http://lists.sourceforge.net/lists/listinfo/docutils-users +.. _Docutils project web site: http://docutils.sourceforge.net/ -- cgit v1.2.1 From 9920a415e33b05a3890a7d0ed848edc81182b62c Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:23:31 +0000 Subject: - Added a "Getting Help" section. - Rearranged the structure. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@478 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index f58a7a62d..7d2de6c0d 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -7,6 +7,12 @@ :Revision: $Revision$ :Date: $Date$ +.. contents:: + + +Introduction +============ + Once the Docutils package is unpacked, you will discover a "``tools``" directory containing several front ends for common Docutils processing. Rather than a single all-purpose program, Docutils has @@ -29,11 +35,25 @@ used for the destination. If no arguments are specified, the standard input (stdin) is used for the source as well. -.. contents:: +Getting Help +------------ + +Users who have questions or need assistance with Docutils or +reStructuredText should `post a message`_ to the `Docutils-Users +mailing list`_. The `Docutils project web site`_ has more +information. +.. _post a message: mailto:docutils-users@lists.sourceforge.net +.. _Docutils-Users mailing list: + http://lists.sourceforge.net/lists/listinfo/docutils-users +.. _Docutils project web site: http://docutils.sourceforge.net/ + + +The Tools +========= buildhtml.py -============ +------------ :Readers: Standalone, PEP :Parser: reStructuredText @@ -69,7 +89,7 @@ override config file settings or replace them altogether. html.py -======= +------- :Reader: Standalone :Parser: reStructuredText @@ -95,7 +115,7 @@ of processing, and links to the Docutils projects, add some options:: Stylesheets ------------ +``````````` ``html.py`` inserts into the generated HTML a link to a cascading stylesheet, defaulting to "``default.css``" (override with a @@ -123,7 +143,7 @@ incremental experimentation. pep.py -====== +------ :Reader: PEP :Parser: reStructuredText @@ -146,7 +166,7 @@ for more information. pep2html.py -=========== +----------- :Reader: PEP :Parser: reStructuredText @@ -167,7 +187,7 @@ files. If no arguments are given, all files of the form docutils-xml.py -=============== +--------------- :Reader: Standalone :Parser: reStructuredText @@ -179,7 +199,7 @@ processors into arbitrary final forms. publish.py -========== +---------- :Reader: Standalone :Parser: reStructuredText @@ -193,7 +213,7 @@ attributes for any leftover "pending" elements are also given. quicktest.py -============ +------------ :Reader: N/A :Parser: reStructuredText -- cgit v1.2.1 From d23a7aba7c10024f062506f8c548b3f66f3e66c6 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:24:11 +0000 Subject: - Check for & exit on identical source & destination paths. - Fixed bug with absolute paths & ``--config``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@479 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 148a3b894..c03634634 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -60,7 +60,7 @@ def make_paths_absolute(dictionary, base_path=None): for option in relative_path_options: if dictionary.has_key(option) and dictionary[option]: dictionary[option] = os.path.normpath( - os.path.join(base_path, dictionary[option])) + os.path.abspath(os.path.join(base_path, dictionary[option]))) class OptionParser(optik.OptionParser): @@ -237,6 +237,9 @@ class OptionParser(optik.OptionParser): destination = args.pop(0) if args: self.error('Maximum 2 arguments allowed.') + if source and source == destination: + self.error('Do not specify the same file for both source and ' + 'destination. It will clobber the source file.') return source, destination -- cgit v1.2.1 From 4b4b1b9a3615ba979d6c5b933e34a14d30dcf3c2 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:25:37 +0000 Subject: Changed "title under/overline too short" system messages from INFO to WARNING, and fixed its insertion location. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@480 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index cfb934e9d..e59102801 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -270,10 +270,10 @@ class RSTState(StateWS): state_machine.unlink() return state_machine.abs_line_offset(), blank_finish - def section(self, title, source, style, lineno): + def section(self, title, source, style, lineno, messages): """Check for a valid subsection and create one if it checks out.""" if self.check_subsection(source, style, lineno): - self.new_subsection(title, lineno) + self.new_subsection(title, lineno, messages) def check_subsection(self, source, style, lineno): """ @@ -320,19 +320,20 @@ class RSTState(StateWS): % lineno, '', literalblock) return error - def new_subsection(self, title, lineno): + def new_subsection(self, title, lineno, messages): """Append new subsection to document tree. On return, check level.""" memo = self.memo mylevel = memo.section_level memo.section_level += 1 sectionnode = nodes.section() self.parent += sectionnode - textnodes, messages = self.inline_text(title, lineno) + textnodes, title_messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) name = normalize_name(titlenode.astext()) sectionnode['name'] = name sectionnode += titlenode sectionnode += messages + sectionnode += title_messages self.document.note_implicit_target(sectionnode, sectionnode) offset = self.state_machine.line_offset + 1 absoffset = self.state_machine.abs_line_offset() + 1 @@ -2035,15 +2036,16 @@ class Text(RSTState): title = context[0].rstrip() underline = match.string.rstrip() source = title + '\n' + underline + messages = [] if len(title) > len(underline): blocktext = context[0] + '\n' + self.state_machine.line - msg = self.reporter.info( + msg = self.reporter.warning( 'Title underline too short at line %s.' % lineno, '', nodes.literal_block(blocktext, blocktext)) - self.parent += msg + messages.append(msg) style = underline[0] context[:] = [] - self.section(title, source, style, lineno - 1) + self.section(title, source, style, lineno - 1, messages) return [], next_state, [] def text(self, match, context, next_state): @@ -2226,14 +2228,15 @@ class Line(SpecializedText): self.parent += msg return [], 'Body', [] title = title.rstrip() + messages = [] if len(title) > len(overline): - msg = self.reporter.info( + msg = self.reporter.warning( 'Title overline too short at line %s.'% lineno, '', nodes.literal_block(source, source)) - self.parent += msg + messages.append(msg) style = (overline[0], underline[0]) self.eofcheck = 0 # @@@ not sure this is correct - self.section(title.lstrip(), source, style, lineno + 1) + self.section(title.lstrip(), source, style, lineno + 1, messages) self.eofcheck = 1 return [], 'Body', [] -- cgit v1.2.1 From 0671afe0513fb59a81bcba14bf3d86fb057f5eb8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:26:37 +0000 Subject: - Parameterized output encoding in PEP template. - Reworked substitutions from ``locals()`` into ``subs`` dict. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@481 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index af1a84dd5..5c3bb0194 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -50,32 +50,38 @@ class Writer(html4css1.Writer): html4css1.Writer.translate(self) options = self.document.options template = open(options.pep_template).read() + # Substitutions dict for template: + subs = {} + subs['encoding'] = options.output_encoding stylesheet = options.pep_stylesheet if stylesheet is None: stylesheet = options.stylesheet - stylesheet = utils.relative_uri(options._destination, stylesheet) + subs['stylesheet'] = utils.relative_uri(options._destination, + stylesheet) pyhome = options.python_home - pephome = options.pep_home + subs['pyhome'] = pyhome + subs['pephome'] = options.pep_home if pyhome == '..': - pepindex = '.' + subs['pepindex'] = '.' else: - pepindex = pyhome + '/peps/' + subs['pepindex'] = pyhome + '/peps/' index = self.document.first_child_matching_class(nodes.field_list) header = self.document[index] - pep = header[0][1].astext() + pepnum = header[0][1].astext() + subs['pep'] = pepnum if options.no_random: - banner = 0 + subs['banner'] = 0 else: import random - banner = random.randrange(64) + subs['banner'] = random.randrange(64) try: - pepnum = '%04i' % int(pep) + subs['pepnum'] = '%04i' % int(pepnum) except: - pepnum = pep - title = header[1][1].astext() - body = ''.join(self.body) - body_suffix = ''.join(self.body_suffix) - self.output = template % locals() + subs['pepnum'] = pepnum + subs['title'] = header[1][1].astext() + subs['body'] = ''.join(self.body) + subs['body_suffix'] = ''.join(self.body_suffix) + self.output = template % subs class HTMLTranslator(html4css1.HTMLTranslator): -- cgit v1.2.1 From 10d83bcc524ddbd5f8c9f7399aca1f8bb8633dc1 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:27:19 +0000 Subject: Fixed bug with absolute paths & ``--config``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@482 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/buildhtml.py b/tools/buildhtml.py index 97b1bf000..b04f811d1 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -131,6 +131,7 @@ class Builder: components=(OptionSpec, pep.Reader, rst.Parser, pep_html.Writer), usage=usage, description=description) self.option_defaults = option_parser.get_default_values() + frontend.make_paths_absolute(self.option_defaults.__dict__) config_parser = frontend.ConfigParser() config_parser.read_standard_files() self.config_settings = config_parser.get_section('options') -- cgit v1.2.1 From ed4dad1927fd297c6312aacac6e4d1295fe9de63 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:28:48 +0000 Subject: Removed margin for first child of table cells. Right-aligned field list names. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@483 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 6 +++++- tools/stylesheets/pep.css | 12 ++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 6f4cde5b4..d160c6b9d 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -170,9 +170,13 @@ td, th { padding-right: 0.5em ; vertical-align: baseline } +td > p:first-child, th > p:first-child { + margin-top: 0em } + th.docinfo-name { font-weight: bold ; text-align: right } th.field-name { - font-weight: bold } + font-weight: bold ; + text-align: right } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 818c4cd20..2e0c7865e 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -220,13 +220,17 @@ table { margin-top: 0.5em ; margin-bottom: 0.5em } -td.num { - text-align: right } - td, th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: baseline } +td > :first-child, th > :first-child { + margin-top: 0em } + +td.num { + text-align: right } + th.field-name { - font-weight: bold } + font-weight: bold ; + text-align: right } -- cgit v1.2.1 From af07d173f8976717923b4bf4b188fec0e86d6670 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:29:40 +0000 Subject: Parameterized output encoding. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@484 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-html-template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/pep-html-template b/tools/pep-html-template index de0c0d4c8..47d71daef 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -1,8 +1,8 @@ - + - + PEP %(pep)s -- %(title)s -- cgit v1.2.1 From b926207786b97cc60fe4480fa55ee8ba5286415d Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:30:45 +0000 Subject: Files skipped (due to an error) are not pushed onto the server. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@485 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 42328ae9c..e48ee6bd7 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -462,12 +462,14 @@ def main(argv=None): else: # do them all peptxt = [] + html = [] files = glob.glob("pep-*.txt") files.sort() for file in files: peptxt.append(file) - make_html(file, verbose=verbose) - html = ["pep-*.html"] + newfile = make_html(file, verbose=verbose) + if newfile: + html.append(newfile) if browse and not update: browse_file("0") -- cgit v1.2.1 From a3aaef18e8533f233feb7921e59d42a47a56e424 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Aug 2002 00:32:51 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@487 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 43 +++++++++++++++++++--- test/test_parsers/test_rst/test_section_headers.py | 26 ++++++------- test/test_transforms/test_doctitle.py | 4 +- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 0669ad00f..2163fe4ac 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -38,12 +38,22 @@ any names; apologies (and please let me know!) if I have. Changes Since 0.2 ======================== +* docutils/frontend.py: + + - Check for & exit on identical source & destination paths. + - Fixed bug with absolute paths & ``--config``. + * docutils/nodes.py: - Added "Invisible" element category class. - Changed ``Node.walk()`` & ``.walkabout()`` to permit more tree modification during a traversal. +* docutils/parsers/rst/states.py: + + - Changed "title under/overline too short" system messages from INFO + to WARNING, and fixed its insertion location. + * docutils/parsers/rst/directives/body.py: Added to project. Contains the "topic" directive. @@ -73,9 +83,26 @@ Changes Since 0.2 - Improved inline literals with ```` around chunks of text and `` `` for runs of spaces. +* docutils/writers/pep_html.py: + + - Parameterized output encoding in PEP template. + - Reworked substitutions from ``locals()`` into ``subs`` dict. + * docs/tools.txt: - - Added "silent" setting for ``buildhtml.py``. + - Added a "silent" setting for ``buildhtml.py``. + - Added a "Getting Help" section. + - Rearranged the structure. + +* docs/rst/quickstart.txt: + + - Added a table of contents. + - Added feedback information. + +* docs/rst/quickref.html: + + - Added a "Getting Help" section. + - Added a style to make section header backlinks more subtle. * spec/pep-0256.txt: Converted to reStructuredText & updated. @@ -91,22 +118,26 @@ Changes Since 0.2 * tools/buildhtml.py: - - Added "--silent" option. + - Added ``--silent`` option. + - Fixed bug with absolute paths & ``--config``. * tools/default.css: - Added style for chunks of inline literals. + - Removed margin for first child of table cells. + - Right-aligned field list names. * 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. * tools/stylesheets/pep.css: - Fixed nested section margins. - - Added style for chunks of inline literals. + - Other changes parallel those of ``../default.css``. Release 0.2 (2002-07-31) @@ -301,8 +332,8 @@ Specific: - Changed ``Messages`` transform to properly filter out system messages below the warning threshold. - - Added ``Decorations`` transform (support for "--generator", - "--date", "--time", "--source-link" options). + - 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. @@ -458,7 +489,7 @@ Specific: * tools/quicktest.py: - - Added the "--attributes" option, hacked a bit. + - Added the ``--attributes`` option, hacked a bit. - Added a second command-line argument (output file); cleaned up. * tools/stylesheets/: Subdirectory added to project. diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 54c556623..4ac348f26 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -112,15 +112,15 @@ Test short underline. """, """\ - - - Title underline too short at line 2. - - Title - ====

    Title + <system_message level="2" type="WARNING"> + <paragraph> + Title underline too short at line 2. + <literal_block> + Title + ==== <paragraph> Test short underline. """], @@ -207,16 +207,16 @@ Test long title and space normalization. """, """\ <document> - <system_message level="1" type="INFO"> - <paragraph> - Title overline too short at line 1. - <literal_block> - ======= - Long Title - ======= <section id="long-title" name="long title"> <title> Long Title + <system_message level="2" type="WARNING"> + <paragraph> + Title overline too short at line 1. + <literal_block> + ======= + Long Title + ======= <paragraph> Test long title and space normalization. """], diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 842906945..0040e54e6 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -99,7 +99,7 @@ Test short underline. <document id="title" name="title"> <title> Title - <system_message level="1" type="INFO"> + <system_message level="2" type="WARNING"> <paragraph> Title underline too short at line 2. <literal_block> @@ -121,7 +121,7 @@ The system_message should move after the document title <document id="long-title" name="long title"> <title> Long Title - <system_message level="1" type="INFO"> + <system_message level="2" type="WARNING"> <paragraph> Title overline too short at line 1. <literal_block> -- cgit v1.2.1 From f3c5decc4be60d2dd06c9dfbfef0f55788657c59 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 9 Aug 2002 01:07:53 +0000 Subject: Bumped version to 0.2.1 to reflect changes to I/O classes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@488 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index d2b58ae0e..9e3df1414 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -56,7 +56,10 @@ Subpackages: """ __docformat__ = 'reStructuredText' -__version__ = '0.2+' + +__version__ = '0.2.1' +"""``major.minor.micro`` version number. The ``micro`` number is bumped any +time there's a change in the API incompatible with one of the front ends.""" class ApplicationError(StandardError): pass -- cgit v1.2.1 From 165ac29709e0fe634da2b3382b3224318a31e591 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 9 Aug 2002 01:09:29 +0000 Subject: - Split ``IO`` classes into subclasses of ``Input`` and ``Output``. - Added automatic closing to ``FileInput`` and ``FileOutput``. - Delayed opening of ``FileOutput`` file until ``write()`` called. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@489 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 139 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 36 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 00285c21d..9b126c502 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -17,14 +17,13 @@ import sys import locale -class IO: +class Input: """ - Base class for abstract input/output wrappers. + Abstract base class for input wrappers. """ - def __init__(self, options, source=None, source_path=None, - destination=None, destination_path=None): + def __init__(self, options, source=None, source_path=None): self.options = options """An option values object with "input_encoding" and "output_encoding" attributes (typically a `docutils.optik.Values` object).""" @@ -35,22 +34,13 @@ class IO: self.source_path = source_path """A text reference to the source.""" - self.destination = destination - """The destination for output data.""" - - self.destination_path = destination_path - """A text reference to the destination.""" - def __repr__(self): - return '%s: source=%r, destination=%r' % (self.__class__, self.source, - self.destination) + return '%s: source=%r, source_path=%r' % (self.__class__, self.source, + self.source_path) def read(self, reader): raise NotImplementedError - def write(self, data): - raise NotImplementedError - def decode(self, data): """ Decode a string, `data`, heuristically. @@ -88,75 +78,152 @@ class IO: % ', '.join([repr(enc) for enc in encodings if enc])) -class FileIO(IO): +class Output: """ - I/O for single, simple file-like objects. + Abstract base class for output wrappers. """ - def __init__(self, options, source=None, source_path=None, - destination=None, destination_path=None): + def __init__(self, options, destination=None, destination_path=None): + self.options = options + """An option values object with "input_encoding" and "output_encoding" + attributes (typically a `docutils.optik.Values` object).""" + + self.destination = destination + """The destination for output data.""" + + self.destination_path = destination_path + """A text reference to the destination.""" + + def __repr__(self): + return ('%s: destination=%r, destination_path=%r' + % (self.__class__, self.destination, self.destination_path)) + + def write(self, data): + raise NotImplementedError + + +class FileInput(Input): + + """ + Input for single, simple file-like objects. + """ + + def __init__(self, options, source=None, source_path=None, autoclose=1): """ :Parameters: - `source`: either a file-like object (which is read directly), or `None` (which implies `sys.stdin` if no `source_path` given). - `source_path`: a path to a file, which is opened and then read. - - `destination`: either a file-like object (which is written - directly) or `None` (which implies `sys.stdout` if no - `destination_path` given). - - `destination_path`: a path to a file, which is opened and then - written. + - `autoclose`: close automatically after read (boolean); always + false if `sys.stdin` is the source. """ - IO.__init__(self, options, source, source_path, destination, - destination_path) + Input.__init__(self, options, source, source_path) + self.autoclose = autoclose if source is None: if source_path: self.source = open(source_path) else: self.source = sys.stdin - if destination is None: - if destination_path: - self.destination = open(destination_path, 'w') - else: - self.destination = sys.stdout + self.autoclose = None def read(self, reader): """Read and decode a single file and return the data.""" data = self.source.read() + if self.autoclose: + self.close() return self.decode(data) + def close(self): + self.source.close() + + +class FileOutput(Output): + + """ + Output for single, simple file-like objects. + """ + + def __init__(self, options, destination=None, destination_path=None, + autoclose=1): + """ + :Parameters: + - `destination`: either a file-like object (which is written + directly) or `None` (which implies `sys.stdout` if no + `destination_path` given). + - `destination_path`: a path to a file, which is opened and then + written. + - `autoclose`: close automatically after write (boolean); always + false if `sys.stdout` is the destination. + """ + Output.__init__(self, options, destination, destination_path) + self.opened = 1 + self.autoclose = autoclose + if destination is None: + if destination_path: + self.opened = None + else: + self.destination = sys.stdout + self.autoclose = None + + def open(self): + self.destination = open(self.destination_path, 'w') + self.opened = 1 + def write(self, data): """Encode and write `data` to a single file.""" output = data.encode(self.options.output_encoding) + if not self.opened: + self.open() self.destination.write(output) + if self.autoclose: + self.close() + + def close(self): + self.destination.close() + self.opened = None -class StringIO(IO): +class StringInput(Input): """ - Direct string I/O. + Direct string input. """ def read(self, reader): """Decode and return the source string.""" return self.decode(self.source) + +class StringOutput(Output): + + """ + Direct string output. + """ + def write(self, data): """Encode and return `data`.""" self.destination = data.encode(self.options.output_encoding) return self.destination -class NullIO(IO): +class NullInput(Input): """ - Degenerate I/O: read & write nothing. + Degenerate input: read nothing. """ def read(self, reader): """Return a null string.""" return u'' + +class NullOutput(Output): + + """ + Degenerate output: write nothing. + """ + def write(self, data): - """Do nothing (send data to the bit bucket).""" + """Do nothing ([don't even] send data to the bit bucket).""" pass -- cgit v1.2.1 From a11abc12fc0b7d1d3b4c0b68dcd28201ade4d22e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 9 Aug 2002 01:11:34 +0000 Subject: inline literals: comments & reordered cases git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@490 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index c3de6df2c..f8a58d736 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -650,12 +650,15 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'tt', '', CLASS='literal')) text = node.astext() for token in self.words_and_spaces.findall(text): - if token in ('\n', ' '): - self.body.append(token) - elif token.strip(): + if token.strip(): + # Protect text like "--an-option" from bad line wrapping: self.body.append('<span class="pre">%s</span>' % self.encode(token)) + elif token in ('\n', ' '): + # Allow breaks at whitespace: + self.body.append(token) else: + # Protect runs of multiple spaces; the last space can wrap: self.body.append(' ' * (len(token) - 1) + ' ') self.body.append('</tt>') raise nodes.SkipNode -- cgit v1.2.1 From 080ca828742f9e92ad4f5eca867035ae4bd7bf8e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 9 Aug 2002 01:17:21 +0000 Subject: - Updated for new I/O classes. - Added ``check_requirements()`` & ``pep_type_error()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@491 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 66 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index e48ee6bd7..42f6809c2 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -31,8 +31,6 @@ Options: The optional argument `peps' is a list of either pep numbers or .txt files. """ -# Requires Python 2.2 - import sys import os import re @@ -42,13 +40,9 @@ import getopt import errno import random import time -from email.Utils import parseaddr - -try: - import docutils -except ImportError: - docutils = None +REQUIRES = {'python': '2.2', + 'docutils': '0.2.1'} PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' @@ -134,6 +128,7 @@ def linkemail(address, pepno): def fixfile(inpath, input_lines, outfile): + from email.Utils import parseaddr basename = os.path.basename(inpath) infile = iter(input_lines) # convert plain text pep to minimal XHTML markup @@ -303,10 +298,11 @@ def fix_rst_pep(inpath, input_lines, outfile): options = pub.set_options() options._source = inpath options._destination = outfile.name - pub.source = io.StringIO( + pub.source = io.StringInput( options, source=''.join(input_lines), source_path=inpath) - pub.destination = io.FileIO( - options, destination=outfile, destination_path=outfile.name) + pub.destination = io.FileOutput( + options, destination=outfile, destination_path=outfile.name, + autoclose=0) pub.publish() @@ -350,9 +346,6 @@ def find_pep(pep_str): num = int(pep_str) return "pep-%04d.txt" % num -PEP_TYPE_DISPATCH = {'text/plain': fixfile, - 'text/x-rst': fix_rst_pep} - def make_html(inpath, verbose=0): input_lines = get_input_lines(inpath) pep_type = get_pep_type(input_lines) @@ -365,11 +358,8 @@ def make_html(inpath, verbose=0): % (inpath, pep_type)) sys.stdout.flush() return None - elif pep_type == 'text/x-rst' and not docutils: - print >> sys.stderr, ('Error: Docutils not present for "%s" PEP file ' - '%s. See README.txt for installation.' - % (pep_type, inpath)) - sys.stdout.flush() + elif PEP_TYPE_DISPATCH[pep_type] == None: + pep_type_error(inpath, pep_type) return None outpath = os.path.splitext(inpath)[0] + ".html" if verbose: @@ -401,6 +391,42 @@ def push_pep(htmlfiles, txtfiles, username, verbose): sys.exit(rc) +PEP_TYPE_DISPATCH = {'text/plain': fixfile, + 'text/x-rst': fix_rst_pep} +PEP_TYPE_MESSAGES = {} + +def check_requirements(): + # Check Python: + try: + from email.Utils import parseaddr + except ImportError: + PEP_TYPE_DISPATCH['text/plain'] = None + PEP_TYPE_MESSAGES['text/plain'] = ( + 'Python %s or better required for "%%(pep_type)s" PEP ' + 'processing; %s present (%%(inpath)s).' + % (REQUIRES['python'], sys.version.split()[0])) + # Check Docutils: + try: + import docutils + except ImportError: + PEP_TYPE_DISPATCH['text/x-rst'] = None + PEP_TYPE_MESSAGES['text/x-rst'] = ( + 'Docutils not present for "%(pep_type)s" PEP file %(inpath)s. ' + 'See README.txt for installation.') + else: + if docutils.__version__ < REQUIRES['docutils']: + PEP_TYPE_DISPATCH['text/x-rst'] = None + PEP_TYPE_MESSAGES['text/x-rst'] = ( + 'Docutils must be reinstalled for "%%(pep_type)s" PEP ' + 'processing (%%(inpath)s). Version %s or better required; ' + '%s present. See README.txt for installation.' + % (REQUIRES['docutils'], docutils.__version__)) + +def pep_type_error(inpath, pep_type): + print >> sys.stderr, 'Error: ' + PEP_TYPE_MESSAGES[pep_type] % locals() + sys.stdout.flush() + + def browse_file(pep): import webbrowser file = find_pep(pep) @@ -426,6 +452,8 @@ def main(argv=None): verbose = 1 browse = 0 + check_requirements() + if argv is None: argv = sys.argv[1:] -- cgit v1.2.1 From d5f026e798598f57d02ab02ffa4b20efb818473f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 9 Aug 2002 01:19:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@492 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 13 ++++++++ docs/dev/todo.txt | 72 +++++++++++++++++++++++++++++++++----------- docs/peps/pep-0258.txt | 10 +++--- docutils/core.py | 8 ++--- docutils/writers/pep_html.py | 1 - tools/buildhtml.py | 4 +-- 6 files changed, 78 insertions(+), 30 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 2163fe4ac..7b58a938c 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -38,11 +38,21 @@ any names; apologies (and please let me know!) if I have. Changes Since 0.2 ======================== +* docutils/__init__.py: + + - Bumped version to 0.2.1 to reflect changes to I/O classes. + * docutils/frontend.py: - Check for & exit on identical source & destination paths. - Fixed bug with absolute paths & ``--config``. +* 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. + * docutils/nodes.py: - Added "Invisible" element category class. @@ -120,6 +130,7 @@ Changes Since 0.2 - Added ``--silent`` option. - Fixed bug with absolute paths & ``--config``. + - Updated for new I/O classes. * tools/default.css: @@ -133,6 +144,8 @@ Changes Since 0.2 - 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()``. * tools/stylesheets/pep.css: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 7649fb083..b2ae4584f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -50,15 +50,16 @@ Bugs whitespace and punctuation as markup delimiters, which may not be applicable in these languages. -- Text like "``--an-option``" can get wrapped badly in HTML browsers, - like "``--\nan-option``". Should inline literals prevent soft - linebreaks? Allow breaks at whitespace or not at all? - - @@@ This shouldn't be recognized as a list item:: A. Einstein was a really smart dude. + Or this:: + + 1. This is the heading of section one + ===================================== + The only problem is, what about this? :: A. Einstein was a really smart dude. @@ -68,12 +69,19 @@ Bugs A. Einstein was a really smart dude. B. So was Carl Sagan. + But what about this? Accidents can happen:: + + A. Einstein was a great influence on + B. Physicist, who was a colleague of + C. Chemist. They all worked in + Princeton, NJ. + Time to put more smarts into the list item recognition code, or just document it as a corner case and require escapes? E.g.:: \A. Einstein was a really smart dude. - (Bug report by Jeremy Hylton.) + (Bug reports by Jeremy Hylton and Dmitry Jemerov.) General @@ -85,11 +93,19 @@ General - Implementation docs. - - spec/doctree.txt: Doctree nodes (DTD element) semantics: + - spec/doctree.txt: Doctree element (DTD element) semantics: - External (public) attributes (node.attributes). - - Internal attributes (node.*). - - Linking mechanism. + - Internal attributes (node.*). (?) + - Linking mechanism. (?) + + Should this document be about the code (implementation details), + or about the DTD (document tree elements)? I'm having trouble + writing it because it's a bit schizo; doesn't know what it is. + Perhaps it should simply document the DTD elements, their + semantics, and only refer to the implementation. Descriptions + of the classes, their methods, and internal attributes belong in + the implementation docs (docstrings for now). - How a Writer works & how to write one @@ -137,9 +153,6 @@ General - Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -- @@@ Add references to the user docs: bugs to the SF bug tracker, - questions to the mailing lists. - Specification ------------- @@ -341,12 +354,35 @@ __ rst/alternatives.html#or-not-to-do first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. -- Decide whether or not to implement Simon Budig's "inline external - targets" syntax idea, and if so, how: +- @@@ Decide whether or not to implement Simon Budig's "inline + external targets" syntax idea, and if so, how? + + - As a regular directive affecting its indented text block:: + + .. inline-urls:: + + This is an anonymous `reference <http://www.example.org + /reference/>`__ of one word ("reference"). Here is a + `phrase reference <http://www.example.org + /phrase_reference/>`__. + + - As a pragma directive affecting the entire document (from that + point on). Perhaps a variation on the regular directive:: + + .. inline-urls:: :pragma: + + Ordinary paragraphs ... + + This is an anonymous `reference <http://www.example.org + /reference/>`__ of one word ("reference"). Here is a + `phrase reference <http://www.example.org + /phrase_reference/>`__. + + Perhaps "``:global:``" instead of "``:pragma:``"? This pattern + could be useful for other pragma directives: local-scope unless + explicitly specified as global/pragma. - - regular directive affecting its indented text block - - pragma directive affecting the entire document - - or a full-blown addition to the spec & parser + - Or as a full-blown addition to the spec & parser. - Add support for pragma (syntax-altering) directives. @@ -369,8 +405,8 @@ Directives - _`parts.citations`: See `Footnote & Citation Gathering`_. - - _`parts.sectnum` (section numbering; add support to .contents; - could be cmdline option also) + - _`parts.sectnum` (automatic section numbering; add support to + the "contents" directive; could be cmdline option also) - _`misc.raw` diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 7f3038116..4f6ce541b 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -288,24 +288,24 @@ Responsibilities: Examples of input sources: - A single file on disk or a stream (implemented as - ``docutils.io.FileIO``). + ``docutils.io.FileInput``). -- Multiple files on disk (``MultiFileIO``?). +- Multiple files on disk (``MultiFileInput``?). - Python source files: modules and packages. - Python strings, as received from a client application - (implemented as ``docutils.io.StringIO``). + (implemented as ``docutils.io.StringInput``). Examples of output destinations: - A single file on disk or a stream (implemented as - ``docutils.io.FileIO``). + ``docutils.io.FileOutput``). - A tree of directories and files on disk. - A Python string, returned to a client application (implemented as - ``docutils.io.StringIO``). + ``docutils.io.StringOutput``). - A single tree-shaped data structure in memory. diff --git a/docutils/core.py b/docutils/core.py index 9e836c6be..6dcc93d8a 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -29,8 +29,8 @@ class Publisher: """ def __init__(self, reader=None, parser=None, writer=None, - source=None, source_class=io.FileIO, - destination=None, destination_class=io.FileIO, + source=None, source_class=io.FileInput, + destination=None, destination_class=io.FileOutput, options=None): """ Initial setup. If any of `reader`, `parser`, or `writer` are not @@ -48,13 +48,13 @@ class Publisher: """A `writers.Writer` instance.""" self.source = source - """The source of input data, an `io.IO` instance.""" + """The source of input data, an `io.Input` instance.""" self.source_class = source_class """The class for dynamically created source objects.""" self.destination = destination - """The destination for docutils output, an `io.IO` instance.""" + """The destination for docutils output, an `io.Output` instance.""" self.destination_class = destination_class """The class for dynamically created destination objects.""" diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 5c3bb0194..b591f9230 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -14,7 +14,6 @@ __docformat__ = 'reStructuredText' import sys -#import random from docutils import nodes, optik, utils from docutils.writers import html4css1 diff --git a/tools/buildhtml.py b/tools/buildhtml.py index b04f811d1..ac9ab75b0 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -108,8 +108,8 @@ class Builder: if not options.silent: print >>sys.stderr, ' ::: Processing .txt:', name sys.stderr.flush() - self.pub.source = io.FileIO(options, source_path=options._source) - self.pub.destination = io.FileIO( + self.pub.source = io.FileInput(options, source_path=options._source) + self.pub.destination = io.FileOutput( options, destination_path=options._destination) self.pub.publish() -- cgit v1.2.1 From 403cb20d5dc1c872855031ed1ea90dc2fa948281 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 10 Aug 2002 02:31:33 +0000 Subject: docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@493 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 42 ++++++++++++++++++++++++++++++++++++++---- docutils/parsers/rst/states.py | 2 +- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index c863c8ef5..0924658a7 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -10,11 +10,15 @@ Docutils document tree element class library. Classes in CamelCase are abstract base classes or auxiliary classes. The one -exception is `Text`, for a text node; uppercase is used to differentiate from -element classes. +exception is `Text`, for a text (PCDATA) node; uppercase is used to +differentiate from element classes. Classes in lower_case_with_underscores +are element classes, matching the XML element generic identifiers in the DTD_. -Classes in lower_case_with_underscores are element classes, matching the XML -element generic identifiers in the DTD_. +The position of each node (the level at which it can occur) is significant and +is represented by abstract base classes (`Root`, `Structural`, `Body`, +`Inline`, etc.). Certain transformations will be easier because we can use +``isinstance(node, base_class)`` to determine the position of the node in the +hierarchy. .. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd """ @@ -676,6 +680,36 @@ class document(Root, Structural, Element): return id def set_name_id_map(self, node, id, msgnode=None, explicit=None): + """ + `self.nameids` maps names to IDs, while `self.nametypes` maps names to + booleans representing hyperlink type (True==explicit, + False==implicit). This method updates the mappings. + + The following state transition table shows how `self.nameids` ("ids") + and `self.nametypes` ("types") change with new input (a call to this + method), and what actions are performed: + + ==== ===== ======== ======== ======= ==== ===== ===== + Old State Input Action New State Notes + ----------- -------- ----------------- ----------- ----- + ids types new type sys.msg. dupname ids types + ==== ===== ======== ======== ======= ==== ===== ===== + -- -- explicit -- -- new True + -- -- implicit -- -- new False + None False explicit -- -- new True + old False explicit implicit old new True + None True explicit explicit new None True + old True explicit explicit new,old None True [#]_ + None False implicit implicit new None False + old False implicit implicit new,old None False + None True implicit implicit new None True + old True implicit implicit new old True + ==== ===== ======== ======== ======= ==== ===== ===== + + .. [#] Do not clear the name-to-id map or invalidate the old target if + both old and new targets are external and refer to identical URIs. + The new target is invalidated regardless. + """ if node.has_key('name'): name = node['name'] if self.nameids.has_key(name): diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index e59102801..fec37d1c9 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -27,7 +27,7 @@ the reStructuredText parser. It defines the following: - `SpecializedText`: Superclass for continuation lines of Text-variants. - `Definition`: Second line of potential definition_list_item. - `Line`: Second line of overlined section title or transition marker. - - `Stuff`: An auxilliary collection class. + - `Stuff`: An auxiliary collection class. :Exception classes: - `MarkupError` -- cgit v1.2.1 From 5bce8db5f80f9e1a03724ee137fb0adf578bc488 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 10 Aug 2002 04:29:04 +0000 Subject: 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. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@494 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 237 +++++++++++++++++++++++---------------------------- 1 file changed, 108 insertions(+), 129 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index d138a8b2c..ce4f951db 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -6,14 +6,35 @@ :Revision: $Revision$ :Date: $Date$ -This document describes the internal data structure representing -document trees in Docutils. The data structure is defined by the -hierarchy of classes in the ``docutils.nodes`` module. It is also -formally described by the `Docutils Generic DTD`_ XML document type -definition, docutils.dtd_, which is the definitive source for element -hierarchy details. - -Below is a simplified diagram of the hierarchy of element types in the +This document describes the XML data structure of Docutils documents, +the relationships and semantics of elements. The Docutils document +structure is formally defined by the `Docutils Generic DTD`_ XML +document type definition, docutils.dtd_, which is the definitive +source for details of element structural relationships. + +The data structure is implemented by the class library in the +``docutils.nodes`` module. This document does not discuss +implementation details; they can be found in documentation for the +``docutils.nodes`` module (docstrings). + +The reader is assumed to have some familiarity with XML or SGML, and +an understanding the data structure meaning of "tree". For a list of +introductory articles, see `Introducing the Extensible Markup Language +(XML)`_. + +.. _Docutils Generic DTD: +.. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd +.. _Introducing the Extensible Markup Language (XML): + http://xml.coverpages.org/xmlIntro.html + +.. contents:: + + +------------------- + Element Hierarchy +------------------- + +Below is a simplified diagram of the hierarchy of elements in the Docutils document tree structure. An element may contain any other elements immediately below it in the diagram. Text in square brackets are notes. Element types in parentheses indicate recursive or @@ -36,94 +57,97 @@ contain further body elements, etc. :: | markup) | +---------+ +The Docutils document model uses a simple, recursive model for section +structure. A document_ node may contain body elements and section_ +elements. Sections in turn may contain body elements and sections. +The level (depth) of a section element is determined from its physical +nesting level; unlike other document models (``<h1>`` in HTML_, +``<sect1>`` in DocBook_, ``<div1>`` in XMLSpec_) the level is not +incorporated into the element name. -------------------- - Element Hierarchy -------------------- +The Docutils document model uses strict element content models. Every +element has a unique structure and semantics, but elements may be +classified into general categories: -A class hierarchy has been implemented in nodes.py. The position of -each node (the level at which it can occur) is significant and is -represented by abstract base classes (Root, Structural, Body, Inline, -etc.). Certain transformations will be easier because we can use -``isinstance(node, base_class)`` to determine the position of the node -in the hierarchy. +* _`Structural elements` (document_, section_, and topic_) may only + contain child elements; they do not directly contain text data. + Child elements of structural elements may be body elements or other + structural elements. Structural elements can only be child elements + of other structural elements. -The elements making up Docutils document trees can be categorized into -the following groups: +* _`Body elements` are contained within structural elements and + compound body elements. There are two subcategories of body + elements: -- _`Root element`: document_ + - _`Compound body elements` (like table_ and bullet_list_) contain + local substructure and further body elements. They do not + directly contain text data. -- _`Title elements`: title_, subtitle_ + - _`Simple body elements` (like paragraph_ and literal_block) + directly contain text data, and may also contain inline elements. + Some simple body elements have a "mixed content model". -- _`Bibliographic elements`: docinfo_, author_, authors_, - organization_, contact_, version_, revision_, status_, date_, - copyright_ +* _`Inline elements` (like emphasis_ and reference_) directly contain + text data, and may also contain inline elements. Inline elements + are contained within simple body elements. Inline elements have a + "mixed content model". -- _`Structural elements`: document_, section_, topic_, transition_ +Only elements which are meant to directly contain text data have a +mixed content model, where text data and elements may be intermixed. +This is unlike the HTML_ document model, where paragraphs and text +data may occur at the same level. -- _`Body elements`: +.. _HTML: http://www.w3.org/MarkUp/ +.. _DocBook: http://docbook.org/tdg/en/html/docbook.html +.. _XMLSpec: http://www.w3.org/XML/1998/06/xmlspec-report.htm - - _`General body elements`: paragraph_, literal_block_, - block_quote_, doctest_block_, table_, figure_, image_, footnote_ - - _`Lists`: bullet_list_, enumerated_list_, definition_list_, - field_list_, option_list_ - - - _`Admonitions`: note_, tip_, warning_, error_, caution_, danger_, - important_ +------------------- + Element Reference +------------------- - - _`Special body elements`: target_, substitution_definition_, - comment_, system_warning_ +Each element in the document tree model is described in its own +section below. Each section contains the following subsections: -- _`Inline elements`: emphasis_, strong_, interpreted_, literal_, - reference_, target_, footnote_reference_, substitution_reference_, - image_, problematic_ +* Description: The semantics of the element. + - Parents: A list of elements which may contain the element. -``Node`` -======== + - Children: A list of elements which may occur within the element. + - Analogies: Describes analogous elements in well-known document + models such as HTML_ or DocBook_. Lists similarities and + differences. -``Text`` -======== + - Processing Expectations: Lists formatting or rendering + expectations for the element. +* Content Model: the content model of the element from the `Docutils + DTD`_. -``Element`` -=========== + - Attributes: Describes the possible values and semantics of each + attribute. Common attributes are described via references. + - Parameter Entities: Lists the parameter entities in which the + element described appears. -``TextElement`` -=============== +* Example: Where possible, a reStructuredText example is shown along + with a fragment of the document tree resulting from parsing. -------------------- - Element Reference -------------------- - ``document`` ============ -description -contents +The ``document`` element is the root (topmost) element of the Docutils +document tree. ``document`` is the direct or indirect ancestor of +every other element in the tree. -External attributes -------------------- -`Common external attributes`_. +contents +Attributes +---------- -Internal attributes -------------------- -- `Common internal attributes`_. -- ``explicittargets`` -- ``implicittargets`` -- ``externaltargets`` -- ``indirecttargets`` -- ``refnames`` -- ``anonymoustargets`` -- ``anonymousrefs`` -- ``autofootnotes`` -- ``autofootnoterefs`` -- ``reporter`` +`Common external attributes`_. --------------------- @@ -188,13 +212,6 @@ The ``source`` attribute The ``xml:space`` attribute -Internal Attributes -=================== - -All element objects share the following _`common internal attributes`: -rawsource_, children_, attributes_, tagname_. - - ------------------------ DTD Parameter Entities ------------------------ @@ -234,40 +251,6 @@ The ``%text.model;`` parameter entity Appendix: Miscellaneous Topics -------------------------------- -Hyperlink Bookkeeping -===================== - -``document.nameids`` maps names to IDs, while ``document.nametypes`` -maps names to booleans representing hyperlink type (True==explicit, -False==implicit). The ``document.set_name_id_map()`` method updates -the mappings. - -The following state transition table shows how ``nameids`` ("ids") and -``nametypes`` ("types") change with new input (a call to -``document.set_name_id_map()``), and what actions are performed: - -==== ===== ======== ======== ======= ==== ===== ===== - Old State Input Action New State Notes ------------ -------- ----------------- ----------- ----- -ids types new type sys.msg. dupname ids types -==== ===== ======== ======== ======= ==== ===== ===== --- -- explicit -- -- new True --- -- implicit -- -- new False -None False explicit -- -- new True -old False explicit implicit old new True -None True explicit explicit new None True -old True explicit explicit new,old None True [#]_ -None False implicit implicit new None False -old False implicit implicit new,old None False -None True implicit implicit new None True -old True implicit implicit new old True -==== ===== ======== ======== ======= ==== ===== ===== - -.. [#] Do not clear the name->id map or invalidate the old target if - both old and new targets are external and refer to identical URIs. - The new target is invalidated regardless. - - Representation of Horizontal Rules ================================== @@ -278,11 +261,11 @@ the implementation of the document tree. Given this source:: Document ======== - Paragraph + Paragraph 1 -------- - Paragraph + Paragraph 2 The horizontal rule indicates a "transition" (in prose terms) or the start of a new "division". Before implementation, the parsed document @@ -293,13 +276,12 @@ tree would be:: <title> Document <paragraph> - Paragraph + Paragraph 1 -------- <--- error here <paragraph> - Paragraph + Paragraph 2 -There are several possibilities for the implementation. Solution 3 -was chosen. +There are several possibilities for the implementation: 1. Implement horizontal rules as "divisions" or segments. A "division" is a title-less, non-hierarchical section. The first @@ -310,10 +292,10 @@ was chosen. <title> Document <paragraph> - Paragraph + Paragraph 1 <division> <paragraph> - Paragraph + Paragraph 2 But the two paragraphs are really at the same level; they shouldn't appear to be at different levels. There's really an invisible @@ -329,18 +311,18 @@ was chosen. Document <division> <paragraph> - Paragraph + Paragraph 1 <division> <paragraph> - Paragraph + Paragraph 2 With this change, documents and sections will directly contain divisions and sections, but not body elements. Only divisions will directly contain body elements. Even without a horizontal rule anywhere, the body elements of a document or section would be contained within a division element. This makes the document tree - deeper. This is similar to the way HTML treats document contents: - grouped within a <BODY> element. + deeper. This is similar to the way HTML_ treats document contents: + grouped within a ``<body>`` element. 3. Implement them as "transitions", empty elements:: @@ -349,23 +331,20 @@ was chosen. <title> Document <paragraph> - Paragraph + Paragraph 1 <transition> <paragraph> - Paragraph + Paragraph 2 A transition would be a "point element", not containing anything, only identifying a point within the document structure. This keeps the document tree flatter, but the idea of a "point element" like "transition" smells bad. A transition isn't a thing itself, it's - the space between two divisions. - - This solution has been chosen for incorporation into the document - tree. + the space between two divisions. However, transitions are a + practical solution. +Solution 3 was chosen for incorporation into the document tree model. -.. _Docutils Generic DTD: -.. _docutils.dtd: http://docutils.sourceforge.net/spec/docutils.dtd .. _reStructuredText: http://docutils.sourceforge.net/spec/rst/reStructuredText.html -- cgit v1.2.1 From 917d3af9d29ddb8b0bf284ccc1cb30e1b17052b1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 10 Aug 2002 04:30:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@495 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 22 ++++--- docs/dev/todo.txt | 71 ++++++++++++++++------ .../test_parsers/test_rst/test_enumerated_lists.py | 24 ++++++++ test/test_parsers/test_rst/test_section_headers.py | 14 +++++ 4 files changed, 104 insertions(+), 27 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 7b58a938c..db97060c6 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -20,13 +20,13 @@ and related projects: Aahz, David Ascher, Fred Bremmer, Simon Budig, Adam Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter Funk, Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen Hermann, - Tony Ibbs, Alan Jaffray, Richard Jones, Garth Kidd, Daniel - Larsson, Marc-Andre Lemburg, Wolfgang Lipp, Edward Loper, Ken - Manheimer, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, - Pearu Peterson, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Ueli - Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, - Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, - Moshe Zadka + Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry Jemerov, Richard + Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang + Lipp, Edward Loper, Ken Manheimer, Paul Moore, Michel Pelletier, + Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, Tavis Rudd, + Ollie Rutherfurd, Ueli Schlaepfer, Gunnar Schwant, tav, Bob + Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward + Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -114,6 +114,14 @@ Changes Since 0.2 - Added a "Getting Help" section. - Added a style to make section header backlinks more subtle. +* 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. + * spec/pep-0256.txt: Converted to reStructuredText & updated. * spec/pep-0258.txt: Converted to reStructuredText & updated. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b2ae4584f..79356e9e4 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -60,10 +60,17 @@ Bugs 1. This is the heading of section one ===================================== - The only problem is, what about this? :: + What about this? :: A. Einstein was a really smart dude. + More text. + + It's a list item followed by a paragraph. Just document it as a + corner case and require escaping if it's not a list item. E.g.:: + + \A. Einstein was a really smart dude. + This should definitely be a list:: A. Einstein was a really smart dude. @@ -76,10 +83,10 @@ Bugs C. Chemist. They all worked in Princeton, NJ. - Time to put more smarts into the list item recognition code, or - just document it as a corner case and require escapes? E.g.:: - - \A. Einstein was a really smart dude. + The first two lines indicate a list. The third item, "C.", should + be interpreted as a paragraph because of the fourth line. An + "Enumerated list ends without a blank line; unexpected unindent at + line 3" warning shall be generated. (Bug reports by Jeremy Hylton and Dmitry Jemerov.) @@ -93,11 +100,8 @@ General - Implementation docs. - - spec/doctree.txt: Doctree element (DTD element) semantics: - - - External (public) attributes (node.attributes). - - Internal attributes (node.*). (?) - - Linking mechanism. (?) + - spec/doctree.txt: DTD element structural relationships, + semantics, and external (public) attributes (node.attributes). Should this document be about the code (implementation details), or about the DTD (document tree elements)? I'm having trouble @@ -161,8 +165,7 @@ Specification - Fill in the blanks in API details. - - Specify the nodes.py internal data structure implementation. - Or link to doctree.txt? + - Specify the nodes.py internal data structure implementation? [Tibs:] Eventually we need to have direct documentation in there on how it all hangs together - the DTD is not enough @@ -171,9 +174,6 @@ Specification - Rework PEP 257, separating style from spec from tools, wrt Docutils? See Doc-SIG from 2001-06-19/20. -- Once doctree.txt is fleshed out, how about breaking (most of) it up - and putting it into nodes.py as docstrings? - PySource Reader --------------- @@ -369,7 +369,7 @@ __ rst/alternatives.html#or-not-to-do - As a pragma directive affecting the entire document (from that point on). Perhaps a variation on the regular directive:: - .. inline-urls:: :pragma: + .. inline-urls:: :global: Ordinary paragraphs ... @@ -378,7 +378,7 @@ __ rst/alternatives.html#or-not-to-do `phrase reference <http://www.example.org /phrase_reference/>`__. - Perhaps "``:global:``" instead of "``:pragma:``"? This pattern + Perhaps "``:pragma:``" instead of "``:global:``"? This pattern could be useful for other pragma directives: local-scope unless explicitly specified as global/pragma. @@ -386,6 +386,10 @@ __ rst/alternatives.html#or-not-to-do - Add support for pragma (syntax-altering) directives. +- Remove leading numbers from section titles for implicit link names? + A section titled "3. Conclusion" could then be referred to by + "Conclusion_" (i.e., without the "3."). + Directives `````````` @@ -396,7 +400,10 @@ Directives - Add more attributes to the image directive: align, border? -- Implement directives: +- Implement directives. Each of the list items below begins with an + identifier of the form, "module_name.directive_function_name". The + directive name itself could be the same as the + directive_function_name, or it could differ. - _`html.imagemap` (Useful outside of HTML? If not, replace with image only in non-HTML writers?) @@ -405,8 +412,32 @@ Directives - _`parts.citations`: See `Footnote & Citation Gathering`_. - - _`parts.sectnum` (automatic section numbering; add support to - the "contents" directive; could be cmdline option also) + - _`parts.sectnum`: Automatic section numbering. Could be a + command-line option also/instead. + + Something like this:: + + .. sectnum:: + + Section One + =========== + + Section Two + =========== + + Subsection One + -------------- + + When processed, the numbers "1", "2", and "2.1" would be prefixed + to the titles automatically. The directive name could be + "sectnum" or "section-numbers" or "section-numbering", perhaps + with a ":global:" attribute. A ":depth:" attribute would also be + useful (analogous to that of the "contents" directive). Perhaps + some kind of styling attribute as well? + + Add support to the "contents" directive. Instead of bullet lists, + the table of contents could be implemented with enumerated lists. + Nested simple enumerators or compound enumerators ("2.1")? - _`misc.raw` diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index 319589fc1..632e32ab3 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -655,8 +655,32 @@ Nested enumerated lists: <paragraph> Item 3. """], +["""\ +A. Einstein was a great influence on +B. Physicist, who was a colleague of +C. Chemist. They all worked in +Princeton, NJ. +""", +# @@@ I think this is the correct result, but I'm not certain: +"""\ +<document> + <enumerated_list enumtype="upperalpha" prefix="" suffix="."> + <list_item> + <paragraph> + Einstein was a great influence on + <list_item> + <paragraph> + Physicist, who was a colleague of + <system_message level="2" type="WARNING"> + <paragraph> + Enumerated list ends without a blank line; unexpected unindent at line 3. + <paragraph> + C. Chemist. They all worked in + Princeton, NJ. +"""], ] + if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 4ac348f26..9602175e2 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -548,6 +548,20 @@ Paragraph. <paragraph> Paragraph. """], +["""\ +1. Numbered Title +================= + +Paragraph. +""", +"""\ +<document> + <section id="1-numbered-title" name="1. numbered title"> + <title> + 1. Numbered Title + <paragraph> + Paragraph. +"""], ] if __name__ == '__main__': -- cgit v1.2.1 From 6f6ef2d4327f050afd2c10d401bcd249a39865ec Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 10 Aug 2002 04:50:25 +0000 Subject: fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@496 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 79356e9e4..e624b72a3 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -388,7 +388,7 @@ __ rst/alternatives.html#or-not-to-do - Remove leading numbers from section titles for implicit link names? A section titled "3. Conclusion" could then be referred to by - "Conclusion_" (i.e., without the "3."). + "``Conclusion_``" (i.e., without the "3."). Directives -- cgit v1.2.1 From 4f85bd78669fa7afd0cc5e0f531bd2a357554b1c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 10 Aug 2002 19:48:17 +0000 Subject: Cleaned up long lines. Simplified line iteration. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@497 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 42f6809c2..fc0814a39 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -46,7 +46,8 @@ REQUIRES = {'python': '2.2', PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' -PEPCVSURL = 'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/nondist/peps/pep-%04d.txt' +PEPCVSURL = ('http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python' + '/nondist/peps/pep-%04d.txt') PEPDIRRUL = 'http://www.python.org/peps/' @@ -139,11 +140,7 @@ def fixfile(inpath, input_lines, outfile): header = [] pep = "" title = "" - while 1: - try: - line = infile.next() - except StopIteration: - break + for line in infile: if not line.strip(): break if line[0].strip(): @@ -165,19 +162,19 @@ def fixfile(inpath, input_lines, outfile): title = "PEP " + pep + " -- " + title if title: print >> outfile, ' <title>%s' % cgi.escape(title) - print >> outfile, ' ' - print >> outfile, '' - # body - print >> outfile, '' - print >> outfile, '> outfile, ' width="100%" border="0">' - print >> outfile, '' - print >> outfile, '\n\n\n\n') def visit_field_name(self, node): + atts = {} if self.in_docinfo: - class_name = 'docinfo-name' + atts['class'] = 'docinfo-name' + else: + atts['class'] = 'field-name' + if len(node.astext()) > 14: + atts['colspan'] = 2 + self.context.append('\n ') else: - class_name = 'field-name' - self.body.append(self.starttag(node, 'th', '', CLASS=class_name)) + self.context.append('') + self.body.append(self.starttag(node, 'th', '', **atts)) def depart_field_name(self, node): - self.body.append(': ') + self.body.append(':') + self.body.append(self.context.pop()) def visit_figure(self, node): self.body.append(self.starttag(node, 'div', CLASS='figure')) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 85a8fb32a..a61d0e01d 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -170,19 +170,15 @@ table.footnote { td, th { padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: baseline } + padding-right: 0.5em } td > p:first-child, th > p:first-child { margin-top: 0em } -th.docinfo-name { +th.docinfo-name, th.field-name { font-weight: bold ; - text-align: right } - -th.field-name { - font-weight: bold ; - text-align: right } + text-align: left ; + white-space: nowrap } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { font-size: 100% } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 583a0f6ce..6580b01a0 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -219,8 +219,7 @@ table { td, th { padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: baseline } + padding-right: 0.5em } td > :first-child, th > :first-child { margin-top: 0em } @@ -230,7 +229,8 @@ td.num { th.field-name { font-weight: bold ; - text-align: right } + text-align: left ; + white-space: nowrap } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { font-size: 100% } -- cgit v1.2.1 From b95ac892ffd6bcd165b5459b0b0f656099c896cf Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:46:40 +0000 Subject: converted definition lists to field lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@693 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 399 ++++++++++++++++++++++++--------------------------- 1 file changed, 185 insertions(+), 214 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 16a700ce4..c490e5044 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -293,19 +293,18 @@ line_block_ element: whitespace is significant, especially newlines. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: The following elements may contain ``address``: docinfo_, authors_ -Children +:Children: ``address`` elements contain text data plus `inline elements`_. -Analogies +:Analogies: ``address`` is analogous to the DocBook "address" element. -Processing +:Processing: As with the line_block_ element, newlines and other whitespace is significant and must be preserved. However, a monospaced typeface need not be used. @@ -320,11 +319,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``address`` element contains the `common attributes`_ (id_, name_, dupname_, source_, and class_), plus `xml:space`_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``address``. @@ -370,19 +369,18 @@ The ``author`` element holds the name of the author of the document. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: The following elements may contain ``author``: docinfo_, authors_ -Children +:Children: ``author`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``author`` is analogous to the DocBook "author" element. -Processing +:Processing: See docinfo_. @@ -393,11 +391,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``author`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``author``. @@ -435,20 +433,19 @@ documents with multiple authors. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``authors``. -Children +:Children: ``authors`` elements may contain the following elements: author_, organization_, address_, contact_ -Analogies +:Analogies: ``authors`` is analogous to the DocBook "authors" element. -Processing +:Processing: See docinfo_. @@ -459,11 +456,11 @@ Content Model ((author_, organization_?, address_?, contact_?)+) -Attributes +:Attributes: The ``authors`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``authors``. @@ -516,18 +513,17 @@ uniformly marked with bullets. Bullets are typically simple dingbats Details ------- -Category - `Compound Body Elements`_ +:Category: `Compound Body Elements`_ -Parents +:Parents: All elements employing the `%body.elements;`_ or `%structure.model;`_ parameter entities in their content models may contain ``bullet_list``. -Children +:Children: ``bullet_list`` elements contain one or more list_item_ elements. -Analogies +:Analogies: ``bullet_list`` is analogous to the HTML "ul" element and to the DocBook "itemizedlist" element. HTML's "ul" is short for "unordered list", which we consider to be a misnomer. "Unordered" @@ -535,7 +531,7 @@ Analogies affecting the meaning of the list. Bullet lists *are* often ordered; the ordering is simply left implicit. -Processing +:Processing: Each list item should begin a new vertical block, prefaced by a bullet/dingbat. @@ -547,7 +543,7 @@ Content Model (list_item_+) -Attributes +:Attributes: The ``bullet_list`` element contains the `common attributes`_ (id_, name_, dupname_, source_, and class_), plus bullet_. @@ -555,7 +551,7 @@ Attributes data. In reStructuredText, it contains one of "-", "+", or "*". It may be ignored in processing. -Parameter Entities +:Parameter Entities: The `%body.elements;`_ parameter entity directly includes ``bullet_list``. The `%structure.model;`_ parameter entity indirectly includes ``bullet_list``. @@ -622,20 +618,19 @@ used to indicate the type of a variable. Details ------- -Category - `Body Subelements`_ (simple) +:Category: `Body Subelements`_ (simple) -Parents +:Parents: Only the definition_list_item_ element contains ``classifier``. -Children +:Children: ``classifier`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``classifier`` has no direct analogues in common DTDs. It can be emulated with primitives or type effects. -Processing +:Processing: See definition_list_item_. @@ -646,7 +641,7 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``classifier`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -705,21 +700,20 @@ is typically used for an email or web address. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: The following elements may contain ``contact``: docinfo_, authors_ -Children +:Children: ``contact`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``contact`` is analogous to the DocBook "email" element. The HTML "address" element serves a similar purpose. -Processing +:Processing: See docinfo_. @@ -730,11 +724,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``contact`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``contact``. @@ -772,20 +766,19 @@ The ``copyright`` element contains the document's copyright statement. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``copyright``. -Children +:Children: ``copyright`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``copyright`` is analogous to the DocBook "copyright" element. -Processing +:Processing: See docinfo_. @@ -796,11 +789,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``copyright`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``copyright``. @@ -844,19 +837,18 @@ last modification of the document. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``date``. -Children +:Children: ``date`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``date`` is analogous to the DocBook "date" element. -Processing +:Processing: Often used with the RCS/CVS keyword "Date". See docinfo_. @@ -867,11 +859,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``date`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``date``. @@ -912,21 +904,20 @@ footer_ element is implemented, populated with processing information Details ------- -Category - `Structural Subelements`_ +:Category: `Structural Subelements`_ -Parents +:Parents: Only the document_ element contains ``decoration``. -Children +:Children: ``decoration`` elements may contain `decorative elements`_. -Analogies +:Analogies: There are no direct analogies to ``decoration`` in HTML or in DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. -Processing +:Processing: See the individual `decorative elements`_. Content Model @@ -939,7 +930,7 @@ Content Model Although the content model doesn't specifically require contents, no empty ``decoration`` elements are ever created. -Attributes +:Attributes: The ``decoration`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -974,20 +965,19 @@ to define a term_ in a definition_list_. Details ------- -Category - `Body Subelements`_ (compound) +:Category: `Body Subelements`_ (compound) -Parents +:Parents: Only definition_list_item_ elements contain ``definition``. -Children +:Children: ``definition`` elements may contain `body elements`_. -Analogies +:Analogies: ``definition`` is analogous to the HTML "dd" element and to the DocBook "listitem" element (inside a "variablelistentry" element). -Processing +:Processing: See definition_list_item_. @@ -998,7 +988,7 @@ Content Model (`%body.elements;`_)+ -Attributes +:Attributes: The ``definition`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1022,23 +1012,22 @@ describe or classify things, for dialogues, or to itemize subtopics Details ------- -Category - `Compound Body Elements`_ +:Category: `Compound Body Elements`_ -Parents +:Parents: All elements employing the `%body.elements;`_ or `%structure.model;`_ parameter entities in their content models may contain ``definition_list``. -Children +:Children: ``definition_list`` elements contain one or more definition_list_item_ elements. -Analogies +:Analogies: ``definition_list`` is analogous to the HTML "dl" element and to the DocBook "variablelist" element. -Processing +:Processing: See definition_list_item_. @@ -1049,11 +1038,11 @@ Content Model (definition_list_item_+) -Attributes +:Attributes: The ``definition_list`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%body.elements;`_ parameter entity directly includes ``definition_list``. The `%structure.model;`_ parameter entity indirectly includes ``definition_list``. @@ -1103,22 +1092,21 @@ term_/definition_ pair (with optional classifier_). Details ------- -Category - `Body Subelements`_ (compound) +:Category: `Body Subelements`_ (compound) -Parents +:Parents: Only the definition_list_ element contains ``definition_list_item``. -Children +:Children: ``definition_list_item`` elements each contain a single term_, an optional classifier_, and a definition_. -Analogies +:Analogies: ``definition_list_item`` is analogous to the DocBook "variablelistentry" element. -Processing +:Processing: The optional classifier_ can be rendered differently from the term_. They should be separated visually, typically by spaces plus a colon or dash. @@ -1131,7 +1119,7 @@ Content Model (term_, classifier_?, definition_) -Attributes +:Attributes: The ``definition_list_item`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1195,21 +1183,20 @@ front matter of a book, such as the title page and copyright page. Details ------- -Category - `Structural Subelements`_ +:Category: `Structural Subelements`_ -Parents +:Parents: Only the document_ element contains ``docinfo``. -Children +:Children: ``docinfo`` elements contain `bibliographic elements`_. -Analogies +:Analogies: ``docinfo`` is analogous to DocBook "info" elements ("bookinfo" etc.). There are no directly analogous HTML elements; the "meta" element carries some of the same information, albeit invisibly. -Processing +:Processing: The ``docinfo`` element may be rendered as a two-column table or in other styles. It may even be invisible or omitted from the processed output. Meta-data may be extracted from ``docinfo`` @@ -1231,7 +1218,7 @@ Content Model (`%bibliographic.elements;`_)+ -Attributes +:Attributes: The ``docinfo`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1307,17 +1294,16 @@ tree. It is the starting point for a document. Details ------- -Category - `Structural Elements`_ +:Category: `Structural Elements`_ -Parents +:Parents: The ``document`` element has no parents. -Children +:Children: ``document`` elements may contain `structural subelements`_, `structural elements`_, and `body elements`_. -Analogies +:Analogies: ``document`` is analogous to the HTML "html" element and to several DocBook elements such as "book". @@ -1345,7 +1331,7 @@ programmatically. See the `%structure.model;`_ parameter entity for details of the body of a ``document``. -Attributes +:Attributes: The ``document`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1401,23 +1387,22 @@ uniformly marked with enumerator labels. Details ------- -Category - `Compound Body Elements`_ +:Category: `Compound Body Elements`_ -Parents +:Parents: All elements employing the `%body.elements;`_ or `%structure.model;`_ parameter entities in their content models may contain ``enumerated_list``. -Children +:Children: ``enumerated_list`` elements contain one or more list_item_ elements. -Analogies +:Analogies: ``enumerated_list`` is analogous to the HTML "ol" element and to the DocBook "orderedlist" element. -Processing +:Processing: Each list item should begin a new vertical block, prefaced by a enumeration marker (such as "1."). @@ -1429,7 +1414,7 @@ Content Model (list_item_+) -Attributes +:Attributes: The ``enumerated_list`` element contains the `common attributes`_ (id_, name_, dupname_, source_, and class_), plus enumtype_, prefix_, suffix_, and start_. @@ -1455,7 +1440,7 @@ Attributes list, in decimal. For lists beginning at value 1 ("1", "a", "A", "i", or "I"), this attribute may be omitted. -Parameter Entities +:Parameter Entities: The `%body.elements;`_ parameter entity directly includes ``enumerated_list``. The `%structure.model;`_ parameter entity indirectly includes ``enumerated_list``. @@ -1545,16 +1530,15 @@ processing information (datestamp, a link to Docutils_, etc.). Details ------- -Category - `Decorative Elements`_ +:Category: `Decorative Elements`_ -Parents +:Parents: Only the decoration_ element contains ``footer``. -Children +:Children: ``footer`` elements may contain `body elements`_. -Analogies +:Analogies: There are no direct analogies to ``footer`` in HTML or DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. @@ -1567,7 +1551,7 @@ Content Model (`%body.elements;`_)+ -Attributes +:Attributes: The ``footer`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1621,16 +1605,15 @@ page. Docutils does not yet make use of the ``header`` element. Details ------- -Category - `Decorative Elements`_ +:Category: `Decorative Elements`_ -Parents +:Parents: Only the decoration_ element contains ``header``. -Children +:Children: ``header`` elements may contain `body elements`_. -Analogies +:Analogies: There are no direct analogies to ``header`` in HTML or DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. @@ -1643,7 +1626,7 @@ Content Model (`%body.elements;`_)+ -Attributes +:Attributes: The ``header`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1706,21 +1689,20 @@ item. Details ------- -Category - `Body Subelements`_ (compound) +:Category: `Body Subelements`_ (compound) -Parents +:Parents: The bullet_list_ and enumerated_list_ elements contain ``list_item``. -Children +:Children: ``list_item`` elements may contain `body elements`_. -Analogies +:Analogies: ``list_item`` is analogous to the HTML "li" element and to the DocBook "listitem" element. -Processing +:Processing: See bullet_list_ or enumerated_list_. @@ -1731,7 +1713,7 @@ Content Model (`%body.elements;`_)+ -Attributes +:Attributes: The ``list_item`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -1832,21 +1814,20 @@ organization, or the organization responsible for the document. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``organization``. -Children +:Children: ``organization`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``organization`` is analogous to the DocBook "orgname", "corpname", or "publishername" elements. -Processing +:Processing: See docinfo_. @@ -1857,11 +1838,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``organization`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``organization``. @@ -1899,19 +1880,18 @@ single paragraph, a fundamental building block of documents. Details ------- -Category - `Simple Body Elements`_ +:Category: `Simple Body Elements`_ -Parents +:Parents: All elements employing the `%body.elements;`_ or `%structure.model;`_ parameter entities in their content models may contain ``paragraph``. -Children +:Children: ``paragraph`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``paragraph`` is analogous to the HTML "p" element and to the DocBook "para" elements. @@ -1923,11 +1903,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``paragraph`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%body.elements;`_ parameter entity directly includes ``paragraph``. The `%structure.model;`_ parameter entity indirectly includes ``paragraph``. @@ -1980,22 +1960,21 @@ It can be used alone or in conjunction with version_. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``revision``. -Children +:Children: ``revision`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``revision`` is analogous to but simpler than the DocBook "revision" element. It closely matches the DocBook "revnumber" element, but in a simpler context. -Processing +:Processing: Often used with the RCS/CVS keyword "Revision". See docinfo_. @@ -2006,11 +1985,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``revision`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``revision``. @@ -2060,18 +2039,17 @@ not after it. Details ------- -Category - `Structural Elements`_ +:Category: `Structural Elements`_ -Parents +:Parents: The following elements may contain ``section``: document_, section_ -Children +:Children: ``section`` elements begin with a title_, and may contain `body elements`_ and transition_ and topic_ elements. -Analogies +:Analogies: ``section`` is analogous to DocBook recursive "section" elements, and to HTML "div" elements combined with "h1" etc. title elements. @@ -2087,11 +2065,11 @@ Content Model See the `%structure.model;`_ parameter entity for details of the body of a ``section``. -Attributes +:Attributes: The ``section`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%section.elements;`_ parameter entity directly includes ``section``. The `%structure.model;`_ parameter entity indirectly includes ``section``. @@ -2153,19 +2131,18 @@ such as "Draft", "Final", "Work In Progress", etc. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``status``. -Children +:Children: ``status`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``status`` is analogous to the DocBook "status" element. -Processing +:Processing: See docinfo_. @@ -2176,11 +2153,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``status`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``status``. @@ -2235,21 +2212,20 @@ The ``subtitle`` element stores the subtitle of a document_. Details ------- -Category - `Structural Subelements`_ +:Category: `Structural Subelements`_ -Parents +:Parents: Only the document_ element contains ``subtitle``. -Children +:Children: ``subtitle`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``subtitle`` is analogous to HTML header elements ("h2" etc.) and to the DocBook "subtitle" element. -Processing +:Processing: A document's subtitle is usually rendered smaller than its title_. @@ -2260,7 +2236,7 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``subtitle`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -2329,20 +2305,19 @@ definition_list_. Details ------- -Category - `Body Subelements`_ (simple) +:Category: `Body Subelements`_ (simple) -Parents +:Parents: Only the definition_list_item_ element contains ``term``. -Children +:Children: ``term`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``term`` is analogous to the HTML "dt" element and to the DocBook "term" element. -Processing +:Processing: See definition_list_item_. @@ -2353,7 +2328,7 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``term`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. @@ -2393,17 +2368,16 @@ topic_. Details ------- -Category - `Structural Subelements`_ +:Category: `Structural Subelements`_ -Parents +:Parents: The following elements may contain ``title``: document_, section_, topic_ -Children +:Children: ``title`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``title`` is analogous to HTML "title" and header ("h1" etc.) elements, and to the DocBook "title" element. @@ -2415,7 +2389,7 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``title`` element contains the `common attributes`_ (id_, name_, dupname_, source_, and class_), plus refid_ and auto_. @@ -2457,20 +2431,19 @@ a ``table`` or a ``list``, or inside another ``topic``. Details ------- -Category - `Structural Elements`_ +:Category: `Structural Elements`_ -Parents +:Parents: The following elements may contain ``topic``: document_, section_ -Children +:Children: ``topic`` elements begin with a title_ and may contain `body elements`_. -Analogies +:Analogies: ``topic`` is analogous to the DocBook "simplesect" element. -Processing +:Processing: A ``topic`` element should be set off from the rest of the document somehow, such as with indentation or a border. @@ -2483,11 +2456,11 @@ Content Model (title_?, (`%body.elements;`_)+) -Attributes +:Attributes: The ``topic`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%structure.model;`_ parameter entity directly includes ``topic``. @@ -2529,20 +2502,19 @@ See `Representation of Horizontal Rules`_ below. Details ------- -Category - `Structural Subelements`_ +:Category: `Structural Subelements`_ -Parents +:Parents: The following elements may contain ``transition``: document_, section_ -Children +:Children: ``transition`` is an empty element and has no children. -Analogies +:Analogies: ``transition`` is analogous to the HTML "hr" element. -Processing +:Processing: The ``transition`` element is typically rendered as vertical whitespace (more than that separating paragraphs), with or without a horizontal line or row of asterisks. In novels, transitions are @@ -2559,11 +2531,11 @@ Content Model The ``transition`` element has no content; it is a "point element". -Attributes +:Attributes: The ``transition`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%structure.model;`_ parameter entity directly includes ``transition``. @@ -2599,21 +2571,20 @@ It can be used alone or in conjunction with revision_. Details ------- -Category - `Bibliographic Elements`_ +:Category: `Bibliographic Elements`_ -Parents +:Parents: Only the docinfo_ element contains ``version``. -Children +:Children: ``version`` elements may contain text data plus `inline elements`_. -Analogies +:Analogies: ``version`` may be considered analogous to the DocBook "revision", "revnumber", or "biblioid" elements. -Processing +:Processing: Sometimes used with the RCS/CVS keyword "Revision". See docinfo_ and revision_. @@ -2625,11 +2596,11 @@ Content Model `%text.model;`_ -Attributes +:Attributes: The ``version`` element contains only the `common attributes`_: id_, name_, dupname_, source_, and class_. -Parameter Entities +:Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes ``version``. -- cgit v1.2.1 From a017e088a148600bf4ec7e20e0dd8967ea9837d0 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:47:24 +0000 Subject: simplified data field lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@694 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 117 +++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index c78e572c2..cb22c621b 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -40,10 +40,9 @@ Specification`_ for syntax details. "important", "note", "tip", "warning" :DTD Elements: attention, caution, danger, error, hint, important, note, tip, warning -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Interpreted as body elements. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Interpreted as body elements. Admonitions are specially marked "topics" that can appear anywhere an ordinary body element can. They contain arbitrary body elements. @@ -100,10 +99,9 @@ Image :Directive Type: "image" :DTD Element: image -:Directive Block: - :Arguments: One, required (image URI). - :Options: Possible. - :Content: None. +:Directive Arguments: One, required (image URI). +:Directive Options: Possible. +:Directive Content: None. An "image" is a simple picture:: @@ -158,11 +156,10 @@ Figure :Directive Type: "figure" :DTD Elements: figure, image, caption, legend -:Directive Block: - - :Arguments: One, required (image URI). - :Options: Possible. - :Content: Interpreted as the figure caption and an optional legend. +:Directive Arguments: One, required (image URI). +:Directive Options: Possible. +:Directive Content: Interpreted as the figure caption and an optional + legend. A "figure" consists of image_ data (including `image options`_), an optional caption (a single paragraph), and an optional legend @@ -202,10 +199,9 @@ Topic :Directive Type: "topic" :DTD Element: topic -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Interpreted as the topic title and body. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Interpreted as the topic title and body. A topic is like a block quote with a title, or a self-contained section with no subsections. Use the "topic" directive to indicate a @@ -229,10 +225,9 @@ Line Block :Directive Type: "line-block" :DTD Element: line_block -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Becomes the body of the line block. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Becomes the body of the line block. The "line-block" directive constructs an element where whitespace (including linebreaks) is significant and inline markup is supported. @@ -261,10 +256,9 @@ Parsed Literal Block :Directive Type: "literal-block" :DTD Element: literal_block -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Becomes the body of the literal block. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Becomes the body of the literal block. Unlike an ordinary literal block, the "parsed-literal" directive constructs a literal block where the text is parsed for inline markup. @@ -278,11 +272,11 @@ Backslash-escapes may be necessary in places. For example, all the element names in this content model are links:: .. parsed-literal:: - + ((title_, - subtitle_?)?, - docinfo_?, - decoration_?, + subtitle_?)?, + docinfo_?, + decoration_?, `%structure.model;`_) @@ -295,10 +289,9 @@ Table of Contents :Directive Type: "contents" :DTD Elements: pending, topic -:Directive Block: - :Arguments: One, optional: title. - :Options: Possible. - :Content: None. +:Directive Arguments: One, optional: title. +:Directive Options: Possible. +:Directive Content: None. The "contents" directive inserts a table of contents (TOC) in two passes: initial parse and transform. During the initial parse, a @@ -352,10 +345,9 @@ Automatic Section Numbering :Directive Type: "sectnum" or "section-autonumbering" (synonyms) :DTD Elements: pending, generated -:Directive Block: - :Arguments: None. - :Options: Possible. - :Content: None. +:Directive Arguments: None. +:Directive Options: Possible. +:Directive Content: None. The "sectnum" (or "section-autonumbering") directive automatically numbers sections and subsections in a document. Section numbers are @@ -387,10 +379,9 @@ Target Footnotes :Directive Type: "target-notes" :DTD Elements: pending, footnote, footnote_reference -:Directive Block: - :Arguments: None. - :Options: None. - :Content: None. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: None. The "target-notes" directive creates a footnote for each external target in the text, and corresponding footnote references after each @@ -406,10 +397,9 @@ Footnotes :Directive Type: "footnotes" :DTD Elements: pending, topic -:Directive Block: - :Arguments: None? - :Options: Possible? - :Content: None. +:Directive Arguments: None? +:Directive Options: Possible? +:Directive Content: None. @@@ @@ -421,10 +411,9 @@ Citations :Directive Type: "citations" :DTD Elements: pending, topic -:Directive Block: - :Arguments: None? - :Options: Possible? - :Content: None. +:Directive Arguments: None? +:Directive Options: Possible? +:Directive Content: None. @@@ @@ -438,10 +427,9 @@ Meta :Directive Type: "meta" :DTD Element: meta (non-standard) -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Must contain a flat field list. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Must contain a flat field list. The "meta" directive is used to specify HTML metadata stored in HTML META tags. "Metadata" is data about data, in this case data about web @@ -509,10 +497,9 @@ Including an External Fragment :Directive Type: "include" :DTD Elements: depend on data being included -:Directive Block: - :Arguments: One, required (path to include file). - :Options: Possible. - :Content: None. +:Directive Arguments: One, required (path to include file). +:Directive Options: Possible. +:Directive Content: None. The "include" directive reads a reStructuredText-formatted text file and parses it in the current document's context at the point of the @@ -534,11 +521,10 @@ Raw Data Pass-Through :Directive Type: "raw" :DTD Element: pending -:Directive Block: - :Arguments: One, required (output format type). - :Options: Possible - :Content: Stored verbatim, uninterpreted. None (empty) if a - "file" or "url" option given. +:Directive Arguments: One, required (output format type). +:Directive Options: Possible +:Directive Content: Stored verbatim, uninterpreted. None (empty) if a + "file" or "url" option given. The "raw" directive indicates non-reStructuredText data that is to be passed untouched to the Writer. The name of the output format is @@ -580,10 +566,9 @@ Restructuredtext-Test-Directive :Directive Type: "restructuredtext-test-directive" :DTD Element: system_warning -:Directive Block: - :Arguments: None. - :Options: None. - :Content: Interpreted as a literal block. +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Interpreted as a literal block. This directive is provided for test purposes only. (Nobody is expected to type in a name *that* long!) It is converted into a -- cgit v1.2.1 From c2291595af5c117f10061fd9bf68fa0ff69d74fa Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 19 Sep 2002 00:51:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@695 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 30 ++- docs/dev/todo.txt | 10 - docutils/parsers/rst/directives/misc.py | 18 +- test/test_parsers/test_rst/test_literal_blocks.py | 30 ++- test/test_parsers/test_rst/test_section_headers.py | 236 ++++++++++++++++++++- test/test_parsers/test_rst/test_tables.py | 96 ++++++++- test/test_parsers/test_rst/test_transitions.py | 28 ++- test/test_statemachine.py | 14 +- tools/quicktest.py | 22 +- 9 files changed, 417 insertions(+), 67 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6d1729895..e8c64f062 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -94,6 +94,23 @@ Specific: ``document``, removed ``messages``. Added ``note_parse_message`` and ``note_transform_message`` methods. +* 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. * docutils/utils.py: @@ -118,6 +135,12 @@ Specific: - 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. + +* docutils/parsers/rst/tableparser.py: + + - Fixed a bug that was producing unwanted empty rows in "simple" + tables. * docutils/parsers/rst/directives/__init__.py: @@ -197,6 +220,7 @@ Specific: - 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. * docutils/writers/pep_html.py: @@ -220,12 +244,14 @@ Specific: - 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 header backlinks more subtle. + - 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. * spec/doctree.txt: @@ -281,6 +307,7 @@ Specific: - 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. * tools/buildhtml.py: @@ -315,6 +342,7 @@ Specific: - Added support for "line_block" elements. - Added style for "address" elements. - Removed "a.footnote-reference" style; doing it with ```` now. + - Improved field list rendering. * tools/stylesheets/pep.css: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 6f68d85d0..d1500a7ed 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -40,16 +40,6 @@ Bugs Idea: two-pass hyperlink resolution, ignoring errors on the first pass? -- @@@ Section headers must have underlines at least 4 characters long. - But when the section title is only 3 characters long, it's natural - to underline with "===" (I just did). The parser should produce a - warning in such cases. - - Or should the parser simply recognize such short underlines? A - zero-tolerance policy might work: over/underlines of 3 or fewer - characters which are shorter than the "title" text are not - recognized as titles, and should generate an "info" message. - - The parser doesn't know anything about double-width characters such as Chinese hanza & Japanese kanji/kana. Also, it's dependent on whitespace and punctuation as markup delimiters, which may not be diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 663325ead..25e0a6467 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -1,14 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -Miscellaneous directives. -""" +"""Miscellaneous directives.""" __docformat__ = 'reStructuredText' @@ -26,7 +22,7 @@ def directive_test_function(match, type_name, data, state, state_machine, state_machine.next_line() indented, indent, offset, blank_finish = state_machine.get_indented() text = '\n'.join(indented) - except IndexError: + except EOFError: text = '' blank_finish = 1 if text: diff --git a/test/test_parsers/test_rst/test_literal_blocks.py b/test/test_parsers/test_rst/test_literal_blocks.py index d1f0f5446..fd322d796 100755 --- a/test/test_parsers/test_rst/test_literal_blocks.py +++ b/test/test_parsers/test_rst/test_literal_blocks.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ @@ -153,6 +153,24 @@ A paragraph: """], ["""\ A paragraph: +:: + + A literal block. +""", +"""\ + + + + Possible title underline, too short for the title. + Treating it as ordinary text because it's so short. + + A paragraph: + + A literal block. +"""], +["""\ +A paragraph: + :: A literal block. diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 718f46569..19e7c3b8b 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -1,14 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. -Tests for states.py. -""" +"""Tests for states.py.""" from __init__ import DocutilsTestSupport @@ -588,6 +586,228 @@ Paragraph. Paragraph. """], +["""\ +ABC +=== + +Short title. +""", +"""\ + +
    + + ABC + <paragraph> + Short title. +"""], +["""\ +ABC +== + +Underline too short. +""", +"""\ +<document source="test data"> + <system_message level="1" line="2" source="test data" type="INFO"> + <paragraph> + Possible title underline, too short for the title. + Treating it as ordinary text because it's so short. + <paragraph> + ABC + == + <paragraph> + Underline too short. +"""], +["""\ +== +ABC +== + +Over & underline too short. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <paragraph> + == + ABC + == + <paragraph> + Over & underline too short. +"""], +["""\ +== +ABC + +Overline too short, no underline. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <paragraph> + == + ABC + <paragraph> + Overline too short, no underline. +"""], +["""\ +== +ABC +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <paragraph> + == + ABC +"""], +["""\ +== + Not a title: a definition list item. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <definition_list> + <definition_list_item> + <term> + == + <definition> + <paragraph> + Not a title: a definition list item. +"""], +["""\ +== + Not a title: a definition list item. +-- + Another definition list item. It's in a different list, + but that's an acceptable limitation given that this will + probably never happen in real life. + + The next line will trigger a warning: +== +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <definition_list> + <definition_list_item> + <term> + == + <definition> + <paragraph> + Not a title: a definition list item. + <system_message level="2" line="3" source="test data" type="WARNING"> + <paragraph> + Definition list ends without a blank line; unexpected unindent. + <system_message level="1" line="3" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <definition_list> + <definition_list_item> + <term> + -- + <definition> + <paragraph> + Another definition list item. It's in a different list, + but that's an acceptable limitation given that this will + probably never happen in real life. + <paragraph> + The next line will trigger a warning: + <system_message level="2" line="9" source="test data" type="WARNING"> + <paragraph> + Definition list ends without a blank line; unexpected unindent. + <paragraph> + == +"""], +["""\ +Paragraph + + == + ABC + == + + Over & underline too short. +""", +"""\ +<document source="test data"> + <paragraph> + Paragraph + <block_quote> + <system_message level="1" line="3" source="test data" type="INFO"> + <paragraph> + Unexpected possible title overline or transition. + Treating it as ordinary text because it's so short. + <paragraph> + == + ABC + == + <paragraph> + Over & underline too short. +"""], +["""\ +... +... + +... +--- + +... +... +... +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <section dupname="..." id="id1"> + <title> + ... + <system_message level="1" line="4" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <section dupname="..." id="id2"> + <title> + ... + <system_message backrefs="id2" level="1" source="test data" type="INFO"> + <paragraph> + Duplicate implicit target name: "...". + <system_message level="1" line="7" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <system_message level="1" line="7" source="test data" type="INFO"> + <paragraph> + Possible incomplete section title. + Treating the overline as ordinary text because it's so short. + <section dupname="..." id="id3"> + <title> + ... + <system_message backrefs="id3" level="1" source="test data" type="INFO"> + <paragraph> + Duplicate implicit target name: "...". + <paragraph> + ... +"""], ] diff --git a/test/test_parsers/test_rst/test_tables.py b/test/test_parsers/test_rst/test_tables.py index 1ff0e7568..e26aec960 100755 --- a/test/test_parsers/test_rst/test_tables.py +++ b/test/test_parsers/test_rst/test_tables.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ @@ -979,6 +979,90 @@ cell 3 the bottom border below is too long cell 3 the bottom border below is too long ============== ======== """], +["""\ +============ ================= +A table with row separators. +------------ ----------------- + +Blank line before. +------------ ----------------- + +Blank lines before and after. + +------------ ----------------- +Blank line after. + +============ ================= +""", +"""\ +<document source="test data"> + <table> + <tgroup cols="2"> + <colspec colwidth="12"> + <colspec colwidth="17"> + <tbody> + <row> + <entry> + <paragraph> + A table with + <entry> + <paragraph> + row separators. + <row> + <entry> + <paragraph> + Blank line + <entry> + <paragraph> + before. + <row> + <entry> + <paragraph> + Blank lines + <entry> + <paragraph> + before and after. + <row> + <entry> + <paragraph> + Blank line + <entry> + <paragraph> + after. +"""], +["""\ +============ ==================== +A table with many row separators. +------------ -------------------- +------------ -------------------- + +------------ -------------------- +============ ==================== +""", +"""\ +<document source="test data"> + <table> + <tgroup cols="2"> + <colspec colwidth="12"> + <colspec colwidth="20"> + <tbody> + <row> + <entry> + <paragraph> + A table with + <entry> + <paragraph> + many row separators. + <row> + <entry> + <entry> + <row> + <entry> + <entry> + <row> + <entry> + <entry> +"""], ] diff --git a/test/test_parsers/test_rst/test_transitions.py b/test/test_parsers/test_rst/test_transitions.py index c2cd69aac..cbbec169f 100755 --- a/test/test_parsers/test_rst/test_transitions.py +++ b/test/test_parsers/test_rst/test_transitions.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for transition markers. """ @@ -137,6 +137,22 @@ Test unexpected transition markers. <paragraph> Paragraph. """], +["""\ +Short transition marker. + +--- + +Paragraph +""", +"""\ +<document source="test data"> + <paragraph> + Short transition marker. + <paragraph> + --- + <paragraph> + Paragraph +"""], ] diff --git a/test/test_statemachine.py b/test/test_statemachine.py index 8c336ca78..4ff5993fb 100755 --- a/test/test_statemachine.py +++ b/test/test_statemachine.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Test module for statemachine.py. """ @@ -154,7 +154,7 @@ class SMWSTests(unittest.TestCase): def test___init__(self): self.assertEquals(self.sm.states.keys(), ['MockState']) - self.assertEquals(len(self.sm.states['MockState'].transitions), 2) + self.assertEquals(len(self.sm.states['MockState'].transitions), 4) def test_get_indented(self): self.sm.input_lines = testtext diff --git a/tools/quicktest.py b/tools/quicktest.py index 2f0c46454..fc74d5121 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -1,14 +1,12 @@ #!/usr/bin/env python -""" -:Author: Garth Kidd -:Contact: garth@deadlybloodyserious.com -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. -""" +# Author: Garth Kidd +# Contact: garth@deadlybloodyserious.com +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. import locale locale.setlocale(locale.LC_ALL, '') @@ -46,8 +44,8 @@ options = [('pretty', 'p', ('attributes', '', 'dump document attributes after processing'), ('debug', 'd', 'debug mode (lots of output)'), ('help', 'h', 'show help text')] -"""See distutils.fancy_getopt.FancyGetopt.__init__ for a description of the -data structure: (long option, short option, description).""" +"""See ``distutils.fancy_getopt.FancyGetopt.__init__`` for a description of +the data structure: (long option, short option, description).""" def usage(): print usage_header @@ -186,7 +184,7 @@ Use the next dialog to build a command line: def main(): # process cmdline arguments: inputFile, outputFile, outputFormat, optargs = getArgs() - options = OptionParser().get_default_values() + options = OptionParser(components=(Parser,)).get_default_values() options.debug = optargs['debug'] parser = Parser() input = inputFile.read() -- cgit v1.2.1 From fe1222623a8f8eae5552984bb8186e69e735cbed Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 02:49:01 +0000 Subject: Made the ``locale.setlocale()`` calls in front ends fault-tolerant. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@697 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 6 ++++++ tools/docutils-xml.py | 17 ++++++++++------- tools/html.py | 17 ++++++++++------- tools/pep.py | 17 ++++++++++------- tools/publish.py | 17 ++++++++++------- tools/quicktest.py | 5 ++++- 6 files changed, 50 insertions(+), 29 deletions(-) diff --git a/tools/buildhtml.py b/tools/buildhtml.py index f2d3b80a4..8375cd844 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -12,6 +12,12 @@ new reStructuredText PEPs). __docformat__ = 'reStructuredText' +import locale +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass + import sys import os import os.path diff --git a/tools/docutils-xml.py b/tools/docutils-xml.py index 72f72ca86..688a38786 100755 --- a/tools/docutils-xml.py +++ b/tools/docutils-xml.py @@ -1,17 +1,20 @@ #!/usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" A minimal front end to the Docutils Publisher, producing Docutils XML. """ import locale -locale.setlocale(locale.LC_ALL, '') +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass from docutils.core import publish, default_description diff --git a/tools/html.py b/tools/html.py index a79aefca8..81c34ab4b 100755 --- a/tools/html.py +++ b/tools/html.py @@ -1,17 +1,20 @@ #!/usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" A minimal front end to the Docutils Publisher, producing HTML. """ import locale -locale.setlocale(locale.LC_ALL, '') +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass from docutils.core import publish, default_description diff --git a/tools/pep.py b/tools/pep.py index 837221495..e44eabe18 100755 --- a/tools/pep.py +++ b/tools/pep.py @@ -1,18 +1,21 @@ #!/usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" A minimal front end to the Docutils Publisher, producing HTML from PEP (Python Enhancement Proposal) documents. """ import locale -locale.setlocale(locale.LC_ALL, '') +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass from docutils.core import publish, default_description diff --git a/tools/publish.py b/tools/publish.py index edd643b04..75de3a141 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -1,17 +1,20 @@ #!/usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" A minimal front end to the Docutils Publisher, producing pseudo-XML. """ import locale -locale.setlocale(locale.LC_ALL, '') +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass from docutils.core import publish, default_description diff --git a/tools/quicktest.py b/tools/quicktest.py index fc74d5121..ccabf4ed6 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -9,7 +9,10 @@ # Copyright: This module has been placed in the public domain. import locale -locale.setlocale(locale.LC_ALL, '') +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass import sys import os -- cgit v1.2.1 From 9af81413d14f2f8e27b1ce1230c7f59872b40c39 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 02:49:37 +0000 Subject: spellchecked & updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@698 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 46673010b..0538d23c9 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -54,7 +54,7 @@ elements, and may be structured into sections. Sections_ are indicated through title style (underlines & optional overlines). Sections contain body elements and/or subsections. Some body elements contain further elements, such as lists containing list items, which -in turn may contain paragraphs and other body elemens. Others, such +in turn may contain paragraphs and other body elements. Others, such as paragraphs, contain text and `inline markup`_ elements. Here are examples of `body elements`_: @@ -325,7 +325,7 @@ the field names):: :Hello: This field has a short field name, so aligning the field body with the first line is feasible. - :Number-of-African-swallows-requried-to-carry-a-coconut: It would + :Number-of-African-swallows-required-to-carry-a-coconut: It would be very difficult to align the field body with the left edge of the first line. It may even be preferable not to begin the body on the same line as the marker. @@ -370,11 +370,11 @@ Reference Names =============== Simple reference names are single words consisting of alphanumerics -plus internal hypens, underscores, and periods; no whitespace or other -characters are allowed. Footnote labels (Footnotes_ & `Footnote -References`_), citation labels (Citations_ & `Citation References`_), -`interpreted text`_ roles, and some `hyperlink references`_ use the -simple reference name syntax. +plus isolated (no two adjacent) internal hyphens, underscores, and +periods; no whitespace or other characters are allowed. Footnote +labels (Footnotes_ & `Footnote References`_), citation labels +(Citations_ & `Citation References`_), `interpreted text`_ roles, and +some `hyperlink references`_ use the simple reference name syntax. Reference names using punctuation or whose names are phrases (two or more space-separated words) are called "phrase-references". @@ -566,7 +566,7 @@ enforced, nor do differences in transition markers accomplish anything. It is recommended that a single consistent style be used. The processing system is free to render transitions in output in any -way it likes. For example, horizontal rules (``<HR>``) in HTML output +way it likes. For example, horizontal rules (``<hr>``) in HTML output would be an obvious choice. @@ -633,7 +633,7 @@ Here are examples of **incorrectly** formatted bullet lists:: (Warning) - The following line appears to be a new sublist, but it is not: - - This is a paragraph contination, not a sublist (since there's + - This is a paragraph continuation, not a sublist (since there's no blank line). This line is also incorrectly indented. - Warnings may be issued by the implementation. @@ -919,7 +919,7 @@ The RCS keyword processing only kicks in when all of these conditions hold: 1. The field list is in bibliographic context (first non-comment - contstruct in the document, after a document title if there is + construct in the document, after a document title if there is one). 2. The field name is a recognized bibliographic field name. @@ -949,7 +949,7 @@ descriptions, documenting a program's options. For example:: This is the second. Blank lines may be omitted between options (as above) or left in (as here and below). - --very-long-option A VMS-syle option. Note the adjustment for + --very-long-option A VMS-style option. Note the adjustment for the required two spaces. --an-even-longer-option @@ -1628,7 +1628,7 @@ indirect. After processing into HTML, the hyperlink might be expressed as:: - See the <A HREF="http://www.python.org">Python</A> home page + See the <a href="http://www.python.org">Python</a> home page for info. An external hyperlink's URI may begin on the same line as the @@ -1805,8 +1805,8 @@ directive code. There are three logical parts to the directive block: Individual directives can employ any combination of these parts. Directive arguments can be filesystem paths, URLs, title text, etc. Directive options are indicated using `field lists`_; the field names -and contents are directive-specific. Argumens and options must form a -contiguous block beginning on the first or second line of the +and contents are directive-specific. Arguments and options must form +a contiguous block beginning on the first or second line of the directive; a blank line indicates the beginning of the directive content block. If either arguments and/or options are employed by the directive, a blank line must separate them from the directive content. @@ -1982,7 +1982,7 @@ Styles [#]_ Interpreted text is unsuitable for this purpose because the set of style names cannot be predefined - it is the domain of the content author, not the author of the parser and output - formatter - and there is no way to associate a stylename + formatter - and there is no way to associate a style name argument with an interpreted text style role. Also, it may be desirable to use the same mechanism for styling blocks:: @@ -2189,7 +2189,7 @@ markup start-strings: - vertical bars: | || etc. It may be desirable to use inline literals for some of these anyhow, -especially if they represent code snippets. It's a judgement call. +especially if they represent code snippets. It's a judgment call. These cases *do* require either literal-quoting or escaping to avoid misinterpretation:: @@ -2293,7 +2293,7 @@ references`_, we can add "index entry", "acronym", "class", "red", A role marker consists of a colon, the role name, and another colon. A role name is a single word consisting of alphanumerics plus internal -hypens, underscores, and periods; no whitespace or other characters +hyphens, underscores, and periods; no whitespace or other characters are allowed. @@ -2470,7 +2470,7 @@ as the link's text. For example:: would be marked up in HTML as:: - See <A HREF="http://www.python.org">http://www.python.org</A> for + See <a href="http://www.python.org">http://www.python.org</a> for info. Two forms of URI are recognized: @@ -2507,7 +2507,7 @@ Two forms of URI are recognized: recognize any absolute URI, as defined in RFC2396_ and RFC2732_. 2. Standalone email addresses, which are treated as if they were - ablsolute URIs with a "mailto:" scheme. Example:: + absolute URIs with a "mailto:" scheme. Example:: someone@somewhere.com -- cgit v1.2.1 From 5a81f0dc164410bf86ccd997dc7a59b6815c6ee1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 02:49:52 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@699 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0256.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index e6715eb14..8dc00f72e 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -184,7 +184,7 @@ The docstring processing system framework is broken up as follows: - Docstring extraction rules. - - Readers, which encapsulate the input context . + - Readers, which encapsulate the input context. - Parsers. -- cgit v1.2.1 From c42533ff80a5543fb3a207c102cf8655b9cb6ffc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 02:51:33 +0000 Subject: Fixed "simple reference name" regexp to ignore text like "object.__method__"; not an anonymous reference. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@700 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index fa940c49a..742aa94f2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -488,7 +488,8 @@ class Inliner: non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' non_whitespace_after = r'(?![ \n])' - simplename = r'(?!_)\w([-.\w]*(?!_)\w)?' + # Alphanumerics with isolated internal [-._] chars (i.e. not 2 together): + simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*' uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" urilast = r"""[_~/\]a-zA-Z0-9]""" # no punctuation emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" -- cgit v1.2.1 From 1e92920c6d84d99f6c6009f1e024260eec434914 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 02:53:58 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@701 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 29 +++++++++------ docs/dev/todo.txt | 42 +++++++++++++++++++--- test/test_parsers/test_rst/test_inline_markup.py | 6 ++-- test/test_parsers/test_rst/test_section_headers.py | 22 ++++++++++++ 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e8c64f062..8dd162252 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,17 +17,17 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - Aahz, David Ascher, Fred Bremmer, Simon Budig, Adam Chodorowski, - Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter Funk, - Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen Hermann, - Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry Jemerov, Richard - Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, Wolfgang - Lipp, Edward Loper, Ken Manheimer, Skip Montanaro, Paul Moore, - Michel Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark - Pilgrim, Tavis Rudd, Ollie Rutherfurd, Kenichi Sato, Ueli - Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, - Guido van Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, - Moshe Zadka + Aahz, David Ascher, Fred Bremmer, Simon Budig, Brett Cannon, Adam + Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter + Funk, Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen + Hermann, Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry Jemerov, + Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, + Julien Letessier, Wolfgang Lipp, Edward Loper, Ken Manheimer, Skip + Montanaro, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, + Pearu Peterson, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, + Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, + Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, + Ka-Ping Yee, Moshe Zadka Thank you! @@ -136,6 +136,8 @@ Specific: 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. * docutils/parsers/rst/tableparser.py: @@ -309,6 +311,11 @@ Specific: - Removed field arguments and made field lists a generic construct. - Removed the 4-character minimum for section title underlines. +* tools: + + - Made the ``locale.setlocale()`` calls in front ends + fault-tolerant. + * tools/buildhtml.py: - Added ``--silent`` option. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index d1500a7ed..7c70c4d71 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -106,9 +106,34 @@ General - @@@@ All system messages should have a "line" attribute, to improve diagnostic output. So all elements constructed by the parser should - have internal "line" ("lineno"/"line_number") attributes. Is there - any way we can get this to happen automagically, without having to - add the attribute manually to each object? + have internal "line" ("lineno"/"line_number") attributes. They'd + also need internal "source" attributes as well (populating the + external "source" attribute would clutter up the output). + + Is there any way we can get this to happen automagically, without + having to add the attribute manually to each object? System + messages get their "source" attribute from the Reporter object (new + one for each source). + + - Add an observer subject interface to StateMachine, called whenever + next_line, previous_line, or goto_line is called? + + - Who to notify? Publisher? Document object? Singleton? + + - Document object: add ``note_source``, ``note_line_number`` + methods. ``note_line_number`` is called by + ``StateMachine.notify_observer``. Whatever reads the source + calls ``note_source`` (``utils.new_document()``, "include" + directive (see misc.include_). + + - Add a ``line=None`` parameter to ``nodes.Node``; if unspecified, + it will get the line number from the observer. + + - Perhaps ``Element.append()`` etc. can also set the ``.document`` + attribute of each node added. The document object could hold the + current line number and source description, which would also be + copied over to the node. Consolodate all assignments (parent, + document, source, line) into a single method. Change stderr Reporter output to the GNU urilities format:: @@ -122,7 +147,7 @@ General where directory separators are colons. "filename.txt:1:" looks like a file or directory path. Does MacOS X still use colons, or has it switched to slashes? In any case, the ubiquity of the GNU utilities - probably overweighs any such problem. + probably outweighs any such problem. - Standalone Reader: Implement an option to turn off the DocTitle transform? @@ -483,6 +508,13 @@ __ rst/alternatives.html#or-not-to-do (And arguably invalid, since in Japanese the word "haiku" contains three syllables.) +- Modify acceptable "simple reference name" syntax to allow for + ``object.__method__`` without requiring inline literals? Simple + reference names currently allow any of "-", "_", and "." internally; + if we limit this to one at a time, problem solved. I.e., none of + these would be recognized as simple names: "one..two", "one-.two", + "one._two", "one__two". + Directives `````````` @@ -560,7 +592,7 @@ Directives in ``match_titles=1``. The reporting mechanism has been revamped to include the file which is the source of system messages; a new ``utils.Reporter`` object will need to be created for each input - source. + source. (Need to notify YAGNI for now: Use C-preprocessor semantics for locating include files? E.g., ``.. include:: file.txt`` will read another file diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index 5b50732f8..2ee79a4b5 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -383,7 +383,8 @@ ref__ ref """], ["""\ -ref_, r_, r_e-f_, -ref_, and anonymousref__, but not _ref_ +ref_, r_, r_e-f_, -ref_, and anonymousref__, +but not _ref_ or __attr__ or object.__attr__ """, """\ <document source="test data"> @@ -402,7 +403,8 @@ ref_, r_, r_e-f_, -ref_, and anonymousref__, but not _ref_ , and \n\ <reference anonymous="1"> anonymousref - , but not _ref_ + , + but not _ref_ or __attr__ or object.__attr__ """], ] diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 19e7c3b8b..385362706 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -808,6 +808,28 @@ Paragraph <paragraph> ... """], +["""\ +.. +Hi +.. + +... +Yo +... +""", +"""\ +<document source="test data"> + <comment xml:space="1"> + <system_message level="2" line="2" source="test data" type="WARNING"> + <paragraph> + Explicit markup ends without a blank line; unexpected unindent. + <section id="hi" name="hi"> + <title> + Hi + <section id="yo" name="yo"> + <title> + Yo +"""], ] -- cgit v1.2.1 From 2394f6dec411fc9ae223f838d162878d370edff7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 Sep 2002 03:52:48 +0000 Subject: table tweak git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@702 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 3 ++- tools/stylesheets/pep.css | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index a61d0e01d..a17b4b9cb 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -170,7 +170,8 @@ table.footnote { td, th { padding-left: 0.5em ; - padding-right: 0.5em } + padding-right: 0.5em ; + vertical-align: top } td > p:first-child, th > p:first-child { margin-top: 0em } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 6580b01a0..2a7f61ecc 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -219,7 +219,8 @@ table { td, th { padding-left: 0.5em ; - padding-right: 0.5em } + padding-right: 0.5em ; + vertical-align: top } td > :first-child, th > :first-child { margin-top: 0em } -- cgit v1.2.1 From 2bdb00f857c57628eba757fdf964045fb9308e1f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:09:08 +0000 Subject: Bumped version to 0.2.4 due to changes to the PEP template & stylesheet. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@707 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 229e85dee..547447bed 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This is the Docutils (Python Documentation Utilities) package. Package Structure @@ -57,7 +55,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.3' +__version__ = '0.2.4' """``major.minor.micro`` version number. The ``micro`` number is bumped any time there's a change in the API incompatible with one of the front ends.""" -- cgit v1.2.1 From 602d35aa352de4dabef20e5fc64d2adf234901a3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:10:48 +0000 Subject: - 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_state_machine_change`` & ``.note_source`` observer methods. - Fixed "xml:space" attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@708 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 71 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 095868297..9120f977e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Docutils document tree element class library. Classes in CamelCase are abstract base classes or auxiliary classes. The one @@ -43,7 +41,16 @@ class Node: """Abstract base class of nodes in a document tree.""" parent = None - """Back-reference to the `Node` containing this `Node`.""" + """Back-reference to the Node immediately containing this Node.""" + + document = None + """The `document` node at the root of the tree containing this Node.""" + + source = None + """Path or description of the input source which generated this Node.""" + + line = None + """The line number (1-based) of the beginning of this Node in `source`.""" def __nonzero__(self): """Node instances are always true.""" @@ -61,6 +68,15 @@ class Node: """Return a copy of self.""" raise NotImplementedError + def setup_child(self, child): + child.parent = self + if self.document: + child.document = self.document + if child.source is None: + child.source = self.document.current_source + if child.line is None: + child.line = self.document.current_line + def walk(self, visitor): """ Traverse a tree of `Node` objects, calling ``visit_...`` methods of @@ -323,12 +339,12 @@ class Element(Node): if isinstance(key, UnicodeType) or isinstance(key, StringType): self.attributes[str(key)] = item elif isinstance(key, IntType): - item.parent = self + self.setup_child(item) self.children[key] = item elif isinstance(key, SliceType): assert key.step is None, 'cannot handle slice with stride' for node in item: - node.parent = self + self.setup_child(node) self.children[key.start:key.stop] = item else: raise TypeError, ('element index must be an integer, a slice, or ' @@ -355,11 +371,11 @@ class Element(Node): def __iadd__(self, other): """Append a node or a list of nodes to `self.children`.""" if isinstance(other, Node): - other.parent = self + self.setup_child(other) self.children.append(other) elif other is not None: for node in other: - node.parent = self + self.setup_child(node) self.children.extend(other) return self @@ -388,17 +404,17 @@ class Element(Node): has_key = hasattr def append(self, item): - item.parent = self + self.setup_child(item) self.children.append(item) def extend(self, item): for node in item: - node.parent = self + self.setup_child(node) self.children.extend(item) def insert(self, index, item): if isinstance(item, Node): - item.parent = self + self.setup_child(item) self.children.insert(index, item) elif item is not None: self[index:index] = item @@ -416,7 +432,7 @@ class Element(Node): """Replace one child `Node` with another child or children.""" index = self.index(old) if isinstance(new, Node): - new.parent = self + self.setup_child(new) self[index] = new elif new is not None: self[index:index+1] = new @@ -508,7 +524,7 @@ class FixedTextElement(TextElement): def __init__(self, rawsource='', text='', *children, **attributes): TextElement.__init__(self, rawsource, text, *children, **attributes) - self.attributes['xml:space'] = 1 + self.attributes['xml:space'] = 'preserve' # ======== @@ -583,6 +599,12 @@ class document(Root, Structural, Element): def __init__(self, options, reporter, *args, **kwargs): Element.__init__(self, *args, **kwargs) + self.current_source = None + """Path to or description of the input source being processed.""" + + self.current_line = None + """Line number (1-based) of `current_source`.""" + self.options = options """Command-line or internal option data record.""" @@ -669,6 +691,8 @@ class document(Root, Structural, Element): self.transform_messages = [] """System messages generated while applying transforms.""" + self.document = self + def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() domroot.appendChild(self._rooted_dom_node(domroot)) @@ -867,6 +891,19 @@ class document(Root, Structural, Element): def note_transform_message(self, message): self.transform_messages.append(message) + def note_state_machine_change(self, state_machine): + self.current_line = state_machine.abs_line_number() +# print >>sys.stderr, '\nnodes.document.note_state_machine_change: ' \ +# 'current_line:', self.current_line +# print >>sys.stderr, ' current_state: ',state_machine.current_state +# sys.stderr.flush() + + def note_source(self, source): + self.current_source = source + #print >>sys.stderr, '\nnodes.document.note_source: ' \ + # 'current_source:', self.current_source + #sys.stderr.flush() + def copy(self): return self.__class__(self.options, self.reporter, **self.attributes) -- cgit v1.2.1 From b4e32649be55802efab6daece98d53e79ea9cb4f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:12:46 +0000 Subject: Initial support for improved diagnostics. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@709 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 742aa94f2..4380b3864 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -156,6 +156,7 @@ class RSTStateMachine(StateMachineWS): section_level=0, inliner=inliner) self.document = self.memo.document + self.attach_observer(self.document.note_state_machine_change) self.reporter = self.memo.reporter self.node = document results = StateMachineWS.run(self, input_lines, input_offset) @@ -179,6 +180,7 @@ class NestedStateMachine(StateMachineWS): self.match_titles = match_titles self.memo = memo self.document = memo.document + self.attach_observer(self.document.note_state_machine_change) self.reporter = memo.reporter self.node = node results = StateMachineWS.run(self, input_lines, input_offset) -- cgit v1.2.1 From 16284d13e8df9dc4191d03834963311fd31129d3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:14:49 +0000 Subject: Added support for the Observer pattern, triggered by input line changes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@710 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 51 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index ba1b98f2e..cc5514808 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -161,6 +161,11 @@ class StateMachine: self.add_states(state_classes) + self.observers = [] + """List of bound methods or functions to call whenever the current + line changes. Observers are called with one argument, ``self``. + Cleared at the end of `run()`.""" + def unlink(self): """Remove circular references to objects no longer required.""" for state in self.states.values(): @@ -249,6 +254,7 @@ class StateMachine: except: self.error() raise + self.observers = [] return results def get_state(self, next_state=None): @@ -274,13 +280,16 @@ class StateMachine: def next_line(self, n=1): """Load `self.line` with the `n`'th next line and return it.""" - self.line_offset += n try: - self.line = self.input_lines[self.line_offset] - except IndexError: - self.line = None - raise EOFError - return self.line + try: + self.line_offset += n + self.line = self.input_lines[self.line_offset] + except IndexError: + self.line = None + raise EOFError + return self.line + finally: + self.notify_observers() def is_next_line_blank(self): """Return 1 if the next line is blank or non-existant.""" @@ -304,17 +313,21 @@ class StateMachine: self.line = None else: self.line = self.input_lines[self.line_offset] + self.notify_observers() return self.line def goto_line(self, line_offset): """Jump to absolute line offset `line_offset`, load and return it.""" - self.line_offset = line_offset - self.input_offset try: - self.line = self.input_lines[self.line_offset] - except IndexError: - self.line = None - raise EOFError - return self.line + try: + self.line_offset = line_offset - self.input_offset + self.line = self.input_lines[self.line_offset] + except IndexError: + self.line = None + raise EOFError + return self.line + finally: + self.notify_observers() def abs_line_offset(self): """Return line offset of current line, from beginning of file.""" @@ -430,6 +443,20 @@ class StateMachine: print >>sys.stderr, ('module %s, line %s, function %s' % (module, line, function)) + def attach_observer(self, observer): + """ + The `observer` parameter is a function or bound method which takes one + argument, ``self`` (this StateMachine object). + """ + self.observers.append(observer) + + def detach_observer(self, observer): + self.observers.remove(observer) + + def notify_observers(self): + for observer in self.observers: + observer(self) + class State: -- cgit v1.2.1 From 74483521b73dcac8f3d331af5ffa9892808674d8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:15:39 +0000 Subject: Fixed "xml:space" attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@711 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_citations.py | 4 +-- test/test_parsers/test_rst/test_comments.py | 40 +++++++++++----------- .../test_rst/test_directives/test_contents.py | 10 +++--- .../test_rst/test_directives/test_figures.py | 6 ++-- .../test_rst/test_directives/test_images.py | 24 ++++++------- .../test_rst/test_directives/test_meta.py | 8 ++--- .../test_directives/test_test_directives.py | 6 ++-- .../test_rst/test_directives/test_topics.py | 6 ++-- .../test_rst/test_directives/test_unknown.py | 6 ++-- test/test_parsers/test_rst/test_doctest_blocks.py | 6 ++-- test/test_parsers/test_rst/test_field_lists.py | 2 +- test/test_parsers/test_rst/test_literal_blocks.py | 24 ++++++------- test/test_parsers/test_rst/test_outdenting.py | 4 +-- test/test_parsers/test_rst/test_section_headers.py | 30 ++++++++-------- test/test_parsers/test_rst/test_substitutions.py | 14 ++++---- test/test_parsers/test_rst/test_tables.py | 16 ++++----- test/test_parsers/test_rst/test_targets.py | 12 +++---- test/test_parsers/test_rst/test_transitions.py | 2 +- test/test_readers/test_pep/test_rfc2822.py | 4 +-- test/test_transforms/test_docinfo.py | 10 +++--- test/test_transforms/test_doctitle.py | 8 ++--- 21 files changed, 121 insertions(+), 121 deletions(-) diff --git a/test/test_parsers/test_rst/test_citations.py b/test/test_parsers/test_rst/test_citations.py index 8e0cd0b85..508a5f9a0 100755 --- a/test/test_parsers/test_rst/test_citations.py +++ b/test/test_parsers/test_rst/test_citations.py @@ -126,9 +126,9 @@ No blank line. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> [citation label with spaces] this isn't a citation - <comment xml:space="1"> + <comment xml:space="preserve"> [*citationlabelwithmarkup*] this isn't a citation """], ] diff --git a/test/test_parsers/test_rst/test_comments.py b/test/test_parsers/test_rst/test_comments.py index 42755e66b..193a6cfc1 100755 --- a/test/test_parsers/test_rst/test_comments.py +++ b/test/test_parsers/test_rst/test_comments.py @@ -27,7 +27,7 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment <paragraph> Paragraph. @@ -40,7 +40,7 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment block. <paragraph> @@ -54,7 +54,7 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment consisting of multiple lines starting on the line after the explicit markup start. @@ -67,9 +67,9 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment. - <comment xml:space="1"> + <comment xml:space="preserve"> Another. <paragraph> Paragraph. @@ -82,7 +82,7 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment <system_message level="2" line="2" source="test data" type="WARNING"> <paragraph> @@ -101,9 +101,9 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment. - <comment xml:space="1"> + <comment xml:space="preserve"> Another. <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> @@ -120,7 +120,7 @@ Paragraph. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment:: <paragraph> Paragraph. @@ -134,7 +134,7 @@ the parser from recognizing a directive. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> comment:: <paragraph> The extra newline before the comment text prevents @@ -149,7 +149,7 @@ the parser from recognizing a hyperlink target. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> _comment: http://example.org <paragraph> The extra newline before the comment text prevents @@ -164,7 +164,7 @@ the parser from recognizing a citation. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> [comment] Not a citation. <paragraph> The extra newline before the comment text prevents @@ -179,7 +179,7 @@ the parser from recognizing a substitution definition. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> |comment| image:: bogus.png <paragraph> The extra newline before the comment text prevents @@ -195,10 +195,10 @@ the parser from recognizing a substitution definition. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> Next is an empty comment, which serves to end this comment and prevents the following block quote being swallowed up. - <comment xml:space="1"> + <comment xml:space="preserve"> <block_quote> <paragraph> A block quote. @@ -221,7 +221,7 @@ term 2 <definition> <paragraph> definition 1 - <comment xml:space="1"> + <comment xml:space="preserve"> a comment <definition_list_item> <term> @@ -248,7 +248,7 @@ term 2 <definition> <paragraph> definition 1 - <comment xml:space="1"> + <comment xml:space="preserve"> a comment <definition_list> <definition_list_item> @@ -275,7 +275,7 @@ term 2 bullet paragraph 1 <paragraph> bullet paragraph 2 - <comment xml:space="1"> + <comment xml:space="preserve"> comment between bullet paragraphs 2 and 3 <paragraph> bullet paragraph 3 @@ -293,7 +293,7 @@ term 2 <list_item> <paragraph> bullet paragraph 1 - <comment xml:space="1"> + <comment xml:space="preserve"> comment between bullet paragraphs 1 (leader) and 2 <paragraph> bullet paragraph 2 @@ -309,7 +309,7 @@ term 2 <list_item> <paragraph> bullet - <comment xml:space="1"> + <comment xml:space="preserve"> trailing comment """], ] diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 645cb3d1d..cd89b1985 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -122,7 +122,7 @@ totest['contents'] = [ Error in "contents" directive options: invalid option value: (option: "local"; value: 'arg') no argument is allowed; "arg" supplied. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. contents:: :local: arg """], @@ -157,7 +157,7 @@ totest['contents'] = [ Error in "contents" directive options: invalid option value: (option: "depth"; value: 'two') invalid literal for int(): two. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. contents:: :depth: two """], @@ -171,7 +171,7 @@ totest['contents'] = [ <paragraph> Error in "contents" directive options: unknown option: "width". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. contents:: :width: 2 """], @@ -186,7 +186,7 @@ totest['contents'] = [ Error in "contents" directive options: invalid option value: (option: "backlinks"; value: 'no way!') "no way!" unknown; choose from "top", "entry", or "none". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. contents:: :backlinks: no way! """], @@ -201,7 +201,7 @@ totest['contents'] = [ Error in "contents" directive options: invalid option value: (option: "backlinks"; value: None) must supply an argument; choose from "top", "entry", or "none". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. contents:: :backlinks: """], diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index cb88ec168..c1994cf88 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -36,7 +36,7 @@ totest['figures'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Image URI contains whitespace. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. figure:: not an image URI """], ["""\ @@ -63,7 +63,7 @@ totest['figures'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Figure caption must be a paragraph or empty comment. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. figure:: picture.png \n\ - A picture with an invalid caption. @@ -78,7 +78,7 @@ totest['figures'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Image URI contains whitespace. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. figure:: not an image URI \n\ And a caption. diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index 1f563020b..db413fb6e 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -35,7 +35,7 @@ totest['images'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Missing image URI argument. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: """], ["""\ @@ -46,7 +46,7 @@ totest['images'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Image URI contains whitespace. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: one two three """], ["""\ @@ -81,7 +81,7 @@ totest['images'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Missing image URI argument. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: :height: 100 :width: 200 @@ -120,7 +120,7 @@ totest['images'] = [ Error in "image" directive options: invalid option data: extension option field body may contain a single paragraph only (option "scale"). - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale: - 50 """], @@ -135,7 +135,7 @@ totest['images'] = [ Error in "image" directive options: invalid option value: (option: "scale"; value: None) object can't be converted to int. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale: """], @@ -149,7 +149,7 @@ totest['images'] = [ <paragraph> Error in "image" directive options: invalid option block. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale 50 """], @@ -162,7 +162,7 @@ totest['images'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Image URI contains whitespace. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png scale: 50 """], @@ -176,7 +176,7 @@ totest['images'] = [ <paragraph> Error in "image" directive options: invalid option block. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :: 50 """], @@ -190,7 +190,7 @@ totest['images'] = [ <paragraph> Error in "image" directive options: unknown option: "sale". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :sale: 50 """], @@ -204,7 +204,7 @@ totest['images'] = [ <paragraph> Error in "image" directive options: invalid option data: extension option field name may not contain multiple words. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale is: 50 """], @@ -219,7 +219,7 @@ totest['images'] = [ Error in "image" directive options: invalid option value: (option: "scale"; value: 'fifty') invalid literal for int(): fifty. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale: fifty """], @@ -234,7 +234,7 @@ totest['images'] = [ <paragraph> Error in "image" directive options: invalid option data: duplicate option "scale". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. image:: picture.png :scale: 50 :scale: 50 diff --git a/test/test_parsers/test_rst/test_directives/test_meta.py b/test/test_parsers/test_rst/test_directives/test_meta.py index 1e92c30b4..758414085 100755 --- a/test/test_parsers/test_rst/test_directives/test_meta.py +++ b/test/test_parsers/test_rst/test_directives/test_meta.py @@ -136,7 +136,7 @@ Paragraph <system_message level="1" line="2" source="test data" type="INFO"> <paragraph> No content for meta tag "empty". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> :empty: """], ["""\ @@ -148,7 +148,7 @@ Paragraph <system_message level="3" line="2" source="test data" type="ERROR"> <paragraph> Invalid meta directive. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. meta:: not a field list """], @@ -170,7 +170,7 @@ Paragraph <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Invalid meta directive. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. meta:: :name: content not a field @@ -184,7 +184,7 @@ Paragraph <system_message level="3" line="2" source="test data" type="ERROR"> <paragraph> Error parsing meta tag attribute "notattval": missing "=". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> :name notattval: content """], ] diff --git a/test/test_parsers/test_rst/test_directives/test_test_directives.py b/test/test_parsers/test_rst/test_directives/test_test_directives.py index 2081e6c1e..e8700e0ce 100755 --- a/test/test_parsers/test_rst/test_directives/test_test_directives.py +++ b/test/test_parsers/test_rst/test_directives/test_test_directives.py @@ -58,7 +58,7 @@ Paragraph. <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> Directive processed. Type="reStructuredText-test-directive", data="", directive block: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Directive block contains one paragraph, with a blank line before. <paragraph> Paragraph. @@ -74,7 +74,7 @@ Paragraph. <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> Directive processed. Type="reStructuredText-test-directive", data="", directive block: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Directive block contains one paragraph, no blank line before. <paragraph> Paragraph. @@ -91,7 +91,7 @@ Paragraph. <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> Directive processed. Type="reStructuredText-test-directive", data="", directive block: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> block <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> diff --git a/test/test_parsers/test_rst/test_directives/test_topics.py b/test/test_parsers/test_rst/test_directives/test_topics.py index 3054ef09d..a3276f01d 100644 --- a/test/test_parsers/test_rst/test_directives/test_topics.py +++ b/test/test_parsers/test_rst/test_directives/test_topics.py @@ -110,7 +110,7 @@ totest['topics'] = [ <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Topics may not be nested within body elements. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. topic:: Nested \n\ Body. @@ -131,7 +131,7 @@ totest['topics'] = [ <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Topics may not be nested within body elements. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. topic:: Nested \n\ Body. @@ -162,7 +162,7 @@ More. <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Topics may not be nested within body elements. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. topic:: \n\ Nested diff --git a/test/test_parsers/test_rst/test_directives/test_unknown.py b/test/test_parsers/test_rst/test_directives/test_unknown.py index db448dec7..1f930a6a1 100755 --- a/test/test_parsers/test_rst/test_directives/test_unknown.py +++ b/test/test_parsers/test_rst/test_directives/test_unknown.py @@ -33,17 +33,17 @@ totest['unknown'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. reStructuredText-unknown-directive:: <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. reStructuredText-unknown-directive:: argument <system_message level="3" line="5" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. reStructuredText-unknown-directive:: block """], diff --git a/test/test_parsers/test_rst/test_doctest_blocks.py b/test/test_parsers/test_rst/test_doctest_blocks.py index 7f5caefae..9e2f07655 100755 --- a/test/test_parsers/test_rst/test_doctest_blocks.py +++ b/test/test_parsers/test_rst/test_doctest_blocks.py @@ -32,7 +32,7 @@ Paragraph. <document source="test data"> <paragraph> Paragraph. - <doctest_block xml:space="1"> + <doctest_block xml:space="preserve"> >>> print "Doctest block." Doctest block. <paragraph> @@ -48,7 +48,7 @@ Paragraph. <document source="test data"> <paragraph> Paragraph. - <doctest_block xml:space="1"> + <doctest_block xml:space="preserve"> >>> print " Indented output." Indented output. """], @@ -63,7 +63,7 @@ Paragraph. <paragraph> Paragraph. <block_quote> - <doctest_block xml:space="1"> + <doctest_block xml:space="preserve"> >>> print " Indented block & output." Indented block & output. """], diff --git a/test/test_parsers/test_rst/test_field_lists.py b/test/test_parsers/test_rst/test_field_lists.py index cf2e3194d..6001d0771 100755 --- a/test/test_parsers/test_rst/test_field_lists.py +++ b/test/test_parsers/test_rst/test_field_lists.py @@ -304,7 +304,7 @@ Multiple body elements: containing multiple elements. <paragraph> Here's a literal block: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> def f(x): return x**2 + x <paragraph> diff --git a/test/test_parsers/test_rst/test_literal_blocks.py b/test/test_parsers/test_rst/test_literal_blocks.py index fd322d796..2fe1c9b88 100755 --- a/test/test_parsers/test_rst/test_literal_blocks.py +++ b/test/test_parsers/test_rst/test_literal_blocks.py @@ -29,7 +29,7 @@ A paragraph:: <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -41,7 +41,7 @@ A paragraph with a space after the colons:: \n\ <document source="test data"> <paragraph> A paragraph with a space after the colons: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -61,11 +61,11 @@ A final paragraph. <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. <paragraph> Another paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Another literal block. With two blank lines following. <paragraph> @@ -84,7 +84,7 @@ one line:: A paragraph on more than one line: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -103,7 +103,7 @@ one line:: <system_message level="3" line="4" source="test data" type="ERROR"> <paragraph> Unexpected indentation. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block with no blank line above. """], @@ -117,7 +117,7 @@ no blank line <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. <system_message level="2" line="4" source="test data" type="WARNING"> <paragraph> @@ -134,7 +134,7 @@ A paragraph: :: <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -148,7 +148,7 @@ A paragraph: <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -165,7 +165,7 @@ A paragraph: Treating it as ordinary text because it's so short. <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -179,7 +179,7 @@ A paragraph: <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A literal block. """], ["""\ @@ -209,7 +209,7 @@ A paragraph:: <document source="test data"> <paragraph> A paragraph: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> A wonky literal block. Literal line 2. \n\ diff --git a/test/test_parsers/test_rst/test_outdenting.py b/test/test_parsers/test_rst/test_outdenting.py index d4daf3b49..e728ebbba 100755 --- a/test/test_parsers/test_rst/test_outdenting.py +++ b/test/test_parsers/test_rst/test_outdenting.py @@ -67,7 +67,7 @@ This paragraph ends the bullet list item before a block quote. <list_item> <paragraph> bullet - <comment xml:space="1"> + <comment xml:space="preserve"> Comments swallow up all indented text following. \n\ (Therefore this is not a) block quote. @@ -78,7 +78,7 @@ This paragraph ends the bullet list item before a block quote. <paragraph> If we want a block quote after this bullet list item, we need to use an empty comment: - <comment xml:space="1"> + <comment xml:space="preserve"> <block_quote> <paragraph> Block quote. diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 385362706..acf5489d8 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -83,7 +83,7 @@ Test unexpected section titles. <system_message level="4" line="4" source="test data" type="SEVERE"> <paragraph> Unexpected section title. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Title ===== <paragraph> @@ -91,12 +91,12 @@ Test unexpected section titles. <system_message level="4" line="7" source="test data" type="SEVERE"> <paragraph> Unexpected section title or transition. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ----- <system_message level="4" line="9" source="test data" type="SEVERE"> <paragraph> Unexpected section title. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Title ----- <paragraph> @@ -116,7 +116,7 @@ Test short underline. <system_message level="2" line="2" source="test data" type="WARNING"> <paragraph> Title underline too short. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Title ==== <paragraph> @@ -161,7 +161,7 @@ Test overline title with inset. <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Incomplete section title. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======================== Test Missing Underline """], @@ -175,7 +175,7 @@ Test overline title with inset. <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Missing underline for overline. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======================== Test Missing Underline """], @@ -190,7 +190,7 @@ Test missing underline, with paragraph. <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Missing underline for overline. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======= Title <paragraph> @@ -211,7 +211,7 @@ Test long title and space normalization. <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Title overline too short. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======= Long Title ======= @@ -230,7 +230,7 @@ Paragraph. <system_message level="4" line="1" source="test data" type="SEVERE"> <paragraph> Title overline & underline mismatch. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======= Title ------- @@ -280,7 +280,7 @@ Test missing titles; nothing in-between. <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Invalid section title or transition marker. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======================== ======================== <paragraph> @@ -288,7 +288,7 @@ Test missing titles; nothing in-between. <system_message level="3" line="6" source="test data" type="ERROR"> <paragraph> Invalid section title or transition marker. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======================== ======================== """], @@ -313,7 +313,7 @@ Paragraph 4. """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> Test return to existing, highest-level section (Title 3). <section id="title-1" name="title 1"> <title> @@ -469,7 +469,7 @@ Paragraph 4. <system_message level="4" line="15" source="test data" type="SEVERE"> <paragraph> Title level inconsistent: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Title 4 ``````` <paragraph> @@ -520,7 +520,7 @@ Paragraph 4. <system_message level="4" line="19" source="test data" type="SEVERE"> <paragraph> Title level inconsistent: - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ``````` Title 4 ``````` @@ -819,7 +819,7 @@ Yo """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> <system_message level="2" line="2" source="test data" type="WARNING"> <paragraph> Explicit markup ends without a blank line; unexpected unindent. diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 9d6acc757..d6e129cb4 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -146,27 +146,27 @@ No blank line after. <system_message level="2" line="6" source="test data" type="WARNING"> <paragraph> Substitution definition "empty" missing contents. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. |empty| <system_message level="3" line="8" source="test data" type="ERROR"> <paragraph> Unknown directive type "directive". - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> directive:: symbol.png <system_message level="2" line="8" source="test data" type="WARNING"> <paragraph> Substitution definition "unknown" empty or invalid. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. |unknown| directive:: symbol.png <system_message level="2" line="10" source="test data" type="WARNING"> <paragraph> Substitution definition "invalid 1" empty or invalid. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. |invalid 1| there's no directive here <system_message level="2" line="11" source="test data" type="WARNING"> <paragraph> Substitution definition "invalid 2" empty or invalid. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. |invalid 2| there's no directive here With some block quote text, line 1. And some more, line 2. @@ -180,9 +180,9 @@ No blank line after. <system_message level="2" line="15" source="test data" type="WARNING"> <paragraph> Substitution definition "invalid 3" empty or invalid. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. |invalid 3| there's no directive here - <comment xml:space="1"> + <comment xml:space="preserve"> | bad name | bad data """], ] diff --git a/test/test_parsers/test_rst/test_tables.py b/test/test_parsers/test_rst/test_tables.py index e26aec960..c188a4214 100755 --- a/test/test_parsers/test_rst/test_tables.py +++ b/test/test_parsers/test_rst/test_tables.py @@ -64,7 +64,7 @@ totest['full_tables'] = [ <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Malformed table. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> +-----------------------+ | A malformed table. | +-----------------------+ @@ -497,7 +497,7 @@ No blank line after table. <paragraph> Malformed table. Malformed table; parse incomplete. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> +--------------+-------------+ | A bad table. | | +--------------+ | @@ -728,7 +728,7 @@ no bottom border <paragraph> Malformed table. No bottom table border found. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ============== ====== A simple table with no bottom border @@ -746,7 +746,7 @@ No blank line after table. <paragraph> Malformed table. No bottom table border found or no blank line after table bottom. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ============== ====== A simple table cell 2 cell 3 cell 4 @@ -806,7 +806,7 @@ cell 3 cell 4 <paragraph> Malformed table. No bottom table border found or no blank line after table bottom. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ============== ====== A simple table cell 2 cell 3 cell 4 @@ -830,7 +830,7 @@ cell 3 cell 4 <paragraph> Malformed table. Column span alignment problem at line offset 2. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ============== ====== A bad table cell 2 cell 3 cell 4 @@ -848,7 +848,7 @@ cell 3 cell 4 <paragraph> Malformed table. Text in column margin at line offset 1. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======== ========= A bad table cell 2 cell 3 cell 4 @@ -973,7 +973,7 @@ cell 3 the bottom border below is too long <paragraph> Malformed table. Bottom/header table border does not match top border. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ============== ====== A simple table this text extends to the right cell 3 the bottom border below is too long diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index e37ecfda1..b56962f96 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -82,17 +82,17 @@ Indirect hyperlink targets: <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. _target1: Not a proper hyperlink target <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. _target2: Although it ends with an underscore, this is not a phrase-link_ <system_message level="2" line="5" source="test data" type="WARNING"> <paragraph> Hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. _target3: A multi-line verson of something ending with an underscore, but not a phrase-link_ """], @@ -109,17 +109,17 @@ __ A multi-line verson of something <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> .. __: Not a proper hyperlink target <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Anonymous hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> __ Although it ends with an underscore, this is not a phrase-link_ <system_message level="2" line="5" source="test data" type="WARNING"> <paragraph> Anonymous hyperlink target contains whitespace. Perhaps a footnote was intended? - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> __ A multi-line verson of something ending with an underscore, but not a phrase-link_ """], diff --git a/test/test_parsers/test_rst/test_transitions.py b/test/test_parsers/test_rst/test_transitions.py index cbbec169f..ca7aee5f4 100755 --- a/test/test_parsers/test_rst/test_transitions.py +++ b/test/test_parsers/test_rst/test_transitions.py @@ -132,7 +132,7 @@ Test unexpected transition markers. <system_message level="4" line="5" source="test data" type="SEVERE"> <paragraph> Unexpected section title or transition. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> -------- <paragraph> Paragraph. diff --git a/test/test_readers/test_pep/test_rfc2822.py b/test/test_readers/test_pep/test_rfc2822.py index 332008218..974d2c54b 100644 --- a/test/test_readers/test_pep/test_rfc2822.py +++ b/test/test_readers/test_pep/test_rfc2822.py @@ -77,7 +77,7 @@ Date: 2002-04-23 <field_body> <paragraph> 2002-04-23 - <comment xml:space="1"> + <comment xml:space="preserve"> Leading blank lines don't affect RFC-2822 header parsing. """], ["""\ @@ -89,7 +89,7 @@ Date: 2002-04-23 """, """\ <document source="test data"> - <comment xml:space="1"> + <comment xml:space="preserve"> A comment should prevent RFC-2822 header parsing. <paragraph> Author: Me diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index e5637d14c..0ecd6e2cb 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -59,7 +59,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ There can only be one abstract. <paragraph> It is automatically moved to the end of the other bibliographic elements. - <comment xml:space="1"> + <comment xml:space="preserve"> Bibliographic element extraction. """], ["""\ @@ -80,7 +80,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <docinfo> <author> Me - <address xml:space="1"> + <address xml:space="preserve"> 123 My Street Example, EX <contact> @@ -110,7 +110,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ Abstract <paragraph> Abstract 1. - <comment xml:space="1"> + <comment xml:space="preserve"> Bibliographic element extraction. """], ["""\ @@ -160,7 +160,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <system_message level="2" source="test data" type="WARNING"> <paragraph> Cannot extract empty bibliographic field "Version". - <comment xml:space="1"> + <comment xml:space="preserve"> and not empty either """], ["""\ @@ -320,7 +320,7 @@ derived (hacked) in parallel in order to stay in sync. test_docinfo.py <date> %s - <comment xml:space="1"> + <comment xml:space="preserve"> RCS keyword extraction. <paragraph> RCS keyword 'RCSfile' doesn't change unless the file name changes, diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 83e92810a..583f79508 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -36,7 +36,7 @@ Paragraph. <document id="title" name="title" source="test data"> <title> Title - <comment xml:space="1"> + <comment xml:space="preserve"> test title promotion <paragraph> Paragraph. @@ -102,7 +102,7 @@ Test short underline. <system_message level="2" line="2" source="test data" type="WARNING"> <paragraph> Title underline too short. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> Title ==== <paragraph> @@ -124,7 +124,7 @@ The system_message should move after the document title <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Title overline too short. - <literal_block xml:space="1"> + <literal_block xml:space="preserve"> ======= Long Title ======= @@ -152,7 +152,7 @@ Paragraph 3. <document id="title-1" name="title 1" source="test data"> <title> Title 1 - <comment xml:space="1"> + <comment xml:space="preserve"> Test multiple second-level titles. <paragraph> Paragraph 1. -- cgit v1.2.1 From 1aa202a450e403c6451909598132d1bf4a2cb162 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:15:39 +0000 Subject: Added support for improved diagnostics. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@712 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 13 ++++++------- docutils/utils.py | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 9fb829b6e..1903fcd35 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger; Ueli Schlaepfer +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger; Ueli Schlaepfer -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This package contains Docutils Reader modules. """ @@ -78,6 +76,7 @@ class Reader(Component): document.reporter.attach_observer(document.note_parse_message) self.parser.parse(self.input, document) document.reporter.detach_observer(document.note_parse_message) + document.current_source = document.current_line = None def transform(self): """Run all of the transforms defined for this Reader.""" diff --git a/docutils/utils.py b/docutils/utils.py index edeb26109..c48dc4e20 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Miscellaneous utilities for the documentation utilities. """ @@ -375,6 +373,7 @@ def new_document(source, options=None): reporter = Reporter(source, options.report_level, options.halt_level, options.warning_stream, options.debug) document = nodes.document(options, reporter, source=source) + document.note_source(source) return document def clean_rcs_keywords(paragraph, keyword_substitutions): -- cgit v1.2.1 From 0b1d625e609900031ac30d765b607e5aedb2f9b6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:16:32 +0000 Subject: Added XML and doctype declarations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@713 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/docutils_xml.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 698908b27..21dd4a0d4 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -13,6 +13,7 @@ Simple internal document tree Writer, writes Docutils XML. __docformat__ = 'reStructuredText' +import docutils from docutils import writers @@ -33,11 +34,25 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" + xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' + #xml_stylesheet = '<?xml-stylesheet type="text/xsl" href="%s"?>\n' + doctype = ( + '<!DOCTYPE document PUBLIC' + ' "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML"' + ' SYSTEM "http://docutils.sourceforge.net/spec/docutils.dtd">\n') + generator = '<!-- Generated by Docutils %s -->\n' + def translate(self): + options = self.document.options indent = newline = '' - if self.document.options.newlines: + if options.newlines: newline = '\n' - if self.document.options.indents: + if options.indents: newline = '\n' indent = ' ' - self.output = self.document.asdom().toprettyxml(indent, newline) + output_prefix = [self.xml_declaration % options.output_encoding, + self.doctype, + self.generator % docutils.__version__] + docnode = self.document.asdom().childNodes[0] + self.output = (''.join(output_prefix) + + docnode.toprettyxml(indent, newline)) -- cgit v1.2.1 From 6b624cc273300380e802d70677249d754fe6365d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 24 Sep 2002 02:18:31 +0000 Subject: Added Docutils version to "generator" meta tag. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@714 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 +++++---- docutils/writers/pep_html.py | 14 +++++++------- tools/pep-html-template | 2 +- tools/pep2html.py | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ff020d85c..9bbd81e15 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -20,6 +20,7 @@ import sys import time import re from types import ListType +import docutils from docutils import nodes, utils, writers, languages @@ -138,9 +139,9 @@ class HTMLTranslator(nodes.NodeVisitor): 'xhtml1-transitional.dtd">\n' html_head = '<html lang="%s">\n<head>\n' content_type = '<meta http-equiv="Content-Type" content="text/html; ' \ - 'charset=%s">\n' - generator = '<meta name="generator" content="Docutils: ' \ - 'http://docutils.sourceforge.net/">\n' + 'charset=%s" />\n' + generator = '<meta name="generator" content="Docutils %s: ' \ + 'http://docutils.sourceforge.net/" />\n' stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' embedded_stylesheet = '<style type="text/css"><!--\n\n%s\n--></style>\n' named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, @@ -156,7 +157,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.doctype, self.html_head % options.language_code, self.content_type % options.output_encoding, - self.generator] + self.generator % docutils.__version__] self.head = [] stylesheet = self.get_stylesheet_reference() if options.embed_stylesheet: diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 1f1a432f2..a883fecd1 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - PEP HTML Writer. """ @@ -14,6 +12,7 @@ __docformat__ = 'reStructuredText' import sys +import docutils from docutils import nodes, optik, utils from docutils.writers import html4css1 @@ -63,6 +62,7 @@ class Writer(html4css1.Writer): # Substitutions dict for template: subs = {} subs['encoding'] = options.output_encoding + subs['version'] = docutils.__version__ subs['stylesheet'] = ''.join(self.stylesheet) pyhome = options.python_home subs['pyhome'] = pyhome diff --git a/tools/pep-html-template b/tools/pep-html-template index 58280a544..49f367bf8 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -3,7 +3,7 @@ <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s"> - <meta name="generator" content="Docutils: http://docutils.sourceforge.net/"> + <meta name="generator" content="Docutils %(version)s: http://docutils.sourceforge.net/"> <title>PEP %(pep)s -- %(title)s %(stylesheet)s diff --git a/tools/pep2html.py b/tools/pep2html.py index ecc3de363..c0a4fc31d 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -41,7 +41,7 @@ import random import time REQUIRES = {'python': '2.2', - 'docutils': '0.2.3'} + 'docutils': '0.2.4'} PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' -- cgit v1.2.1 From 794964358a1bb001f592d7e7c8b77559fe9ad24f Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 24 Sep 2002 02:21:48 +0000 Subject: Changed public identifier to docutils.sf.net. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@715 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/pysource.dtd | 4 ++-- docs/ref/docutils.dtd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/pysource.dtd b/docs/dev/pysource.dtd index bb61fb2ff..02d754358 100644 --- a/docs/dev/pysource.dtd +++ b/docs/dev/pysource.dtd @@ -16,9 +16,9 @@ More information about this DTD and the Docutils project can be found at http://docutils.sourceforge.net/. The latest version of this DTD is available from http://docutils.sourceforge.net/spec/pysource.dtd. -The proposed formal public identifier for this DTD is:: +The formal public identifier for this DTD is:: - +//IDN python.org//DTD Docutils Python Source//EN//XML + +//IDN docutils.sourceforge.net//DTD Docutils Python Source//EN//XML --> @@ -439,9 +439,9 @@ either the string separating it from the `option` (typically either %basic.atts; uri CDATA #REQUIRED alt CDATA #IMPLIED - height &number; #IMPLIED - width &number; #IMPLIED - scale &number; #IMPLIED> + height %number; #IMPLIED + width %number; #IMPLIED + scale %number; #IMPLIED> @@ -459,8 +459,8 @@ Table elements: table, tgroup, colspec, thead, tbody, row, entry. -- cgit v1.2.1 From 3873a3c91b0f82c9af3f321ee134a9dfd21e00d1 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 25 Sep 2002 03:02:13 +0000 Subject: fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@719 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/docutils_xml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 21dd4a0d4..e005c7861 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -39,7 +39,7 @@ class Writer(writers.Writer): doctype = ( '\n') + ' "http://docutils.sourceforge.net/spec/docutils.dtd">\n') generator = '\n' def translate(self): -- cgit v1.2.1 From 2570dd555418b4a1402dc828a5a6f5a158ea29fe Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 25 Sep 2002 03:03:05 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@720 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 2 +- docs/dev/todo.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 9774d6f4c..1cf10f0c6 100644 --- a/README.txt +++ b/README.txt @@ -5,7 +5,7 @@ :Author: David Goodger :Contact: goodger@users.sourceforge.net :Date: $Date$ -:Web-site: http://docutils.sourceforge.net/ +:Web site: http://docutils.sourceforge.net/ Thank you for downloading the Python Docutils project archive. As this is a work in progress, please check the project website for diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 3c3d81ff6..a9436ce4c 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -563,6 +563,10 @@ Directives "local" concept comes in. This part of the implementation can be left for later. + - _`parts.contents`: Add a "suppress" or "prune" option? It would + suppress contents display for sections in a branch from that point + down. Or a new directive, like "prune-contents"? + - Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The directive name itself could be the same as the -- cgit v1.2.1 From 94712189fa21bb13cf4d85953f65216079339dc6 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 26 Sep 2002 02:02:29 +0000 Subject: (cosmetic) changed "-" bullets to "*". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@722 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 176 +++++++++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a9436ce4c..85f3323c8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -25,7 +25,7 @@ you'd like to tackle, please do! Bugs ---- -- The "contents" directive now automatically names the "topic" +* The "contents" directive now automatically names the "topic" produced (using its title), so that it can be referred to by name. However, this naming happens late in the game, after most references have been resolved. So the following indirect target produces a @@ -40,7 +40,7 @@ Bugs Idea: two-pass hyperlink resolution, ignoring errors on the first pass? -- The parser doesn't know anything about double-width characters such +* The parser doesn't know anything about double-width characters such as Chinese hanza & Japanese kanji/kana. Also, it's dependent on whitespace and punctuation as markup delimiters, which may not be applicable in these languages. @@ -49,7 +49,7 @@ Bugs General ------- -- Refactor +* Refactor - Rename methods & variables according to the `coding conventions`_ below. @@ -58,28 +58,28 @@ General checked for correctness and refactored. I'm afraid it's a bit of a spaghetti mess now. -- Add validation? See http://pytrex.sourceforge.net, RELAX NG. +* Add validation? See http://pytrex.sourceforge.net, RELAX NG. -- Ask Python-dev for opinions (GvR for a pronouncement) on special +* Ask Python-dev for opinions (GvR for a pronouncement) on special variables (__author__, __version__, etc.): convenience vs. namespace pollution. Ask opinions on whether or not Docutils should recognize & use them. -- In reader.get_reader_class (& parser & writer too), should we be +* In reader.get_reader_class (& parser & writer too), should we be importing "standalone" or "docutils.readers.standalone"? (This would avoid importing top-level modules if the module name is not in docutils/readers. Potential nastiness.) -- Perhaps store a name-to-id mapping file? This could be stored +* Perhaps store a name-to-id mapping file? This could be stored permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) -- Need a Unicode to HTML entities codec for HTML writer? +* Need a Unicode to HTML entities codec for HTML writer? -- Perhaps the ``Component.supports`` method should deal with +* Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -- @@@ Transforms need a priority system. The "first reader" ... +* @@@ Transforms need a priority system. The "first reader" ... "last writer" system is no longer adequate for pending transforms. For example, the ``references.TargetNotes`` transform needs to run after ``references.Hyperlinks.resolve_indirect()`` but before @@ -97,14 +97,14 @@ General No, that would require too many imports to construct. Document transform priorities. -- @@@ Break up ``references.Hyperlinks`` into multiple smaller +* @@@ Break up ``references.Hyperlinks`` into multiple smaller transforms. -- Make it easier to say, "Here's a reStructuredText string; give me +* Make it easier to say, "Here's a reStructuredText string; give me HTML." Maybe ``core.publish_string()``; rename ``core.publish`` to ``core.publish_file()``? -- @@@@ All system messages should have a "line" attribute, to improve +* @@@@ All system messages should have a "line" attribute, to improve diagnostic output. So all elements constructed by the parser should have internal "line" ("lineno"/"line_number") attributes. They'd need internal "source" attributes as well (populating the external @@ -136,7 +136,7 @@ General copied over to the node. Consolidate all assignments (parent, document, source, line) into a single method. -- @@@ Change stderr Reporter output to the GNU utilities format:: +* @@@ Change stderr Reporter output to the GNU utilities format:: file:line: message @@ -150,10 +150,10 @@ General switched to slashes? In any case, the ubiquity of the GNU utilities probably outweighs any such problem. -- Standalone Reader: Implement an option to turn off the DocTitle +* Standalone Reader: Implement an option to turn off the DocTitle transform? -- Add /usr/etc/docutils.conf to config file list? System-wide, +* Add /usr/etc/docutils.conf to config file list? System-wide, whereas /etc/docutils.conf is machine-specific. /usr/local/etc/docutils.conf too? See the `Filesystem Hierarchy Standard`_. @@ -164,34 +164,34 @@ General Documentation ------------- -- User docs. +* User docs. Implementation Docs ``````````````````` -- Internal module documentation (docstrings). +* Internal module documentation (docstrings). -- spec/doctree.txt: DTD element structural relationships, semantics, +* spec/doctree.txt: DTD element structural relationships, semantics, and attributes. -- How a Writer works & how to write one +* How a Writer works & how to write one -- Howto: Transforms +* Howto: Transforms -- Howto: Directives +* Howto: Directives -- Document the ``pending`` elements, how they're generated and when +* Document the ``pending`` elements, how they're generated and when they're triggered ("first reader", "last writer", etc.). -- Document the transforms (perhaps in docstrings?): how they're used, +* Document the transforms (perhaps in docstrings?): how they're used, what they do, dependencies & order considerations. Specification ````````````` -- Complete PEP 258 Docutils Design Specification. +* Complete PEP 258 Docutils Design Specification. - Fill in the blanks in API details. @@ -201,7 +201,7 @@ Specification there on how it all hangs together - the DTD is not enough (indeed, is it still meant to be correct? [Yes, it is.]). -- Rework PEP 257, separating style from spec from tools, wrt Docutils? +* Rework PEP 257, separating style from spec from tools, wrt Docutils? See Doc-SIG from 2001-06-19/20. @@ -210,15 +210,15 @@ PySource Reader General: -- Analyze Tony Ibbs' PySource code. +* Analyze Tony Ibbs' PySource code. -- Analyze Doug Hellmann's HappyDoc project. +* Analyze Doug Hellmann's HappyDoc project. -- Take the best ideas and integrate them into Docutils 0.3. +* Take the best ideas and integrate them into Docutils 0.3. Miscellaneous ideas: -- If we can detect that a comment block begins with ``##``, a la +* If we can detect that a comment block begins with ``##``, a la JavaDoc, it might be useful to indicate interspersed section headers & explanatory text in a module. For example:: @@ -239,7 +239,7 @@ Miscellaneous ideas: # etc. -- HappyDoc's idea of using comment blocks when there's no docstring +* HappyDoc's idea of using comment blocks when there's no docstring may be useful to get around the conflict between `additional docstrings`_ and ``from __future__ import`` for module docstrings. A module could begin like this:: @@ -260,9 +260,9 @@ Miscellaneous ideas: .. _additional docstrings: pep-0258.html#additional-docstrings -- Multi-file output should be divisible at arbitrary level. +* Multi-file output should be divisible at arbitrary level. -- Support all forms of ``import`` statements: +* Support all forms of ``import`` statements: - ``import module``: listed as "module" - ``import module as alias``: "alias (module)" @@ -279,22 +279,22 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do -- Clean up the code; refactor as required. +* Clean up the code; refactor as required. -- Add motivation sections for constructs in spec. +* Add motivation sections for constructs in spec. -- Allow very long titles (on two or more lines)? +* Allow very long titles (on two or more lines)? -- And for the sake of completeness, should definition list terms be +* And for the sake of completeness, should definition list terms be allowed to be very long (two or more lines) also? -- Support generic hyperlink references to targets in other documents? +* Support generic hyperlink references to targets in other documents? Not in an HTML-centric way, though (it's trivial to say ``http://www.example.com/doc#name``, and useless in non-HTML contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. -- Add _`character processing`? For example: +* Add _`character processing`? For example: - ``--`` to em-dash (or ``--`` to en-dash, and ``---`` to em-dash). (Look for pre-existing conventions.) @@ -313,31 +313,31 @@ __ rst/alternatives.html#or-not-to-do Which component is responsible for this, the parser, the reader, or the writer? -- Implement the header row separator modification to table.el. (Wrote +* Implement the header row separator modification to table.el. (Wrote to Takaaki Ota & the table.el mailing list on 2001-08-12, suggesting support for "=====" header rows. On 2001-08-17 he replied, saying he'd put it on his to-do list, but "don't hold your breath".) -- Tony says inline markup rule 7 could do with a *little* more +* Tony says inline markup rule 7 could do with a *little* more exposition in the spec, to make clear what is going on for people with head colds. -- Alan Jaffray suggested (and I agree) that it would be sensible to: +* Alan Jaffray suggested (and I agree) that it would be sensible to: - have a directive to specify a default role for interpreted text - allow the reST processor to take an argument for the default role - issue a warning when processing documents with no default role which contain interpreted text with no explicitly specified role -- Perhaps the default implicit role for interpreted text could be +* Perhaps the default implicit role for interpreted text could be "title", as in, "title of a book". It'd be a text-only reference, no hyperlink. Idea from Aahz' 2002-05-09 Doc-SIG post. -- @@ Fix the parser's indentation handling to conform with the +* @@ Fix the parser's indentation handling to conform with the stricter definition in the spec. (Explicit markup blocks should be strict or forgiving?) -- @@ Tighten up the spec for indentation of "constructs using complex +* @@ Tighten up the spec for indentation of "constructs using complex markers": field lists and option lists? Bodies may begin on the same line as the marker or on a subsequent line (with blank lines optional). Require that for bodies beginning on the same line as @@ -367,7 +367,7 @@ __ rst/alternatives.html#or-not-to-do the left edge of the first line if it began on the same line as the field name. -- Allow for variant styles by interpreting indented lists as if they +* Allow for variant styles by interpreting indented lists as if they weren't indented? For example, currently the list below will be parsed as a list within a block quote:: @@ -392,13 +392,13 @@ __ rst/alternatives.html#or-not-to-do See the Doc-SIG discussion starting 2001-04-18 with Ed Loper's "Structuring: a summary; and an attempt at EBNF", item 4. -- Make the parser modular. Allow syntax constructs to be added or +* Make the parser modular. Allow syntax constructs to be added or disabled at run-time. Or is subclassing enough? -- Continue to report (info, level 1) enumerated lists whose start +* Continue to report (info, level 1) enumerated lists whose start value is not ordinal-1? -- Generalize the "doctest block" construct (which is overly +* Generalize the "doctest block" construct (which is overly Python-centric) to other interactive sessions? "Doctest block" could be renamed to "I/O block" or "interactive block", and each of these could also be recognized as such by the parser: @@ -424,7 +424,7 @@ __ rst/alternatives.html#or-not-to-do Tony Ibbs spoke out against this idea (2002-06-14 Doc-SIG thread "docutils feedback"). -- Generalize the "literal block" construct to allow blocks with a +* Generalize the "literal block" construct to allow blocks with a per-line quoting to avoid indentation? For example, in this email reply quoting the original, the block quoted with "``>``" (and prefaced by "``::``") would be treated as a literal block:: @@ -441,7 +441,7 @@ __ rst/alternatives.html#or-not-to-do first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. -- @@@ Decide whether or not to implement Simon Budig's "inline +* @@@ Decide whether or not to implement Simon Budig's "inline external targets" syntax idea, and if so, how? - As a regular directive affecting its indented text block:: @@ -471,13 +471,13 @@ __ rst/alternatives.html#or-not-to-do - Or as a full-blown addition to the spec & parser. -- Add support for pragma (syntax-altering) directives. +* Add support for pragma (syntax-altering) directives. -- Remove leading numbers from section titles for implicit link names? +* Remove leading numbers from section titles for implicit link names? A section titled "3. Conclusion" could then be referred to by "``Conclusion_``" (i.e., without the "3."). -- Syntax for the "line-block" directive? How about a +* Syntax for the "line-block" directive? How about a literal-block-like prefix, perhaps "``;;``"? (It is, after all, a *semi-literal* literal block, no?) Example:: @@ -509,7 +509,7 @@ __ rst/alternatives.html#or-not-to-do (And arguably invalid, since in Japanese the word "haiku" contains three syllables.) -- Modify acceptable "simple reference name" syntax to allow for +* Modify acceptable "simple reference name" syntax to allow for ``object.__method__`` without requiring inline literals? Simple reference names currently allow any of "-", "_", and "." internally; if we limit this to one at a time, problem solved. I.e., none of @@ -520,11 +520,11 @@ __ rst/alternatives.html#or-not-to-do Directives `````````` -- Allow directives to be added at run-time? +* Allow directives to be added at run-time? -- Use the language module for directive attribute names? +* Use the language module for directive attribute names? -- Implement attributes on existing directives: +* Implement attributes on existing directives: - _`images.image`: "align", "border"? @@ -567,7 +567,7 @@ Directives suppress contents display for sections in a branch from that point down. Or a new directive, like "prune-contents"? -- Implement directives. Each of the list items below begins with an +* Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The directive name itself could be the same as the directive_function_name, or it could differ. @@ -797,9 +797,9 @@ Reference Merging When merging two or more subdocuments (such as docstrings), conflicting references may need to be resolved. There may be: -- duplicate reference and/or substitution names that need to be made +* duplicate reference and/or substitution names that need to be made unique; and/or -- duplicate footnote numbers that need to be renumbered. +* duplicate footnote numbers that need to be renumbered. Should this be done before or after reference-resolving transforms are applied? What about references from within one subdocument to @@ -846,19 +846,19 @@ Index HTML Writer ----------- -- @@ Construct a _`templating system`, as in ht2html/yaptu, using +* @@ Construct a _`templating system`, as in ht2html/yaptu, using directives and substitutions for dynamic stuff. -- Add more support for elements, especially for navigation +* Add more support for elements, especially for navigation bars. -- ```` tags should be XML empty tags: ````. +* ```` tags should be XML empty tags: ````. Front-End Tools --------------- -- What about if we don't know which Reader and/or Writer we are +* What about if we don't know which Reader and/or Writer we are going to use? If the Reader/Writer is specified on the command-line? (Will this ever happen?) @@ -895,12 +895,12 @@ Front-End Tools conflicts) to splitting common and component-specific options apart. -- Parameterize help text & defaults somehow? Perhaps a callback? Or +* Parameterize help text & defaults somehow? Perhaps a callback? Or initialize ``cmdline_options`` in ``__init__`` or ``init_options``? -- Disable common options that don't apply? +* Disable common options that don't apply? -- Implement the "sectnum" directive as a command-line option also? +* Implement the "sectnum" directive as a command-line option also? Project Policies @@ -955,19 +955,19 @@ specified in the `Style Guide for Python Code`_ and `Docstring Conventions`_ PEPs, with the following clarifications (from most to least important): -- 4 spaces per indentation level. No tabs. Indent continuation lines +* 4 spaces per indentation level. No tabs. Indent continuation lines according to the Emacs python-mode standard. -- No one-liner compound statements (i.e., no ``if x: return``: use two +* No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is O.K.). -- Lines should be no more than 78 characters long. +* Lines should be no more than 78 characters long. -- Use "StudlyCaps" for class names (except for element classes in +* Use "StudlyCaps" for class names (except for element classes in docutils.nodes). -- Use "lowercase" or "lowercase_with_underscores" for function, +* Use "lowercase" or "lowercase_with_underscores" for function, method, and variable names. For short names, maximum two words, joined lowercase may be used (e.g. "tagname"). For long names with three or more words, or where it's hard to parse the split between @@ -975,7 +975,7 @@ least important): "note_explicit_target", "explicit_target"). If in doubt, use underscores. -- Use 'single quotes' for string literals, and """triple double +* Use 'single quotes' for string literals, and """triple double quotes""" for docstrings. .. _Style Guide for Python Code: @@ -996,10 +996,10 @@ well. Any new files contributed to the project should clearly state their intentions regarding copyright, in one of the following ways: -- Public domain (preferred): include the statement "This +* Public domain (preferred): include the statement "This module/document has been placed in the public domain." -- Copyright & open source license: include a copyright notice, along +* Copyright & open source license: include a copyright notice, along with either an embedded license statement, a reference to an accompanying license file, or a license URL. @@ -1025,24 +1025,24 @@ in a stable state (usable and as problem-free as possible). The Docutils project shall follow the `Python Check-in Policies`_ (as applicable), with particular emphasis as follows: -- Before checking in any changes, run the entire Docutils test suite +* Before checking in any changes, run the entire Docutils test suite to be sure that you haven't broken anything. From a shell:: cd docutils/test alltests.py -- When adding new functionality (or fixing bugs), be sure to add test +* When adding new functionality (or fixing bugs), be sure to add test cases to the test suite. Practise test-first programming; it's fun, it's addictive, and it works! -- The `sandbox CVS directory`_ is the place to put new, incomplete or +* The `sandbox CVS directory`_ is the place to put new, incomplete or experimental code. See `Additions to Docutils`_ and `The Sandbox`_ below. -- For bugs or omissions that have an obvious fix and can't possibly +* For bugs or omissions that have an obvious fix and can't possibly mess up anything else, go right ahead and check it in directly. -- For larger changes, use your best judgement. If you're unsure of +* For larger changes, use your best judgement. If you're unsure of the impact, or feel that you require advice or approval, patches or `the sandbox`_ are the way to go. @@ -1068,19 +1068,19 @@ usable_, and `reasonably complete`_. Adding to the `main source tree`_ or to a `parallel project`_ implies a commitment to the Docutils user community. -- Why the sandbox? +* Why the sandbox? Developers should be able to try out new components while they're being developed for addition to main source tree. See `The Sandbox`_ below. -- _`Good shape` means that the component code is clean, readable, and +* _`Good shape` means that the component code is clean, readable, and free of junk code (unused legacy code; by analogy with "junk DNA"). -- _`Usable` means that the code does what it claims to do. An "XYZ +* _`Usable` means that the code does what it claims to do. An "XYZ Writer" should produce reasonable XYZ. -- _`Reasonably complete` means that the code must handle all input. +* _`Reasonably complete` means that the code must handle all input. Here "handle" means that no input can cause the code to fail (cause an exception, or silently and incorrectly produce nothing). "Reasonably complete" does not mean "finished" (no work left to be @@ -1103,12 +1103,12 @@ Mailing Lists Developers should subscribe to the mailing lists: -- The `Python Documentation Special Interest Group (Doc-SIG) mailing +* The `Python Documentation Special Interest Group (Doc-SIG) mailing list`__ for high-level discussions on syntax, strategy, and design (email to Doc-SIG@python.org). -- Docutils-develop__, for implementation discussions +* Docutils-develop__, for implementation discussions (email to docutils-develop@lists.sourceforge.net). -- Docutils-checkins__, to monitor CVS checkin messages (automatically +* Docutils-checkins__, to monitor CVS checkin messages (automatically generated; normally read-only). __ http://mail.python.org/mailman/listinfo/doc-sig -- cgit v1.2.1 From cac2218319dcef955484715559292526f574ff29 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 2 Oct 2002 03:09:55 +0000 Subject: added to project git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@740 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/include1.txt | 4 + .../test_rst/test_directives/include2.txt | 5 + .../test_parsers/test_rst/test_directives/raw1.txt | 1 + .../test_rst/test_directives/test_include.py | 129 ++++++++++++++++++++ .../test_rst/test_directives/test_raw.py | 84 +++++++++++++ .../test_rst/test_directives/test_replace.py | 135 +++++++++++++++++++++ 6 files changed, 358 insertions(+) create mode 100644 test/test_parsers/test_rst/test_directives/include1.txt create mode 100644 test/test_parsers/test_rst/test_directives/include2.txt create mode 100644 test/test_parsers/test_rst/test_directives/raw1.txt create mode 100755 test/test_parsers/test_rst/test_directives/test_include.py create mode 100755 test/test_parsers/test_rst/test_directives/test_raw.py create mode 100755 test/test_parsers/test_rst/test_directives/test_replace.py diff --git a/test/test_parsers/test_rst/test_directives/include1.txt b/test/test_parsers/test_rst/test_directives/include1.txt new file mode 100644 index 000000000..82f605320 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/include1.txt @@ -0,0 +1,4 @@ +Inclusion 1 +----------- + +This file is used by ``test_include.py``. diff --git a/test/test_parsers/test_rst/test_directives/include2.txt b/test/test_parsers/test_rst/test_directives/include2.txt new file mode 100644 index 000000000..c4121c52c --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/include2.txt @@ -0,0 +1,5 @@ +Here are some paragraphs +that can appear at any level. + +This file is used by +``test_include.py``. diff --git a/test/test_parsers/test_rst/test_directives/raw1.txt b/test/test_parsers/test_rst/test_directives/raw1.txt new file mode 100644 index 000000000..7ea03651b --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/raw1.txt @@ -0,0 +1 @@ +

    This file is used by test_raw.py.

    diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py new file mode 100755 index 000000000..cad84c7e0 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -0,0 +1,129 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for misc.py "include" directive. +""" + +import os.path +from __init__ import DocutilsTestSupport + + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +mydir = os.path.dirname(suite.func_code.co_filename) +include1 = os.path.join(mydir, 'include1.txt') +include2 = os.path.join(mydir, 'include2.txt') + +totest = {} + +totest['include'] = [ +["""\ +Include Test +============ + +.. include:: %s + +A paragraph. +""" % include1, +"""\ + +
    + + Include Test + <section id="inclusion-1" name="inclusion 1"> + <title> + Inclusion 1 + <paragraph> + This file is used by \n\ + <literal> + test_include.py + . + <paragraph> + A paragraph. +"""], +["""\ +Include Test +============ + +.. include:: %s + :literal: + +A paragraph. +""" % include1, +"""\ +<document source="test data"> + <section id="include-test" name="include test"> + <title> + Include Test + <literal_block source="%s" xml:space="preserve"> + Inclusion 1 + ----------- + \n\ + This file is used by ``test_include.py``. + <paragraph> + A paragraph. +""" % include1], +["""\ +Let's test the parse context. + + This paragraph is in a block quote. + + .. include:: %s + +The included paragraphs should also be in the block quote. +""" % include2, +"""\ +<document source="test data"> + <paragraph> + Let's test the parse context. + <block_quote> + <paragraph> + This paragraph is in a block quote. + <paragraph> + Here are some paragraphs + that can appear at any level. + <paragraph> + This file is used by \n\ + <literal> + test_include.py + . + <paragraph> + The included paragraphs should also be in the block quote. +"""], +["""\ +Include Test +============ + +.. include:: nonexistent.txt + +A paragraph. +""", +"""\ +<document source="test data"> + <section id="include-test" name="include test"> + <title> + Include Test + <system_message level="4" line="4" source="test data" type="SEVERE"> + <paragraph> + Problems with "include" directive path: + [Errno 2] No such file or directory: 'nonexistent.txt'. + <literal_block xml:space="preserve"> + .. include:: nonexistent.txt + <paragraph> + A paragraph. +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_directives/test_raw.py b/test/test_parsers/test_rst/test_directives/test_raw.py new file mode 100755 index 000000000..54f3892d0 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_raw.py @@ -0,0 +1,84 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for misc.py "raw" directive. +""" + +import os.path +from __init__ import DocutilsTestSupport + + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +mydir = os.path.dirname(suite.func_code.co_filename) +raw1 = os.path.join(mydir, 'raw1.txt') + +totest = {} + +totest['raw'] = [ +["""\ +.. raw:: html + + <span>This is some plain old raw text.</span> +""", +"""\ +<document source="test data"> + <raw format="html" xml:space="preserve"> + <span>This is some plain old raw text.</span> +"""], +["""\ +.. raw:: html + :file: %s +""" % raw1, +"""\ +<document source="test data"> + <raw format="html" source="%s" xml:space="preserve"> + <p>This file is used by <tt>test_raw.py</tt>.</p> +""" % raw1], +["""\ +.. raw:: html + :file: rawfile.html + :url: http://example.org/ +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + The "file" and "url" options may not be simultaneously specified for the "raw" directive. + <literal_block xml:space="preserve"> + .. raw:: html + :file: rawfile.html + :url: http://example.org/ +"""], +["""\ +.. raw:: html + :file: rawfile.html + + <p>Can't have both content and file attribute.</p> +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + "raw" directive may not both specify an external file and have content. + <literal_block xml:space="preserve"> + .. raw:: html + :file: rawfile.html + + <p>Can't have both content and file attribute.</p> +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_parsers/test_rst/test_directives/test_replace.py b/test/test_parsers/test_rst/test_directives/test_replace.py new file mode 100755 index 000000000..52a1c2321 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_replace.py @@ -0,0 +1,135 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for misc.py "replace" directive. +""" + +from __init__ import DocutilsTestSupport + + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['replace'] = [ +["""\ +Test the |name| directive. + +.. |name| replace:: "**replace**" +""", +"""\ +<document source="test data"> + <paragraph> + Test the \n\ + <substitution_reference refname="name"> + name + directive. + <substitution_definition name="name"> + " + <strong> + replace + " +"""], +["""\ +.. |name| replace:: paragraph 1 + + paragraph 2 +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "replace" directive: may contain a single paragraph only. + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Substitution definition "name" empty or invalid. + <literal_block xml:space="preserve"> + .. |name| replace:: paragraph 1 + + paragraph 2 +"""], +["""\ +.. |name| replace:: +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + The "replace" directive is empty; content required. + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Substitution definition "name" empty or invalid. + <literal_block xml:space="preserve"> + .. |name| replace:: +"""], +["""\ +.. |Python| replace:: Python, *the* best language around + +.. _Python: http://www.python.org/ + +I recommend you try |Python|_. +""", +"""\ +<document source="test data"> + <substitution_definition name="python"> + Python, + <emphasis> + the + best language around + <target id="python" name="python" refuri="http://www.python.org/"> + <paragraph> + I recommend you try + <reference refname="python"> + <substitution_reference refname="python"> + Python + . +"""], +["""\ +.. |name| replace:: *error in **inline ``markup +""", +"""\ +<document source="test data"> + <system_message id="id1" level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Inline emphasis start-string without end-string. + <system_message id="id3" level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Inline strong start-string without end-string. + <system_message id="id5" level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Inline literal start-string without end-string. + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "replace" directive: may contain a single paragraph only. + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Substitution definition "name" empty or invalid. + <literal_block xml:space="preserve"> + .. |name| replace:: *error in **inline ``markup +"""], +["""\ +.. replace:: not valid outside of a substitution definition +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Invalid context: the "replace" directive can only be used within a substitution definition. + <literal_block xml:space="preserve"> + .. replace:: not valid outside of a substitution definition +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 35e6041e605bdf30c29b55a99f2e97648ab4f4cd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:12:39 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@741 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/test_admonitions.py | 23 +++-- .../test_rst/test_directives/test_contents.py | 26 +++--- .../test_rst/test_directives/test_figures.py | 12 +-- .../test_rst/test_directives/test_images.py | 38 ++++---- .../test_rst/test_directives/test_meta.py | 53 +++++++++-- .../test_directives/test_test_directives.py | 103 ++++++++++++++++++--- .../test_rst/test_directives/test_topics.py | 80 +++++++++------- .../test_rst/test_directives/test_unknown.py | 12 +-- test/test_parsers/test_rst/test_substitutions.py | 26 ++++++ 9 files changed, 266 insertions(+), 107 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_admonitions.py b/test/test_parsers/test_rst/test_directives/test_admonitions.py index 7e319d5dd..a0b894659 100755 --- a/test/test_parsers/test_rst/test_directives/test_admonitions.py +++ b/test/test_parsers/test_rst/test_directives/test_admonitions.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for admonitions.py directives. """ @@ -109,6 +109,17 @@ totest['admonitions'] = [ <paragraph> No blank lines in-between. """], +["""\ +.. note:: +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + The "note" admonition is empty; content required. + <literal_block xml:space="preserve"> + .. note:: +"""], ] diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index cd89b1985..fbd7c517c 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for parts.py contents directive. """ @@ -75,7 +75,9 @@ totest['contents'] = [ .details: title: <title> - Table of Contents + Table + of + Contents """], ["""\ .. contents:: *Table* of ``Contents`` @@ -119,7 +121,7 @@ totest['contents'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "contents" directive options: + Error in "contents" directive: invalid option value: (option: "local"; value: 'arg') no argument is allowed; "arg" supplied. <literal_block xml:space="preserve"> @@ -154,7 +156,7 @@ totest['contents'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "contents" directive options: + Error in "contents" directive: invalid option value: (option: "depth"; value: 'two') invalid literal for int(): two. <literal_block xml:space="preserve"> @@ -169,7 +171,7 @@ totest['contents'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "contents" directive options: + Error in "contents" directive: unknown option: "width". <literal_block xml:space="preserve"> .. contents:: @@ -183,7 +185,7 @@ totest['contents'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "contents" directive options: + Error in "contents" directive: invalid option value: (option: "backlinks"; value: 'no way!') "no way!" unknown; choose from "top", "entry", or "none". <literal_block xml:space="preserve"> @@ -198,7 +200,7 @@ totest['contents'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "contents" directive options: + Error in "contents" directive: invalid option value: (option: "backlinks"; value: None) must supply an argument; choose from "top", "entry", or "none". <literal_block xml:space="preserve"> diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index c1994cf88..e19c555c8 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for images.py figure directives. """ diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index db413fb6e..1c05774af 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for images.py image directives. """ @@ -34,7 +34,8 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Missing image URI argument. + Error in "image" directive: + 1 argument(s) required, 0 supplied. <literal_block xml:space="preserve"> .. image:: """], @@ -80,7 +81,8 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Missing image URI argument. + Error in "image" directive: + 1 argument(s) required, 0 supplied. <literal_block xml:space="preserve"> .. image:: :height: 100 @@ -117,9 +119,9 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: - invalid option data: extension option field body may contain - a single paragraph only (option "scale"). + Error in "image" directive: + invalid option value: (option: "scale"; value: '- 50') + negative value; must be positive or zero. <literal_block xml:space="preserve"> .. image:: picture.png :scale: - 50 @@ -132,7 +134,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option value: (option: "scale"; value: None) object can't be converted to int. <literal_block xml:space="preserve"> @@ -147,7 +149,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option block. <literal_block xml:space="preserve"> .. image:: picture.png @@ -174,7 +176,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option block. <literal_block xml:space="preserve"> .. image:: picture.png @@ -188,7 +190,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: unknown option: "sale". <literal_block xml:space="preserve"> .. image:: picture.png @@ -202,7 +204,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option data: extension option field name may not contain multiple words. <literal_block xml:space="preserve"> .. image:: picture.png @@ -216,7 +218,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option value: (option: "scale"; value: 'fifty') invalid literal for int(): fifty. <literal_block xml:space="preserve"> @@ -232,7 +234,7 @@ totest['images'] = [ <document source="test data"> <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Error in "image" directive options: + Error in "image" directive: invalid option data: duplicate option "scale". <literal_block xml:space="preserve"> .. image:: picture.png diff --git a/test/test_parsers/test_rst/test_directives/test_meta.py b/test/test_parsers/test_rst/test_directives/test_meta.py index 758414085..9e2e29232 100755 --- a/test/test_parsers/test_rst/test_directives/test_meta.py +++ b/test/test_parsers/test_rst/test_directives/test_meta.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for html.py meta directives. """ @@ -126,6 +126,8 @@ Paragraph <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Empty meta directive. + <literal_block xml:space="preserve"> + .. meta:: """], ["""\ .. meta:: @@ -145,7 +147,7 @@ Paragraph """, """\ <document source="test data"> - <system_message level="3" line="2" source="test data" type="ERROR"> + <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Invalid meta directive. <literal_block xml:space="preserve"> @@ -156,6 +158,32 @@ Paragraph .. meta:: :name: content not a field + :name: content +""", +"""\ +<document source="test data"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="content" name="name"> + writer: 'html' + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Invalid meta directive. + <literal_block xml:space="preserve"> + .. meta:: + :name: content + not a field + :name: content +"""], +["""\ +.. meta:: + :name: content + :name: content + not a field """, """\ <document source="test data"> @@ -167,11 +195,20 @@ Paragraph nodes: <meta content="content" name="name"> writer: 'html' - <system_message level="3" line="3" source="test data" type="ERROR"> + <pending> + .. internal attributes: + .transform: docutils.transforms.components.Filter + .stage: 'first writer' + .details: + nodes: + <meta content="content" name="name"> + writer: 'html' + <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Invalid meta directive. <literal_block xml:space="preserve"> .. meta:: + :name: content :name: content not a field """], diff --git a/test/test_parsers/test_rst/test_directives/test_test_directives.py b/test/test_parsers/test_rst/test_directives/test_test_directives.py index e8700e0ce..2e15793e9 100755 --- a/test/test_parsers/test_rst/test_directives/test_test_directives.py +++ b/test/test_parsers/test_rst/test_directives/test_test_directives.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for misc.py test directives. """ @@ -29,7 +29,7 @@ Paragraph. <document source="test data"> <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> - Directive processed. Type="reStructuredText-test-directive", data="", directive block: None + Directive processed. Type="reStructuredText-test-directive", arguments=[], options={}, content: None <paragraph> Paragraph. """], @@ -42,7 +42,51 @@ Paragraph. <document source="test data"> <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> - Directive processed. Type="reStructuredText-test-directive", data="argument", directive block: None + Directive processed. Type="reStructuredText-test-directive", arguments=['argument'], options={}, content: None + <paragraph> + Paragraph. +"""], +["""\ +.. reStructuredText-test-directive:: argument + :option: value + +Paragraph. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Directive processed. Type="reStructuredText-test-directive", arguments=['argument'], options={'option': 'value'}, content: None + <paragraph> + Paragraph. +"""], +["""\ +.. reStructuredText-test-directive:: :option: value + +Paragraph. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Directive processed. Type="reStructuredText-test-directive", arguments=[], options={'option': 'value'}, content: None + <paragraph> + Paragraph. +"""], +["""\ +.. reStructuredText-test-directive:: :option: + +Paragraph. +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "reStructuredText-test-directive" directive: + invalid option value: (option: "option"; value: None) + argument required but none supplied. + <literal_block xml:space="preserve"> + .. reStructuredText-test-directive:: :option: <paragraph> Paragraph. """], @@ -57,7 +101,7 @@ Paragraph. <document source="test data"> <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> - Directive processed. Type="reStructuredText-test-directive", data="", directive block: + Directive processed. Type="reStructuredText-test-directive", arguments=[], options={}, content: <literal_block xml:space="preserve"> Directive block contains one paragraph, with a blank line before. <paragraph> @@ -65,7 +109,9 @@ Paragraph. """], ["""\ .. reStructuredText-test-directive:: - Directive block contains one paragraph, no blank line before. + + + Directive block contains one paragraph, with two blank lines before. Paragraph. """, @@ -73,9 +119,23 @@ Paragraph. <document source="test data"> <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> - Directive processed. Type="reStructuredText-test-directive", data="", directive block: + Directive processed. Type="reStructuredText-test-directive", arguments=[], options={}, content: <literal_block xml:space="preserve"> - Directive block contains one paragraph, no blank line before. + Directive block contains one paragraph, with two blank lines before. + <paragraph> + Paragraph. +"""], +["""\ +.. reStructuredText-test-directive:: + Directive block contains one paragraph, no blank line before. + +Paragraph. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Directive processed. Type="reStructuredText-test-directive", arguments=['Directive block contains one paragraph, no blank line before.'], options={}, content: None <paragraph> Paragraph. """], @@ -90,9 +150,7 @@ Paragraph. <document source="test data"> <system_message level="1" line="1" source="test data" type="INFO"> <paragraph> - Directive processed. Type="reStructuredText-test-directive", data="", directive block: - <literal_block xml:space="preserve"> - block + Directive processed. Type="reStructuredText-test-directive", arguments=['block'], options={}, content: None <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Explicit markup ends without a blank line; unexpected unindent. @@ -101,6 +159,21 @@ Paragraph. <paragraph> Paragraph. """], +["""\ +.. reStructuredText-test-directive:: argument + :option: * value1 + * value2 + +Paragraph. +""", +"""\ +<document source="test data"> + <system_message level="1" line="1" source="test data" type="INFO"> + <paragraph> + Directive processed. Type="reStructuredText-test-directive", arguments=['argument'], options={'option': '* value1\\n* value2'}, content: None + <paragraph> + Paragraph. +"""], ] diff --git a/test/test_parsers/test_rst/test_directives/test_topics.py b/test/test_parsers/test_rst/test_directives/test_topics.py index a3276f01d..e549f2824 100644 --- a/test/test_parsers/test_rst/test_directives/test_topics.py +++ b/test/test_parsers/test_rst/test_directives/test_topics.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for the "topic" directive. """ @@ -25,15 +25,23 @@ totest['topics'] = [ """, """\ <document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "topic" directive: + 1 argument(s) required, 0 supplied. + <literal_block xml:space="preserve"> + .. topic:: """], ["""\ .. topic:: Title """, """\ <document source="test data"> - <topic> - <title> - Title + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Content block expected for the "topic" directive; none found. + <literal_block xml:space="preserve"> + .. topic:: Title """], ["""\ .. topic:: Title @@ -57,11 +65,16 @@ totest['topics'] = [ """, """\ <document source="test data"> - <topic> - <title> - Title + <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Body. + Error in "topic" directive: + 1 argument(s) required, 0 supplied. + <literal_block xml:space="preserve"> + .. topic:: + \n\ + Title + \n\ + Body. """], ["""\ .. topic:: Title @@ -69,14 +82,12 @@ totest['topics'] = [ """, """\ <document source="test data"> - <topic> - <title> - Title - <system_message level="2" line="2" source="test data" type="WARNING"> - <paragraph> - The second line of a topic block must be blank. + <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> - Body. + Content block expected for the "topic" directive; none found. + <literal_block xml:space="preserve"> + .. topic:: Title + Body. """], ["""\ .. topic:: @@ -86,14 +97,15 @@ totest['topics'] = [ """, """\ <document source="test data"> - <topic> - <title> - Title - <system_message level="2" line="4" source="test data" type="WARNING"> - <paragraph> - The second line of a topic block must be blank. + <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> - Body. + Error in "topic" directive: + 1 argument(s) required, 0 supplied. + <literal_block xml:space="preserve"> + .. topic:: + \n\ + Title + Body. """], ["""\ .. topic:: Title @@ -109,7 +121,7 @@ totest['topics'] = [ Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - Topics may not be nested within body elements. + Topics may not be nested within topics or body elements. <literal_block xml:space="preserve"> .. topic:: Nested \n\ @@ -130,7 +142,7 @@ totest['topics'] = [ Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - Topics may not be nested within body elements. + Topics may not be nested within topics or body elements. <literal_block xml:space="preserve"> .. topic:: Nested \n\ @@ -144,9 +156,7 @@ totest['topics'] = [ ["""\ .. topic:: Title - .. topic:: - - Nested + .. topic:: Nested Body. @@ -161,11 +171,9 @@ More. Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - Topics may not be nested within body elements. + Topics may not be nested within topics or body elements. <literal_block xml:space="preserve"> - .. topic:: - \n\ - Nested + .. topic:: Nested \n\ Body. <paragraph> diff --git a/test/test_parsers/test_rst/test_directives/test_unknown.py b/test/test_parsers/test_rst/test_directives/test_unknown.py index 1f930a6a1..fa73541ef 100755 --- a/test/test_parsers/test_rst/test_directives/test_unknown.py +++ b/test/test_parsers/test_rst/test_directives/test_unknown.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for unknown directives. """ diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index d6e129cb4..3fb695201 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -75,12 +75,37 @@ Here's a series of substitution definitions: <image alt="very long substitution text, split across lines" uri="symbol.png"> """], ["""\ +.. |symbol 1| image:: symbol.png + + Followed by a block quote. +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "image" directive: + no content permitted.. + <literal_block xml:space="preserve"> + image:: symbol.png + \n\ + Followed by a block quote. + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Substitution definition "symbol 1" empty or invalid. + <literal_block xml:space="preserve"> + .. |symbol 1| image:: symbol.png + \n\ + Followed by a block quote. +"""], +["""\ .. |symbol 1| image:: symbol.png Followed by a paragraph. .. |symbol 2| image:: symbol.png +.. + Followed by a block quote. """, """\ @@ -91,6 +116,7 @@ Followed by a paragraph. Followed by a paragraph. <substitution_definition name="symbol 2"> <image alt="symbol 2" uri="symbol.png"> + <comment xml:space="preserve"> <block_quote> <paragraph> Followed by a block quote. -- cgit v1.2.1 From 6e26d36491f9f2c7ac4790d64ccf28d9a3de92b7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:13:24 +0000 Subject: Added ``path()`` and ``nonnegative_int()`` directive option helper functions. Updated docstring. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@742 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 140 ++++++++++++++++++++++------ 1 file changed, 110 insertions(+), 30 deletions(-) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 9cdde6d31..58175040f 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -1,39 +1,79 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This package contains directive implementation modules. The interface for directive functions is as follows:: - def directivefn(match, type_name, data, state, state_machine, - option_presets): + def directive_fn(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + code... + + # Set function attributes: + directive_fn.arguments = ... + directive_fn.options = ... + direcitve_fn.content = ... + +Parameters: + +- ``name`` is the directive type or name. + +- ``arguments`` is a list of positional arguments. + +- ``options`` is a dictionary mapping option names to values. + +- ``content`` is a list of strings, the directive content. + +- ``lineno`` is the line number of the first line of the directive. -Where: +- ``content_offset`` is the line offset of the first line of the content from + the beginning of the current input. Used when initiating a nested parse. + +- ``block_text`` is a string containing the entire directive. Include it as + the content of a literal block in a system message if there is a problem. -- ``match`` is a regular expression match object which matched the first line - of the directive. ``match.group(1)`` gives the directive name. -- ``type_name`` is the directive type or name. -- ``data`` contains the remainder of the first line of the directive after the - "::". - ``state`` is the state which called the directive function. + - ``state_machine`` is the state machine which controls the state which called the directive function. -- ``option_presets`` is a dictionary of preset options which may be added to - the element the directive produces. Currently, only an "alt" option is - passed by substitution definitions (value: the substitution name), which may - be used by an embedded image directive. -Directive functions return a tuple of two values: +Function attributes, interpreted by the directive parser (which calls the +directive function): + +- ``arguments``: A 3-tuple specifying the expected positional arguments, or + ``None`` if the directive has no arguments. The 3 items in the tuple are + ``(required, optional, whitespace OK in last argument)``: + + 1. The number of required arguments. + 2. The number of optional arguments. + 3. A boolean, indicating if the final argument may contain whitespace. + + Arguments are normally single whitespace-separated words. The final + argument may contain whitespace if the third item in the argument spec tuple + is 1/True. If the form of the arguments is more complex, specify only one + argument (either required or optional) and indicate that final whitespace is + OK; the client code must do any context-sensitive parsing. + +- ``options``: A dictionary, mapping known option names to conversion + functions such as `int` or `float`. ``None`` or an empty dict implies no + options to parse. + +- ``content``: A boolean; true if content is allowed. Client code must handle + the case where content is required but not supplied (an empty content list + will be supplied). + +Directive functions return a list of nodes which will be inserted into the +document tree at the point where the directive was encountered (can be an +empty list). -- a list of nodes which will be inserted into the document tree at the point - where the directive was encountered (can be an empty list), and -- a boolean: true iff the directive block finished at a blank line. +See `Creating reStructuredText Directives`_ for more information. + +.. _Creating reStructuredText Directives: + http://docutils.sourceforge.net/spec/howto/rst-directives.html """ __docformat__ = 'reStructuredText' @@ -64,11 +104,13 @@ _directive_registry = { 'target-notes': ('references', 'target_notes'), 'meta': ('html', 'meta'), #'imagemap': ('html', 'imagemap'), - #'raw': ('misc', 'raw'), + 'raw': ('misc', 'raw'), + 'include': ('misc', 'include'), + 'replace': ('misc', 'replace'), 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} -"""Mapping of directive name to (module name, function name). The directive -'name' is canonical & must be lowercase; language-dependent names are defined -in the language package.""" +"""Mapping of directive name to (module name, function name). The directive +name is canonical & must be lowercase. Language-dependent names are defined +in the ``language`` subpackage.""" _modules = {} """Cache of imported directive modules.""" @@ -111,13 +153,51 @@ def directive(directive_name, language_module): return function def flag(argument): + """ + Check for a valid flag option (no argument) and return ``None``. + + Raise ``ValueError`` if an argument is found. + """ if argument and argument.strip(): raise ValueError('no argument is allowed; "%s" supplied' % argument) else: return None def unchanged(argument): - return argument # unchanged! + """ + Return the argument, unchanged. + + Raise ``ValueError`` if no argument is found. + """ + if argument is None: + raise ValueError('argument required but none supplied') + else: + return argument # unchanged! + +def path(argument): + """ + Return the path argument unwrapped (with newlines removed). + + Raise ``ValueError`` if no argument is found or if the path contains + internal whitespace. + """ + if argument is None: + raise ValueError('argument required but none supplied') + else: + path = ''.join([s.strip() for s in argument.splitlines()]) + if path.find(' ') == -1: + return path + else: + raise ValueError('path contains whitespace') + +def nonnegative_int(argument): + """ + Check for a nonnegative integer argument; raise ``ValueError`` if not. + """ + value = int(argument) + if value < 0: + raise ValueError('negative value; must be positive or zero') + return value def format_values(values): return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]), @@ -127,8 +207,8 @@ def choice(argument, values): try: value = argument.lower().strip() except AttributeError: - raise TypeError('must supply an argument; choose from %s' - % format_values(values)) + raise ValueError('must supply an argument; choose from %s' + % format_values(values)) if value in values: return value else: -- cgit v1.2.1 From a93ae74d425bb3a12c671949a57a92cc83ec6dce Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:14:48 +0000 Subject: Added "include", "raw", and "replace" directives, courtesy of Dethe Elza. Updated all directive functions to new API, including better reporting. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@743 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 170 ++++++++++++++++++++++++++++---- 1 file changed, 150 insertions(+), 20 deletions(-) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 25e0a6467..484422bec 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -1,4 +1,4 @@ -# Author: David Goodger +# Authors: David Goodger, Dethe Elza # Contact: goodger@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ @@ -8,30 +8,160 @@ __docformat__ = 'reStructuredText' +import sys +from urllib2 import urlopen, URLError +from docutils import nodes, statemachine +from docutils.parsers.rst import directives, states -from docutils import nodes +def include(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Include a reST file as part of the content of this reST file.""" + path = ''.join(arguments[0].splitlines()) + if path.find(' ') != -1: + error = state_machine.reporter.error( + '"%s" directive path contains whitespace.' % name, '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + try: + include_file = open(path) + except IOError, error: + severe = state_machine.reporter.severe( + 'Problems with "%s" directive path:\n%s.' % (name, error), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] + include_text = include_file.read() + include_file.close() + if options.has_key('literal'): + literal_block = nodes.literal_block(include_text, include_text, + source=path) + literal_block.line = 1 + return literal_block + else: + include_lines = statemachine.string2lines(include_text, + convert_whitespace=1) + current_source = state.document.current_source + state.document.note_source(path) + state.memo.reporter.source = path + state.nested_parse(include_lines, 0, node=state_machine.node, + match_titles=state_machine.match_titles) + state.document.note_source(current_source) + state.memo.reporter.source = current_source + return [] -def raw(match, type_name, data, state, state_machine, option_presets): - return [], 1 +include.arguments = (1, 0, 1) +include.options = {'literal': directives.flag} -def directive_test_function(match, type_name, data, state, state_machine, - option_presets): - lineno = state_machine.abs_line_number() - try: - state_machine.next_line() - indented, indent, offset, blank_finish = state_machine.get_indented() - text = '\n'.join(indented) - except EOFError: - text = '' - blank_finish = 1 +def raw(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """ + Pass through content unchanged + + Content is included in output based on type argument + + Content may be included inline (content section of directive) or + imported from a file or url. + """ + attributes = {'format': arguments[0]} + if content: + if options.has_key('file') or options.has_key('url'): + error = state_machine.reporter.error( + '"%s" directive may not both specify an external file and ' + 'have content.' % name, '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + text = '\n'.join(content) + elif options.has_key('file'): + if options.has_key('url'): + error = state_machine.reporter.error( + 'The "file" and "url" options may not be simultaneously ' + 'specified for the "%s" directive.' % name, '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + try: + raw_file = open(options['file']) + except IOError, error: + severe = state_machine.reporter.severe( + 'Problems with "%s" directive path:\n%s.' % (name, error), + '', nodes.literal_block(block_text, block_text), + line=lineno) + return [severe] + text = raw_file.read() + raw_file.close() + attributes['source'] = options['file'] + elif options.has_key('url'): + try: + raw_file = urlopen(options['url']) + except (URLError, IOError, OSError), error: + severe = state_machine.reporter.severe( + 'Problems with "%s" directive URL "%s":\n%s.' + % (name, options['url'], error), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [severe] + text = raw_file.read() + raw_file.close() + attributes['source'] = options['file'] + else: + error = state_machine.reporter.warning( + 'The "%s" directive requires content; none supplied.' % (name), + '', nodes.literal_block(block_text, block_text), line=lineno) + return [error] + raw_node = nodes.raw('', text, **attributes) + return [raw_node] + +raw.arguments = (1, 0, 1) +raw.options = {'file': directives.path, + 'url': directives.path} +raw.content = 1 + +def replace(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not isinstance(state, states.SubstitutionDef): + error = state_machine.reporter.error( + 'Invalid context: the "%s" directive can only be used within a ' + 'substitution definition.' % (name), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + text = '\n'.join(content) + element = nodes.Element(text) if text: + state.nested_parse(content, content_offset, element) + if len(element) != 1 or not isinstance(element[0], nodes.paragraph): + messages = [] + for node in element: + if isinstance(node, nodes.system_message): + if node.has_key('backrefs'): + del node['backrefs'] + messages.append(node) + error = state_machine.reporter.error( + 'Error in "%s" directive: may contain a single paragraph ' + 'only.' % (name), line=lineno) + messages.append(error) + return messages + else: + return element[0].children + else: + error = state_machine.reporter.error( + 'The "%s" directive is empty; content required.' % (name), + line=lineno) + return [error] + +replace.content = 1 + +def directive_test_function(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if content: + text = '\n'.join(content) info = state_machine.reporter.info( - 'Directive processed. Type="%s", data="%s", directive block:' - % (type_name, data), '', nodes.literal_block(text, text), - line=lineno) + 'Directive processed. Type="%s", arguments=%r, options=%r, ' + 'content:' % (name, arguments, options), '', + nodes.literal_block(text, text), line=lineno) else: info = state_machine.reporter.info( - 'Directive processed. Type="%s", data="%s", directive block: ' - 'None' % (type_name, data), line=lineno) - return [info], blank_finish + 'Directive processed. Type="%s", arguments=%r, options=%r, ' + 'content: None' % (name, arguments, options), line=lineno) + return [info] + +directive_test_function.arguments = (0, 1, 1) +directive_test_function.options = {'option': directives.unchanged} +directive_test_function.content = 1 -- cgit v1.2.1 From 7b12a12a016617200529e8b611ad2f2a866ad7f9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:17:43 +0000 Subject: Updated all directive functions to new API, including better reporting. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@744 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/admonitions.py | 83 ++++++++++------- docutils/parsers/rst/directives/body.py | 89 ++++++++---------- docutils/parsers/rst/directives/html.py | 55 ++++++----- docutils/parsers/rst/directives/images.py | 121 +++++++++---------------- docutils/parsers/rst/directives/parts.py | 87 +++++------------- docutils/parsers/rst/directives/references.py | 23 ++--- 6 files changed, 193 insertions(+), 265 deletions(-) diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index e1506610f..000dd4708 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Admonition directives. """ @@ -17,39 +15,60 @@ from docutils.parsers.rst import states from docutils import nodes -def admonition(node_class, match, type_name, data, state, state_machine, - option_presets): - indented, indent, line_offset, blank_finish \ - = state_machine.get_first_known_indented(match.end()) - text = '\n'.join(indented) +def admonition(node_class, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + text = '\n'.join(content) admonition_node = node_class(text) if text: - state.nested_parse(indented, line_offset, admonition_node) - return [admonition_node], blank_finish + state.nested_parse(content, content_offset, admonition_node) + return [admonition_node] + else: + error = state_machine.reporter.error( + 'The "%s" admonition is empty; content required.' % (name), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + +def attention(*args): + return admonition(nodes.attention, *args) + +attention.content = 1 + +def caution(*args): + return admonition(nodes.caution, *args) + +caution.content = 1 + +def danger(*args): + return admonition(nodes.danger, *args) + +danger.content = 1 + +def error(*args): + return admonition(nodes.error, *args) + +error.content = 1 + +def important(*args): + return admonition(nodes.important, *args) -def attention(*args, **kwargs): - return admonition(nodes.attention, *args, **kwargs) +important.content = 1 -def caution(*args, **kwargs): - return admonition(nodes.caution, *args, **kwargs) +def note(*args): + return admonition(nodes.note, *args) -def danger(*args, **kwargs): - return admonition(nodes.danger, *args, **kwargs) +note.content = 1 -def error(*args, **kwargs): - return admonition(nodes.error, *args, **kwargs) +def tip(*args): + return admonition(nodes.tip, *args) -def important(*args, **kwargs): - return admonition(nodes.important, *args, **kwargs) +tip.content = 1 -def note(*args, **kwargs): - return admonition(nodes.note, *args, **kwargs) +def hint(*args): + return admonition(nodes.hint, *args) -def tip(*args, **kwargs): - return admonition(nodes.tip, *args, **kwargs) +hint.content = 1 -def hint(*args, **kwargs): - return admonition(nodes.hint, *args, **kwargs) +def warning(*args): + return admonition(nodes.warning, *args) -def warning(*args, **kwargs): - return admonition(nodes.warning, *args, **kwargs) +warning.content = 1 diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 7d74e7a2b..55be7e36f 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Directives for additional body elements. """ @@ -17,57 +15,50 @@ import sys from docutils import nodes -def topic(match, type_name, data, state, state_machine, option_presets): - lineno = state_machine.abs_line_number() - initial_offset = state_machine.line_offset - indented, indent, line_offset, blank_finish \ - = state_machine.get_first_known_indented(match.end()) - blocktext = '\n'.join(state_machine.input_lines[ - initial_offset : line_offset + len(indented) - 1]) +def topic(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): if not state_machine.match_titles: error = state_machine.reporter.error( - 'Topics may not be nested within body elements.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error], blank_finish - if not indented: - return [], blank_finish - title_text = indented.pop(0) + 'Topics may not be nested within topics or body elements.', '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + if not content: + warning = state_machine.reporter.warning( + 'Content block expected for the "%s" directive; none found.' + % name, '', nodes.literal_block(block_text, block_text), + line=lineno) + return [warning] + title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) title = nodes.title(title_text, '', *textnodes) - if indented: - if indented[0].strip(): - warning = state_machine.reporter.warning( - 'The second line of a topic block must be blank.', - line=lineno + 1 + line_offset - initial_offset) - messages.append(warning) - text = '\n'.join(indented) - else: - text = '' + text = '\n'.join(content) topic_node = nodes.topic(text, title, *messages) if text: - state.nested_parse(indented, line_offset + 1, topic_node) - return [topic_node], blank_finish + state.nested_parse(content, content_offset, topic_node) + return [topic_node] +topic.arguments = (1, 0, 1) +topic.content = 1 -def line_block(match, type_name, data, state, state_machine, option_presets, +def line_block(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine, node_class=nodes.line_block): - lineno = state_machine.abs_line_number() - indented, indent, line_offset, blank_finish \ - = state_machine.get_first_known_indented(match.end()) - while indented and not indented[-1].strip(): - indented.pop() - if not indented: + if not content: warning = state_machine.reporter.warning( - 'Text block expected for the "%s" directive; none found.' - % type_name, line=lineno) - return [warning], blank_finish - text = '\n'.join(indented) - textnodes, messages = state.inline_text(text, lineno) - node = node_class(text, '', *textnodes) - return [node] + messages, blank_finish + 'Content block expected for the "%s" directive; none found.' + % name, nodes.literal_block(block_text, block_text), line=lineno) + return [warning] + text = '\n'.join(content) + text_nodes, messages = state.inline_text(text, lineno) + node = node_class(text, '', *text_nodes) + return [node] + messages + +line_block.content = 1 +def parsed_literal(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + return line_block(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine, + node_class=nodes.literal_block) -def parsed_literal(match, type_name, data, state, state_machine, - option_presets): - return line_block(match, type_name, data, state, state_machine, - option_presets, node_class=nodes.literal_block) +parsed_literal.content = 1 diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index 732ef7b56..560554d49 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -1,49 +1,46 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Directives for typically HTML-specific constructs. """ __docformat__ = 'reStructuredText' - +import sys from docutils import nodes, utils from docutils.parsers.rst import states from docutils.transforms import components -def meta(match, type_name, data, state, state_machine, option_presets): - line_offset = state_machine.line_offset - block, indent, offset, blank_finish = \ - state_machine.get_first_known_indented(match.end(), until_blank=1) +def meta(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): node = nodes.Element() - if block: + if content: new_line_offset, blank_finish = state.nested_list_parse( - block, offset, node, initial_state='MetaBody', - blank_finish=blank_finish, state_machine_kwargs=metaSMkwargs) - if (new_line_offset - offset) != len(block): + content, content_offset, node, initial_state='MetaBody', + blank_finish=1, state_machine_kwargs=metaSMkwargs) + if (new_line_offset - content_offset) != len(content): # incomplete parse of block? - blocktext = '\n'.join(state_machine.input_lines[ - line_offset : state_machine.line_offset+1]) - msg = state_machine.reporter.error( - 'Invalid meta directive.', '', - nodes.literal_block(blocktext, blocktext), - line=state_machine.abs_line_number()) - node += msg + error = state_machine.reporter.error( + 'Invalid meta directive.', '', + nodes.literal_block(block_text, block_text), line=lineno) + node += error else: - msg = state_machine.reporter.error( - 'Empty meta directive.', line=state_machine.abs_line_number()) - node += msg - return node.get_children(), blank_finish + error = state_machine.reporter.error( + 'Empty meta directive.', '', + nodes.literal_block(block_text, block_text), line=lineno) + node += error + return node.get_children() + +meta.content = 1 -def imagemap(match, type_name, data, state, state_machine, option_presets): - return [], 0 +def imagemap(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + return [] class MetaBody(states.SpecializedBody): diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index bb997bc58..1617947ba 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Directives for figures and simple images. """ @@ -23,81 +21,50 @@ align_values = ('top', 'middle', 'bottom', 'left', 'center', 'right') def align(argument): return directives.choice(argument, align_values) -image_option_spec = {'alt': directives.unchanged, - 'height': int, - 'width': int, - 'scale': int, - 'align': align} - -def image(match, type_name, data, state, state_machine, option_presets): - lineno = state_machine.abs_line_number() - line_offset = state_machine.line_offset - datablock, indent, offset, blank_finish = \ - state_machine.get_first_known_indented(match.end(), until_blank=1) - blocktext = '\n'.join(state_machine.input_lines[ - line_offset : line_offset + len(datablock) + 1]) - for i in range(len(datablock)): - if datablock[i][:1] == ':': - attlines = datablock[i:] - datablock = datablock[:i] - break - else: - attlines = [] - if not datablock: - error = state_machine.reporter.error( - 'Missing image URI argument.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error], blank_finish - attoffset = line_offset + i - reference = ''.join([line.strip() for line in datablock]) +def image(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + reference = ''.join(arguments[0].split('\n')) if reference.find(' ') != -1: error = state_machine.reporter.error( 'Image URI contains whitespace.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error], blank_finish - if attlines: - success, data, blank_finish = state.parse_extension_options( - image_option_spec, attlines, blank_finish) - if success: # data is a dict of options - option_presets.update(data) - else: # data is an error string - error = state_machine.reporter.error( - 'Error in "%s" directive options:\n%s.' - % (match.group(1), data), '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error], blank_finish - option_presets['uri'] = reference - imagenode = nodes.image(blocktext, **option_presets) - return [imagenode], blank_finish + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + options['uri'] = reference + image_node = nodes.image(block_text, **options) + return [image_node] + +image.arguments = (1, 0, 1) +image.options = {'alt': directives.unchanged, + 'height': directives.nonnegative_int, + 'width': directives.nonnegative_int, + 'scale': directives.nonnegative_int, + 'align': align} -def figure(match, type_name, data, state, state_machine, option_presets): - lineno = state_machine.abs_line_number() - line_offset = state_machine.line_offset - (imagenode,), blank_finish = image(match, type_name, data, state, - state_machine, option_presets) - indented, indent, offset, blank_finish \ - = state_machine.get_first_known_indented(sys.maxint) - blocktext = '\n'.join(state_machine.input_lines[ - line_offset : state_machine.line_offset + 1]) - if isinstance(imagenode, nodes.system_message): - if indented: - imagenode[-1] = nodes.literal_block(blocktext, blocktext) - return [imagenode], blank_finish - figurenode = nodes.figure('', imagenode) - if indented: +def figure(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + (image_node,) = image(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine) + if isinstance(image_node, nodes.system_message): + return [image_node] + figure_node = nodes.figure('', image_node) + if content: node = nodes.Element() # anonymous container for parsing - state.nested_parse(indented, line_offset, node) - firstnode = node[0] - if isinstance(firstnode, nodes.paragraph): - caption = nodes.caption(firstnode.rawsource, '', - *firstnode.children) - figurenode += caption - elif not (isinstance(firstnode, nodes.comment) - and len(firstnode) == 0): + state.nested_parse(content, content_offset, node) + first_node = node[0] + if isinstance(first_node, nodes.paragraph): + caption = nodes.caption(first_node.rawsource, '', + *first_node.children) + figure_node += caption + elif not (isinstance(first_node, nodes.comment) + and len(first_node) == 0): error = state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [figurenode, error], blank_finish + nodes.literal_block(block_text, block_text), line=lineno) + return [figure_node, error] if len(node) > 1: - figurenode += nodes.legend('', *node[1:]) - return [figurenode], blank_finish + figure_node += nodes.legend('', *node[1:]) + return [figure_node] + +figure.arguments = (1, 0, 1) +figure.options = image.options +figure.content = 1 diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 9a3e9e71c..9512b835d 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger, Dmitry Jemerov +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger, Dmitry Jemerov -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Directives for document parts. """ @@ -26,70 +24,33 @@ def backlinks(arg): else: return value -contents_option_spec = {'depth': int, - 'local': directives.flag, - 'backlinks': backlinks} - #'qa': unchanged} - -def contents(match, type_name, data, state, state_machine, option_presets): +def contents(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): """Table of contents.""" - lineno = state_machine.abs_line_number() - line_offset = state_machine.line_offset - datablock, indent, offset, blank_finish = \ - state_machine.get_first_known_indented(match.end(), until_blank=1) - blocktext = '\n'.join(state_machine.input_lines[ - line_offset : line_offset + len(datablock) + 1]) - for i in range(len(datablock)): - if datablock[i][:1] == ':': - attlines = datablock[i:] - datablock = datablock[:i] - break - else: - attlines = [] - i = 0 - titletext = ' '.join([line.strip() for line in datablock]) - if titletext: - textnodes, messages = state.inline_text(titletext, lineno) - title = nodes.title(titletext, '', *textnodes) + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) else: messages = [] title = None pending = nodes.pending(parts.Contents, 'first writer', {'title': title}, - blocktext) - if attlines: - success, data, blank_finish = state.parse_extension_options( - contents_option_spec, attlines, blank_finish) - if success: # data is a dict of options - pending.details.update(data) - else: # data is an error string - error = state_machine.reporter.error( - 'Error in "%s" directive options:\n%s.' - % (match.group(1), data), '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error] + messages, blank_finish + block_text) + pending.details.update(options) state_machine.document.note_pending(pending) - return [pending] + messages, blank_finish + return [pending] + messages -sectnum_option_spec = {'depth': int} +contents.arguments = (0, 1, 1) +contents.options = {'depth': directives.nonnegative_int, + 'local': directives.flag, + 'backlinks': backlinks} -def sectnum(match, type_name, data, state, state_machine, option_presets): +def sectnum(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): """Automatic section numbering.""" - lineno = state_machine.abs_line_number() - line_offset = state_machine.line_offset - datablock, indent, offset, blank_finish = \ - state_machine.get_first_known_indented(match.end(), until_blank=1) pending = nodes.pending(parts.SectNum, 'last reader', {}) - success, data, blank_finish = state.parse_extension_options( - sectnum_option_spec, datablock, blank_finish) - if success: # data is a dict of options - pending.details.update(data) - else: # data is an error string - blocktext = '\n'.join(state_machine.input_lines[ - line_offset : line_offset + len(datablock) + 1]) - error = state_machine.reporter.error( - 'Error in "%s" directive options:\n%s.' - % (match.group(1), data), '', - nodes.literal_block(blocktext, blocktext), line=lineno) - return [error], blank_finish + pending.details.update(options) state_machine.document.note_pending(pending) - return [pending], blank_finish + return [pending] + +sectnum.options = {'depth': int} diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py index 0a8b2afd0..815bc1477 100644 --- a/docutils/parsers/rst/directives/references.py +++ b/docutils/parsers/rst/directives/references.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger, Dmitry Jemerov +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger, Dmitry Jemerov -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Directives for references and targets. """ @@ -16,15 +14,10 @@ from docutils import nodes from docutils.transforms import references -def target_notes(match, type_name, data, state, state_machine, - option_presets): +def target_notes(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): """Target footnote generation.""" pending = nodes.pending(references.TargetNotes, 'first reader', {}) state_machine.document.note_pending(pending) nodelist = [pending] - if data: - warning = state_machine.reporter.warning( - 'The "%s" directive takes no data; "%s" ignored.' - % (match.group(1), data), line=state_machine.abs_line_number()) - nodelist.append(warning) - return nodelist, state_machine.is_next_line_blank() + return nodelist -- cgit v1.2.1 From 9d50fb6eee483d2125cc5ca65c4b23ff6d51ff0a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:18:24 +0000 Subject: Reworked directive API. 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``. Generalized some state transition return values (``next_state``). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@745 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 203 ++++++++++++++++++++++++++++++++++------- 1 file changed, 170 insertions(+), 33 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 4380b3864..35d08ca7c 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -21,6 +21,7 @@ the reStructuredText parser. It defines the following: - `FieldList`: Second+ fields. - `OptionList`: Second+ option_list_items. - `RFC2822List`: Second+ RFC2822-style fields. + - `ExtensionOptions`: Parses directive option fields. - `Explicit`: Second+ explicit markup constructs. - `SubstitutionDef`: For embedded directives in substitution definitions. - `Text`: Classifier of second line of a text block. @@ -1188,8 +1189,7 @@ class Body(RSTState): fieldbody = nodes.field_body('\n'.join(indented)) fieldnode += fieldbody if indented: - self.nested_parse(indented, input_offset=line_offset, - node=fieldbody) + self.parse_field_body(indented, line_offset, fieldbody) return fieldnode, blank_finish def parse_field_marker(self, match): @@ -1198,6 +1198,9 @@ class Body(RSTState): field = field[:field.find(':')] # strip off trailing ':' etc. return field + def parse_field_body(self, indented, offset, node): + self.nested_parse(indented, input_offset=offset, node=node) + def option_marker(self, match, context, next_state): """Option list item.""" optionlist = nodes.option_list() @@ -1660,26 +1663,129 @@ class Body(RSTState): def directive(self, match, **option_presets): type_name = match.group(1) - directivefunction = directives.directive(type_name, - self.memo.language) - data = match.string[match.end():].strip() - if directivefunction: - return directivefunction(match, type_name, data, self, - self.state_machine, option_presets) + directive_function = directives.directive(type_name, + self.memo.language) + if directive_function: + return self.parse_directive( + directive_function, match, type_name, option_presets) else: - return self.unknown_directive(type_name, data) + return self.unknown_directive(type_name) + + def parse_directive(self, directive_fn, match, type_name, option_presets): + """ + Parse a directive then run its directive function. + + Parameters: + + - `directive_fn`: The function implementing the directive. Must have + function attributes ``arguments``, ``options``, and ``content``. - def unknown_directive(self, type_name, data): + - `match`: A regular expression match object which matched the first + line of the directive. + + - `type_name`: The directive name, as used in the source text. + + - `option_presets`: A dictionary of preset options, defaults for the + directive options. Currently, only an "alt" option is passed by + substitution definitions (value: the substitution name), which may + be used by an embedded image directive. + + Returns a 2-tuple: list of nodes, and a "blank finish" boolean. + """ + arguments = [] + options = {} + content = [] + argument_spec = option_spec = content_spec = None + if hasattr(directive_fn, 'arguments'): + argument_spec = directive_fn.arguments + if argument_spec[:2] == (0, 0): + argument_spec = None + if hasattr(directive_fn, 'options'): + option_spec = directive_fn.options + if hasattr(directive_fn, 'content'): + content_spec = directive_fn.content lineno = self.state_machine.abs_line_number() - indented, indent, offset, blank_finish = \ - self.state_machine.get_first_known_indented(0, strip_indent=0) - text = '\n'.join(indented) - error = self.reporter.error( - 'Unknown directive type "%s".' % type_name, '', - nodes.literal_block(text, text), line=lineno) - return [error], blank_finish + initial_line_offset = self.state_machine.line_offset + indented, indent, line_offset, blank_finish \ + = self.state_machine.get_first_known_indented(match.end(), + strip_top=0) + block_text = '\n'.join(self.state_machine.input_lines[ + initial_line_offset : self.state_machine.line_offset + 1]) + if indented and not indented[0].strip(): + indented.pop(0) + line_offset += 1 + while indented and not indented[-1].strip(): + indented.pop() + if indented and (argument_spec or option_spec): + for i in range(len(indented)): + if not indented[i].strip(): + break + else: + i += 1 + arg_block = indented[:i] + content = indented[i+1:] + content_offset = line_offset + i + 1 + else: + content = indented + content_offset = line_offset + arg_block = [] + while content and not content[0].strip(): + content.pop(0) + content_offset += 1 + try: + if option_spec: + options, arg_block = self.parse_directive_options( + option_presets, option_spec, arg_block) + if argument_spec: + arguments = self.parse_directive_arguments(argument_spec, + arg_block) + if content and not content_spec: + raise MarkupError('no content permitted.') + except MarkupError, detail: + error = self.reporter.error( + 'Error in "%s" directive:\n%s.' % (type_name, detail), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [error], blank_finish + result = directive_fn( + type_name, arguments, options, content, lineno, content_offset, + block_text, self, self.state_machine) + return result, blank_finish + + def parse_directive_options(self, option_presets, option_spec, arg_block): + options = option_presets.copy() + for i in range(len(arg_block)): + if arg_block[i][:1] == ':': + opt_block = arg_block[i:] + arg_block = arg_block[:i] + break + else: + opt_block = [] + if opt_block: + success, data = self.parse_extension_options(option_spec, + opt_block) + if success: # data is a dict of options + options.update(data) + else: # data is an error string + raise MarkupError(data) + return options, arg_block + + def parse_directive_arguments(self, argument_spec, arg_block): + required, optional, last_whitespace = argument_spec + arg_text = '\n'.join(arg_block) + arguments = arg_text.split() + if len(arguments) < required: + raise MarkupError('%s argument(s) required, %s supplied' + % (required, len(arguments))) + elif len(arguments) > required + optional: + if last_whitespace: + arguments = arg_text.split(None, required + optional - 1) + else: + raise MarkupError( + 'maximum %s argument(s) allowed, %s supplied' + % (required + optional, len(arguments))) + return arguments - def parse_extension_options(self, option_spec, datalines, blank_finish): + def parse_extension_options(self, option_spec, datalines): """ Parse `datalines` for a field list containing extension options matching `option_spec`. @@ -1688,28 +1794,39 @@ class Body(RSTState): - `option_spec`: a mapping of option name to conversion function, which should raise an exception on bad input. - `datalines`: a list of input strings. - - `blank_finish`: :Return: - Success value, 1 or 0. - An option dictionary on success, an error string on failure. - - Updated `blank_finish` flag. """ node = nodes.field_list() newline_offset, blank_finish = self.nested_list_parse( - datalines, 0, node, initial_state='FieldList', - blank_finish=blank_finish) + datalines, 0, node, initial_state='ExtensionOptions', + blank_finish=1) if newline_offset != len(datalines): # incomplete parse of block - return 0, 'invalid option block', blank_finish + return 0, 'invalid option block' try: options = utils.extract_extension_options(node, option_spec) except KeyError, detail: - return 0, ('unknown option: "%s"' % detail), blank_finish + return 0, ('unknown option: "%s"' % detail) except (ValueError, TypeError), detail: - return 0, ('invalid option value: %s' % detail), blank_finish + return 0, ('invalid option value: %s' % detail) except utils.ExtensionOptionError, detail: - return 0, ('invalid option data: %s' % detail), blank_finish - return 1, options, blank_finish + return 0, ('invalid option data: %s' % detail) + if blank_finish: + return 1, options + else: + return 0, 'option data incompletely parsed' + + def unknown_directive(self, type_name): + lineno = self.state_machine.abs_line_number() + indented, indent, offset, blank_finish = \ + self.state_machine.get_first_known_indented(0, strip_indent=0) + text = '\n'.join(indented) + error = self.reporter.error( + 'Unknown directive type "%s".' % type_name, '', + nodes.literal_block(text, text), line=lineno) + return [error], blank_finish def comment(self, match): if not match.string[match.end():].strip() \ @@ -1968,7 +2085,7 @@ class BulletList(SpecializedBody): listitem, blank_finish = self.list_item(match.end()) self.parent += listitem self.blank_finish = blank_finish - return [], 'BulletList', [] + return [], next_state, [] class DefinitionList(SpecializedBody): @@ -1998,7 +2115,7 @@ class EnumeratedList(SpecializedBody): self.parent += listitem self.blank_finish = blank_finish self.lastordinal = ordinal - return [], 'EnumeratedList', [] + return [], next_state, [] class FieldList(SpecializedBody): @@ -2010,7 +2127,7 @@ class FieldList(SpecializedBody): field, blank_finish = self.field(match) self.parent += field self.blank_finish = blank_finish - return [], 'FieldList', [] + return [], next_state, [] class OptionList(SpecializedBody): @@ -2025,7 +2142,7 @@ class OptionList(SpecializedBody): self.invalid_input() self.parent += option_list_item self.blank_finish = blank_finish - return [], 'OptionList', [] + return [], next_state, [] class RFC2822List(SpecializedBody, RFC2822Body): @@ -2045,6 +2162,26 @@ class RFC2822List(SpecializedBody, RFC2822Body): blank = SpecializedBody.invalid_input +class ExtensionOptions(FieldList): + + """ + Parse field_list fields for extension options. + + No nested parsing is done (including inline markup parsing). + """ + + def parse_field_body(self, indented, offset, node): + """Override `Body.parse_field_body` for simpler parsing.""" + lines = [] + for line in indented + ['']: + if line.strip(): + lines.append(line) + elif lines: + text = '\n'.join(lines) + node += nodes.paragraph(text, text) + lines = [] + + class Explicit(SpecializedBody): """Second and subsequent explicit markup construct.""" @@ -2411,8 +2548,8 @@ class Line(SpecializedText): state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList, - OptionList, Explicit, Text, Definition, Line, - SubstitutionDef, RFC2822Body, RFC2822List) + OptionList, ExtensionOptions, Explicit, Text, Definition, + Line, SubstitutionDef, RFC2822Body, RFC2822List) """Standard set of State classes used to start `RSTStateMachine`.""" -- cgit v1.2.1 From 394d2be476955d3831b50cb7bfe3fa94ecd5edf5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:20:00 +0000 Subject: Added ``strip_top`` parameter to ``StateMachineWS.get_first_known_indented``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@746 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index cc5514808..63f35c741 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -814,7 +814,8 @@ class StateMachineWS(StateMachine): offset += 1 return indented, offset, blank_finish - def get_first_known_indented(self, indent, until_blank=0, strip_indent=1): + def get_first_known_indented(self, indent, until_blank=0, strip_indent=1, + strip_top=1): """ Return an indented block and info. @@ -827,6 +828,7 @@ class StateMachineWS(StateMachine): (1). - `strip_indent`: Strip `indent` characters of indentation if true (1, default). + - `strip_top`: Strip blank lines from the beginning of the block. :Return: - the indented block, @@ -840,9 +842,10 @@ class StateMachineWS(StateMachine): self.input_lines[self.line_offset + 1:], until_blank, strip_indent) self.next_line(len(indented) - 1) # advance to last indented line - while indented and not indented[0].strip(): - indented.pop(0) - offset += 1 + if strip_top: + while indented and not indented[0].strip(): + indented.pop(0) + offset += 1 return indented, indent, offset, blank_finish -- cgit v1.2.1 From 689b92b482a34e74dfaf541a3cf75dada3577a93 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:20:42 +0000 Subject: Fixed content model bug in ``TargetNotes``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@747 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 566b0cef3..fcbd8b817 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -701,7 +701,9 @@ class TargetNotes(Transform): footnote_name = 'target_note: ' + footnote_id footnote['auto'] = 1 footnote['name'] = footnote_name - footnote += nodes.reference('', refuri, refuri=refuri) + 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: -- cgit v1.2.1 From 2aec785bc1ae304360badbf509f5b3a8ef786fb5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:22:29 +0000 Subject: Added "replace" directive. Updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@748 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 77 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 242c01564..6f6b1ca88 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -22,8 +22,9 @@ space), followed by the directive type and two colons (collectively, the "directive marker"). The directive block begins immediately after the directive marker, and includes all subsequent indented lines. The directive block is divided into arguments, options (a field list), and -content. See the Directives_ section in the `reStructuredText Markup -Specification`_ for syntax details. +content (in that order), any of which may appear. See the Directives_ +section in the `reStructuredText Markup Specification`_ for syntax +details. .. _Directives: ./reStructuredText.html#directives .. _reStructuredText Markup Specification: ./reStructuredText.html @@ -199,9 +200,9 @@ Topic :Directive Type: "topic" :DTD Element: topic -:Directive Arguments: None. +:Directive Arguments: 1, required (topic title). :Directive Options: None. -:Directive Content: Interpreted as the topic title and body. +:Directive Content: Interpreted as the topic body. A topic is like a block quote with a title, or a self-contained section with no subsections. Use the "topic" directive to indicate a @@ -209,9 +210,9 @@ self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. Body elements (including topics) may not contain nested topics. -The first line of the directive content block is interpreted as the -topic title; the second line must be blank. All subsequent lines make -up the topic body, interpreted as body elements. For example:: +The directive's sole argument is interpreted as the topic title; the +next line must be blank. All subsequent lines make up the topic body, +interpreted as body elements. For example:: topic:: Topic Title @@ -331,7 +332,7 @@ The following options are recognized: ``depth`` : integer The number of section levels that are collected in the table of contents. The default is unlimited depth. -``local`` : empty +``local`` : flag (empty) Generate a local table of contents. Entries will only include subsections of the section in which the directive is given. If no explicit title is given, the table of contents will not be titled. @@ -490,10 +491,8 @@ Non-standard element: imagemap. Miscellaneous --------------- -Including an External Fragment -============================== - -**NOT IMPLEMENTED YET** +Including an External Document Fragment +======================================= :Directive Type: "include" :DTD Elements: depend on data being included @@ -505,11 +504,23 @@ The "include" directive reads a reStructuredText-formatted text file and parses it in the current document's context at the point of the directive. For example:: + This first example will be parsed at the document level, and can + thus contain any construct, including section headers. + .. include:: inclusion.txt + This second will be parsed in a block quote context. + Therefore it may only contain body elements. It may not + contain section headers. + + .. include:: inclusion.txt + +If an included document fragment contains section structure, the title +adornments must match those of the master document. + The following options are recognized: -``literal`` : empty +``literal`` : flag (empty) The entire included text is inserted into the document as a single literal block (useful for program listings). @@ -517,12 +528,10 @@ The following options are recognized: Raw Data Pass-Through ===================== -**NOT IMPLEMENTED YET** - :Directive Type: "raw" :DTD Element: pending :Directive Arguments: One, required (output format type). -:Directive Options: Possible +:Directive Options: Possible. :Directive Content: Stored verbatim, uninterpreted. None (empty) if a "file" or "url" option given. @@ -547,8 +556,9 @@ output stream:: \documentclass[twocolumn]{article} -Raw data can also be read from an external file, specified in an -option. In this case, the content block must be empty. For example:: +Raw data can also be read from an external file, specified in a +directive option. In this case, the content block must be empty. For +example:: .. raw:: html :file: inclusion.html @@ -556,11 +566,40 @@ option. In this case, the content block must be empty. For example:: The following options are recognized: ``file`` : string - The filesystem path of a raw data file to be included. + The local filesystem path of a raw data file to be included. ``url`` : string An Internet URL reference to a raw data file to be included. +Replacement Text +================ + +:Directive Type: "replace" +:DTD Element: pending +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: A single paragraph; may contain inline markup. + +The "replace" directive is used to indicate replacement text for a +substitution reference. It may be used within substitution +definitions only. For example, this directive can be used to expand +abbreviations:: + + .. |reST| replace:: reStructuredText + + Yes, |reST| is a long word, so I can't blame anyone for wanting to + abbreviate it. + +As reStructuredText doesn't support nested inline markup, the only way +to create a reference with styled text is to use substitutions with +the "replace" directive:: + + I recommend you try |Python|_. + + .. |Python| replace:: Python, *the* best language around + .. _Python: http://www.python.org/ + + Restructuredtext-Test-Directive =============================== -- cgit v1.2.1 From 631b6fed566f55d7adfa2a93d103786306c79b06 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:23:20 +0000 Subject: Added to project. Original by Dethe Elza, edited & extended by David Goodger. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@749 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/rst-directives.txt | 343 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 docs/howto/rst-directives.txt diff --git a/docs/howto/rst-directives.txt b/docs/howto/rst-directives.txt new file mode 100644 index 000000000..a1f40e973 --- /dev/null +++ b/docs/howto/rst-directives.txt @@ -0,0 +1,343 @@ +====================================== + Creating reStructuredText Directives +====================================== + +:Authors: Dethe Elza, David Goodger +:Contact: delza@enfoldingsystems.com +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + +Directives are the primary extension mechanism of reStructuredText. +This document aims to make the creation of new directives as easy and +understandable as possible. There are only a couple of +reStructuredText-specific features the developer needs to know to +create a basic directive. + +The syntax of directives is detailed in the `reStructuredText Markup +Specification`_, and standard directives are described in +`reStructuredText Directives`_. + +.. _reStructuredText Markup Specification: + ../rst/reStructuredText.html#directives +.. _reStructuredText Directives: ../rst/directives.html + + +.. contents:: Table of Contents + + +Define the Directive Function +============================= + +The directive function does any processing that the directive +requires. This may require the use of other parts of the +reStructuredText parser. This is where the directive actually *does* +something. + +The directive implementation itself is a callback function whose +signature is as follows:: + + def directive_fn(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + code... + + # Set function attributes: + directive_fn.arguments = ... + directive_fn.options = ... + direcitve_fn.content = ... + +Function attributes are described below (see `Specify Directive +Arguments, Options, and Content`_). The directive function parameters +are as follows: + +- ``name`` is the directive type or name. + +- ``arguments`` is a list of positional arguments, as specified in the + ``arguments`` function attribute. + +- ``options`` is a dictionary mapping option names to values. The + options handled by a directive function are specified in the + ``options`` function attribute. + +- ``content`` is a list of strings, the directive content. Use the + ``content`` function attribute to allow directive content. + +- ``lineno`` is the line number of the first line of the directive. + +- ``content_offset`` is the line offset of the first line of the + content from the beginning of the current input. Used when + initiating a nested parse. + +- ``block_text`` is a string containing the entire directive. Include + it as the content of a literal block in a system message if there is + a problem. + +- ``state`` is the state which called the directive function. + +- ``state_machine`` is the state machine which controls the state + which called the directive function. + +Directive functions return a list of nodes which will be inserted into +the document tree at the point where the directive was encountered. +This can be an empty list if there is nothing to insert. Directives +have no corresponding element; choose the most appropriate elements +from the existing Docutils elements. See `The Docutils Document +Tree`_ and the ``docutils.nodes`` module. + +.. _The Docutils Document Tree: ../doctree.html + + +Specify Directive Arguments, Options, and Content +================================================= + +Function attributes are interpreted by the directive parser (the +``docutils.parsers.rst.states.Body.parse_directive()`` method). If +unspecified, directive function attributes are assumed to have the +value ``None``. Three directive function attributes are recognized: + +- ``arguments``: A 3-tuple specifying the expected positional + arguments, or ``None`` if the directive has no arguments. The 3 + items in the tuple are: + + 1. The number of required arguments. + 2. The number of optional arguments. + 3. A boolean, indicating if the final argument may contain whitespace. + + Arguments are normally single whitespace-separated words. The final + argument may contain whitespace when indicated by the value 1 (True) + for the third item in the argument spec tuple. In this case, the + final argument in the ``arguments`` parameter to the directive + function will contain spaces and/or newlines, preserved from the + input text. + + If the form of the arguments is more complex, specify only one + argument (either required or optional) and indicate that final + whitespace is OK (1/True); the client code must do any + context-sensitive parsing. + +- ``options``: The option specification. ``None`` or an empty dict + implies no options to parse. + + An option specification must be defined detailing the options + available to the directive. An option spec is a mapping of option + name to conversion function; conversion functions are applied to + each option value to check validity and convert them to the expected + type. Python's built-in conversion functions are often usable for + this, such as ``int``, ``float``, and ``bool`` (included in Python + from version 2.2.1). Other useful conversion functions are included + in the ``docutils.parsers.rst.directives`` package (in the + ``__init__.py`` module): + + - ``flag``: For options with no option arguments. Checks for an + argument (raises ``ValueError`` if found), returns ``None`` for + valid flag options. + + - ``unchanged``: Returns the argument, unchanged. Raises + ``ValueError`` if no argument is found. + + - ``path``: Returns the path argument unwrapped (with newlines + removed). Raises ``ValueError`` if no argument is found or if the + path contains internal whitespace. + + - ``nonnegative_int``: Checks for a nonnegative integer argument, + and raises ``ValueError`` if not. + + A further utility function, ``choice``, is supplied to enable + options whose argument must be a member of a finite set of possible + values. A custom conversion function must be written to use it. + For example:: + + from docutils.parsers.rst import directives + + def yesno(argument): + return directives.choice(argument, ('yes', 'no')) + + For example, here is an option spec for a directive which allows two + options, "name" and "value", each with an option argument:: + + directive_fn.options = {'name': unchanged, 'value': int} + +- ``content``: A boolean; true if content is allowed. Directive + functions must handle the case where content is required but not + present in the input text (an empty content list will be supplied). + +The final step of the ``parse_directive()`` method is to call the +directive function itself. + + +Register the Directive +====================== + +Register the new directive in ``directives/__init__.py``, in the +``_directive_registry`` dictionary. This allows the reStructuredText +parser to find and use the directive. + + +Examples +======== + +For the most direct and accurate information, "Use the Source, Luke!". +All standard directives are documented in `reStructuredText +Directives`_, and the source code implementing them is located in the +``docutils/parsers/rst/directives`` package. The ``__init__.py`` +module contains a mapping of directive name to module & function name. +Several representative directives are described below. + + +Admonitions +----------- + +Admonition directives, such as "note" and "caution", are quite simple. +They have no directive arguments or options. Admonition directive +content is interpreted as ordinary reStructuredText. The directive +function simply hands off control to a generic directive function:: + + def note(*args): + return admonition(nodes.note, *args) + + attention.content = 1 + +Note that the only thing distinguishing the various admonition +directives is the element (node class) generated. In the code above, +the node class is passed as the first argument to the generic +directive function, where the actual processing takes place:: + + def admonition(node_class, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + text = '\n'.join(content) + admonition_node = node_class(text) + if text: + state.nested_parse(content, content_offset, admonition_node) + return [admonition_node] + else: + warning = state_machine.reporter.warning( + 'The "%s" admonition is empty; content required.' + % (name), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [warning] + +Three things are noteworthy in the function above: + +1. The ``admonition_node = node_class(text)`` line creates the wrapper + element, using the class passed in from the initial (stub) + directive function. + +2. The call to ``state.nested_parse()`` is what does the actual + processing. It parses the directive content and adds any generated + elements as child elements of ``admonition_node``. + +3. If there was no directive content, a warning is generated and + returned. The call to ``state_machine.reporter.warning()`` + includes a literal block containing the entire directive text + (``block_text``) and the line (``lineno``) of the top of the + directive. + + +"image" +------- + +The "image" directive is used to insert a picture into a document. +This directive has one argument, the path to the image file, and +supports several options. There is no directive content. Here's the +image directive function:: + + def image(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + reference = ''.join(arguments[0].split('\n')) + if reference.find(' ') != -1: + error = state_machine.reporter.error( + 'Image URI contains whitespace.', '', + nodes.literal_block(block_text, block_text), + line=lineno) + return [error] + options['uri'] = reference + image_node = nodes.image(block_text, **options) + return [image_node] + + image.arguments = (1, 0, 1) + image.options = {'alt': directives.unchanged, + 'height': directives.nonnegative_int, + 'width': directives.nonnegative_int, + 'scale': directives.nonnegative_int, + 'align': align} + +Several things are noteworthy in the code above: + +1. The "image" directive requires a single argument, which is allowed + to contain whitespace (see the argument spec above, + ``image.arguments = (1, 0, 1)``). This is to allow for long URLs + which may span multiple lines. The first line of the ``image`` + function joins the URL, discarding any embedded newlines. Then the + result is checked for embedded spaces, which are *not* allowed. + +2. The reference is added to the ``options`` dictionary under the + "uri" key; this becomes an attribute of the ``nodes.image`` element + object. Any other attributes have already been set explicitly in + the source text. + +3. The "align" option depends on the following definitions (which + actually occur earlier in the source code):: + + align_values = ('top', 'middle', 'bottom', 'left', 'center', + 'right') + + def align(argument): + return directives.choice(argument, align_values) + + +"contents" +---------- + +The "contents" directive is used to insert an auto-generated table of +contents (TOC) into a document. It takes one optional argument, a +title for the TOC. If no title is specified, a default title is used +instead. The directive also handles several options. Here's the +code:: + + def contents(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Table of contents.""" + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) + else: + messages = [] + title = None + pending = nodes.pending(parts.Contents, 'first writer', + {'title': title}, block_text) + pending.details.update(options) + state_machine.document.note_pending(pending) + return [pending] + messages + + contents.arguments = (0, 1, 1) + contents.options = {'depth': directives.nonnegative_int, + 'local': directives.flag, + 'backlinks': backlinks} + +Aspects of note include: + +1. The ``contents.arguments = (0, 1, 1)`` function attribute specifies + a single, *optional* argument. If no argument is present, the + ``arguments`` parameter to the directive function will be an empty + list. + +2. If an argument *is* present, its text is passed to + ``state.inline_text()`` for parsing. Titles may contain inline + markup, such as emphasis or inline literals. + +3. The table of contents is not generated right away. Typically, a + TOC is placed near the beginning of a document, and is a summary or + outline of the section structure of the document. The entire + document must already be processed before a summary can be made. + This directive leaves a ``nodes.pending`` placeholder element in + the document tree, marking the position of the TOC and including a + ``details`` internal attribute containing all the directive + options, effectively communicating the options forward. The actual + table of contents processing is performed by a transform, + ``docutils.transforms.parts.Contents``, after the rest of the + document has been parsed. [#]_ + +.. [#] Please note that the priority system for transforms, indicated + above by ``'first writer'`` in the call to the ``nodes.pending`` + class, is due for an overhaul. -- cgit v1.2.1 From a3bc9fff9ecee87efe0f053530371b7a408d86a0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:25:25 +0000 Subject: Updated with text from a Doc-SIG response to Dallas Mahrt. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@750 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/semantics.txt | 85 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/docs/dev/semantics.txt b/docs/dev/semantics.txt index f6ec09ebd..e42c9ea01 100644 --- a/docs/dev/semantics.txt +++ b/docs/dev/semantics.txt @@ -7,13 +7,78 @@ :Date: $Date$ These are notes for a possible future PEP providing the final piece of -the Python docstring puzzle. +the Python docstring puzzle: docstring semantics or documentation +methodology. `PEP 257`_, Docstring Conventions, sketches out some +guidelines, but does not get into methodology details. + +I haven't explored documentation methodology more because, in my +opinion, it is a completely separate issue from syntax, and it's even +more controversial than syntax. Nobody wants to be told how to lay +out their documentation, a la JavaDoc_. I think the JavaDoc way is +butt-ugly, but it *is* an established standard for the Java world. +Any standard documentation methodology has to be formal enough to be +useful but remain light enough to be usable. If the methodology is +too strict, too heavy, or too ugly, many/most will not want to use it. + +I think a standard methodology could benefit the Python community, but +it would be a hard sell. A PEP would be the place to start. For most +human-readable documentation needs, the free-form text approach is +adequate. We'd only need a formal methodology if we want to extract +the parameters into a data dictionary, index, or summary of some kind. + PythonDoc ========= -A Python version of the JavaDoc semantics (not syntax). A set of -conventions which are understood by the Docutils. +(Not to be confused with Daniel Larsson's pythondoc_ project.) + +A Python version of the JavaDoc_ semantics (not syntax). A set of +conventions which are understood by the Docutils. What JavaDoc has +done is to establish a syntax that enables a certain documentation +methodology, or standard *semantics*. JavaDoc is not just syntax; it +prescribes a methodology. + +- Use field lists or definition lists for "tagged blocks". By this I + mean that field lists can be used similarly to JavaDoc's ``@tag`` + syntax. That's actually one of the motivators behind field lists. + For example, we could have:: + + """ + :Parameters: + - `lines`: a list of one-line strings without newlines. + - `until_blank`: Stop collecting at the first blank line if + true (1). + - `strip_indent`: Strip common leading indent if true (1, + default). + + :Return: + - a list of indented lines with mininum indent removed; + - the amount of the indent; + - whether or not the block finished with a blank line or at + the end of `lines`. + """ + + This is taken straight out of docutils/statemachine.py, in which I + experimented with a simple documentation methodology. Another + variation I've thought of exploits the Grouch_-compatible + "classifier" element of definition lists. For example:: + + :Parameters: + `lines` : [string] + List of one-line strings without newlines. + `until_blank` : boolean + Stop collecting at the first blank line if true (1). + `strip_indent` : boolean + Strip common leading indent if true (1, default). + +- Field lists could even be used in a one-to-one correspondence with + JavaDoc ``@tags``, although I doubt if I'd recommend it. Several + ports of JavaDoc's ``@tag`` methodology exist in Python, most + recently Ed Loper's "epydoc_". + + +Other Ideas +=========== - Can we extract comments from parsed modules? Could be handy for documenting function/method parameters:: @@ -31,11 +96,17 @@ conventions which are understood by the Docutils. it would be quite hard to add a new param to this method without realising you should document it -- Use field lists or definition lists for "tagged blocks". +- Frederic Giacometti's `iPhrase Python documentation conventions`_ is + an attachment to his Doc-SIG post of 2001-05-30. + -- Frederic Giacometti's "iPhrase Python documentation conventions" is - an attachment to his Doc-SIG post of 2001-05-30 - (http://mail.python.org/pipermail/doc-sig/2001-May/001840.html). +.. _PEP 257: http://www.python.org/peps/pep-0257.html +.. _JavaDoc: http://java.sun.com/j2se/javadoc/ +.. _pythondoc: http://starship.python.net/crew/danilo/pythondoc/ +.. _Grouch: http://www.mems-exchange.org/software/grouch/ +.. _epydoc: http://epydoc.sf.net/ +.. _iPhrase Python documentation conventions: + http://mail.python.org/pipermail/doc-sig/2001-May/001840.html .. -- cgit v1.2.1 From a9be40d6b5f5902c3b68e4416553fef4583cd7a6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 03:31:01 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@751 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 46 ++++++++++++++++++++++++++++++++++---------- README.txt | 21 ++++++++++++-------- docs/dev/todo.txt | 57 +++++++++++++++++++------------------------------------ 3 files changed, 68 insertions(+), 56 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6b59efc28..02ae42bd7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -5,7 +5,7 @@ :Author: David Goodger :Contact: goodger@users.sourceforge.net :Date: $Date$ -:Web-site: http://docutils.sourceforge.net/ +:Web site: http://docutils.sourceforge.net/ .. contents:: @@ -22,12 +22,12 @@ and related projects: Funk, Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen Hermann, Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry Jemerov, Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, - Julien Letessier, Wolfgang Lipp, Edward Loper, Ken Manheimer, Skip - Montanaro, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, - Pearu Peterson, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, - Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, - Laurence Tratt, Guido van Rossum, Barry Warsaw, Edward Welbourne, - Ka-Ping Yee, Moshe Zadka + Julien Letessier, Wolfgang Lipp, Edward Loper, Dallas Mahrt, Ken + Manheimer, Skip Montanaro, Paul Moore, Michel Pelletier, Sam + Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, Tavis Rudd, + Ollie Rutherfurd, Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, + tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, + Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -124,6 +124,8 @@ Specific: - 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``. * docutils/utils.py: @@ -153,16 +155,27 @@ Specific: - 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``. * docutils/parsers/rst/tableparser.py: - Fixed a bug that was producing unwanted empty rows in "simple" tables. +* docutils/parsers/rst/directives: Updated all directive functions to + new API. + * docutils/parsers/rst/directives/__init__.py: - - Added ``flag()``, ``unchanged()``, and ``choice()`` directive - option helper functions. + - Added ``flag()``, ``unchanged()``, ``path()``, + ``nonnegative_int()``, and ``choice()`` directive option helper + functions. * docutils/parsers/rst/directives/body.py: Added to project. Contains the "topic", "line-block", and "parsed-literal" directives. @@ -172,6 +185,11 @@ Specific: - Added an "align" attribute to the "image" & "figure" directives (by Adam Chodorowski). +* docutils/parsers/rst/directives/misc.py: + + - Added "include", "raw", and "replace" directives, courtesy of + Dethe Elza. + * docutils/parsers/rst/directives/parts.py: - Added the "sectnum" directive; by Dmitry Jemerov. @@ -309,10 +327,18 @@ Specific: * spec/pep-0258.txt: Converted to reStructuredText & updated. +* spec/semantics.txt: Updated with text from a Doc-SIG response to + Dallas Mahrt. + +* 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/rst/directives.txt: - Added directives: "topic", "sectnum", "target-notes", - "line-block", "parsed-literal", "include". + "line-block", "parsed-literal", "include", "replace". - Formalized descriptions of directive details. - Added an "align" attribute to the "image" & "figure" directives (by Adam Chodorowski). diff --git a/README.txt b/README.txt index 1cf10f0c6..bb66165d2 100644 --- a/README.txt +++ b/README.txt @@ -7,6 +7,9 @@ :Date: $Date$ :Web site: http://docutils.sourceforge.net/ +.. contents:: + + Thank you for downloading the Python Docutils project archive. As this is a work in progress, please check the project website for updated working files. This project should be considered highly @@ -38,8 +41,6 @@ Support for the following sources is planned: .. _PEPs (Python Enhancement Proposals): http://www.python.org/peps/pep-0012.html -.. contents:: - Releases & Snapshots ==================== @@ -69,9 +70,9 @@ for details.) Requirements ============ -To run the code, Python 2.0 or later must already be installed. -Python 2.1 or later is required to run the test suite. You can get -Python from http://www.python.org/. +To run the code, Python 2.1 or later must already be installed. The +latest release is recommended (2.1.3 or 2.2.1 as of this writing). +Python is available from http://www.python.org/. Project Files & Directories @@ -102,7 +103,8 @@ Project Files & Directories * spec: The project specification directory. Contains PEPs (Python Enhancement Proposals), XML DTDs (document type definitions), and other documents. The ``spec/rst`` directory contains the - reStructuredText specification. + reStructuredText specification. The ``spec/howto`` directory + contains How-To documents for developers. * tools: Directory for Docutils front-end tools. See docs/tools.txt for documentation. @@ -119,8 +121,9 @@ The first step is to expand the ``.tar.gz`` or ``.tgz`` archive. It contains a distutils setup file "setup.py". OS-specific installation instructions follow. -GNU/Linux, Unix, MacOS X, etc. ------------------------------- + +GNU/Linux, BSDs, Unix, MacOS X, etc. +------------------------------------ 1. Open a shell. @@ -138,6 +141,7 @@ GNU/Linux, Unix, MacOS X, etc. You can also just run install.py; it does the same thing. + Windows ------- @@ -155,6 +159,7 @@ Windows If your system is set up to run Python when you double-click on .py files, you can run install.py to do the same as the above. + MacOS 8/9 --------- diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 85f3323c8..71af1d1a8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -173,16 +173,17 @@ Implementation Docs * Internal module documentation (docstrings). * spec/doctree.txt: DTD element structural relationships, semantics, - and attributes. + and attributes. In progress; element descriptions to be completed. -* How a Writer works & how to write one +* How-to docs: In spec/howto/? -* Howto: Transforms + - How a Writer works & how to write one -* Howto: Directives + - Transforms * Document the ``pending`` elements, how they're generated and when - they're triggered ("first reader", "last writer", etc.). + they're triggered ("first reader", "last writer", etc.; priority + system due to be reworked, as noted above). * Document the transforms (perhaps in docstrings?): how they're used, what they do, dependencies & order considerations. @@ -294,6 +295,19 @@ __ rst/alternatives.html#or-not-to-do contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. +* In target URLs, it would be useful to not explicitly specify the + file extension. If we're generating HTML, then ".html" is + appropriate; if PDF, then ".pdf"; etc. How about using ".*" to + indicate "choose the most appropriate filename extension? For + example:: + + .. _Another Document: another.* + + Should the choice be from among existing files only? + + This may not be just a parser issue though; it may need framework + support. + * Add _`character processing`? For example: - ``--`` to em-dash (or ``--`` to en-dash, and ``---`` to em-dash). @@ -579,37 +593,6 @@ Directives - _`parts.citations`: See `Footnote & Citation Gathering`_. - - _`misc.raw`: See `Raw Data Pass-Through`__ in rst/directives.txt. - - __ rst/directives.html#raw-data-pass-through - - - _`misc.include`: ``#include`` one file in another. See `Including - an External Fragment`__ in rst/directives.txt. But how to parse - wrt sections, reference names, conflicts? For now, we'll parse it - in the current document's context (C-preprocessor semantics). - Perhaps later, when there's a need, we'll figure out how to - provide separate parsing (parse separately and then merge). - - Implementation ideas: Model the directive parsing on the "images" - directive. A separate, nested parse is probably needed, since - it's not a good idea to alter the already-read data. Use - ``state.nested_parse()`` (see directives/admonitions.py), and pass - in ``match_titles=1``. The reporting mechanism has been revamped - to include the file which is the source of system messages; a new - ``utils.Reporter`` object will need to be created for each input - source. (Need to notify ``document.note_source(source)`` upon - entering a new source file, and again when returning to the old - source file.) - - YAGNI for now: Use C-preprocessor semantics for locating include - files? E.g., ``.. include:: file.txt`` will read another file - into the current one, relative to the current file's directory, - and ``.. include:: <standard>`` will read a standard include file - from ``docutils/include/``. (Should "quotes" be required around - non-standard include files?) - - __ rst/directives.html#including-an-external-fragment - - _`misc.exec`: Execute Python code & insert the results. Perhaps dangerous? @@ -852,8 +835,6 @@ HTML Writer * Add more support for <link> elements, especially for navigation bars. -* ``<meta>`` tags should be XML empty tags: ``<meta />``. - Front-End Tools --------------- -- cgit v1.2.1 From e11dfe778b470ccb244767b6f9f2c959db6bec82 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 2 Oct 2002 04:49:26 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@753 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 71af1d1a8..e0a65e596 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -124,7 +124,7 @@ General methods. ``note_line_number`` is called by ``StateMachine.notify_observers``. Whatever reads the source calls ``note_source`` (``utils.new_document()``, "include" - directive (see misc.include_). + directive. - Add a ``line=None`` parameter to ``nodes.Node``; if unspecified, it will get the line number from the observer. (``source=None`` @@ -739,7 +739,8 @@ Directives be followed by a formatting string, using strftime codes. Default is "%Y-%m-%d" (ISO 8601 date), but time fields can also be used. - - Combined with misc.include_, implement canned macros? E.g.:: + - Combined with the "include" directive, implement canned macros? + E.g.:: .. include:: <macros> -- cgit v1.2.1 From d3256371e06859fd101eacc5e35f21364b74b651 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 01:38:26 +0000 Subject: Added field_list, field, field_name, field_body elements. Changed "Analogies" to "Analogues". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@754 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 270 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 236 insertions(+), 34 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index b7901b370..a67b00db4 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -229,7 +229,7 @@ following subsections: - Children: A list of elements which may occur within the element. - - Analogies: Describes analogous elements in well-known document + - Analogues: Describes analogous elements in well-known document models such as HTML_ or DocBook_. Lists similarities and differences. @@ -299,7 +299,7 @@ Details :Children: ``address`` elements contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``address`` is analogous to the DocBook "address" element. :Processing: @@ -375,7 +375,7 @@ Details :Children: ``author`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``author`` is analogous to the DocBook "author" element. :Processing: @@ -440,7 +440,7 @@ Details ``authors`` elements may contain the following elements: author_, organization_, address_, contact_ -:Analogies: +:Analogues: ``authors`` is analogous to the DocBook "authors" element. :Processing: @@ -521,7 +521,7 @@ Details :Children: ``bullet_list`` elements contain one or more list_item_ elements. -:Analogies: +:Analogues: ``bullet_list`` is analogous to the HTML "ul" element and to the DocBook "itemizedlist" element. HTML's "ul" is short for "unordered list", which we consider to be a misnomer. "Unordered" @@ -624,7 +624,7 @@ Details :Children: ``classifier`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``classifier`` has no direct analogues in common DTDs. It can be emulated with primitives or type effects. @@ -707,7 +707,7 @@ Details ``contact`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``contact`` is analogous to the DocBook "email" element. The HTML "address" element serves a similar purpose. @@ -773,7 +773,7 @@ Details ``copyright`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``copyright`` is analogous to the DocBook "copyright" element. :Processing: @@ -843,7 +843,7 @@ Details :Children: ``date`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``date`` is analogous to the DocBook "date" element. :Processing: @@ -910,7 +910,7 @@ Details :Children: ``decoration`` elements may contain `decorative elements`_. -:Analogies: +:Analogues: There are no direct analogies to ``decoration`` in HTML or in DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. @@ -971,7 +971,7 @@ Details :Children: ``definition`` elements may contain `body elements`_. -:Analogies: +:Analogues: ``definition`` is analogous to the HTML "dd" element and to the DocBook "listitem" element (inside a "variablelistentry" element). @@ -1021,7 +1021,7 @@ Details ``definition_list`` elements contain one or more definition_list_item_ elements. -:Analogies: +:Analogues: ``definition_list`` is analogous to the HTML "dl" element and to the DocBook "variablelist" element. @@ -1100,7 +1100,7 @@ Details ``definition_list_item`` elements each contain a single term_, an optional classifier_, and a definition_. -:Analogies: +:Analogues: ``definition_list_item`` is analogous to the DocBook "variablelistentry" element. @@ -1189,7 +1189,7 @@ Details :Children: ``docinfo`` elements contain `bibliographic elements`_. -:Analogies: +:Analogues: ``docinfo`` is analogous to DocBook "info" elements ("bookinfo" etc.). There are no directly analogous HTML elements; the "meta" element carries some of the same information, albeit invisibly. @@ -1301,7 +1301,7 @@ Details ``document`` elements may contain `structural subelements`_, `structural elements`_, and `body elements`_. -:Analogies: +:Analogues: ``document`` is analogous to the HTML "html" element and to several DocBook elements such as "book". @@ -1396,7 +1396,7 @@ Details ``enumerated_list`` elements contain one or more list_item_ elements. -:Analogies: +:Analogues: ``enumerated_list`` is analogous to the HTML "ol" element and to the DocBook "orderedlist" element. @@ -1489,25 +1489,227 @@ See list_item_ for another example. ``field`` ========= -`To be completed`_. +The ``field`` element contains a pair of field_name_ and field_body_ +elements. + + +Details +------- + +:Category: `Body Subelements`_ + +:Parents: + The following elements may contain ``field``: docinfo_, + field_list_ + +:Children: + Each ``field`` element contains one field_name_ and one + field_body_ element. + +:Analogues: + ``field`` has no direct analogues in common DTDs. + +:Processing: See field_list_. + + +Content Model +------------- + +.. parsed-literal:: + + (field_name_, field_body_) + +:Attributes: + The ``field`` element contains only the `common attributes`_: + id_, name_, dupname_, source_, and class_. + +:Parameter Entities: + The `%bibliographic.elements;`_ parameter entity directly includes + ``field``. + + +Examples +-------- + +See the examples for the field_list_ and docinfo_ elements. ``field_body`` ============== -`To be completed`_. +The ``field_body`` element contains body elements. It is analogous to +a database field's data. + + +Details +------- + +:Category: `Body Subelements`_ + +:Parents: + Only the field_ element contains ``field_body``. + +:Children: + ``field_body`` elements may contain `body elements`_. + +:Analogues: + ``field_body`` has no direct analogues in common DTDs. + +:Processing: See field_list_. + + +Content Model +------------- + +.. parsed-literal:: + + (`%body.elements;`_)* + +:Attributes: + The ``field_body`` element contains only the `common attributes`_: + id_, name_, dupname_, source_, and class_. + + +Examples +-------- + +See the examples for the field_list_ and docinfo_ elements. ``field_list`` ============== -`To be completed`_. +The ``field_list`` element contains two-column table-like structures +resembling database records (label & data pairs). Field lists are +often meant for further processing. In reStructuredText, field lists +are used to represent bibliographic fields (contents of the docinfo_ +element) and directive options. + + +Details +------- + +:Category: `Compound Body Elements`_ + +:Parents: + All elements employing the `%body.elements;`_ or + `%structure.model;`_ parameter entities in their content models + may contain ``field_list``. + +:Children: + ``field_list`` elements contain one or more field_ elements. + +:Analogues: + ``field_list`` has no direct analogues in common DTDs. It can be + emulated with primitives such as tables. + +:Processing: + A ``field_list`` is typically rendered as a two-column list, where + the first column contains "labels" (usually with a colon suffix). + However, field lists are often used for extension syntax or + special processing. Such structures do not survive as field lists + to be rendered. + + +Content Model +------------- + +.. parsed-literal:: + + (field_+) + +:Attributes: + The ``field_list`` element contains only the `common attributes`_: + id_, name_, dupname_, source_, and class_. + +:Parameter Entities: + The `%body.elements;`_ parameter entity directly includes + ``field_list``. The `%structure.model;`_ parameter entity + indirectly includes ``field_list``. + + +Examples +-------- + +reStructuredText source:: + + :Author: Me + :Version: 1 + :Date: 2001-08-11 + :Parameter i: integer + +Pseudo-XML_ fragment from simple parsing:: + + <field_list> + <field> + <field_name> + Author + <field_body> + <paragraph> + Me + <field> + <field_name> + Version + <field_body> + <paragraph> + 1 + <field> + <field_name> + Date + <field_body> + <paragraph> + 2001-08-11 + <field> + <field_name> + Parameter i + <field_body> + <paragraph> + integer + +Complete pseudo-XML_ result after parsing and applying transforms:: ``field_name`` ============== -`To be completed`_. +The ``field_name`` element contains text data only. It is analogous +to a database field's name. + + +Details +------- + +:Category: `Body Subelements`_ + +:Parents: + Only the field_ element contains ``field_name``. + +:Children: + ``field_name`` elements have no children. They may contain text + data only. + +:Analogues: + ``field_name`` has no direct analogues in common DTDs. + +:Processing: See field_list_. + + +Content Model +------------- + +.. parsed-literal:: + + (#PCDATA) + +:Attributes: + The ``field_name`` element contains only the `common attributes`_: + id_, name_, dupname_, source_, and class_. + + +Examples +-------- + +See the examples for the field_list_ and docinfo_ elements. ``figure`` @@ -1536,7 +1738,7 @@ Details :Children: ``footer`` elements may contain `body elements`_. -:Analogies: +:Analogues: There are no direct analogies to ``footer`` in HTML or DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. @@ -1611,7 +1813,7 @@ Details :Children: ``header`` elements may contain `body elements`_. -:Analogies: +:Analogues: There are no direct analogies to ``header`` in HTML or DocBook. Equivalents are typically constructed from primitives and/or generated by the processing system. @@ -1696,7 +1898,7 @@ Details :Children: ``list_item`` elements may contain `body elements`_. -:Analogies: +:Analogues: ``list_item`` is analogous to the HTML "li" element and to the DocBook "listitem" element. @@ -1821,7 +2023,7 @@ Details ``organization`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``organization`` is analogous to the DocBook "orgname", "corpname", or "publishername" elements. @@ -1889,7 +2091,7 @@ Details ``paragraph`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``paragraph`` is analogous to the HTML "p" element and to the DocBook "para" elements. @@ -1967,7 +2169,7 @@ Details ``revision`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``revision`` is analogous to but simpler than the DocBook "revision" element. It closely matches the DocBook "revnumber" element, but in a simpler context. @@ -2047,7 +2249,7 @@ Details ``section`` elements begin with a title_, and may contain `body elements`_ and transition_ and topic_ elements. -:Analogies: +:Analogues: ``section`` is analogous to DocBook recursive "section" elements, and to HTML "div" elements combined with "h1" etc. title elements. @@ -2137,7 +2339,7 @@ Details :Children: ``status`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``status`` is analogous to the DocBook "status" element. :Processing: @@ -2219,7 +2421,7 @@ Details ``subtitle`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``subtitle`` is analogous to HTML header elements ("h2" etc.) and to the DocBook "subtitle" element. @@ -2311,7 +2513,7 @@ Details :Children: ``term`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``term`` is analogous to the HTML "dt" element and to the DocBook "term" element. @@ -2375,7 +2577,7 @@ Details :Children: ``title`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``title`` is analogous to HTML "title" and header ("h1" etc.) elements, and to the DocBook "title" element. @@ -2438,7 +2640,7 @@ Details ``topic`` elements begin with a title_ and may contain `body elements`_. -:Analogies: +:Analogues: ``topic`` is analogous to the DocBook "simplesect" element. :Processing: @@ -2509,7 +2711,7 @@ Details :Children: ``transition`` is an empty element and has no children. -:Analogies: +:Analogues: ``transition`` is analogous to the HTML "hr" element. :Processing: @@ -2578,7 +2780,7 @@ Details ``version`` elements may contain text data plus `inline elements`_. -:Analogies: +:Analogues: ``version`` may be considered analogous to the DocBook "revision", "revnumber", or "biblioid" elements. -- cgit v1.2.1 From ec406bee86804c0a7b29ac94a3bb2e7915b6e7a9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 01:39:17 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@755 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 02ae42bd7..de8a75e19 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -303,7 +303,7 @@ Specific: docstrings. - Wrote descriptions of all common attributes and parameter entities. Filled in introductory material. - - Working through the element descriptions: 29 down, 54 to go. + - Working through the element descriptions: 33 down, 50 to go. * spec/docutils.dtd: -- cgit v1.2.1 From 96b04fd6263cf2a87810a3fdeec2ee023c2392f5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 01:56:16 +0000 Subject: fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@756 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index a67b00db4..75f57ef1c 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -1666,8 +1666,6 @@ Pseudo-XML_ fragment from simple parsing:: <paragraph> integer -Complete pseudo-XML_ result after parsing and applying transforms:: - ``field_name`` ============== -- cgit v1.2.1 From b53fe4bfc549c05db10526da6555fbd1ed73a57e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:17:55 +0000 Subject: Added ``-V``/``--version`` option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@758 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/quicktest.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/quicktest.py b/tools/quicktest.py index ccabf4ed6..200f46c20 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -17,6 +17,7 @@ except: import sys import os import getopt +import docutils from docutils.frontend import OptionParser from docutils.utils import new_document from docutils.parsers.rst import Parser @@ -46,7 +47,8 @@ options = [('pretty', 'p', ('xml', 'x', 'output pretty XML (indented)'), ('attributes', '', 'dump document attributes after processing'), ('debug', 'd', 'debug mode (lots of output)'), - ('help', 'h', 'show help text')] + ('version', 'V', 'show Docutils version then exit'), + ('help', 'h', 'show help text then exit')] """See ``distutils.fancy_getopt.FancyGetopt.__init__`` for a description of the data structure: (long option, short option, description).""" @@ -140,6 +142,10 @@ def posixGetArgs(argv): if o in ['-h', '--help']: usage() sys.exit() + elif o in ['-V', '--version']: + print >>sys.stderr, ('quicktest.py (Docutils %s)' + % docutils.__version) + sys.exit() elif o in ['-r', '--rawxml']: outputFormat = 'rawxml' elif o in ['-s', '--styledxml']: -- cgit v1.2.1 From 35448a37349d3788f2daafb762fd4e730d184b00 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:20:13 +0000 Subject: Clarified term/classifier delimiter & inline markup ambiguity (definition lists). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@759 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 0538d23c9..88d7a4917 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -733,13 +733,13 @@ definition. Each definition list item contains a term, an optional classifier, and a definition. A term is a simple one-line word or phrase. An -optional classifier may follow the term on the same line, after " : " -(space, colon, space). A definition is a block indented relative to -the term, and may contain multiple paragraphs and other body elements. -There may be no blank line between a term and a definition (this -distinguishes definition lists from `block quotes`_). Blank lines are -required before the first and after the last definition list item, but -are optional in-between. For example:: +optional classifier may follow the term on the same line, after an +inline " : " (space, colon, space). A definition is a block indented +relative to the term, and may contain multiple paragraphs and other +body elements. There may be no blank line between a term line and a +definition block (this distinguishes definition lists from `block +quotes`_). Blank lines are required before the first and after the +last definition list item, but are optional in-between. For example:: term 1 Definition 1. @@ -752,6 +752,10 @@ are optional in-between. For example:: term 3 : classifier Definition 3. +Inline markup is parsed in the term line before the term/classifier +delimiter (" : ") is recognized. The delimiter will only be +recognized if it appears outside of any inline markup. + A definition list may be used in various ways, including: - As a dictionary or glossary. The term is the word itself, a -- cgit v1.2.1 From 92c9d9791c3f0077dccc6b8c043db231d6af3654 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:21:23 +0000 Subject: Added the "Running the Test Suite" section; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@760 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/README.txt b/README.txt index bb66165d2..07511f7df 100644 --- a/README.txt +++ b/README.txt @@ -51,13 +51,13 @@ snapshots always contain the latest code and documentation, usually updated within an hour of changes being committed to the repository, and usually bug-free: -- Snapshot of Docutils code, tests, documentation, and +* Snapshot of Docutils code, tests, documentation, and specifications: http://docutils.sf.net/docutils-snapshot.tgz -- Snapshot of the Sandbox (experimental, contributed code): +* Snapshot of the Sandbox (experimental, contributed code): http://docutils.sf.net/docutils-sandbox-snapshot.tgz -- `Snapshot of web files` (the files that generate the web site): +* `Snapshot of web files` (the files that generate the web site): http://docutils.sf.net/docutils-web-snapshot.tgz To keep up to date on the latest developments, download fresh copies @@ -109,9 +109,9 @@ Project Files & Directories * tools: Directory for Docutils front-end tools. See docs/tools.txt for documentation. -* test: Unit tests; ``test/alltests.py`` runs all the tests. Not - required to use the software, but very useful if you're planning to - modify it. +* 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. Installation @@ -189,13 +189,15 @@ Usage After unpacking and installing the Docutils package, the following shell commands will generate HTML for all included documentation:: - cd docutils/tools + cd <archive_directory_path>/tools buildhtml.py ../ -For official releases, the directory may be called "docutils-X.Y", -where "X.Y" is the release version. Alternatively:: +The final directory name of the ``<archive_directory_path>`` is +"docutils" for snapshots. For official releases, the directory may be +called "docutils-X.Y", where "X.Y" is the release version. +Alternatively:: - cd docutils + cd <archive_directory_path> tools/buildhtml.py --config=tools/docutils.conf Some files may generate system messages (warnings and errors). The @@ -218,6 +220,42 @@ Contributions are welcome! .. _Docutils Front-End Tools: docs/tools.html +Running the Test Suite +====================== + +To run the entire test suite, after installation_ open a shell and use +the following commands:: + + cd <archive_directory_path>/test + ./alltests.py + +You should see a long line of periods, one for each test, and then a +summary like this:: + + Ran 518 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 +email`_. Please include all relevant output, information about your +operating system, Python version, and Docutils version. To see the +Docutils version, use these commands:: + + cd ../tools + ./quicktest.py --version + +.. _open a bug report: + http://sourceforge.net/tracker/?group_id=38414&atid=422030 +.. _send email: mailto:docutils-users@lists.sourceforge.net + ?subject=Docutils%20test%20suite%20failure + + Getting Help ============ -- cgit v1.2.1 From ed28012e60a40b2a0774a987d0d25240e2f592a8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:21:58 +0000 Subject: Improved definition list term/classifier parsing. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@761 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 35d08ca7c..bc19f07ab 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -882,7 +882,7 @@ class Inliner: self.implicit_inline(text[match.end():], lineno)) except MarkupMismatch: pass - return [nodes.Text(unescape(text))] + return [nodes.Text(unescape(text), rawsource=unescape(text, 1))] dispatch = {'*': emphasis, '**': strong, @@ -2365,17 +2365,24 @@ class Text(RSTState): def term(self, lines, lineno): """Return a definition_list's term and optional classifier.""" assert len(lines) == 1 - nodelist = [] - parts = lines[0].split(' : ', 1) # split into 1 or 2 parts - termpart = parts[0].rstrip() - textnodes, messages = self.inline_text(termpart, lineno) - nodelist = [nodes.term(termpart, '', *textnodes)] - if len(parts) == 2: - classifierpart = parts[1].lstrip() - textnodes, cpmessages = self.inline_text(classifierpart, lineno) - nodelist.append(nodes.classifier(classifierpart, '', *textnodes)) - messages += cpmessages - return nodelist, messages + text_nodes, messages = self.inline_text(lines[0], lineno) + term_node = nodes.term() + node_list = [term_node] + for i in range(len(text_nodes)): + node = text_nodes[i] + if isinstance(node, nodes.Text): + parts = node.rawsource.split(' : ', 1) + if len(parts) == 1: + term_node += node + else: + term_node += nodes.Text(parts[0].rstrip()) + classifier_node = nodes.classifier('', parts[1]) + classifier_node += text_nodes[i+1:] + node_list.append(classifier_node) + break + else: + term_node += node + return node_list, messages class SpecializedText(Text): -- cgit v1.2.1 From cb0016ca80adbac585187f7fb51c6edc8c039545 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:23:18 +0000 Subject: Added a "rawsource" attribute to the ``Text`` class, for pre-backslash-escape-resolution text. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@762 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 9120f977e..fe8c1c904 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -29,7 +29,7 @@ import re import xml.dom.minidom from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType -from UserString import MutableString +from UserString import UserString # ============================== @@ -152,7 +152,7 @@ class Node: method(self) -class Text(Node, MutableString): +class Text(Node, UserString): """ Instances are terminal nodes (leaves) containing text only; no child @@ -162,6 +162,12 @@ class Text(Node, MutableString): tagname = '#text' + def __init__(self, data, rawsource=''): + UserString.__init__(self, data) + + self.rawsource = rawsource + """The raw text from which this element was constructed.""" + def __repr__(self): data = repr(self.data) if len(data) > 70: -- cgit v1.2.1 From 54fa9c50bab333a45d75a6a72d5d82a4faf083f4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 22:25:42 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@763 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- COPYING.txt | 10 ++++---- HISTORY.txt | 10 ++++++++ docs/ref/docutils.dtd | 8 +++---- .../test_parsers/test_rst/test_definition_lists.py | 27 +++++++++++++++++----- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/COPYING.txt b/COPYING.txt index 883e6836b..504ff7111 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -5,20 +5,20 @@ :Author: David Goodger :Contact: goodger@users.sourceforge.net :Date: $Date$ -:Web-site: http://docutils.sourceforge.net/ +:Web site: http://docutils.sourceforge.net/ Most of the files included in this project are in the public domain, and therefore have no license requirement and no restrictions on copying or usage. The exceptions are: -- docutils/optik.py, copyright Gregory P. Ward, licensed under the BSD - license (which can be found in the module's source code). +- docutils/optik.py, copyright Gregory P. Ward, released under a + BSD-style license (which can be found in the module's source code). -- docutils/roman.py, copyright by Mark Pilgrim, licensed under the +- docutils/roman.py, copyright by Mark Pilgrim, released under the `Python 2.1.1 license`_. - test/difflib.py, copyright by the Python Software Foundation, - licensed under the `Python 2.2 license`_. This file is included for + released under the `Python 2.2 license`_. This file is included for compatibility with Python versions less than 2.2; if you have Python 2.2 or higher, difflib.py is not needed and may be removed. (It's only used to report test failures anyhow; it isn't installed diff --git a/HISTORY.txt b/HISTORY.txt index de8a75e19..a1ec3a974 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -105,6 +105,9 @@ Specific: attributes, and ``.note_state_machine_change`` & ``.note_source`` observer methods. + - Added a "rawsource" attribute to the ``Text`` class, for text + before backslash-escape resolution. + * docutils/statemachine.py: - Factored out ``State.add_initial_transitions()`` so it can be @@ -162,6 +165,7 @@ Specific: without parsing field bodies. Factored ``Body.parse_field_body()`` out of ``Body.field()``, overridden in ``ExtensionOptions``. + - Improved definition list term/classifier parsing. * docutils/parsers/rst/tableparser.py: @@ -358,6 +362,8 @@ Specific: 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). * tools: @@ -387,6 +393,10 @@ Specific: - Added ``check_requirements()`` & ``pep_type_error()``. - Added some exception handling. +* tools/quicktest.py: + + - Added ``-V``/``--version`` option. + * tools/stylesheets/default.css: Moved into the stylesheets directory. - Added style for chunks of inline literals. diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 41eb5d791..f55f6bcea 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -340,10 +340,10 @@ http://www.oasis-open.org/html/tm9901.htm). <!ATTLIST option_string %basic.atts;> <!-- -`delimiter` contains the string preceding the `option_argument`: -either the string separating it from the `option` (typically either -"=" or " ") or the string between option arguments (typically either -"," or " "). +`delimiter` contains the text preceding the `option_argument`: either +the text separating it from the `option_string` (typically either "=" +or " ") or the text between option arguments (typically either "," or +" "). --> <!ELEMENT option_argument (#PCDATA)> <!ATTLIST option_argument diff --git a/test/test_parsers/test_rst/test_definition_lists.py b/test/test_parsers/test_rst/test_definition_lists.py index 5bfd8ebd5..2cb0a6082 100755 --- a/test/test_parsers/test_rst/test_definition_lists.py +++ b/test/test_parsers/test_rst/test_definition_lists.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ @@ -274,6 +274,21 @@ Term \: not a classifier Because the colon is escaped. """], ["""\ +``Term : not a classifier`` + Because the ' : ' is inside an inline literal. +""", +"""\ +<document source="test data"> + <definition_list> + <definition_list_item> + <term> + <literal> + Term : not a classifier + <definition> + <paragraph> + Because the ' : ' is inside an inline literal. +"""], +["""\ Term `with *inline ``text **errors : classifier `with *errors ``too Definition `with *inline ``text **markup errors. """, -- cgit v1.2.1 From e26ecd23dc5bbebf30ef99cf2769b9e1f48ffabe Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 3 Oct 2002 23:47:04 +0000 Subject: fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@764 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 07511f7df..da44b00d1 100644 --- a/README.txt +++ b/README.txt @@ -57,7 +57,7 @@ and usually bug-free: * Snapshot of the Sandbox (experimental, contributed code): http://docutils.sf.net/docutils-sandbox-snapshot.tgz -* `Snapshot of web files` (the files that generate the web site): +* Snapshot of web files (the files that generate the web site): http://docutils.sf.net/docutils-web-snapshot.tgz To keep up to date on the latest developments, download fresh copies -- cgit v1.2.1 From d373703eae08290d20056ef966d1edec7b612cc3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:18:51 +0000 Subject: typos and minor edits git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@765 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 6 +++--- docs/user/rst/quickstart.txt | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index 2cea6caed..02a1eedde 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -24,7 +24,7 @@ <p align="right"><em><a href="http://docutils.sourceforge.net/docs/rst/quickref.html" >http://docutils.sourceforge.net/docs/rst/quickref.html</a></em> <br align="right"><em>Being a cheat-sheet for reStructuredText</em> - <br align="right"><em>Updated 2002-09-18</em> + <br align="right"><em>Updated 2002-10-07</em> <p>The full details of the markup may be found on the @@ -43,7 +43,7 @@ <ul> <li><a href="#inline-markup">Inline Markup</a></li> - <li><a href="#escaping">Escaping with Bashslashes</a></li> + <li><a href="#escaping">Escaping with Backslashes</a></li> <li><a href="#section-structure">Section Structure</a></li> <li><a href="#paragraphs">Paragraphs</a></li> <li><a href="#bullet-lists">Bullet Lists</a></li> @@ -187,7 +187,7 @@ nothing is processed). <h2><a href="#contents" name="escaping" class="backref" - >Escaping with Bashslashes</a></h2> + >Escaping with Backslashes</a></h2> <p>(<a href="../../spec/rst/reStructuredText.html#backslashes">details?</a>) diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index ea97a7550..c40c67cdd 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -70,12 +70,12 @@ inside the double back-quotes -- so asterisks "``*``" etc. are left alone. If you find that you want to use one of the "special" characters in -text, it will generally be OK -- ReST is pretty smart. For example, -this * asterisk is handled just fine. If you actually want text -\*surrounded by asterisks* to **not** be italicised, then you need to -indicate that the asterisk is not special. You do this by placing a -backslash just before it, like so "``\*``" (quickref__), or by -enclosing it in double back-quotes (inline literals), like this:: +text, it will generally be OK -- reStructuredText is pretty smart. +For example, this * asterisk is handled just fine. If you actually +want text \*surrounded by asterisks* to **not** be italicised, then +you need to indicate that the asterisk is not special. You do this by +placing a backslash just before it, like so "``\*``" (quickref__), or +by enclosing it in double back-quotes (inline literals), like this:: ``\*`` @@ -309,11 +309,10 @@ results in: .. image:: images/biohazard.png -The ``images/biohazard.png`` part indicates the filname of the image you -wish to appear -in the document. There's no restriction placed on the image (format, size -etc). If the image is to appear in HTML and you wish to supply additional -information, you may:: +The ``images/biohazard.png`` part indicates the filename of the image +you wish to appear in the document. There's no restriction placed on +the image (format, size etc). If the image is to appear in HTML and +you wish to supply additional information, you may:: .. image:: images/biohazard.png :height: 100 -- cgit v1.2.1 From 45d96016aabd12df32ac212fc5c5136d2b1f0dbb Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:19:43 +0000 Subject: Bumped version to 0.2.5 to reflect changes to Reporter output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@766 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 547447bed..15d1ea097 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,7 +55,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.4' +__version__ = '0.2.5' """``major.minor.micro`` version number. The ``micro`` number is bumped any time there's a change in the API incompatible with one of the front ends.""" -- cgit v1.2.1 From 1a6999bd968058d9eab5203c5d49227de238b093 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:20:23 +0000 Subject: Added ``--expose-internal-attribute`` option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@767 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 155893521..24cf7735c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -173,7 +173,10 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): # Hidden options, for development use only: (optik.SUPPRESS_HELP, ['--dump-internals'], - {'action': 'store_true'}),)) + {'action': 'store_true'}), + (optik.SUPPRESS_HELP, + ['--expose-internal-attribute'], + {'action': 'append', 'dest': 'expose_internals'}),)) """Command-line options common to all Docutils front ends. Option specs specific to individual Docutils components are also used (see `populate_from_components()`).""" -- cgit v1.2.1 From 68b497a1eb985ebedf7ffb0deeff342899551ef5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:21:06 +0000 Subject: Changed "system_message" output to GNU-Tools format. Updated for improved diagnostics (line numbers on almost all system messages). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@768 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index fe8c1c904..9b4d73cb1 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -782,7 +782,7 @@ class document(Root, Structural, Element): self.nameids[name] = None msg = self.reporter.system_message( level, 'Duplicate explicit target name: "%s".' % name, - backrefs=[id]) + backrefs=[id], base_node=node) if msgnode != None: msgnode += msg dupname(node) @@ -800,7 +800,7 @@ class document(Root, Structural, Element): if not explicit or (not old_explicit and old_id is not None): msg = self.reporter.info( 'Duplicate implicit target name: "%s".' % name, - backrefs=[id]) + backrefs=[id], base_node=node) if msgnode != None: msgnode += msg @@ -876,7 +876,8 @@ class document(Root, Structural, Element): name = subdef['name'] if self.substitution_defs.has_key(name): msg = self.reporter.error( - 'Duplicate substitution definition name: "%s".' % name) + 'Duplicate substitution definition name: "%s".' % name, + base_node=subdef) if msgnode != None: msgnode += msg oldnode = self.substitution_defs[name] @@ -899,16 +900,9 @@ class document(Root, Structural, Element): def note_state_machine_change(self, state_machine): self.current_line = state_machine.abs_line_number() -# print >>sys.stderr, '\nnodes.document.note_state_machine_change: ' \ -# 'current_line:', self.current_line -# print >>sys.stderr, ' current_state: ',state_machine.current_state -# sys.stderr.flush() def note_source(self, source): self.current_source = source - #print >>sys.stderr, '\nnodes.document.note_source: ' \ - # 'current_source:', self.current_source - #sys.stderr.flush() def copy(self): return self.__class__(self.options, self.reporter, @@ -1051,20 +1045,20 @@ class entry(Part, Element): pass class system_message(Special, PreBibliographic, Element, BackLinkable): - def __init__(self, comment=None, *children, **attributes): - if comment: - p = paragraph('', comment) + def __init__(self, message=None, *children, **attributes): + if message: + p = paragraph('', message) children = (p,) + children - Element.__init__(self, '', *children, **attributes) + try: + Element.__init__(self, '', *children, **attributes) + except: + print 'system_message: children=%r' % (children,) + raise def astext(self): - if self.hasattr('line'): - line = ', line %s' % self['line'] - else: - line = '' - return '%s/%s (%s%s) %s' % (self['type'], self['level'], - self['source'], line, - Element.astext(self)) + line = self.get('line', '') + return '%s:%s: (%s/%s) %s' % (self['source'], line, self['type'], + self['level'], Element.astext(self)) class pending(Special, Invisible, PreBibliographic, Element): -- cgit v1.2.1 From 3b4c2985f3efb3e92507e3067995f7a313bee040 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:25:17 +0000 Subject: Updated (Reporter API). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@769 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/admonitions.py | 2 +- docutils/parsers/rst/directives/body.py | 4 ++-- docutils/parsers/rst/directives/html.py | 8 ++++---- docutils/parsers/rst/directives/images.py | 4 ++-- docutils/parsers/rst/directives/misc.py | 19 +++++++++---------- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/docutils/parsers/rst/directives/admonitions.py b/docutils/parsers/rst/directives/admonitions.py index 000dd4708..7a349ad75 100644 --- a/docutils/parsers/rst/directives/admonitions.py +++ b/docutils/parsers/rst/directives/admonitions.py @@ -24,7 +24,7 @@ def admonition(node_class, name, arguments, options, content, lineno, return [admonition_node] else: error = state_machine.reporter.error( - 'The "%s" admonition is empty; content required.' % (name), '', + 'The "%s" admonition is empty; content required.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 55be7e36f..8bc2d7a4f 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -19,13 +19,13 @@ def topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): if not state_machine.match_titles: error = state_machine.reporter.error( - 'Topics may not be nested within topics or body elements.', '', + 'Topics may not be nested within topics or body elements.', nodes.literal_block(block_text, block_text), line=lineno) return [error] if not content: warning = state_machine.reporter.warning( 'Content block expected for the "%s" directive; none found.' - % name, '', nodes.literal_block(block_text, block_text), + % name, nodes.literal_block(block_text, block_text), line=lineno) return [warning] title_text = arguments[0] diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index 560554d49..88675c284 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -26,12 +26,12 @@ def meta(name, arguments, options, content, lineno, if (new_line_offset - content_offset) != len(content): # incomplete parse of block? error = state_machine.reporter.error( - 'Invalid meta directive.', '', + 'Invalid meta directive.', nodes.literal_block(block_text, block_text), line=lineno) node += error else: error = state_machine.reporter.error( - 'Empty meta directive.', '', + 'Empty meta directive.', nodes.literal_block(block_text, block_text), line=lineno) node += error return node.get_children() @@ -66,7 +66,7 @@ class MetaBody(states.SpecializedBody): if not indented: line = self.state_machine.line msg = self.reporter.info( - 'No content for meta tag "%s".' % name, '', + 'No content for meta tag "%s".' % name, nodes.literal_block(line, line), line=self.state_machine.abs_line_number()) return msg, blank_finish @@ -84,7 +84,7 @@ class MetaBody(states.SpecializedBody): line = self.state_machine.line msg = self.reporter.error( 'Error parsing meta tag attribute "%s": %s.' - % (token, detail), '', nodes.literal_block(line, line), + % (token, detail), nodes.literal_block(line, line), line=self.state_machine.abs_line_number()) return msg, blank_finish self.document.note_pending(pending) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 1617947ba..8509bf7fc 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -26,7 +26,7 @@ def image(name, arguments, options, content, lineno, reference = ''.join(arguments[0].split('\n')) if reference.find(' ') != -1: error = state_machine.reporter.error( - 'Image URI contains whitespace.', '', + 'Image URI contains whitespace.', nodes.literal_block(block_text, block_text), line=lineno) return [error] options['uri'] = reference @@ -58,7 +58,7 @@ def figure(name, arguments, options, content, lineno, elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): error = state_machine.reporter.error( - 'Figure caption must be a paragraph or empty comment.', '', + 'Figure caption must be a paragraph or empty comment.', nodes.literal_block(block_text, block_text), line=lineno) return [figure_node, error] if len(node) > 1: diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 484422bec..58af1336f 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -20,14 +20,14 @@ def include(name, arguments, options, content, lineno, path = ''.join(arguments[0].splitlines()) if path.find(' ') != -1: error = state_machine.reporter.error( - '"%s" directive path contains whitespace.' % name, '', + '"%s" directive path contains whitespace.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] try: include_file = open(path) except IOError, error: severe = state_machine.reporter.severe( - 'Problems with "%s" directive path:\n%s.' % (name, error), '', + 'Problems with "%s" directive path:\n%s.' % (name, error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] include_text = include_file.read() @@ -67,7 +67,7 @@ def raw(name, arguments, options, content, lineno, if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( '"%s" directive may not both specify an external file and ' - 'have content.' % name, '', + 'have content.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] text = '\n'.join(content) @@ -75,7 +75,7 @@ def raw(name, arguments, options, content, lineno, if options.has_key('url'): error = state_machine.reporter.error( 'The "file" and "url" options may not be simultaneously ' - 'specified for the "%s" directive.' % name, '', + 'specified for the "%s" directive.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] try: @@ -83,8 +83,7 @@ def raw(name, arguments, options, content, lineno, except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), - '', nodes.literal_block(block_text, block_text), - line=lineno) + nodes.literal_block(block_text, block_text), line=lineno) return [severe] text = raw_file.read() raw_file.close() @@ -95,7 +94,7 @@ def raw(name, arguments, options, content, lineno, except (URLError, IOError, OSError), error: severe = state_machine.reporter.severe( 'Problems with "%s" directive URL "%s":\n%s.' - % (name, options['url'], error), '', + % (name, options['url'], error), nodes.literal_block(block_text, block_text), line=lineno) return [severe] text = raw_file.read() @@ -104,7 +103,7 @@ def raw(name, arguments, options, content, lineno, else: error = state_machine.reporter.warning( 'The "%s" directive requires content; none supplied.' % (name), - '', nodes.literal_block(block_text, block_text), line=lineno) + nodes.literal_block(block_text, block_text), line=lineno) return [error] raw_node = nodes.raw('', text, **attributes) return [raw_node] @@ -119,7 +118,7 @@ def replace(name, arguments, options, content, lineno, if not isinstance(state, states.SubstitutionDef): error = state_machine.reporter.error( 'Invalid context: the "%s" directive can only be used within a ' - 'substitution definition.' % (name), '', + 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] text = '\n'.join(content) @@ -154,7 +153,7 @@ def directive_test_function(name, arguments, options, content, lineno, text = '\n'.join(content) info = state_machine.reporter.info( 'Directive processed. Type="%s", arguments=%r, options=%r, ' - 'content:' % (name, arguments, options), '', + 'content:' % (name, arguments, options), nodes.literal_block(text, text), line=lineno) else: info = state_machine.reporter.info( -- cgit v1.2.1 From 9f5cd7076855bb066a91602e60862435a4c63b40 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:25:40 +0000 Subject: Updated for improved diagnostics & Reporter API. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@770 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 75 ++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index bc19f07ab..f64eb3f5f 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -333,9 +333,9 @@ class RSTState(StateWS): return None def title_inconsistent(self, sourcetext, lineno): - literalblock = nodes.literal_block('', sourcetext) - error = self.reporter.severe('Title level inconsistent:', '', - literalblock, line=lineno) + error = self.reporter.severe( + 'Title level inconsistent:', nodes.literal_block('', sourcetext), + line=lineno) return error def new_subsection(self, title, lineno, messages): @@ -382,6 +382,7 @@ class RSTState(StateWS): literalnext = 0 textnodes, messages = self.inline_text(text, lineno) p = nodes.paragraph(data, '', *textnodes) + p.line = lineno return [p] + messages, literalnext def inline_text(self, text, lineno): @@ -1182,9 +1183,11 @@ class Body(RSTState): def field(self, match): name = self.parse_field_marker(match) + lineno = self.state_machine.abs_line_number() indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) fieldnode = nodes.field() + fieldnode.line = lineno fieldnode += nodes.field_name(name, name) fieldbody = nodes.field_body('\n'.join(indented)) fieldnode += fieldbody @@ -1404,8 +1407,7 @@ class Body(RSTState): lineno = self.state_machine.abs_line_number() - len(block) + 1 if detail: message += '\n' + detail - error = self.reporter.error(message, '', - nodes.literal_block(data, data), + error = self.reporter.error(message, nodes.literal_block(data, data), line=lineno) return [error] @@ -1491,11 +1493,13 @@ class Body(RSTState): """ % vars(Inliner), re.VERBOSE),) def footnote(self, match): + lineno = self.state_machine.abs_line_number() indented, indent, offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) label = match.group(1) name = normalize_name(label) footnote = nodes.footnote('\n'.join(indented)) + footnote.line = lineno if name[0] == '#': # auto-numbered name = name[1:] # autonumber label footnote['auto'] = 1 @@ -1513,17 +1517,19 @@ class Body(RSTState): if name: self.document.note_explicit_target(footnote, footnote) else: - self.document.set_id(footnote) + self.document.set_id(footnote, footnote) if indented: self.nested_parse(indented, input_offset=offset, node=footnote) return [footnote], blank_finish def citation(self, match): + lineno = self.state_machine.abs_line_number() indented, indent, offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) label = match.group(1) name = normalize_name(label) citation = nodes.citation('\n'.join(indented)) + citation.line = lineno citation += nodes.label('', label) citation['name'] = name self.document.note_citation(citation) @@ -1558,6 +1564,7 @@ class Body(RSTState): refname = self.is_reference(reference) if refname: target = nodes.target(blocktext, '', refname=refname) + target.line = lineno self.add_target(targetmatch.group('name'), '', target) self.document.note_indirect_target(target) return [target], blank_finish @@ -1566,12 +1573,13 @@ class Body(RSTState): if reference.find(' ') != -1: warning = self.reporter.warning( 'Hyperlink target contains whitespace. Perhaps a footnote ' - 'was intended?', '', + 'was intended?', nodes.literal_block(blocktext, blocktext), line=lineno) nodelist.append(warning) else: unescaped = unescape(reference) target = nodes.target(blocktext, '') + target.line = lineno self.add_target(targetmatch.group('name'), unescaped, target) nodelist.append(target) return nodelist, blank_finish @@ -1628,6 +1636,7 @@ class Body(RSTState): name = normalize_name(subname) substitutionnode = nodes.substitution_definition( blocktext, name=name, alt=subname) + substitutionnode.line = lineno if block: block[0] = block[0].strip() newabsoffset, blank_finish = self.nested_list_parse( @@ -1646,7 +1655,7 @@ class Body(RSTState): if len(substitutionnode) == 0: msg = self.reporter.warning( 'Substitution definition "%s" empty or invalid.' - % subname, '', + % subname, nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg else: @@ -1657,7 +1666,7 @@ class Body(RSTState): else: msg = self.reporter.warning( 'Substitution definition "%s" missing contents.' % subname, - '', nodes.literal_block(blocktext, blocktext), line=lineno) + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], blank_finish @@ -1674,7 +1683,7 @@ class Body(RSTState): def parse_directive(self, directive_fn, match, type_name, option_presets): """ Parse a directive then run its directive function. - + Parameters: - `directive_fn`: The function implementing the directive. Must have @@ -1689,21 +1698,17 @@ class Body(RSTState): directive options. Currently, only an "alt" option is passed by substitution definitions (value: the substitution name), which may be used by an embedded image directive. - + Returns a 2-tuple: list of nodes, and a "blank finish" boolean. """ arguments = [] options = {} content = [] - argument_spec = option_spec = content_spec = None - if hasattr(directive_fn, 'arguments'): - argument_spec = directive_fn.arguments - if argument_spec[:2] == (0, 0): - argument_spec = None - if hasattr(directive_fn, 'options'): - option_spec = directive_fn.options - if hasattr(directive_fn, 'content'): - content_spec = directive_fn.content + argument_spec = getattr(directive_fn, 'arguments', None) + if argument_spec and argument_spec[:2] == (0, 0): + argument_spec = None + option_spec = getattr(directive_fn, 'options', None) + content_spec = getattr(directive_fn, 'content', None) lineno = self.state_machine.abs_line_number() initial_line_offset = self.state_machine.line_offset indented, indent, line_offset, blank_finish \ @@ -1743,7 +1748,7 @@ class Body(RSTState): raise MarkupError('no content permitted.') except MarkupError, detail: error = self.reporter.error( - 'Error in "%s" directive:\n%s.' % (type_name, detail), '', + 'Error in "%s" directive:\n%s.' % (type_name, detail), nodes.literal_block(block_text, block_text), line=lineno) return [error], blank_finish result = directive_fn( @@ -1824,7 +1829,7 @@ class Body(RSTState): self.state_machine.get_first_known_indented(0, strip_indent=0) text = '\n'.join(indented) error = self.reporter.error( - 'Unknown directive type "%s".' % type_name, '', + 'Unknown directive type "%s".' % type_name, nodes.literal_block(text, text), line=lineno) return [error], blank_finish @@ -1947,7 +1952,7 @@ class Body(RSTState): lineno = self.state_machine.abs_line_number() - len(block) + 1 warning = self.reporter.warning( 'Anonymous hyperlink target contains whitespace. Perhaps a ' - 'footnote was intended?', '', + 'footnote was intended?', nodes.literal_block(blocktext, blocktext), line=lineno) nodelist.append(warning) @@ -1967,14 +1972,14 @@ class Body(RSTState): elif len(match.string.strip()) < 4: msg = self.reporter.info( 'Unexpected possible title overline or transition.\n' - "Treating it as ordinary text because it's so short.", '', + "Treating it as ordinary text because it's so short.", line=self.state_machine.abs_line_number()) self.parent += msg raise statemachine.TransitionCorrection('text') else: blocktext = self.state_machine.line msg = self.reporter.severe( - 'Unexpected section title or transition.', '', + 'Unexpected section title or transition.', nodes.literal_block(blocktext, blocktext), line=self.state_machine.abs_line_number()) self.parent += msg @@ -2279,8 +2284,8 @@ class Text(RSTState): if not self.state_machine.match_titles: blocktext = context[0] + '\n' + self.state_machine.line msg = self.reporter.severe( - 'Unexpected section title.', '', - nodes.literal_block(blocktext, blocktext), line=lineno) + 'Unexpected section title.', + nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], next_state, [] title = context[0].rstrip() @@ -2291,14 +2296,14 @@ class Text(RSTState): if len(underline) < 4: msg = self.reporter.info( 'Possible title underline, too short for the title.\n' - "Treating it as ordinary text because it's so short.", '', + "Treating it as ordinary text because it's so short.", line=lineno) self.parent += msg raise statemachine.TransitionCorrection('text') else: blocktext = context[0] + '\n' + self.state_machine.line msg = self.reporter.warning( - 'Title underline too short.', '', + 'Title underline too short.', nodes.literal_block(blocktext, blocktext), line=lineno) messages.append(msg) style = underline[0] @@ -2483,7 +2488,7 @@ class Line(SpecializedText): self.short_overline(context, blocktext, lineno, 2) else: msg = self.reporter.severe( - 'Incomplete section title.', '', + 'Incomplete section title.', nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], 'Body', [] @@ -2496,7 +2501,7 @@ class Line(SpecializedText): self.short_overline(context, blocktext, lineno, 2) else: msg = self.reporter.severe( - 'Missing underline for overline.', '', + 'Missing underline for overline.', nodes.literal_block(source, source), line=lineno) self.parent += msg return [], 'Body', [] @@ -2506,7 +2511,7 @@ class Line(SpecializedText): self.short_overline(context, blocktext, lineno, 2) else: msg = self.reporter.severe( - 'Title overline & underline mismatch.', '', + 'Title overline & underline mismatch.', nodes.literal_block(source, source), line=lineno) self.parent += msg return [], 'Body', [] @@ -2518,7 +2523,7 @@ class Line(SpecializedText): self.short_overline(context, blocktext, lineno, 2) else: msg = self.reporter.warning( - 'Title overline too short.', '', + 'Title overline too short.', nodes.literal_block(source, source), line=lineno) messages.append(msg) style = (overline[0], underline[0]) @@ -2536,7 +2541,7 @@ class Line(SpecializedText): if len(overline.rstrip()) < 4: self.short_overline(context, blocktext, lineno, 1) msg = self.reporter.error( - 'Invalid section title or transition marker.', '', + 'Invalid section title or transition marker.', nodes.literal_block(blocktext, blocktext), line=lineno) self.parent += msg return [], 'Body', [] @@ -2544,7 +2549,7 @@ class Line(SpecializedText): def short_overline(self, context, blocktext, lineno, lines=1): msg = self.reporter.info( 'Possible incomplete section title.\nTreating the overline as ' - "ordinary text because it's so short.", '', line=lineno) + "ordinary text because it's so short.", line=lineno) self.parent += msg self.state_correction(context, lines) -- cgit v1.2.1 From 91e0da642bed568b2dcba1e02ba6ee07c4d35e9d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:27:29 +0000 Subject: Added support for the ``--expose-internal-attributes`` option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@771 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 5e5498a8a..3ba62ecef 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Authors: David Goodger, Ueli Schlaepfer -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Authors: David Goodger, Ueli Schlaepfer +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Transforms needed by most or all documents: - `Decorations`: Generate a document's header & footer. @@ -133,6 +132,9 @@ class FinalChecks(Transform): def transform(self): visitor = FinalCheckVisitor(self.document) self.document.walk(visitor) + if self.document.options.expose_internals: + visitor = InternalAttributeExposer(self.document) + self.document.walk(visitor) class FinalCheckVisitor(nodes.SparseNodeVisitor): @@ -147,7 +149,8 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): id = self.document.nameids.get(refname) if id is None: msg = self.document.reporter.error( - 'Unknown target name: "%s".' % (node['refname'])) + 'Unknown target name: "%s".' % (node['refname']), + base_node=node) msgid = self.document.set_id(msg) prb = nodes.problematic( node.rawsource, node.rawsource, refid=msgid) @@ -163,6 +166,19 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): visit_footnote_reference = visit_citation_reference = visit_reference +class InternalAttributeExposer(nodes.GenericNodeVisitor): + + def __init__(self, document): + nodes.GenericNodeVisitor.__init__(self, document) + self.internal_attributes = document.options.expose_internals + + def default_visit(self, node): + for att in self.internal_attributes: + value = getattr(node, att, None) + if value is not None: + node['internal:' + att] = value + + class Pending(Transform): """ -- cgit v1.2.1 From 32fd41aa1be5a9e8d356d08a67bf38a036c2af08 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:28:06 +0000 Subject: Improved Reporter diagnostics (line numbers on almost all system messages). Changed Reporter method API slightly. Added ``get_source_line()`` function. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@772 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 58 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/docutils/utils.py b/docutils/utils.py index c48dc4e20..2f2c4c9f1 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -141,70 +141,75 @@ class Reporter: for observer in self.observers: observer(message) - def system_message(self, level, comment=None, category='', - *children, **attributes): + def system_message(self, level, message, *children, **kwargs): """ Return a system_message object. Raise an exception or generate a warning if appropriate. """ - msg = nodes.system_message(comment, level=level, + attributes = kwargs.copy() + category = kwargs.get('category', '') + if kwargs.has_key('category'): + del attributes['category'] + if kwargs.has_key('base_node'): + source, line = get_source_line(kwargs['base_node']) + del attributes['base_node'] + if source is not None: + attributes.setdefault('source', source) + if line is not None: + attributes.setdefault('line', line) + attributes.setdefault('source', self.source) + msg = nodes.system_message(message, level=level, type=self.levels[level], *children, **attributes) - msg['source'] = self.source debug, report_level, halt_level, stream = self[category].astuple() if level >= report_level or debug and level == 0: if category: - print >>stream, 'Reporter "%s":' % category, msg.astext() + print >>stream, msg.astext(), '[%s]' % category else: - print >>stream, 'Reporter:', msg.astext() + print >>stream, msg.astext() if level >= halt_level: raise SystemMessage(msg) if level > 0 or debug: self.notify_observers(msg) return msg - def debug(self, comment=None, category='', *children, **attributes): + def debug(self, *args, **kwargs): """ Level-0, "DEBUG": an internal reporting issue. Typically, there is no effect on the processing. Level-0 system messages are handled separately from the others. """ - return self.system_message( - 0, comment, category, *children, **attributes) + return self.system_message(0, *args, **kwargs) - def info(self, comment=None, category='', *children, **attributes): + def info(self, *args, **kwargs): """ Level-1, "INFO": a minor issue that can be ignored. Typically there is no effect on processing, and level-1 system messages are not reported. """ - return self.system_message( - 1, comment, category, *children, **attributes) + return self.system_message(1, *args, **kwargs) - def warning(self, comment=None, category='', *children, **attributes): + def warning(self, *args, **kwargs): """ Level-2, "WARNING": an issue that should be addressed. If ignored, there may be unpredictable problems with the output. """ - return self.system_message( - 2, comment, category, *children, **attributes) + return self.system_message(2, *args, **kwargs) - def error(self, comment=None, category='', *children, **attributes): + def error(self, *args, **kwargs): """ Level-3, "ERROR": an error that should be addressed. If ignored, the output will contain errors. """ - return self.system_message( - 3, comment, category, *children, **attributes) + return self.system_message(3, *args, **kwargs) - def severe(self, comment=None, category='', *children, **attributes): + def severe(self, *args, **kwargs): """ Level-4, "SEVERE": a severe error that must be addressed. If ignored, the output will contain severe errors. Typically level-4 system messages are turned into exceptions which halt processing. """ - return self.system_message( - 4, comment, category, *children, **attributes) + return self.system_message(4, *args, **kwargs) class ConditionSet: @@ -406,3 +411,14 @@ def relative_path(source, target): target_parts.reverse() parts = ['..'] * (len(source_parts) - 1) + target_parts return '/'.join(parts) + +def get_source_line(node): + """ + Return the "source" and "line" attributes from the `node` given or from + it's closest ancestor. + """ + while node: + if node.source or node.line: + return node.source, node.line + node = node.parent + return None, None -- cgit v1.2.1 From 0590bfaf42788314fb22491b5497079843713f2e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:28:42 +0000 Subject: Added "-A" option. Fixed typo. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@773 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/quicktest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/quicktest.py b/tools/quicktest.py index 200f46c20..1ee77b3c4 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -45,7 +45,7 @@ options = [('pretty', 'p', ('styledxml=', 's', 'output raw XML with XSL style sheet ' 'reference (filename supplied in the option argument)'), ('xml', 'x', 'output pretty XML (indented)'), - ('attributes', '', 'dump document attributes after processing'), + ('attributes', 'A', 'dump document attributes after processing'), ('debug', 'd', 'debug mode (lots of output)'), ('version', 'V', 'show Docutils version then exit'), ('help', 'h', 'show help text then exit')] @@ -58,7 +58,7 @@ def usage(): if longopt[-1:] == '=': opts = '-%s arg, --%sarg' % (shortopt, longopt) else: - opts = '-%s, --%s' % (shortopt, longopt), + opts = '-%s, --%s' % (shortopt, longopt) print '%-15s' % opts, if len(opts) > 14: print '%-16s' % '\n', -- cgit v1.2.1 From 58036bb54a184a823272be8ddf5f52c619d4f83c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 8 Oct 2002 01:35:57 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@774 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 25 +++++++++------ docs/dev/todo.txt | 18 +++++++++-- docs/user/tools.txt | 14 +++++++-- docutils/transforms/__init__.py | 13 ++++---- docutils/transforms/components.py | 13 ++++---- docutils/transforms/frontmatter.py | 28 +++++++++-------- docutils/transforms/parts.py | 13 ++++---- docutils/transforms/peps.py | 13 ++++---- docutils/transforms/references.py | 36 ++++++++++++---------- test/test_parsers/test_rst/test_footnotes.py | 4 +-- test/test_parsers/test_rst/test_section_headers.py | 4 +-- test/test_parsers/test_rst/test_substitutions.py | 2 +- test/test_parsers/test_rst/test_targets.py | 20 ++++++------ test/test_transforms/test_contents.py | 12 ++++---- test/test_transforms/test_docinfo.py | 30 +++++++++--------- test/test_transforms/test_doctitle.py | 12 ++++---- test/test_transforms/test_filter.py | 12 ++++---- test/test_transforms/test_final_checks.py | 14 ++++----- test/test_transforms/test_footnotes.py | 20 ++++++------ test/test_transforms/test_hyperlinks.py | 25 +++++++-------- test/test_transforms/test_messages.py | 14 ++++----- test/test_transforms/test_sectnum.py | 12 ++++---- test/test_transforms/test_substitutions.py | 14 ++++----- test/test_utils.py | 30 +++++++++--------- 24 files changed, 214 insertions(+), 184 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index a1ec3a974..181196f81 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -19,15 +19,15 @@ and related projects: Aahz, David Ascher, Fred Bremmer, Simon Budig, Brett Cannon, Adam Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter - Funk, Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen - Hermann, Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry Jemerov, - Richard Jones, Garth Kidd, Daniel Larsson, Marc-Andre Lemburg, - Julien Letessier, Wolfgang Lipp, Edward Loper, Dallas Mahrt, Ken - Manheimer, Skip Montanaro, Paul Moore, Michel Pelletier, Sam - Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, Tavis Rudd, - Ollie Rutherfurd, Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, - tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, Barry Warsaw, - Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Funk, Jorge Gonzalez, Engelbert Gruber, Simon Hefti, Doug + Hellmann, Juergen Hermann, Jeremy Hylton, Tony Ibbs, Alan Jaffray, + Dmitry Jemerov, Richard Jones, Garth Kidd, Daniel Larsson, + Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, Edward Loper, + Dallas Mahrt, Ken Manheimer, Skip Montanaro, Paul Moore, Michel + Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, + Tavis Rudd, Ollie Rutherfurd, Kenichi Sato, Ueli Schlaepfer, + Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van + Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -54,6 +54,7 @@ Specific: 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. * docutils/core.py: @@ -69,6 +70,7 @@ Specific: ``OptionParser.populate_from_components()`` to combine it all. - Require list of keys in ``make_paths_absolute`` (was implicit in global ``relative_path_options``). + - Added ``--expose-internal-attribute`` option. * docutils/io.py: @@ -104,6 +106,7 @@ Specific: - Added ``document.current_source`` & ``.current_line`` attributes, and ``.note_state_machine_change`` & ``.note_source`` observer methods. + - Changed "system_message" output to GNU-Tools format. - Added a "rawsource" attribute to the ``Text`` class, for text before backslash-escape resolution. @@ -233,6 +236,10 @@ Specific: - Added the ``TargetNotes`` generic transform. +* docutils/transforms/universal.py: + + - Added support for the ``--expose-internal-attributes`` option. + * docutils/writers/docutils-xml.py: - Added XML and doctype declarations. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e0a65e596..749188f6d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -89,13 +89,25 @@ General - A queue, with entries ``(priority, transform, pending=None)``. - Transform classes can have ``priority`` class attributes. + Each transform could have a unique priority. Use a look-up table? + No, that would require too many imports to construct. - Priorities can be numeric. Integers (0..100? 0..999? 0..9999?)? Floats (would be easier to squeeze in new ones)? - Priorities can be strings. Numeric (000..999? 0000..9999?)? Alphanumeric (a..z? 1, 1a, 1b, ...?)? - - Each transform would have a unique priority. Use a look-up table? - No, that would require too many imports to construct. Document - transform priorities. + - Document transform priorities. + - Add a ``Transformer`` class to register and execute transforms. + Perhaps ``Transformer.add_transform(transform, priority=None)``, + where ``priority`` can be used to override the transform class' + ``default_priority`` class attribute (used if ``None``). + - Perhaps a ``Transformer.add_transforms(transform_list)`` method + for quick population. ``docutils.Component`` could be the host + for the "transforms" class attribute and an ``add_transforms()``. + A ``self.add_transforms()`` call could be added to component + initialization routines. + - How to handle ``pending`` elements? Perhaps a + ``Transformer.add_transform(transform, priority=None)`` method? + Just call it from ``nodes.document.note_pending()``. * @@@ Break up ``references.Hyperlinks`` into multiple smaller transforms. diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 2626b2419..6422eab05 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -328,6 +328,13 @@ Some knowledge of Python_ is assumed for some attributes. ==================== ================================================ Config Entry Name Description ==================== ================================================ +expose_internals (Hidden option, for development use only.) List + of internal attribues to expose as external + attributes (with "internal:" namespace prefix). + + Default: don't (None). Options: + ``--expose-internal-attribute``. +-------------------- ------------------------------------------------ compact_lists (HTML Writer.) Remove extra vertical whitespace between items of bullet lists and enumerated lists, when list items are "simple" (i.e., all @@ -361,9 +368,10 @@ debug Report debug-level system messages. Default: don't (None). Options: ``--debug, --no-debug``. -------------------- ------------------------------------------------ -dump_internals (Hidden option.) At the end of processing, - print out all internal attributes of the - document (``document.__dict__``). +dump_internals (Hidden option, for development use only.) At + the end of processing, print out all internal + attributes of the document + (``document.__dict__``). Default: don't (None). Options: ``--dump-internals``. diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index b2b9337d5..bfdf3b2b9 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Authors: David Goodger, Ueli Schlaepfer -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Authors: David Goodger, Ueli Schlaepfer +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# 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: diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index dee54a215..6b0c2648c 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Docutils component-related transforms. """ diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index fbe281075..c3b5bca83 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Authors: David Goodger, Ueli Schlaepfer -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Authors: David Goodger, Ueli Schlaepfer +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Transforms related to the front matter of a document (information found before the main text): @@ -266,7 +265,8 @@ class DocInfo(Transform): elif issubclass(biblioclass, nodes.topic): if topics[normedname]: field[-1] += self.document.reporter.warning( - 'There can only be one "%s" field.' % name) + 'There can only be one "%s" field.' % name, + base_node=field) raise TransformError title = nodes.title(name, labels[normedname]) topics[normedname] = biblioclass( @@ -291,19 +291,22 @@ class DocInfo(Transform): 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) + '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) + '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) + 'anything other than a single paragraph.' % name, + base_node=field) return None return 1 @@ -339,7 +342,8 @@ class DocInfo(Transform): '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))) + % (name, ''.join(self.language.author_separators)), + base_node=field) raise def authors_from_one_paragraph(self, field): diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 78a99b121..bbb27245a 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Authors: David Goodger, Ueli Schlaepfer, Dmitry Jemerov -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Authors: David Goodger, Ueli Schlaepfer, Dmitry Jemerov +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Transforms related to document parts. - `Contents`: Used to build a table of contents. diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 8c188b443..9ef0e9b85 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# 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 diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index fcbd8b817..52ee4d9b6 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -1,11 +1,10 @@ -#! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Transforms for resolving references: - `Hyperlinks`: Used to resolve hyperlink targets and references. @@ -72,8 +71,9 @@ class Hyperlinks(Transform): != len(self.document.anonymous_targets): msg = self.document.reporter.error( 'Anonymous hyperlink mismatch: %s references but %s ' - 'targets.' % (len(self.document.anonymous_refs), - len(self.document.anonymous_targets))) + 'targets.\nSee "backrefs" attribute for IDs.' + % (len(self.document.anonymous_refs), + len(self.document.anonymous_targets))) msgid = self.document.set_id(msg) for ref in self.document.anonymous_refs: prb = nodes.problematic( @@ -185,7 +185,8 @@ class Hyperlinks(Transform): naming += '(id="%s")' % target['id'] msg = self.document.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' - 'which does not exist.' % (naming, target['refname'])) + 'which does not exist.' % (naming, target['refname']), + base_node=target) msgid = self.document.set_id(msg) for ref in reflist: prb = nodes.problematic( @@ -216,7 +217,7 @@ class Hyperlinks(Transform): return msg = self.document.reporter.info( 'Indirect hyperlink target "%s" is not referenced.' - % name) + % name, base_node=target) target.referenced = 1 return delatt = 'refname' @@ -229,7 +230,7 @@ class Hyperlinks(Transform): return msg = self.document.reporter.info( 'Indirect hyperlink target id="%s" is not referenced.' - % id) + % id, base_node=target) target.referenced = 1 return delatt = 'refid' @@ -272,7 +273,7 @@ class Hyperlinks(Transform): continue msg = self.document.reporter.info( 'External hyperlink target "%s" is not referenced.' - % name) + % name, base_node=target) target.referenced = 1 continue for ref in reflist: @@ -313,7 +314,7 @@ class Hyperlinks(Transform): continue msg = self.document.reporter.info( 'Internal hyperlink target "%s" is not referenced.' - % name) + % name, base_node=target) target.referenced = 1 continue for ref in reflist: @@ -522,7 +523,7 @@ class Footnotes(Transform): msg = self.document.reporter.error( 'Too many autonumbered footnote references: only %s ' 'corresponding footnotes available.' - % len(self.autofootnote_labels)) + % 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'): @@ -560,7 +561,8 @@ class Footnotes(Transform): except IndexError: msg = self.document.reporter.error( 'Too many symbol footnote references: only %s ' - 'corresponding footnotes available.' % len(labels)) + 'corresponding footnotes available.' % len(labels), + base_node=ref) msgid = self.set_id(msg) for ref in self.document.symbol_footnote_refs[i:]: if ref.resolved or ref.hasattr('refid'): @@ -642,7 +644,7 @@ class Substitutions(Transform): else: msg = self.document.reporter.error( 'Undefined substitution referenced: "%s".' - % refname) + % refname, base_node=ref) msgid = self.document.set_id(msg) prb = nodes.problematic( ref.rawsource, ref.rawsource, refid=msgid) diff --git a/test/test_parsers/test_rst/test_footnotes.py b/test/test_parsers/test_rst/test_footnotes.py index 6c72d3255..f58be22ea 100755 --- a/test/test_parsers/test_rst/test_footnotes.py +++ b/test/test_parsers/test_rst/test_footnotes.py @@ -236,7 +236,7 @@ Mixed anonymous and labelled auto-numbered footnotes: <paragraph> Auto-numbered footnote 5. <footnote auto="1" dupname="five" id="id9"> - <system_message backrefs="id9" level="2" source="test data" type="WARNING"> + <system_message backrefs="id9" level="2" line="12" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "five". <paragraph> @@ -303,7 +303,7 @@ and labelled auto-numbered footnotes: <paragraph> Auto-numbered footnote 5. <footnote auto="1" dupname="five" id="id12"> - <system_message backrefs="id12" level="2" source="test data" type="WARNING"> + <system_message backrefs="id12" level="2" line="14" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "five". <paragraph> diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index acf5489d8..7b92edaa9 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -788,7 +788,7 @@ Paragraph <section dupname="..." id="id2"> <title> ... - <system_message backrefs="id2" level="1" source="test data" type="INFO"> + <system_message backrefs="id2" level="1" line="5" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "...". <system_message level="1" line="7" source="test data" type="INFO"> @@ -802,7 +802,7 @@ Paragraph <section dupname="..." id="id3"> <title> ... - <system_message backrefs="id3" level="1" source="test data" type="INFO"> + <system_message backrefs="id3" level="1" line="8" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "...". <paragraph> diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 3fb695201..b8f794ffe 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -133,7 +133,7 @@ Here are some duplicate substitution definitions: Here are some duplicate substitution definitions: <substitution_definition dupname="symbol"> <image alt="symbol" uri="symbol.png"> - <system_message level="3" source="test data" type="ERROR"> + <system_message level="3" line="4" source="test data" type="ERROR"> <paragraph> Duplicate substitution definition name: "symbol". <substitution_definition name="symbol"> diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index b56962f96..612db9290 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -170,7 +170,7 @@ Duplicate external targets (different URIs): <paragraph> Duplicate external targets (different URIs): <target dupname="target" id="target" refuri="first"> - <system_message backrefs="id1" level="2" source="test data" type="WARNING"> + <system_message backrefs="id1" level="2" line="5" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "target". <target dupname="target" id="id1" refuri="second"> @@ -187,7 +187,7 @@ Duplicate external targets (same URIs): <paragraph> Duplicate external targets (same URIs): <target id="target" name="target" refuri="first"> - <system_message backrefs="id1" level="1" source="test data" type="INFO"> + <system_message backrefs="id1" level="1" line="5" source="test data" type="INFO"> <paragraph> Duplicate explicit target name: "target". <target dupname="target" id="id1" refuri="first"> @@ -217,7 +217,7 @@ Paragraph. <section dupname="title" id="id1"> <title> Title - <system_message backrefs="id1" level="1" source="test data" type="INFO"> + <system_message backrefs="id1" level="1" line="9" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "title". <paragraph> @@ -240,7 +240,7 @@ Paragraph. <section dupname="title" id="title"> <title> Title - <system_message backrefs="id1" level="1" source="test data" type="INFO"> + <system_message backrefs="id1" level="1" line="6" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "title". <target id="id1" name="title"> @@ -269,13 +269,13 @@ Third. <target dupname="title" id="title"> <paragraph> First. - <system_message backrefs="id1" level="2" source="test data" type="WARNING"> + <system_message backrefs="id1" level="2" line="7" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "title". <target dupname="title" id="id1"> <paragraph> Second. - <system_message backrefs="id2" level="2" source="test data" type="WARNING"> + <system_message backrefs="id2" level="2" line="11" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "title". <target dupname="title" id="id2"> @@ -312,24 +312,24 @@ Explicit internal target. <citation dupname="target" id="id1"> <label> target - <system_message backrefs="id1" level="1" source="test data" type="INFO"> + <system_message backrefs="id1" level="1" line="8" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "target". <paragraph> Citation target. <footnote auto="1" dupname="target" id="id2"> - <system_message backrefs="id2" level="2" source="test data" type="WARNING"> + <system_message backrefs="id2" level="2" line="10" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "target". <paragraph> Autonumber-labeled footnote target. - <system_message backrefs="id3" level="2" source="test data" type="WARNING"> + <system_message backrefs="id3" level="2" line="12" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "target". <target dupname="target" id="id3"> <paragraph> Explicit internal target. - <system_message backrefs="id4" level="2" source="test data" type="WARNING"> + <system_message backrefs="id4" level="2" line="16" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "target". <target dupname="target" id="id4" refuri="Explicit_external_target"> diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 52ac1e079..8618f4a20 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for `docutils.transforms.parts.Contents` (via `docutils.transforms.universal.LastReaderPending`). """ diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index 0ecd6e2cb..9fafa4ccb 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.frontmatter.DocInfo. """ @@ -94,7 +94,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <field_body> <paragraph> Abstract 2 (should generate a warning). - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="9" source="test data" type="WARNING"> <paragraph> There can only be one "Abstract" field. <date> @@ -134,7 +134,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <list_item> <paragraph> must be a paragraph - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Cannot extract bibliographic field "Author" containing anything other than a single paragraph. <status> @@ -150,14 +150,14 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ But only one <paragraph> paragraph. - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Cannot extract compound bibliographic field "Date". <field> <field_name> Version <field_body> - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="6" source="test data" type="WARNING"> <paragraph> Cannot extract empty bibliographic field "Version". <comment xml:space="preserve"> @@ -248,7 +248,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <field_name> Authors <field_body> - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> Cannot extract empty bibliographic field "Authors". <field> @@ -262,7 +262,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <list_item> <paragraph> Two - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Bibliographic field "Authors" incompatible with extraction: it must contain either a single paragraph (with authors separated by one of ";,"), multiple paragraphs (one per author), or a bullet list with one paragraph (one author) per item. <field> @@ -272,7 +272,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ <bullet_list bullet="-"> <list_item> <list_item> - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="6" source="test data" type="WARNING"> <paragraph> Bibliographic field "Authors" incompatible with extraction: it must contain either a single paragraph (with authors separated by one of ";,"), multiple paragraphs (one per author), or a bullet list with one paragraph (one author) per item. <field> @@ -285,7 +285,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ One <paragraph> Two - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="10" source="test data" type="WARNING"> <paragraph> Bibliographic field "Authors" incompatible with extraction: it must contain either a single paragraph (with authors separated by one of ";,"), multiple paragraphs (one per author), or a bullet list with one paragraph (one author) per item. <field> @@ -298,7 +298,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ One <paragraph> Two - <system_message level="2" source="test data" type="WARNING"> + <system_message level="2" line="15" source="test data" type="WARNING"> <paragraph> Bibliographic field "Authors" incompatible with extraction: it must contain either a single paragraph (with authors separated by one of ";,"), multiple paragraphs (one per author), or a bullet list with one paragraph (one author) per item. """], diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 583f79508..3e08eb232 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.frontmatter.DocTitle. """ diff --git a/test/test_transforms/test_filter.py b/test/test_transforms/test_filter.py index 7feee25cd..53b3246cb 100644 --- a/test/test_transforms/test_filter.py +++ b/test/test_transforms/test_filter.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.components.Filter. """ diff --git a/test/test_transforms/test_final_checks.py b/test/test_transforms/test_final_checks.py index e1cc61850..36c55efda 100755 --- a/test/test_transforms/test_final_checks.py +++ b/test/test_transforms/test_final_checks.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.universal.FinalChecks. """ @@ -34,7 +34,7 @@ Unknown reference_. <problematic id="id2" refid="id1"> reference_ . - <system_message backrefs="id2" id="id1" level="3" source="test data" type="ERROR"> + <system_message backrefs="id2" id="id1" level="3" line="1" source="test data" type="ERROR"> <paragraph> Unknown target name: "reference". """], diff --git a/test/test_transforms/test_footnotes.py b/test/test_transforms/test_footnotes.py index 2a1ac150f..4da43e055 100755 --- a/test/test_transforms/test_footnotes.py +++ b/test/test_transforms/test_footnotes.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.references.Footnotes. """ @@ -218,12 +218,12 @@ Mixed anonymous and labelled auto-numbered footnotes: <footnote auto="1" dupname="five" id="id9"> <label> 6 - <system_message backrefs="id9" level="2" source="test data" type="WARNING"> + <system_message backrefs="id9" level="2" line="12" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "five". <paragraph> Auto-numbered footnote 5 again (duplicate). - <system_message backrefs="id11" id="id10" level="3" source="test data" type="ERROR"> + <system_message backrefs="id11" id="id10" level="3" line="3" source="test data" type="ERROR"> <paragraph> Too many autonumbered footnote references: only 2 corresponding footnotes available. """], @@ -367,12 +367,12 @@ and labelled auto-numbered footnotes: <footnote auto="1" dupname="five" id="id13"> <label> 7 - <system_message backrefs="id13" level="2" source="test data" type="WARNING"> + <system_message backrefs="id13" level="2" line="15" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "five". <paragraph> Auto-numbered footnote 5 again (duplicate). - <system_message backrefs="id15" id="id14" level="3" source="test data" type="ERROR"> + <system_message backrefs="id15" id="id14" level="3" line="4" source="test data" type="ERROR"> <paragraph> Too many autonumbered footnote references: only 2 corresponding footnotes available. """], diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 32ecc182d..6fd3c1d5c 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.references.Hyperlinks. """ @@ -127,7 +127,7 @@ indirect_ internal <section dupname="implicit" id="id1"> <title> Implicit - <system_message backrefs="id1" level="1" source="test data" type="INFO"> + <system_message backrefs="id1" level="1" line="7" source="test data" type="INFO"> <paragraph> Duplicate implicit target name: "implicit". <paragraph> @@ -135,7 +135,7 @@ indirect_ internal indirect_ internal <target id="indirect" name="indirect" refname="implicit"> - <system_message backrefs="id3" id="id2" level="2" source="test data" type="WARNING"> + <system_message backrefs="id3" id="id2" level="2" line="11" source="test data" type="WARNING"> <paragraph> Indirect hyperlink target "indirect" (id="indirect") refers to target "implicit", which does not exist. """], @@ -210,7 +210,7 @@ __ ztarget_ <target dupname="ztarget" id="ztarget"> <paragraph> First - <system_message backrefs="id1" level="2" source="test data" type="WARNING"> + <system_message backrefs="id1" level="2" line="5" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "ztarget". <target dupname="ztarget" id="id1"> @@ -220,7 +220,7 @@ __ ztarget_ <problematic id="id4" refid="id3"> `indirect internal`__ <target anonymous="1" id="id2" refname="ztarget"> - <system_message backrefs="id4" id="id3" level="2" source="test data" type="WARNING"> + <system_message backrefs="id4" id="id3" level="2" line="11" source="test data" type="WARNING"> <paragraph> Indirect hyperlink target (id="id2") refers to target "ztarget", which does not exist. """], @@ -295,7 +295,7 @@ The results of the transform are not visible at the XML level. <document source="test data"> <target id="external-hyperlink" name="external hyperlink" refuri="http://uri"> <target id="indirect-target" name="indirect target" refuri="http://uri"> - <system_message level="1" source="test data" type="INFO"> + <system_message level="1" line="2" source="test data" type="INFO"> <paragraph> Indirect hyperlink target "indirect target" is not referenced. """], @@ -408,7 +408,7 @@ Duplicate external target_'s (different URIs): target 's (different URIs): <target dupname="target" id="target" refuri="first"> - <system_message backrefs="id1" level="2" source="test data" type="WARNING"> + <system_message backrefs="id1" level="2" line="5" source="test data" type="WARNING"> <paragraph> Duplicate explicit target name: "target". <target dupname="target" id="id1" refuri="second"> @@ -434,6 +434,7 @@ __ http://example.org <system_message backrefs="id3 id4 id5" id="id2" level="3" source="test data" type="ERROR"> <paragraph> Anonymous hyperlink mismatch: 3 references but 1 targets. + See "backrefs" attribute for IDs. """], ]) diff --git a/test/test_transforms/test_messages.py b/test/test_transforms/test_messages.py index 56cc3725d..60c768f76 100755 --- a/test/test_transforms/test_messages.py +++ b/test/test_transforms/test_messages.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.universal.Messages. """ @@ -54,7 +54,7 @@ document by the test framework.) <section class="system-messages"> <title> Docutils System Messages - <system_message backrefs="id2" id="id1" level="3" source="test data" type="ERROR"> + <system_message backrefs="id2" id="id1" level="3" line="1" source="test data" type="ERROR"> <paragraph> Undefined substitution referenced: "unknown substitution". """], diff --git a/test/test_transforms/test_sectnum.py b/test/test_transforms/test_sectnum.py index da916dc8e..c4d275539 100644 --- a/test/test_transforms/test_sectnum.py +++ b/test/test_transforms/test_sectnum.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger, Dmitry Jemerov -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger, Dmitry Jemerov +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for `docutils.transforms.parts.SectNum` (via `docutils.transforms.universal.LastReaderPending`). """ diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 763cd8311..ad411db43 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for docutils.transforms.references.Substitutions. """ @@ -48,7 +48,7 @@ Here's an |unknown| substitution. <problematic id="id2" refid="id1"> |unknown| substitution. - <system_message backrefs="id2" id="id1" level="3" source="test data" type="ERROR"> + <system_message backrefs="id2" id="id1" level="3" line="1" source="test data" type="ERROR"> <paragraph> Undefined substitution referenced: "unknown". """], diff --git a/test/test_utils.py b/test/test_utils.py index 2d6fca071..b2771f25c 100755 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -33,7 +33,7 @@ class ReporterTests(unittest.TestCase): debug output """) self.assertEquals(self.stream.getvalue(), - 'Reporter: DEBUG/0 (test data) debug output\n') + 'test data:: (DEBUG/0) debug output\n') def test_level1(self): sw = self.reporter.system_message(1, 'a little reminder') @@ -52,7 +52,7 @@ class ReporterTests(unittest.TestCase): a warning """) self.assertEquals(self.stream.getvalue(), - 'Reporter: WARNING/2 (test data) a warning\n') + 'test data:: (WARNING/2) a warning\n') def test_level3(self): sw = self.reporter.system_message(3, 'an error') @@ -62,12 +62,12 @@ class ReporterTests(unittest.TestCase): an error """) self.assertEquals(self.stream.getvalue(), - 'Reporter: ERROR/3 (test data) an error\n') + 'test data:: (ERROR/3) an error\n') def test_level4(self): self.assertRaises(utils.SystemMessage, self.reporter.system_message, 4, 'a severe error, raises an exception') - self.assertEquals(self.stream.getvalue(), 'Reporter: SEVERE/4 (test data) ' + self.assertEquals(self.stream.getvalue(), 'test data:: (SEVERE/4) ' 'a severe error, raises an exception\n') @@ -163,7 +163,7 @@ class ReporterCategoryTests(unittest.TestCase): self.assertEquals(self.stream.getvalue(), '') sw = self.reporter.debug('debug output') self.assertEquals(self.stream.getvalue(), - 'Reporter: DEBUG/0 (test data) debug output\n') + 'test data:: (DEBUG/0) debug output\n') def test_info(self): sw = self.reporter.info('some info') @@ -171,39 +171,39 @@ class ReporterCategoryTests(unittest.TestCase): sw = self.reporter.info('some info', category='lemon.curry') self.assertEquals( self.stream.getvalue(), - 'Reporter "lemon.curry": INFO/1 (test data) some info\n') + 'test data:: (INFO/1) some info [lemon.curry]\n') def test_warning(self): sw = self.reporter.warning('a warning') self.assertEquals(self.stream.getvalue(), - 'Reporter: WARNING/2 (test data) a warning\n') + 'test data:: (WARNING/2) a warning\n') sw = self.reporter.warning('a warning', category='lemon.curry') self.assertEquals(self.stream.getvalue(), """\ -Reporter: WARNING/2 (test data) a warning -Reporter "lemon.curry": WARNING/2 (test data) a warning +test data:: (WARNING/2) a warning +test data:: (WARNING/2) a warning [lemon.curry] """) def test_error(self): sw = self.reporter.error('an error') self.assertEquals(self.stream.getvalue(), - 'Reporter: ERROR/3 (test data) an error\n') + 'test data:: (ERROR/3) an error\n') self.assertRaises(utils.SystemMessage, self.reporter.error, 'an error', category='lemon.curry') self.assertEquals(self.stream.getvalue(), """\ -Reporter: ERROR/3 (test data) an error -Reporter "lemon.curry": ERROR/3 (test data) an error +test data:: (ERROR/3) an error +test data:: (ERROR/3) an error [lemon.curry] """) def test_severe(self): self.assertRaises(utils.SystemMessage, self.reporter.severe, 'a severe error') self.assertEquals(self.stream.getvalue(), - 'Reporter: SEVERE/4 (test data) a severe error\n') + 'test data:: (SEVERE/4) a severe error\n') self.assertRaises(utils.SystemMessage, self.reporter.severe, 'a severe error', category='lemon.curry') self.assertEquals(self.stream.getvalue(), """\ -Reporter: SEVERE/4 (test data) a severe error -Reporter "lemon.curry": SEVERE/4 (test data) a severe error +test data:: (SEVERE/4) a severe error +test data:: (SEVERE/4) a severe error [lemon.curry] """) -- cgit v1.2.1 From 383b5f2df15a495db48a857018a8ba4e44fa55aa Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 00:43:47 +0000 Subject: many improvements, thanks to Jorge Gonzalez git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@775 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 141 ++++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 50 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index 02a1eedde..65f4f7bb8 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -24,7 +24,7 @@ <p align="right"><em><a href="http://docutils.sourceforge.net/docs/rst/quickref.html" >http://docutils.sourceforge.net/docs/rst/quickref.html</a></em> <br align="right"><em>Being a cheat-sheet for reStructuredText</em> - <br align="right"><em>Updated 2002-10-07</em> + <br align="right"><em>Updated 2002-10-08</em> <p>The full details of the markup may be found on the @@ -56,18 +56,21 @@ <li><a href="#doctest-blocks">Doctest Blocks</a></li> <li><a href="#tables">Tables</a></li> <li><a href="#transitions">Transitions</a></li> + <li><a href="#explicit-markup">Explicit Markup</a> + <ul> <li><a href="#footnotes">Footnotes</a></li> <li><a href="#citations">Citations</a></li> - <li><a href="#hyperlink-targets">Hyperlink Targets</a></li> + <li><a href="#hyperlink-targets">Hyperlink Targets</a> <ul> <li><a href="#external-hyperlink-targets">External Hyperlink Targets</a></li> <li><a href="#internal-hyperlink-targets">Internal Hyperlink Targets</a></li> <li><a href="#indirect-hyperlink-targets">Indirect Hyperlink Targets</a></li> <li><a href="#implicit-hyperlink-targets">Implicit Hyperlink Targets</a></li> - </ul> + </ul></li> <li><a href="#directives">Directives</a></li> <li><a href="#substitution-references-and-definitions">Substitution References and Definitions</a></li> <li><a href="#comments">Comments</a></li> + </ul></li> <li><a href="#getting-help">Getting Help</a></li> </ul> @@ -76,6 +79,10 @@ <p>(<a href="../../spec/rst/reStructuredText.html#inline-markup">details?</a>) + <p>Inline markup allows words and phrases within text to have + character styles (like italics and boldface) and functionality + (like hyperlinks). + <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> <thead> <tr align="left" bgcolor="#99CCFF"> @@ -87,39 +94,47 @@ <tr valign="top"> <td nowrap><samp>*emphasis*</samp> <td><em>emphasis</em> - <td>  + <td>Normally rendered as italics. <tr valign="top"> <td nowrap><samp>**strong emphasis**</samp> <td><strong>strong emphasis</strong> - <td>  + <td>Normally rendered as boldface. <tr valign="top"> <td nowrap><samp>`interpreted text`</samp> - <td>interpreted text - <td>What interpreted text <em>means</em> is domain dependent. + <td>(see note at right) + <td>The rendering and <em>meaning</em> of interpreted text is + domain- or application-dependent. It can be used for things + like index entries or explicit descriptive markup (like program + identifiers). <tr valign="top"> <td nowrap><samp>``inline literal``</samp> <td><code>inline literal</code> - <td>Spaces should be preserved, but line breaks will not be. + <td>Normally rendered as monospaced text. Spaces should be + preserved, but line breaks will not be. <tr valign="top"> <td nowrap><samp>reference_</samp> <td><a href="#hyperlink-targets">reference</a> - <td>A simple, one-word hyperlink reference. See <a href="#hyperlinks">Hyperlinks</a>. + <td>A simple, one-word hyperlink reference. See <a + href="#hyperlinks" >Hyperlinks</a>. <tr valign="top"> <td nowrap><samp>`phrase reference`_</samp> <td><a href="#hyperlink-targets">phrase reference</a> - <td>A hyperlink reference with spaces or punctuation needs to be quoted with backquotes. - See <a href="#hyperlink-targets">Hyperlinks</a>. + <td>A hyperlink reference with spaces or punctuation needs to be + quoted with backquotes. See <a + href="#hyperlink-targets">Hyperlinks</a>. <tr valign="top"> <td nowrap><samp>anonymous__</samp> <td><a href="#hyperlink-targets">anonymous</a> - <td>Both simple and phrase references may be anonymous (two underscores). - See <a href="#hyperlink-targets">Hyperlinks</a>. + <td>With two underscores instead of one, both simple and phrase + references may be anonymous (the reference text is not repeated + at the target). See <a + href="#hyperlink-targets">Hyperlinks</a>. <tr valign="top"> <td nowrap><samp>_`inline internal target`</samp> @@ -129,13 +144,15 @@ <tr valign="top"> <td nowrap><samp>|substitution reference|</samp> - <td>(see note) - <td>The result is substituted in from the <a href="#substitution-references-and-definitions">substitution definition</a>. - It could be text, an image, a hyperlink, or a combination of these and others. + <td>(see note at right) + <td>The result is substituted in from the <a + href="#substitution-references-and-definitions">substitution + definition</a>. It could be text, an image, a hyperlink, or a + combination of these and others. <tr valign="top"> <td nowrap><samp>footnote reference [1]_</samp> - <td>footnote reference <a href="#footnotes">[1]</a> + <td>footnote reference <sup><a href="#footnotes">1</a></sup> <td>See <a href="#footnotes">Footnotes</a>. <tr valign="top"> @@ -159,21 +176,23 @@ (with backslash)</a> or quote them (with double backquotes; i.e. use inline literals). - <p>In detail, the reStructuredText specifications says that in - inline markup: + <p>In detail, the reStructuredText specification says that in + inline markup, the following rules apply to start-strings and + end-strings (inline markup delimiters): + <ol> <li>The start-string must start a text block or be - immediately preceded by whitespace,  - <samp>' " ( [ {</samp> or  <samp><</samp>. + immediately preceded by whitespace or any of  + <samp>' " ( [ {</samp> or <samp><</samp>. <li>The start-string must be immediately followed by non-whitespace. <li>The end-string must be immediately preceded by non-whitespace. - <li>The end-string must end a text block or be immediately - followed by whitespace,  - <samp>' " . , : ; ! ? - ) ] }</samp> or  <samp>></samp>. + <li>The end-string must end a text block (end of document or + followed by a blank line) or be immediately followed by whitespace + or any of <samp>' " . , : ; ! ? - ) ] }</samp> or <samp>></samp>. <li>If a start-string is immediately preceded by one of  - <samp>' " ( [ {</samp> or  <samp><</samp>, it must not be + <samp>' " ( [ {</samp> or <samp><</samp>, it must not be immediately followed by the corresponding character from  - <samp>' " ) ] }</samp> or  <samp>></samp>. + <samp>' " ) ] }</samp> or <samp>></samp>. <li>An end-string must be separated by at least one character from the start-string. <li>An <a href="#escaping">unescaped</a> backslash preceding a start-string or end-string will @@ -798,8 +817,17 @@ A transition marker is a horizontal line gap spanning one or more lines, marking text divisions or signaling changes in subject, time, point of view, or emphasis. - <h2><a href="#contents" name="footnotes" class="backref" - >Footnotes</a></h2> + <h2><a href="#contents" name="explicit-markup" class="backref" + >Explicit Markup</a></h3> + + <p>Explicit markup blocks are used for constructs which float + (footnotes), have no direct paper-document representation, + (hyperlink targets, comments), or require specialized processing + (directives). They all begin with two periods and whitespace, the + "explicit markup start". + + <h3><a href="#contents" name="footnotes" class="backref" + >Footnotes</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#footnotes">details?</a>) @@ -822,7 +850,7 @@ A transition marker is a horizontal line <br><samp>   there's no colon after the ``]``.</samp> <td> - Footnote references, like <sup><a href="#5">[5]</a></sup>. + Footnote references, like <sup><a href="#5">5</a></sup>. Note that footnotes may get rearranged, e.g., to the bottom of the "page". @@ -891,8 +919,8 @@ A transition marker is a horizontal line same relative order. Similarly for auto-symbol footnotes ("<samp>[*]_</samp>"). - <h2><a href="#contents" name="citations" class="backref" - >Citations</a></h2> + <h3><a href="#contents" name="citations" class="backref" + >Citations</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#citations">details?</a>) @@ -944,13 +972,13 @@ A transition marker is a horizontal line </table> - <h2><a href="#contents" name="hyperlink-targets" class="backref" - >Hyperlink Targets</a></h2> + <h3><a href="#contents" name="hyperlink-targets" class="backref" + >Hyperlink Targets</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#hyperlink-targets">details?</a>) - <h3><a href="#contents" name="external-hyperlink-targets" class="backref" - >External Hyperlink Targets</a></h3> + <h4><a href="#contents" name="external-hyperlink-targets" class="backref" + >External Hyperlink Targets</a></h4> <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> <thead> @@ -988,8 +1016,8 @@ A transition marker is a horizontal line printed documents, where the link needs to be presented explicitly, for example as a footnote. - <h3><a href="#contents" name="internal-hyperlink-targets" class="backref" - >Internal Hyperlink Targets</a></h3> + <h4><a href="#contents" name="internal-hyperlink-targets" class="backref" + >Internal Hyperlink Targets</a></h4> <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> <thead> @@ -1024,8 +1052,8 @@ A transition marker is a horizontal line </table> - <h3><a href="#contents" name="indirect-hyperlink-targets" class="backref" - >Indirect Hyperlink Targets</a></h3> + <h4><a href="#contents" name="indirect-hyperlink-targets" class="backref" + >Indirect Hyperlink Targets</a></h4> <p>(<a href="../../spec/rst/reStructuredText.html#indirect-hyperlink-targets">details?</a>) @@ -1058,10 +1086,14 @@ A transition marker is a horizontal line (<i>indirectly</i> pointing at the Python website via the "<samp>Python_</samp>" reference) and an <b>anonymous hyperlink target</b>. In the text, a double-underscore suffix is used to - indicate an <b>anonymous hyperlink reference</b>. + indicate an <b>anonymous hyperlink reference</b>. In an anonymous + hyperlink target, the reference text is not repeated. This is + useful for references with long text or throw-away references, but + the target should be kept close to the reference to prevent them + going out of sync. - <h3><a href="#contents" name="implicit-hyperlink-targets" class="backref" - >Implicit Hyperlink Targets</a></h3> + <h4><a href="#contents" name="implicit-hyperlink-targets" class="backref" + >Implicit Hyperlink Targets</a></h4> <p>(<a href="../../spec/rst/reStructuredText.html#implicit-hyperlink-targets">details?</a>) @@ -1087,11 +1119,17 @@ A transition marker is a horizontal line targets, too</a>. </table> - <h2><a href="#contents" name="directives" class="backref" - >Directives</a></h2> + <h3><a href="#contents" name="directives" class="backref" + >Directives</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#directives">details?</a>) + <p>Directives are a general-purpose extension mechanism, a way of + adding support for new constructs without adding new syntax. For + a description of all standard directives, see <a + href="../../spec/rst/directives.html" >reStructuredText + Directives</a>. + <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> <thead> <tr align="left" bgcolor="#99CCFF"> @@ -1109,8 +1147,8 @@ A transition marker is a horizontal line <p><img src="images/ball1.gif" alt="ball1"> </table> - <h2><a href="#contents" name="substitution-references-and-definitions" - class="backref" >Substitution References and Definitions</a></h2> + <h3><a href="#contents" name="substitution-references-and-definitions" + class="backref" >Substitution References and Definitions</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#substitution-definitions">details?</a>) @@ -1140,11 +1178,14 @@ dispose of medical waste.</samp> </table> - <h2><a href="#contents" name="comments" class="backref" - >Comments</a></h2> + <h3><a href="#contents" name="comments" class="backref" + >Comments</a></h3> <p>(<a href="../../spec/rst/reStructuredText.html#comments">details?</a>) + <p>Any text which begins with an explicit markup start but doesn't + use the syntax of any of the constructs above, is a comment. + <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> <thead> <tr align="left" bgcolor="#99CCFF"> @@ -1164,13 +1205,13 @@ dispose of medical waste.</samp> <tr valign="top"> <td> - <samp>An empty "comment" directive does not</samp> + <samp>An empty "comment" does not</samp> <br><samp>"consume" following blocks.</samp> <p><samp>..</samp> <p><samp>        So this block is not "lost",</samp> <br><samp>        despite its indentation.</samp> <td> - An empty "comment" directive does not + An empty "comment" does not "consume" following blocks. <blockquote> So this block is not "lost", -- cgit v1.2.1 From 8016246d7ce753e06932376eaed76ab26e6eeb22 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 00:48:31 +0000 Subject: fixed DOCTYPE declaration git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@776 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 16 ++++++++-------- tools/pep-html-template | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9bbd81e15..6a784103d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -133,15 +133,15 @@ class HTMLTranslator(nodes.NodeVisitor): """ xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' - doctype = '<!DOCTYPE html' \ - ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' \ - ' SYSTEM "http://www.w3.org/TR/xhtml1/DTD/' \ - 'xhtml1-transitional.dtd">\n' + doctype = ('<!DOCTYPE html' + ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' + ' "http://www.w3.org/TR/xhtml1/DTD/' + 'xhtml1-transitional.dtd">\n') html_head = '<html lang="%s">\n<head>\n' - content_type = '<meta http-equiv="Content-Type" content="text/html; ' \ - 'charset=%s" />\n' - generator = '<meta name="generator" content="Docutils %s: ' \ - 'http://docutils.sourceforge.net/" />\n' + content_type = ('<meta http-equiv="Content-Type" content="text/html; ' + 'charset=%s" />\n') + generator = ('<meta name="generator" content="Docutils %s: ' + 'http://docutils.sourceforge.net/" />\n') stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' embedded_stylesheet = '<style type="text/css"><!--\n\n%s\n--></style>\n' named_tags = {'a': 1, 'applet': 1, 'form': 1, 'frame': 1, 'iframe': 1, diff --git a/tools/pep-html-template b/tools/pep-html-template index 49f367bf8..5549c5d6d 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="%(encoding)s"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s"> -- cgit v1.2.1 From 7413a2c5688f098e12539710604fa046ed41b0c2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 00:49:50 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@777 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 129 ++++++++++++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 67 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 749188f6d..e28f59b80 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -87,80 +87,78 @@ General Ideas: - - A queue, with entries ``(priority, transform, pending=None)``. - - Transform classes can have ``priority`` class attributes. - Each transform could have a unique priority. Use a look-up table? - No, that would require too many imports to construct. - - Priorities can be numeric. Integers (0..100? 0..999? - 0..9999?)? Floats (would be easier to squeeze in new ones)? - - Priorities can be strings. Numeric (000..999? 0000..9999?)? - Alphanumeric (a..z? 1, 1a, 1b, ...?)? - - Document transform priorities. - - Add a ``Transformer`` class to register and execute transforms. - Perhaps ``Transformer.add_transform(transform, priority=None)``, - where ``priority`` can be used to override the transform class' - ``default_priority`` class attribute (used if ``None``). - - Perhaps a ``Transformer.add_transforms(transform_list)`` method - for quick population. ``docutils.Component`` could be the host - for the "transforms" class attribute and an ``add_transforms()``. - A ``self.add_transforms()`` call could be added to component - initialization routines. - - How to handle ``pending`` elements? Perhaps a - ``Transformer.add_transform(transform, priority=None)`` method? - Just call it from ``nodes.document.note_pending()``. + - Add a ``Transformer`` class that registers and executes + transforms. -* @@@ Break up ``references.Hyperlinks`` into multiple smaller - transforms. + - Class contains a queue, with entries ``(priority, transform, + pending=None)``. -* Make it easier to say, "Here's a reStructuredText string; give me - HTML." Maybe ``core.publish_string()``; rename ``core.publish`` to - ``core.publish_file()``? + - Perhaps ``Transformer.add_transform(transform, priority=None)``, + where ``priority`` can be used to override the transform class' + ``default_priority`` class attribute (used if ``None``). -* @@@@ All system messages should have a "line" attribute, to improve - diagnostic output. So all elements constructed by the parser should - have internal "line" ("lineno"/"line_number") attributes. They'd - need internal "source" attributes as well (populating the external - "source" attribute would clutter up the output). + - Perhaps a ``Transformer.add_transforms(transform_list)`` method + for quick population. ``docutils.Component`` could be the host + for the ``default_transforms`` class attribute and an + ``add_transforms()`` method. - Is there any way we can get this to happen automagically, without - having to add the attribute manually to each object? System - messages get their "source" attribute from the Reporter object (new - one for each source). + - How to handle ``pending`` elements? Perhaps a + ``Transformer.add_pending(pending, priority=None)`` method? + Just call it from ``nodes.document.note_pending()``. Need to + re-sort the queue whenever a new transform is added. - - Add an observer subject interface to StateMachine, called whenever - next_line, previous_line, or goto_line is called? + - Who creates a ``Transformer`` object? Attach it to the + ``document`` object? Needs to be accessible when instantiating + other components? Or when "runtime initializing" them. - - Who to notify? Publisher? Document object? Singleton? + - Should components initialize the ``Transformer`` object (add + ``self.add_transforms()`` calls to components' ``__init__``), or + should the ``Transformer`` initialize itself, accessing the + transform lists of the components? - - Document object: add ``note_source``, ``note_line_number`` - methods. ``note_line_number`` is called by - ``StateMachine.notify_observers``. Whatever reads the source - calls ``note_source`` (``utils.new_document()``, "include" - directive. + - Pass a ``Transformer`` object at component instantiation time? - - Add a ``line=None`` parameter to ``nodes.Node``; if unspecified, - it will get the line number from the observer. (``source=None`` - too?) + - Transform classes can have ``priority`` class attributes. + Each transform could have a unique priority. Use a look-up table? + No, that would require too many imports to construct. - - Perhaps ``Element.append()`` etc. can also set the ``.document`` - attribute of each node added. The document object could hold the - current line number and source description, which would also be - copied over to the node. Consolidate all assignments (parent, - document, source, line) into a single method. + - Priorities can be numeric. Integers (0..100? 0..999? + 100..999? 0..9999?)? Floats (would be easier to squeeze in new + ones)? -* @@@ Change stderr Reporter output to the GNU utilities format:: + - Priorities can be strings. Numeric (000..999? 100..999? + 0000..9999?)? Alphanumeric (a..z? 1, 1a, 1b, ...?)? - file:line: message + - Document transform priorities. - or the BSD 4.3 cc format:: + - Change ``Transform.transform()`` to ``Transform.apply()``? + + :: + + +--------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish() | + +--------------------------+ + / | \ + / | \ + 1,3,5 / 6 | \ 7 + +--------+ +-------------+ +--------+ + | READER | ====> | TRANSFORMER | ===> | WRITER | + +--------+ +-------------+ +--------+ + / \\ | + / \\ | + 2 / 4 \\ 8 | + +-----+ +--------+ +-----+ + | I/O | | PARSER | | I/O | + +-----+ +--------+ +-----+ - file(line): message +* @@@ Break up ``references.Hyperlinks`` into multiple smaller + transforms. - The GNU utilities format doesn't work well on MacOS 9 & earlier, - where directory separators are colons. "filename.txt:1:" looks like - a file or directory path. Does MacOS X still use colons, or has it - switched to slashes? In any case, the ubiquity of the GNU utilities - probably outweighs any such problem. +* Make it easier to say, "Here's a reStructuredText string; give me + HTML." Maybe ``core.publish_string()``; rename ``core.publish`` to + ``core.publish_file()``? * Standalone Reader: Implement an option to turn off the DocTitle transform? @@ -535,12 +533,9 @@ __ rst/alternatives.html#or-not-to-do (And arguably invalid, since in Japanese the word "haiku" contains three syllables.) -* Modify acceptable "simple reference name" syntax to allow for - ``object.__method__`` without requiring inline literals? Simple - reference names currently allow any of "-", "_", and "." internally; - if we limit this to one at a time, problem solved. I.e., none of - these would be recognized as simple names: "one..two", "one-.two", - "one._two", "one__two". +* Implement auto-enumerated lists? See `Auto-Enumerated Lists`__. + + __ rst/alternatives.html#auto-enumerated-lists Directives @@ -616,7 +611,7 @@ Directives default and only enabled with an explicit command-line option or config file setting. Even then, an interactive prompt may be useful, such as: - + The file.txt document you are processing contains a "system" directive requesting that the ``sudo rm -rf /`` command be executed. Allow it to execute? (y/N) -- cgit v1.2.1 From efdd39867964b92520a58c6796658895e412c441 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 00:51:53 +0000 Subject: changed docstring field lists into comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@778 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 12 +++++------- docutils/frontend.py | 12 +++++------- docutils/io.py | 12 +++++------- docutils/languages/__init__.py | 12 +++++------- docutils/languages/de.py | 12 +++++------- docutils/languages/en.py | 12 +++++------- docutils/languages/sv.py | 12 +++++------- docutils/parsers/__init__.py | 12 ++++++------ docutils/parsers/rst/__init__.py | 15 +++++++-------- docutils/parsers/rst/languages/__init__.py | 12 +++++------- docutils/parsers/rst/languages/en.py | 12 +++++------- docutils/parsers/rst/languages/sv.py | 12 +++++------- docutils/readers/pep.py | 12 +++++------- docutils/readers/standalone.py | 12 +++++------- docutils/writers/__init__.py | 12 +++++------- docutils/writers/docutils_xml.py | 12 +++++------- docutils/writers/pseudoxml.py | 12 +++++------- test/DocutilsTestSupport.py | 12 +++++------- test/alltests.py | 12 ++++++------ test/package_unittest.py | 12 ++++++------ test/test_nodes.py | 12 ++++++------ test/test_parsers/test_rst/test_SimpleTableParser.py | 12 ++++++------ test/test_parsers/test_rst/test_TableParser.py | 12 ++++++------ test/test_parsers/test_rst/test_block_quotes.py | 12 ++++++------ test/test_parsers/test_rst/test_bullet_lists.py | 12 ++++++------ test/test_parsers/test_rst/test_citations.py | 12 ++++++------ test/test_parsers/test_rst/test_comments.py | 12 ++++++------ test/test_parsers/test_rst/test_doctest_blocks.py | 12 ++++++------ test/test_parsers/test_rst/test_enumerated_lists.py | 12 ++++++------ test/test_parsers/test_rst/test_field_lists.py | 12 ++++++------ test/test_parsers/test_rst/test_footnotes.py | 12 ++++++------ test/test_parsers/test_rst/test_functions.py | 12 ++++++------ test/test_parsers/test_rst/test_inline_markup.py | 12 ++++++------ test/test_parsers/test_rst/test_option_lists.py | 12 ++++++------ test/test_parsers/test_rst/test_outdenting.py | 12 ++++++------ test/test_parsers/test_rst/test_paragraphs.py | 12 ++++++------ test/test_parsers/test_rst/test_substitutions.py | 12 ++++++------ test/test_parsers/test_rst/test_targets.py | 12 ++++++------ test/test_readers/test_pep/test_inline_markup.py | 12 ++++++------ test/test_readers/test_pep/test_rfc2822.py | 12 ++++++------ test/test_utils.py | 12 ++++++------ 41 files changed, 231 insertions(+), 264 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 8354d8393..6eee3829e 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Calling the `publish` convenience function (or instantiating a `Publisher` object) with component names will result in default behavior. For custom behavior (setting component options), create diff --git a/docutils/frontend.py b/docutils/frontend.py index 24cf7735c..f99c3f667 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Command-line and common processing for Docutils front-end tools. Exports the following classes: diff --git a/docutils/io.py b/docutils/io.py index db156b9a0..6f7c138bd 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - I/O classes provide a uniform API for low-level input and output. Subclasses will exist for a variety of input/output mechanisms. """ diff --git a/docutils/languages/__init__.py b/docutils/languages/__init__.py index bdddb5697..eb241a02e 100644 --- a/docutils/languages/__init__.py +++ b/docutils/languages/__init__.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This package contains modules for language-dependent features of Docutils. """ diff --git a/docutils/languages/de.py b/docutils/languages/de.py index 8c512dc14..b6068da2a 100644 --- a/docutils/languages/de.py +++ b/docutils/languages/de.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger; Gunnar Schwant +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger; Gunnar Schwant -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - German language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/en.py b/docutils/languages/en.py index fb320511d..4ca94d632 100644 --- a/docutils/languages/en.py +++ b/docutils/languages/en.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - English-language mappings for language-dependent features of Docutils. """ diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index f2019c16e..97fbcd470 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: Adam Chodorowski +# Contact: chodorowski@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: Adam Chodorowski -:Contact: chodorowski@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Swedish language mappings for language-dependent features of Docutils. """ diff --git a/docutils/parsers/__init__.py b/docutils/parsers/__init__.py index 0294da0f8..b5717e0d3 100644 --- a/docutils/parsers/__init__.py +++ b/docutils/parsers/__init__.py @@ -1,11 +1,11 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +This package contains Docutils parser modules. """ __docformat__ = 'reStructuredText' diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 4bc8970c4..1a8b26c72 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -1,13 +1,12 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`. +This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`, +the reStructuredText parser. Usage ===== diff --git a/docutils/parsers/rst/languages/__init__.py b/docutils/parsers/rst/languages/__init__.py index 4a5441e9e..8f78fc481 100644 --- a/docutils/parsers/rst/languages/__init__.py +++ b/docutils/parsers/rst/languages/__init__.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This package contains modules for language-dependent features of reStructuredText. """ diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 34c4c101a..f162c7a9a 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - English-language mappings for language-dependent features of reStructuredText. """ diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 2d45a5222..b68040cf3 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: Adam Chodorowski +# Contact: chodorowski@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: Adam Chodorowski -:Contact: chodorowski@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Swedish language mappings for language-dependent features of reStructuredText. """ diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b051d63b9..b1b514886 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Python Enhancement Proposal (PEP) Reader. """ diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 24a8074e7..0eca2e7da 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Standalone file Reader for the reStructuredText markup syntax. """ diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 4dabe2241..42bdeb8ce 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - This package contains Docutils Writer modules. """ diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index e005c7861..14b218dcd 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Simple internal document tree Writer, writes Docutils XML. """ diff --git a/docutils/writers/pseudoxml.py b/docutils/writers/pseudoxml.py index c1ba29347..02dde58f3 100644 --- a/docutils/writers/pseudoxml.py +++ b/docutils/writers/pseudoxml.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Simple internal document tree Writer, writes indented pseudo-XML. """ diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 4f1a4c76b..6e9c804e5 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -1,12 +1,10 @@ -#! /usr/bin/env python +# Authors: David Goodger; Garth Kidd +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. """ -:Authors: David Goodger; Garth Kidd -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - Exports the following: :Modules: diff --git a/test/alltests.py b/test/alltests.py index ed16f095d..e5b2e57bc 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -1,12 +1,12 @@ #!/usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" All modules named 'test_*.py' in the current directory, and recursively in subdirectories (packages) called 'test_*', are loaded and test suites within are run. diff --git a/test/package_unittest.py b/test/package_unittest.py index ad9b33aba..019d6fb38 100644 --- a/test/package_unittest.py +++ b/test/package_unittest.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: Garth Kidd -:Contact: garth@deadlybloodyserious.com -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: Garth Kidd +# Contact: garth@deadlybloodyserious.com +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" This module extends unittest.py with `loadTestModules()`, by loading multiple test modules from a directory. Optionally, test packages are also loaded, recursively. diff --git a/test/test_nodes.py b/test/test_nodes.py index 3766a695d..a33607c2c 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Test module for nodes.py. """ diff --git a/test/test_parsers/test_rst/test_SimpleTableParser.py b/test/test_parsers/test_rst/test_SimpleTableParser.py index dca3798c0..3bb669db1 100644 --- a/test/test_parsers/test_rst/test_SimpleTableParser.py +++ b/test/test_parsers/test_rst/test_SimpleTableParser.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_TableParser.py b/test/test_parsers/test_rst/test_TableParser.py index daba2c1b0..08b13fc8c 100755 --- a/test/test_parsers/test_rst/test_TableParser.py +++ b/test/test_parsers/test_rst/test_TableParser.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_block_quotes.py b/test/test_parsers/test_rst/test_block_quotes.py index 4488415d1..86256cc56 100755 --- a/test/test_parsers/test_rst/test_block_quotes.py +++ b/test/test_parsers/test_rst/test_block_quotes.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_bullet_lists.py b/test/test_parsers/test_rst/test_bullet_lists.py index ee64a2c1d..12ede6cf1 100755 --- a/test/test_parsers/test_rst/test_bullet_lists.py +++ b/test/test_parsers/test_rst/test_bullet_lists.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_citations.py b/test/test_parsers/test_rst/test_citations.py index 508a5f9a0..a92e151a4 100755 --- a/test/test_parsers/test_rst/test_citations.py +++ b/test/test_parsers/test_rst/test_citations.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_comments.py b/test/test_parsers/test_rst/test_comments.py index 193a6cfc1..a90135ec5 100755 --- a/test/test_parsers/test_rst/test_comments.py +++ b/test/test_parsers/test_rst/test_comments.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_doctest_blocks.py b/test/test_parsers/test_rst/test_doctest_blocks.py index 9e2f07655..c9637c6d6 100755 --- a/test/test_parsers/test_rst/test_doctest_blocks.py +++ b/test/test_parsers/test_rst/test_doctest_blocks.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index 9f4f97cce..b89691516 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_field_lists.py b/test/test_parsers/test_rst/test_field_lists.py index 6001d0771..4bdf07527 100755 --- a/test/test_parsers/test_rst/test_field_lists.py +++ b/test/test_parsers/test_rst/test_field_lists.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_footnotes.py b/test/test_parsers/test_rst/test_footnotes.py index f58be22ea..00e5c1f5d 100755 --- a/test/test_parsers/test_rst/test_footnotes.py +++ b/test/test_parsers/test_rst/test_footnotes.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_functions.py b/test/test_parsers/test_rst/test_functions.py index 2cf7c6a7e..e6694b2c5 100755 --- a/test/test_parsers/test_rst/test_functions.py +++ b/test/test_parsers/test_rst/test_functions.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index 2ee79a4b5..5c45c3c27 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_option_lists.py b/test/test_parsers/test_rst/test_option_lists.py index ba5e3ad12..e7f17f615 100755 --- a/test/test_parsers/test_rst/test_option_lists.py +++ b/test/test_parsers/test_rst/test_option_lists.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_outdenting.py b/test/test_parsers/test_rst/test_outdenting.py index e728ebbba..1522b7f30 100755 --- a/test/test_parsers/test_rst/test_outdenting.py +++ b/test/test_parsers/test_rst/test_outdenting.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_paragraphs.py b/test/test_parsers/test_rst/test_paragraphs.py index 150387f75..8ec8cbbc5 100755 --- a/test/test_parsers/test_rst/test_paragraphs.py +++ b/test/test_parsers/test_rst/test_paragraphs.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index b8f794ffe..7a1c9c7a1 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index 612db9290..afa7d6fbb 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for states.py. """ diff --git a/test/test_readers/test_pep/test_inline_markup.py b/test/test_readers/test_pep/test_inline_markup.py index 2096ee969..aed06e770 100644 --- a/test/test_readers/test_pep/test_inline_markup.py +++ b/test/test_readers/test_pep/test_inline_markup.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for inline markup in PEPs (readers/pep.py). """ diff --git a/test/test_readers/test_pep/test_rfc2822.py b/test/test_readers/test_pep/test_rfc2822.py index 974d2c54b..13d1c96ea 100644 --- a/test/test_readers/test_pep/test_rfc2822.py +++ b/test/test_readers/test_pep/test_rfc2822.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Tests for RFC-2822 headers in PEPs (readers/pep.py). """ diff --git a/test/test_utils.py b/test/test_utils.py index b2771f25c..06da8c0e2 100755 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -""" -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. +""" Test module for utils.py. """ -- cgit v1.2.1 From 14bdfad14a8717b9672fe5b7a4e9b1aecb1e02ce Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 00:59:53 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@779 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index 65f4f7bb8..b1a1bb3ed 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -821,7 +821,7 @@ A transition marker is a horizontal line >Explicit Markup</a></h3> <p>Explicit markup blocks are used for constructs which float - (footnotes), have no direct paper-document representation, + (footnotes), have no direct paper-document representation (hyperlink targets, comments), or require specialized processing (directives). They all begin with two periods and whitespace, the "explicit markup start". -- cgit v1.2.1 From 71cd002d07424cfa16059a3069f16bc4efac13a1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 9 Oct 2002 01:39:12 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@780 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e28f59b80..b29f6d10d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -133,7 +133,7 @@ General - Change ``Transform.transform()`` to ``Transform.apply()``? - :: + Updated project model under consideration for PEP 258:: +--------------------------+ | Docutils: | -- cgit v1.2.1 From 0aae6532d69456b387c15261eba7e2f8e1adf146 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 10 Oct 2002 03:02:49 +0000 Subject: fixed bug with embedded stylesheets & paths git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@781 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 11 +++++++---- docutils/writers/pep_html.py | 11 ++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 6a784103d..922867b1e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -17,6 +17,7 @@ __docformat__ = 'reStructuredText' import sys +import os import time import re from types import ListType @@ -159,11 +160,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.content_type % options.output_encoding, self.generator % docutils.__version__] self.head = [] - stylesheet = self.get_stylesheet_reference() if options.embed_stylesheet: + stylesheet = self.get_stylesheet_reference(os.getcwd()) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] else: + stylesheet = self.get_stylesheet_reference() self.stylesheet = [self.stylesheet_link % stylesheet] self.body_prefix = ['</head>\n<body>\n'] self.body_pre_docinfo = [] @@ -178,11 +180,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.compact_simple = None self.in_docinfo = None - def get_stylesheet_reference(self): + def get_stylesheet_reference(self, relative_to=None): options = self.options if options.stylesheet_path: - return utils.relative_path(options._destination, - options.stylesheet_path) + if relative_to == None: + relative_to = options._destination + return utils.relative_path(relative_to, options.stylesheet_path) else: return options.stylesheet diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index a883fecd1..69c0492bc 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -93,20 +93,21 @@ class Writer(html4css1.Writer): class HTMLTranslator(html4css1.HTMLTranslator): - def get_stylesheet_reference(self): + def get_stylesheet_reference(self, relative_to=None): options = self.options + if relative_to == None: + relative_to = options._destination if options.pep_stylesheet_path: - return utils.relative_path(options._destination, + return utils.relative_path(relative_to, options.pep_stylesheet_path) elif options.pep_stylesheet: return options.pep_stylesheet elif options._stylesheet_path: - return utils.relative_path(options._destination, - options.stylesheet_path) + return utils.relative_path(relative_to, options.stylesheet_path) else: return options.stylesheet def depart_field_list(self, node): html4css1.HTMLTranslator.depart_field_list(self, node) - if node.hasattr('class') and node['class'] == 'rfc2822': + if node.get('class') == 'rfc2822': self.body.append('<hr />\n') -- cgit v1.2.1 From bceac09bdf0941abdbdb4690f76cac31fee63176 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 10 Oct 2002 03:02:57 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@782 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 7 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b29f6d10d..96ed3ac28 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -70,7 +70,7 @@ General avoid importing top-level modules if the module name is not in docutils/readers. Potential nastiness.) -* Perhaps store a name-to-id mapping file? This could be stored +* Perhaps store a _`name-to-id mapping file`? This could be stored permanently, read by subsequent processing runs, and updated with new entries. ("Persistent ID mapping"?) @@ -170,11 +170,100 @@ General .. _Filesystem Hierarchy Standard: http://www.pathname.com/fhs. +* Add object numbering and object references (tables & figures). + + We'll need _`persistent sequences`, such as chapter numbers. See + OpenOffice XML "fields". + + We need to name the objects: + + - "name" attribute for the "figure" directive? :: + + .. figure:: image.png + :name: image's name + + How to name tables, which don't need directives? + + - But this could also be done this way (perhaps more generally):: + + .. _figure name: + + .. figure:: image.png + + Applies equally well to tables. + + We'll also need syntax for object references. See OpenOffice XML + "reference fields": + + - Parameterized substitutions? For example:: + + See |figure (figure name)|, on |page (figure name)|. + + .. |figure (name)| figure-ref:: (name) + .. |page (name)| page-ref:: (name) + + The result would be:: + + See figure 3.11 on page 157. + + But this would require substitution directives to be processed at + reference-time, not at definition-time as they are now. Or, + perhaps the directives could just leave ``pending`` elements + behind, and the transforms do the work? How to pass the data + through? + + - An interpreted text approach is better:: + + See :figure:`figure name` on :page:`figure name`. + + The "figure" and "page" roles could generate some boilerplate + text. The position of the role (prefix or suffix) could also be + utilized. + +* Think about large documents made up of multiple subdocument files. + Issues: continuity (`persistent sequences`_ above), cross-references + (`name-to-id mapping file`_ above and `targets in other documents`_ + below). + + When writing a book, the author probably wants to split it up into + files, perhaps one per chapter (but perhaps even more detailed). + However, we'd like to be able to have references from one chapter to + another, and have continuous numbering (pages and chapters, as + applicable). Of course, none of this is implemented yet. There has + been some thought put into some aspects; see `the "include" + directive`__ and the `Reference Merging`_ transform below. + + When I was working with SGML in Japan, we had a system where there + was a top-level coordinating file, book.sgml, which contained the + top-level structure of a book: the <book> element, containing the + book <title> and empty component elements (<preface>, <chapter>, + <appendix>, etc.), each with filename attributes pointing to the + actual source for the component. Something like this:: + + <book id="bk01"> + <title>Title of the Book + + + + + + + + (The "inrefid" attribute stood for "insertion reference ID".) + + The processing system would process each component separately, but + it would recognize and use the book file to coordinate chapter and + page numbering, and keep a persistent ID to (title, page number) + mapping database for cross-references. Docutils could use a similar + system for large-scale, multipart documents. + + __ rst/directives.html#including-an-external-document-fragment + Documentation ------------- -* User docs. +* User docs. What's needed? Implementation Docs @@ -185,7 +274,7 @@ Implementation Docs * spec/doctree.txt: DTD element structural relationships, semantics, and attributes. In progress; element descriptions to be completed. -* How-to docs: In spec/howto/? +* How-to docs: In spec/howto/. - How a Writer works & how to write one @@ -210,7 +299,8 @@ Specification [Tibs:] Eventually we need to have direct documentation in there on how it all hangs together - the DTD is not enough - (indeed, is it still meant to be correct? [Yes, it is.]). + (indeed, is it still meant to be correct? [Yes, it is. + --DG]). * Rework PEP 257, separating style from spec from tools, wrt Docutils? See Doc-SIG from 2001-06-19/20. @@ -299,8 +389,8 @@ __ rst/alternatives.html#or-not-to-do * And for the sake of completeness, should definition list terms be allowed to be very long (two or more lines) also? -* Support generic hyperlink references to targets in other documents? - Not in an HTML-centric way, though (it's trivial to say +* Support generic hyperlink references to _`targets in other + documents`? Not in an HTML-centric way, though (it's trivial to say ``http://www.example.com/doc#name``, and useless in non-HTML contexts). XLink/XPointer? ``.. baseref::``? See Doc-SIG 2001-08-10. @@ -547,7 +637,7 @@ Directives * Implement attributes on existing directives: - - _`images.image`: "align", "border"? + - _`images.image`: "border"? - _`parts.sectnum`: "start", "local"? -- cgit v1.2.1 From 169d69a9240948a2f22df0161ddc36406eaea21e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 01:33:01 +0000 Subject: Fixed a bug with images; they must be inline, so wrapped in

    . git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@784 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 922867b1e..7f1504158 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -689,10 +689,15 @@ class HTMLTranslator(nodes.NodeVisitor): del atts['uri'] if not atts.has_key('alt'): atts['alt'] = atts['src'] + if isinstance(node.parent, nodes.TextElement): + self.context.append('') + else: + self.body.append('

    ') + self.context.append('

    \n') self.body.append(self.emptytag(node, 'img', '', **atts)) def depart_image(self, node): - pass + self.body.append(self.context.pop()) def visit_important(self, node): self.visit_admonition(node, 'important') -- cgit v1.2.1 From 4603963c8427450ad344a270c018d1cc1f6effe1 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 01:33:23 +0000 Subject: bugfix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@785 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 52ee4d9b6..cc073e9c7 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -563,7 +563,7 @@ class Footnotes(Transform): 'Too many symbol footnote references: only %s ' 'corresponding footnotes available.' % len(labels), base_node=ref) - msgid = self.set_id(msg) + msgid = self.document.set_id(msg) for ref in self.document.symbol_footnote_refs[i:]: if ref.resolved or ref.hasattr('refid'): continue -- cgit v1.2.1 From 62de3120694f48834addfcd85a9c85dc95feac42 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 01:34:35 +0000 Subject: Added "--tab-width" option. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@786 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 9 +++++++-- docutils/parsers/rst/__init__.py | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 6422eab05..0cf585f6e 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -446,7 +446,7 @@ pep_home (PEP/HTML Writer.) Home URL prefix for PEPs. ``--pep-home``. -------------------- ------------------------------------------------ pep_references (reStructuredText Parser.) Recognize and link - to PEP references (like "PEP 258") + to PEP references (like "PEP 258"). Default: disabled (None); enabled (1) in PEP Reader. Options: ``--pep-references``. @@ -490,7 +490,7 @@ report_level Verbosity threshold at or above which system --verbose, -v, --quiet, -q``. -------------------- ------------------------------------------------ rfc_references (reStructuredText Parser.) Recognize and link - to RFC references (like "RFC 822") + to RFC references (like "RFC 822"). Default: disabled (None); enabled (1) in PEP Reader. Options: ``--rfc-references``. @@ -528,6 +528,11 @@ stylesheet-path (HTML Writer.) Path to CSS stylesheet [#pwd]_. Default: None. Options: ``--stylesheet``. -------------------- ------------------------------------------------ +tab_width (reStructuredText Parser.) Number of spaces for + hard tab expansion. + + Default: 8. Options: ``--tab-width``. +-------------------- ------------------------------------------------ toc_backlinks Enable backlinks from section titles to table of contents entries ("entry"), to the top of the TOC ("top"), or disable ("none"). diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 1a8b26c72..c8077de48 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -65,7 +65,10 @@ class Parser(docutils.parsers.Parser): {'action': 'store_true'}), ('Recognize and link to RFC references (like "RFC 822").', ['--rfc-references'], - {'action': 'store_true'}),)) + {'action': 'store_true'}), + ('Set number of spaces for tab expansion (default 8).', + ['--tab-width'], + {'metavar': '', 'type': 'int', 'default': 8}),)) def __init__(self, rfc2822=None, inliner=None): if rfc2822: @@ -84,5 +87,6 @@ class Parser(docutils.parsers.Parser): initial_state=self.initial_state, debug=debug) inputlines = docutils.statemachine.string2lines( - inputstring, convert_whitespace=1) + inputstring, tab_width=document.options.tab_width, + convert_whitespace=1) self.statemachine.run(inputlines, document, inliner=self.inliner) -- cgit v1.2.1 From 8bc9254160b3f3ff159192bfe612168fb89dca6d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 01:40:35 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@787 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 +++++- docs/dev/todo.txt | 41 ++++++++++++++++++++++++++++----------- docs/ref/rst/directives.txt | 6 +++++- docs/ref/rst/restructuredtext.txt | 10 ++++++---- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 181196f81..2f77a998c 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -45,6 +45,8 @@ General: Specific: +* FAQ.txt: Frequently asked questions, added to project. + * docutils/__init__.py: - Bumped version to 0.2.1 to reflect changes to I/O classes. @@ -144,7 +146,8 @@ Specific: * docutils/parser/rst/__init__.py: - - Added the "--pep-references" and "--rfc-references" options. + - Added options: "--pep-references", "--rfc-references", + "--tab-width". * docutils/parsers/rst/states.py: @@ -272,6 +275,7 @@ Specific: 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

    . * docutils/writers/pep_html.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 96ed3ac28..f2d33ddb8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -173,7 +173,8 @@ General * Add object numbering and object references (tables & figures). We'll need _`persistent sequences`, such as chapter numbers. See - OpenOffice XML "fields". + `OpenOffice.org XML`_ "fields". Should the sequences be automatic + or manual (user-specifyable)? We need to name the objects: @@ -182,18 +183,32 @@ General .. figure:: image.png :name: image's name - How to name tables, which don't need directives? + To name tables, we could use a "table" directive:: - - But this could also be done this way (perhaps more generally):: + .. table:: optional title here + :name: table's name + + ===== ===== + x not x + ===== ===== + True False + False True + ===== ===== + + This would also allow other attributes to be set, like border + styles. The same technique could be used for other objects. + + - The object could also be done this way:: .. _figure name: .. figure:: image.png - Applies equally well to tables. + This may be a more general solution, equally applicable to tables. + However, explicit naming using an option seems simpler to users. - We'll also need syntax for object references. See OpenOffice XML - "reference fields": + We'll also need syntax for object references. See `OpenOffice.org + XML`_ "reference fields": - Parameterized substitutions? For example:: @@ -210,15 +225,17 @@ General reference-time, not at definition-time as they are now. Or, perhaps the directives could just leave ``pending`` elements behind, and the transforms do the work? How to pass the data - through? + through? Too complicated. - - An interpreted text approach is better:: + - An interpreted text approach is simpler and better:: See :figure:`figure name` on :page:`figure name`. - The "figure" and "page" roles could generate some boilerplate - text. The position of the role (prefix or suffix) could also be - utilized. + The "figure" and "page" roles could generate appropriate + boilerplate text. The position of the role (prefix or suffix) + could also be utilized. + + .. _OpenOffice.org XML: http://xml.openoffice.org/ * Think about large documents made up of multiple subdocument files. Issues: continuity (`persistent sequences`_ above), cross-references @@ -259,6 +276,8 @@ General __ rst/directives.html#including-an-external-document-fragment +* Change ``document.options`` to ``document.settings``? + Documentation ------------- diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 6f6b1ca88..495fec567 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -132,15 +132,19 @@ The following options are recognized: Alternate text: a short description of the image, displayed by applications that cannot display images, or spoken by applications for visually impaired users. + ``height`` : integer The height of the image in pixels, used to reserve space or scale the image vertically. + ``width`` : integer The width of the image in pixels, used to reserve space or scale the image horizontally. + ``scale`` : integer The uniform scaling factor of the image, a percentage (but no "%" symbol is required or allowed). "100" means full-size. + ``align`` : "top", "middle", "bottom", "left", "center", or "right" The alignment of the image, equivalent to the HTML ```` tag's "align" attribute. The values "top", "middle", and "bottom" @@ -158,7 +162,7 @@ Figure :Directive Type: "figure" :DTD Elements: figure, image, caption, legend :Directive Arguments: One, required (image URI). -:Directive Options: Possible. +:Directive Options: Possible; same as those of the `image`_ directive. :Directive Content: Interpreted as the figure caption and an optional legend. diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 88d7a4917..642aace28 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -433,9 +433,9 @@ rearranging the document fragment into a complete document with a title and possibly other metadata elements (author, date, etc.; see `Bibliographic Fields`_). -Specifically, there is no way to specify a document title and subtitle -explicitly in reStructuredText. Instead, a lone top-level section -title (see Sections_ below) can be treated as the document +Specifically, there is no way to indicate a document title and +subtitle explicitly in reStructuredText. Instead, a lone top-level +section title (see Sections_ below) can be treated as the document title. Similarly, a lone second-level section title immediately after the "document title" can become the document subtitle. See the `DocTitle transform`_ for details. @@ -1483,7 +1483,9 @@ may be the only character in the label. For example:: .. [*] This is the footnote. A transform will insert symbols as labels into corresponding footnotes -and footnote references. +and footnote references. The number of references must be equal to +the number of footnotes. One symbol footnote cannot have multiple +references. The standard Docutils system uses the following symbols for footnote marks [#]_: -- cgit v1.2.1 From 405a11b3fa212ad811335b06ec5eef1d561ca79e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 01:40:52 +0000 Subject: Frequently asked questions, added to project. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@788 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 FAQ.txt diff --git a/FAQ.txt b/FAQ.txt new file mode 100644 index 000000000..bf447ab8e --- /dev/null +++ b/FAQ.txt @@ -0,0 +1,159 @@ +===================================== + Docutils Frequently Asked Questions +===================================== + +:Date: $Date$ +:Web site: http://docutils.sourceforge.net/ + +.. Please note that until there's a Q&A-specific construct available, + this FAQ will use section titles for questions. Therefore + questions must fit on one line. The title may be a summary of the + question, with the full question in the section body. + + +.. contents:: +.. sectnum:: + + +This is a work in progress. Please feel free to ask questions and/or +provide answers; `send email`__ to the `Docutils-Users mailing +list`__. + +__ mailto:docutils-users@lists.sourceforge.net +__ http://lists.sourceforge.net/lists/listinfo/docutils-users + + +Docutils +======== + +What is Docutils? +----------------- + + +Why is it named "Docutils"? +--------------------------- + + +reStructuredText +================ + +What is reStructuredText? +------------------------- + + +Why is it named "reStructuredText"? +----------------------------------- + + +What's the standard abbreviation for "reStructuredText"? +-------------------------------------------------------- + +"RST" and "ReST" (or "reST") are both acceptable. "reSTX" is not. + + +What's the standard filename extension for a reStructuredText file? +------------------------------------------------------------------- + +It's ".txt". Some people would like to use ".rest" or ".rst" or +".restx", but why bother? ReStructuredText source files are meant to +be readable as plaintext, and most operating systems know that ".txt" +means "text file". + + +How can I indicate the document title? Subtitle? +------------------------------------------------- + +If there's only one highest-level section title at the beginning of a +document, it is treated specially, as the document title. Similarly, +a lone second-highest-level section title may become the document +subtitle if it immediately follows the document title. + +For example:: + + This is the Document Title + ========================== + + This is the Document Subtitle + ----------------------------- + + Here's an ordinary paragraph. + +Counterexample:: + + Here's an ordinary paragraph. + + This is *not* a Document Title + ============================== + + The "ordinary paragraph" above the section title + prevents it from becoming the document title. + + +HTML Writer +=========== + +Unexpected results from tools/html.py: H1, H1 instead of H1, H2. Why? +---------------------------------------------------------------------- + +Here's the question in full: + + I have this text:: + + Heading 1 + ========= + + All my life, I wanted to be H1. + + Heading 1.1 + ----------- + + But along came H1, and so shouldn't I be H2? + No! I'm H1! + + Heading 1.1.1 + ************* + + Yeah, imagine me, I'm stuck at H3! No?!? + + When I run it through tools/html.py, I get unexpected results + (below). I was expecting H1, H2, then H3; instead, I get H1, H1, + H2. What gives? :: + + ... + + + ... + Heading 1 + + + +

    +

    Heading 1

    <-- first H1 +

    All my life, I wanted to be H1.

    +
    +

    Heading 1.1

    <-- H1 +

    But along came H1, and so now I must be H2.

    +
    +

    Heading 1.1.1

    +

    Yeah, imagine me, I'm stuck at H3!

    + ... + +Check the "class" attribute on the H1 tags, and you will see a +difference. The first H1 is actually ``

    ``; this is +the document title, and the default stylesheet renders it centered. +There can also be an ``

    `` for the document +subtitle. + +If there's only one highest-level section title at the beginning of a +document, it is treated specially, as the document title. (Similarly, +a lone second-highest-level section title may become the document +subtitle.) Rather than use a plain H1 for that, we use ``

    `` so that we can use H1 again within the document. Why +we do this? HTML only has H1-H6, so by making H1 do double duty, we +effectively reserve these tags to provide 6 levels of heading beyond +the single document title. + +HTML is being used for dumb formatting for nothing but final display. +A stylesheet *is* required, and you're welcome to roll your own. + +(Thanks to Mark McEahern for the question and much of the answer.) -- cgit v1.2.1 From 3620667162c07ecf1949ba2ea8b131656c8a4246 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 22:51:46 +0000 Subject: Improve vertical spacing? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@790 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index a17b4b9cb..97b7b6032 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -131,6 +131,7 @@ pre.line-block { pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; + margin-bottom: 0 ; background-color: #eeeeee } span.classifier { -- cgit v1.2.1 From 70fd40988236e1a7a3de69edd4475a40486c2e31 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 22:55:29 +0000 Subject: Allow for Unicode string I/O: don't decode/encode if ``options.input_encoding``/``.output_encoding`` are ``None``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@791 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 6f7c138bd..c78bb4f17 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -213,7 +213,10 @@ class StringInput(Input): def read(self, reader): """Decode and return the source string.""" - return self.decode(self.source) + if self.options.input_encoding is None: + return self.source + else: + return self.decode(self.source) class StringOutput(Output): @@ -226,7 +229,10 @@ class StringOutput(Output): def write(self, data): """Encode `data`, store it in `self.destination`, and return it.""" - self.destination = data.encode(self.options.output_encoding) + if self.options.output_encoding is None: + self.destination = data + else: + self.destination = data.encode(self.options.output_encoding) return self.destination -- cgit v1.2.1 From e8e13a29e1e04d22c0f89c6e792db273f4946731 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Oct 2002 22:56:47 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@792 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/dev/todo.txt | 81 ++++++++++++++++++++++++++++++++++++++++++++++++-- docs/peps/pep-0258.txt | 8 +++-- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 2f77a998c..7a333b5d2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -83,6 +83,7 @@ Specific: - Try to get path/stream name automatically in ``FileInput`` & ``FileOutput``. - Added defaults for source & destination paths. + - Allow for Unicode string I/O. * docutils/nodes.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f2d33ddb8..f170e85be 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -197,7 +197,7 @@ General This would also allow other attributes to be set, like border styles. The same technique could be used for other objects. - + - The object could also be done this way:: .. _figure name: @@ -243,7 +243,7 @@ General below). When writing a book, the author probably wants to split it up into - files, perhaps one per chapter (but perhaps even more detailed). + files, perhaps one per chapter (but perhaps even more detailed). However, we'd like to be able to have references from one chapter to another, and have continuous numbering (pages and chapters, as applicable). Of course, none of this is implemented yet. There has @@ -276,6 +276,51 @@ General __ rst/directives.html#including-an-external-document-fragment + Aahz's idea: + + First the ToC:: + + .. ToC-list:: + Introduction.txt + Objects.txt + Data.txt + Control.txt + + Then a sample use:: + + .. include:: ToC.txt + + As I said earlier in chapter :chapter:`Objects.txt`, the + reference count gets increased every time a binding is made. + + Which produces:: + + As I said earlier in chapter 2, the + reference count gets increased every time a binding is made. + + The ToC in this form doesn't even need to be references to actual + reST documents; I'm simply doing it that way for a minimum of + future-proofing, in case I do want to add the ability to pick up + references within external chapters. + + Perhaps, instead of ToC (which would overload the "contents" + directive concept already in use), we could use "manifest". A + "manifest" directive might associate local reference names with + files:: + + .. manifest:: + intro: Introduction.txt + objects: Objects.txt + data: Data.txt + control: Control.txt + + Then the sample becomes:: + + .. include:: manifest.txt + + As I said earlier in chapter :chapter:`objects`, the + reference count gets increased every time a binding is made. + * Change ``document.options`` to ``document.settings``? @@ -802,7 +847,7 @@ Directives The words "paragraph", "marked", and "index" would become index entries pointing at the words in the first paragraph. The index entry words appear verbatim in the text. (Don't worry about the - ugly ":index:" part; if indexing is the only application of + ugly ":index:" part; if indexing is the only/main application of interpreted text in your documents, it can be implicit and omitted.) The two directives provide manual indexing, where the index entry words ("markup" and "syntax") do not appear in the @@ -844,6 +889,36 @@ Directives Also "see / see also" index entries. + Given:: + + Here's a paragraph. + + .. index:: paragraph + + (The "index" directive above actually targets the *preceding* + object.) The directive should produce something like this XML:: + + + + Here's a paragraph. + + + This kind of content model would also allow true inline + index-entries:: + + Here's a `paragraph`:index:. + + If the "index" role were the default for the application, it could be + dropped:: + + Here's a `paragraph`. + + Both of these would result in this XML:: + + + Here's a paragraph. + + - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need some kind of "alternate" mechanism? Perhaps use a "pending" diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 5af970734..15a3317cb 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -223,14 +223,18 @@ Writers produce the final output (HTML, XML, TeX, etc.). Writers translate the internal document tree structure into the final data format, possibly running Writer-specific transforms_ first. +By the time the document gets to the Writer, it should be in final +form. The Writer's job is simply (and only) to translate from the +Docutils doctree structure to the target format. Some small +transforms may be required, but they should be local and +format-specific. + Each writer is a module or package exporting a "Writer" class with a "write" method. The base "Writer" class can be found in the ``docutils/writers/__init__.py`` module. Responsibilities: -- Run transforms over the doctree(s). - - Translate doctree(s) into specific output formats. - Transform references into format-native forms. -- cgit v1.2.1 From 4d2d22cb30463cc94d84909bea9be6d23847e049 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Oct 2002 03:03:57 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@794 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f170e85be..90d6328e6 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -323,6 +323,22 @@ General * Change ``document.options`` to ``document.settings``? +* Add functional testing to Docutils: Readers, Writers, front ends. + +* Changes to sandbox/davidg/infrastructure/docutils-update? + + - Modify the script to only update the snapshots if files have + actually changed in CVS (saving some SourceForge server cycles). + + - Make passing the test suite a prerequisite to snapshot update, + but only if the process is completely automatic. + + - Rewrite in Python? + +* Publisher: "Ordinary setup" shouldn't requre specific ordering; at + the very least, there ought to be error checking higher up in the + call chain. [Aahz] + Documentation ------------- @@ -436,6 +452,10 @@ Miscellaneous ideas: from module)" - ``from module import *``: "all identifiers (``*``) from module" +* Have links to colorized Python source files from API docs? And + vice-versa: backlinks from the colorized source files to the API + docs! + reStructuredText Parser ----------------------- -- cgit v1.2.1 From a6b131e106913f99334c8bfbffff5ab2f0be62e3 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Oct 2002 17:35:48 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@796 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 90d6328e6..e7bcf670a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -133,7 +133,7 @@ General - Change ``Transform.transform()`` to ``Transform.apply()``? - Updated project model under consideration for PEP 258:: + Updated project dataflow model under consideration for PEP 258:: +--------------------------+ | Docutils: | @@ -148,10 +148,10 @@ General +--------+ +-------------+ +--------+ / \\ | / \\ | - 2 / 4 \\ 8 | - +-----+ +--------+ +-----+ - | I/O | | PARSER | | I/O | - +-----+ +--------+ +-----+ + 2 / 4 \\ 8 | + +-------+ +--------+ +--------+ + | INPUT | | PARSER | | OUTPUT | + +-------+ +--------+ +--------+ * @@@ Break up ``references.Hyperlinks`` into multiple smaller transforms. @@ -321,7 +321,7 @@ General As I said earlier in chapter :chapter:`objects`, the reference count gets increased every time a binding is made. -* Change ``document.options`` to ``document.settings``? +* Change all occurrences of "options" to "settings"? * Add functional testing to Docutils: Readers, Writers, front ends. @@ -339,6 +339,22 @@ General the very least, there ought to be error checking higher up in the call chain. [Aahz] + ``Publisher.set_options`` requires that all components be set up + before it's called. Perhaps the I/O *objects* shouldn't be set, but + I/O *classes*. Then options are set up (``.set_options``), and + ``Publisher.set_io`` (or equivalent code) is called with source & + destination paths, creating the I/O objects. + + Perhaps I/O objects shouldn't be instantiated until required. For + split output, the Writer may be called multiple times, once for each + doctree, and each doctree should have a separate Output object (with + a different path). Is the "Builder" pattern applicable here? + +* Perhaps I/O objects should become full-fledged components (i.e. + subclasses of ``docutils.Component``, as are Readers, Parsers, and + Writers now), and thus have associated option/setting specs and + transforms. + Documentation ------------- -- cgit v1.2.1 From 8d72cb201e01c55d7a23c00f72e959c5c171534c Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Oct 2002 19:34:35 +0000 Subject: filled in answers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@797 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 9 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index bf447ab8e..b45a36ac7 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -17,7 +17,8 @@ This is a work in progress. Please feel free to ask questions and/or provide answers; `send email`__ to the `Docutils-Users mailing -list`__. +list`__. Project members should feel free to edit the source text +file directly. __ mailto:docutils-users@lists.sourceforge.net __ http://lists.sourceforge.net/lists/listinfo/docutils-users @@ -29,9 +30,58 @@ Docutils What is Docutils? ----------------- +Docutils_ is a system for processing plaintext documentation into +useful formats, such as HTML, XML, and TeX. It supports multiple +types of input, such as standalone files (implemented), inline +documentation from Python modules and packages (under development), +`PEPs (Python Enhancement Proposals)`_ (implemented), and others as +discovered. -Why is it named "Docutils"? ---------------------------- +For an overview of the Docutils project implementation, see `PEP +258`_, "Docutils Design Specification". + +Docutils is implemented in Python_. + +.. _Docutils: http://docutils.sourceforge.net/ +.. _PEPs (Python Enhancement Proposals): + http://www.python.org/peps/pep-0012.html +.. _PEP 258: spec/pep-0258.html +.. _Python: http://www.python.org/ + + +Why is it called "Docutils"? +---------------------------- + +Docutils is short for "Python Documentation Utilities". The name +"Docutils" was inspired by "Distutils", the Python Distribution +Utilities architected by Greg Ward, a component of Python's standard +library. + +The earliest know use of the term "docutils" in a Python context was a +`fleeting reference`__ in a message by Fred Drake on 1999-12-02 in the +Python Doc-SIG mailing list. It was suggested `as a project name`__ +on 2000-11-27 on Doc-SIG, again by Fred Drake, in response to a +question from Tony "Tibs" Ibbs: "What do we want to *call* this +thing?". This was shortly after David Goodger first `announced +reStructuredText`__ on Doc-SIG. + +Tibs used the name "Docutils" for his effort + + to document what the Python docutils package should support, with + a particular emphasis on documentation strings ("docstrings") + + (http://homepage.ntlworld.com/tibsnjoan/docutils/STpy.html) + +Tibs joined the current project (and its predecessors) and has +graciously donated the name "Docutils". + +For more history of reStructuredText and the Docutils project, see `An +Introduction to reStructuredText`_. + +.. _An Introduction to reStructuredText: spec/rst/introduction.html +__ http://mail.python.org/pipermail/doc-sig/1999-December/000878.html +__ http://mail.python.org/pipermail/doc-sig/2000-November/001252.html +__ http://mail.python.org/pipermail/doc-sig/2000-November/001239.html reStructuredText @@ -40,15 +90,45 @@ reStructuredText What is reStructuredText? ------------------------- +reStructuredText_ is an easy-to-read, what-you-see-is-what-you-get +plaintext markup syntax and parser system. The reStructuredText +parser is a component of Docutils_. reStructuredText is a revision +and reinterpretation of the StructuredText_ and Setext_ lightweight +markup systems. + +If you are reading this on the web, you can see for yourself. `The +source for this FAQ`__ is written in reStructuredText; open it in +another window and compare them side by side. + +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _StructuredText: + http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage/ +.. _Setext: mirror/setext.html +__ FAQ.txt + -Why is it named "reStructuredText"? ------------------------------------ +Why is it called "reStructuredText"? +------------------------------------ + +The name came from a combination of "StructuredText", one of +reStructuredText's predecessors, with "re" (as in the ``re.py`` +regular expression module), "revised", "reworked", and +"reinterpreted". For a detailed history of reStructuredText and the +Docutils project, see `An Introduction to reStructuredText`_. What's the standard abbreviation for "reStructuredText"? -------------------------------------------------------- -"RST" and "ReST" (or "reST") are both acceptable. "reSTX" is not. +"RST" and "ReST" (or "reST") are both acceptable. Care should be +taken with capitalization, to avoid confusion with "REST__", an +acronym for "Representational State Transfer". + +The abbreviations "reSTX" and "rSTX"/"rstx" should **not** be used; +they overemphasize reStructuredText's precedessor, Zope's +StructuredText. + +__ http://www.xml.com/pub/a/2002/02/06/rest.html What's the standard filename extension for a reStructuredText file? @@ -56,8 +136,10 @@ What's the standard filename extension for a reStructuredText file? It's ".txt". Some people would like to use ".rest" or ".rst" or ".restx", but why bother? ReStructuredText source files are meant to -be readable as plaintext, and most operating systems know that ".txt" -means "text file". +be readable as plaintext, and most operating systems already associate +".txt" with text files. Using a specialized filename extension would +require that users alter their OS settings, which is something that +many users will not be willing or able to do. How can I indicate the document title? Subtitle? @@ -117,7 +199,7 @@ Here's the question in full: When I run it through tools/html.py, I get unexpected results (below). I was expecting H1, H2, then H3; instead, I get H1, H1, - H2. What gives? :: + H2:: ... @@ -138,6 +220,8 @@ Here's the question in full:

    Yeah, imagine me, I'm stuck at H3!

    ... + What gives? + Check the "class" attribute on the H1 tags, and you will see a difference. The first H1 is actually ``

    ``; this is the document title, and the default stylesheet renders it centered. -- cgit v1.2.1 From 437f8cf61373e7647ec1fbc49f6a04451fce25e4 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Oct 2002 19:44:00 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@798 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index b45a36ac7..e8a8f4254 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -65,12 +65,9 @@ question from Tony "Tibs" Ibbs: "What do we want to *call* this thing?". This was shortly after David Goodger first `announced reStructuredText`__ on Doc-SIG. -Tibs used the name "Docutils" for his effort - - to document what the Python docutils package should support, with - a particular emphasis on documentation strings ("docstrings") - - (http://homepage.ntlworld.com/tibsnjoan/docutils/STpy.html) +Tibs used the name "Docutils" for `his effort`__ "to document what the +Python docutils package should support, with a particular emphasis on +documentation strings". Tibs joined the current project (and its predecessors) and has graciously donated the name "Docutils". @@ -82,6 +79,7 @@ Introduction to reStructuredText`_. __ http://mail.python.org/pipermail/doc-sig/1999-December/000878.html __ http://mail.python.org/pipermail/doc-sig/2000-November/001252.html __ http://mail.python.org/pipermail/doc-sig/2000-November/001239.html +__ http://homepage.ntlworld.com/tibsnjoan/docutils/STpy.html reStructuredText -- cgit v1.2.1 From 0836bddfb244f0eadd3a4bd93a3e62e560934ae1 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 12 Oct 2002 19:45:13 +0000 Subject: fiddled git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@799 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index e8a8f4254..5d4b3fa23 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -67,10 +67,8 @@ reStructuredText`__ on Doc-SIG. Tibs used the name "Docutils" for `his effort`__ "to document what the Python docutils package should support, with a particular emphasis on -documentation strings". - -Tibs joined the current project (and its predecessors) and has -graciously donated the name "Docutils". +documentation strings". Tibs joined the current project (and its +predecessors) and graciously donated the name. For more history of reStructuredText and the Docutils project, see `An Introduction to reStructuredText`_. -- cgit v1.2.1 From a4760f9d42ef26b2132ff305a85e370a95ed93a5 Mon Sep 17 00:00:00 2001 From: grubert Date: Tue, 15 Oct 2002 08:58:50 +0000 Subject: + add directives mapping for german. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@801 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 docutils/parsers/rst/languages/de.py diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py new file mode 100644 index 000000000..e381a18a2 --- /dev/null +++ b/docutils/parsers/rst/languages/de.py @@ -0,0 +1,44 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +German-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + 'Achtung': 'attention', + 'Vorsicht': 'caution', + 'Gefahr': 'danger', + 'Fehler': 'error', + 'Hinweis': 'hint', + 'Wichtig': 'important', + 'Notiz': 'note', + 'Tip': 'tip', + 'Warnung': 'warning', + 'Topic': 'topic', # Inhalt, Thema or berbegriff + 'line-block': 'line-block', + 'parsed-literal': 'parsed-literal', + #'questions': 'questions', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'Bild': 'image', + 'figure': 'figure', # also Bild ? + #'raw': 'raw', + 'Inhalt': 'contents', + 'sectnum': 'sectnum', + 'section-numbering': 'sectnum', + 'target-notes': 'target-notes', + #'footnotes': 'footnotes', + #'citations': 'citations', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""English name to registered (in directives/__init__.py) directive name +mapping.""" -- cgit v1.2.1 From 86fdc1b7f9f5b407fb2ee5881799b5120e277992 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:30:45 +0000 Subject: Vertical whitespace improvements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@805 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 20 +++++++++++++++----- tools/stylesheets/default.css | 13 ++++++------- tools/stylesheets/pep.css | 12 ++++++------ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 7f1504158..61610416a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -422,8 +422,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_definition(self, node): self.body.append('\n') self.body.append(self.starttag(node, 'dd', '')) - if len(node) and isinstance(node[0], nodes.paragraph): + if len(node): node[0].set_class('first') + node[-1].set_class('last') def depart_definition(self, node): self.body.append('\n') @@ -442,8 +443,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_description(self, node): self.body.append(self.starttag(node, 'td', '')) - if len(node) and isinstance(node[0], nodes.paragraph): + if len(node): node[0].set_class('first') + node[-1].set_class('last') def depart_description(self, node): self.body.append('') @@ -472,6 +474,11 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'tr', '')) self.body.append('%s:\n' % self.language.labels[name]) + if len(node): + if isinstance(node[0], nodes.Element): + node[0].set_class('first') + if isinstance(node[0], nodes.Element): + node[-1].set_class('last') def depart_docinfo_item(self): self.body.append('\n') @@ -509,8 +516,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('\n' % tagname.lower()) if len(node) == 0: # empty cell self.body.append(' ') - elif isinstance(node[0], nodes.paragraph): + else: node[0].set_class('first') + node[-1].set_class('last') def depart_entry(self, node): self.body.append(self.context.pop()) @@ -557,8 +565,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_body(self, node): self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) - if len(node) and isinstance(node[0], nodes.paragraph): + if len(node): node[0].set_class('first') + node[-1].set_class('last') def depart_field_body(self, node): self.body.append('\n') @@ -735,8 +744,9 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_list_item(self, node): self.body.append(self.starttag(node, 'li', '')) - if len(node) and isinstance(node[0], nodes.paragraph): + if len(node): node[0].set_class('first') + node[-1].set_class('last') def depart_list_item(self, node): self.body.append('\n') diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 97b7b6032..b929f6503 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -8,6 +8,12 @@ Default cascading style sheet for the HTML output of Docutils. */ +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + a.target { color: blue } @@ -109,9 +115,6 @@ p.credits { font-style: italic ; font-size: smaller } -p.first { - margin-top: 0 } - p.label { white-space: nowrap } @@ -131,7 +134,6 @@ pre.line-block { pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; - margin-bottom: 0 ; background-color: #eeeeee } span.classifier { @@ -174,9 +176,6 @@ td, th { padding-right: 0.5em ; vertical-align: top } -td > p:first-child, th > p:first-child { - margin-top: 0em } - th.docinfo-name, th.field-name { font-weight: bold ; text-align: left ; diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 2a7f61ecc..8cc2a13fb 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -8,6 +8,12 @@ Default cascading style sheet for the PEP HTML output of Docutils. */ +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + .navigation { width: 100% ; background: #99ccff ; @@ -174,9 +180,6 @@ p.credits { font-style: italic ; font-size: smaller } -p.first { - margin-top: 0 } - p.label { white-space: nowrap } @@ -222,9 +225,6 @@ td, th { padding-right: 0.5em ; vertical-align: top } -td > :first-child, th > :first-child { - margin-top: 0em } - td.num { text-align: right } -- cgit v1.2.1 From 80745027b66d8622155b91d846ea220d4e60c7ed Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:31:37 +0000 Subject: Docutils Internationalization git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@806 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/i18n.txt | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 docs/howto/i18n.txt diff --git a/docs/howto/i18n.txt b/docs/howto/i18n.txt new file mode 100644 index 000000000..9aeda9f6a --- /dev/null +++ b/docs/howto/i18n.txt @@ -0,0 +1,91 @@ +================================ + Docutils_ Internationalization +================================ + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + + +.. contents:: + + +This document describes the internationalization (hereafter "i18n": +"i" + 18 letters + "n") facilities of the Docutils_ project. +`Introduction to i18n`_ by Tomohiro KUBOTA is a good general +reference. + +.. Note:: + + The i18n facilities of Docutils should be considered a "first + draft". They work so far, but improvements are welcome. + Specifically, standard i18n facilities like "gettext" have yet to + be explored. + +Docutils is designed to work flexibly with text in multiple languages +(one language at a time). Language-specific features are (or should +be [#]_) fully parameterized. To enable a new language, two modules +have to be added to the project: one for Docutils itself (the +`Docutils Language Module`_) and one for the reStructuredText parser +(the `reStructuredText Language Module`_). + +Language modules are named using a case-insensitive language +identifier as defined in `RFC 1766`_. A typical language identifier +consists of a 2-letter language code from `ISO 639`_ (3-letter codes +can be used if no 2-letter code exists; RFC 1766 is currently being +revised to allow 3-letter codes). If no language identifier is +specified, the default is "en" for English. Examples of module names +include ``en.py``, ``fr.py``, and ``ja.py`` + +.. [#] If anything in Docutils is insufficiently parameterized, it + should be considered a bug. Please report bugs to the Docutils + project bug tracker on SourceForge at + http://sourceforge.net/tracker/?group_id=38414&atid=422030. + +.. _Docutils: http://docutils.sourceforge.net/ +.. _Introduction to i18n: + http://www.debian.org/doc/manuals/intro-i18n/ +.. _RFC 1766: http://www.faqs.org/rfcs/rfc1766.html +.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html + + +Docutils Language Module +======================== + +Modules in ``docutils/languages`` contain language mappings for +markup-independent language-specific features of Docutils: + +``labels`` + This is a mapping of node class names to language-dependent + boilerplate label text. The label text is used by Writer + components when they encounter document tree elements whose class + names are the mapping keys. + +``bibliographic_fields`` + This is a mapping of language-dependent field names (converted to + lower case) to node classes (in ``docutils.nodes``). It is used + when parsing bibliographic fields. + +``author_separators`` + This is a list of strings used to parse the 'Authors' + bibliographic field. They separate individual authors' names, and + are tried in order (i.e., earlier items take priority, and the + first item that matches wins). The English-language module + defines them as ``[';', ',']``; semi-colons can be used to + separate names like "Arthur Pewtie, Esq.". + + +reStructuredText Language Module +================================ + +Modules in ``docutils/parsers/rst/languages`` contain language +mappings for language-specific features of the reStructuredText +parser: + +``directives`` + This is a mapping from language-dependent directive names to + canonical directive names. The canonical directive names are + registered in ``docutils/parsers/rst/directives/__init__.py``, in + ``_directive_registry``. -- cgit v1.2.1 From 5ce44d6a3d7af489b2440604fed7ecdaa6999de2 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:32:52 +0000 Subject: Added support for pre-acceptance PEPs (no PEP number yet). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@807 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/peps.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 9ef0e9b85..f7cea6953 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -52,11 +52,23 @@ class Headers(Transform): value = field[1].astext() try: pep = int(value) + cvs_url = self.pep_cvs_url % pep except ValueError: - raise DataError('"PEP" header must contain an integer; ' - '"%s" is an invalid value.' % value) - else: - break + 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.') @@ -80,9 +92,9 @@ class Headers(Transform): date = time.strftime( '%d-%b-%Y', time.localtime(os.stat(self.document['source'])[8])) - body += nodes.paragraph() - uri = self.pep_cvs_url % pep - body[0][:] = [nodes.reference('', date, refuri=uri)] + if cvs_url: + body += nodes.paragraph( + '', '', nodes.reference('', date, refuri=cvs_url)) else: # empty continue @@ -106,9 +118,9 @@ class Headers(Transform): para[:] = newbody[:-1] # drop trailing space elif name == 'last-modified': utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) - date = para.astext() - uri = self.pep_cvs_url % pep - para[:] = [nodes.reference('', date, refuri=uri)] + if cvs_url: + date = para.astext() + para[:] = [nodes.reference('', date, refuri=cvs_url)] elif name == 'content-type': pep_type = para.astext() uri = self.pep_url % 12 -- cgit v1.2.1 From 16a25cf1c6c5e5fa9214bce8c3d45e882783215a Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:35:34 +0000 Subject: Added warnings for unknown directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@808 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 24 ++++++++++++++++++------ docutils/parsers/rst/states.py | 7 +++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 58175040f..034a88e64 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -78,6 +78,7 @@ See `Creating reStructuredText Directives`_ for more information. __docformat__ = 'reStructuredText' +from docutils import nodes from docutils.parsers.rst.languages import en as _fallback_language_module @@ -118,39 +119,50 @@ _modules = {} _directives = {} """Cache of imported directive functions.""" -def directive(directive_name, language_module): +def directive(directive_name, language_module, document): """ Locate and return a directive function from its language-dependent name. If not found in the current language, check English. """ normname = directive_name.lower() + messages = [] if _directives.has_key(normname): - return _directives[normname] + return _directives[normname], messages try: canonicalname = language_module.directives[normname] except (KeyError, AttributeError): + warning = document.reporter.warning( + 'No directive entry for "%s" in module "%s".' + % (directive_name, language_module.__name__), + line=document.current_line) try: # Try English as a fallback: canonicalname = _fallback_language_module.directives[normname] + warning[-1] += nodes.Text( + 'Using English fallback for directive "%s".' % directive_name) except KeyError: + warning[-1] += nodes.Text( + 'Trying "%s" as canonical directive name.' % directive_name) # The canonical name should be an English name, but just in case: canonicalname = normname + messages.append(warning) try: modulename, functionname = _directive_registry[canonicalname] except KeyError: - return None + return None, messages if _modules.has_key(modulename): module = _modules[modulename] else: try: module = __import__(modulename, globals(), locals()) except ImportError: - return None + return None, messages try: function = getattr(module, functionname) + _directives[normname] = function except AttributeError: - return None - return function + return None, messages + return function, messages def flag(argument): """ diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index f64eb3f5f..27784dc27 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1672,8 +1672,9 @@ class Body(RSTState): def directive(self, match, **option_presets): type_name = match.group(1) - directive_function = directives.directive(type_name, - self.memo.language) + directive_function, messages = directives.directive( + type_name, self.memo.language, self.document) + self.parent += messages if directive_function: return self.parse_directive( directive_function, match, type_name, option_presets) @@ -1969,6 +1970,8 @@ class Body(RSTState): """Section title overline or transition marker.""" if self.state_machine.match_titles: return [match.string], 'Line', [] + elif match.string.strip() == '::': + raise statemachine.TransitionCorrection('text') elif len(match.string.strip()) < 4: msg = self.reporter.info( 'Unexpected possible title overline or transition.\n' -- cgit v1.2.1 From 694c4be8294331e8a851661f34f0a1071ed80363 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:36:46 +0000 Subject: Generalized ``Publisher.set_io``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@809 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 6eee3829e..c243df22d 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -115,10 +115,12 @@ class Publisher: self.options = option_parser.parse_args(argv) def set_io(self): - self.source = self.source_class(self.options, - source_path=self.options._source) - self.destination = self.destination_class( - self.options, destination_path=self.options._destination) + if self.source is None: + self.source = self.source_class(self.options, + source_path=self.options._source) + if self.destination is None: + self.destination = self.destination_class( + self.options, destination_path=self.options._destination) def publish(self, argv=None, usage=None, description=None, option_spec=None): @@ -129,7 +131,7 @@ class Publisher: """ if self.options is None: self.process_command_line(argv, usage, description, option_spec) - self.set_io() + self.set_io() document = self.reader.read(self.source, self.parser, self.options) output = self.writer.write(document, self.destination) if self.options.dump_internals: -- cgit v1.2.1 From ba3923167324a379d0282beba72817ec0ca349fc Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:38:42 +0000 Subject: Beginnings of transform overhaul. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@810 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 13 ++++++++++++- docutils/nodes.py | 3 +++ docutils/transforms/__init__.py | 40 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 15d1ea097..a52dbb51d 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -91,7 +91,18 @@ class OptionSpec: directory.""" -class Component(OptionSpec): +class TransformSpec: + + """ + Runtime transform specification base class. + + TransformSpec subclass objects used by `docutils.transforms.Transformer`. + """ + + default_transforms = () + + +class Component(OptionSpec, TransformSpec): """Base class for Docutils components.""" diff --git a/docutils/nodes.py b/docutils/nodes.py index 9b4d73cb1..c95c514ca 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -697,6 +697,9 @@ class document(Root, Structural, Element): self.transform_messages = [] """System messages generated while applying transforms.""" + self.transformer = None + """`docutils.transforms.Transformer` object.""" + self.document = self def asdom(self, dom=xml.dom.minidom): diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index bfdf3b2b9..328d246e7 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -28,13 +28,13 @@ these standard transforms. __docformat__ = 'reStructuredText' -from docutils import languages, ApplicationError, Component +from docutils import languages, ApplicationError, TransformSpec class TransformError(ApplicationError): pass -class Transform(Component): +class Transform: """ Docutils transform component abstract base class. @@ -64,3 +64,39 @@ class Transform(Component): def transform(self): """Override to transform the document tree.""" raise NotImplementedError('subclass must override this method') + + +class Transformer(TransformSpec): + + """ + The Transformer class records and applies transforms to documents. + """ + + def __init__(self): + self.transforms = [] + """Queue of transforms to apply.""" + + self.applying = None + """Boolean: am I now applying tranforms?""" + + def add_transform(self, transform_class, priority=None): + if priority is None: + priority = transform_class.priority + self.transforms.append((priority, transform_class, None)) + if self.applying: + self.transforms.sort() + + def add_transforms(self, transform_list): + for transform_class in transform_list: + self.transforms.append((transform_class.priority, transform_class, + None)) + if self.applying: + self.transforms.sort() + + def add_pending(self, pending, priority=None): + transform_class = pending.transform + if priority is None: + priority = transform_class.priority + self.transforms.append((priority, transform_class, pending)) + if self.applying: + self.transforms.sort() -- cgit v1.2.1 From fd593bed5456e2ef6d58dab0b1379764d0ab3823 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 01:45:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@811 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 3 ++ HISTORY.txt | 14 +++++++++ README.txt | 2 ++ docs/dev/todo.txt | 34 +++++++++++++++++----- docs/howto/rst-directives.txt | 11 ++++++- docutils/parsers/rst/languages/en.py | 4 ++- .../test_rst/test_directives/test_unknown.py | 12 ++++++++ test/test_parsers/test_rst/test_substitutions.py | 4 +++ 8 files changed, 74 insertions(+), 10 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 5d4b3fa23..ad470996e 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -73,6 +73,9 @@ predecessors) and graciously donated the name. For more history of reStructuredText and the Docutils project, see `An Introduction to reStructuredText`_. +Please note that the name is "Docutils", not "DocUtils" or "Doc-Utils" +or any other variation. + .. _An Introduction to reStructuredText: spec/rst/introduction.html __ http://mail.python.org/pipermail/doc-sig/1999-December/000878.html __ http://mail.python.org/pipermail/doc-sig/2000-November/001252.html diff --git a/HISTORY.txt b/HISTORY.txt index 7a333b5d2..2fc9ace9b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -57,10 +57,12 @@ Specific: - 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. * docutils/core.py: - Made ``publish()`` a bit more convenient. + - Generalized ``Publisher.set_io``. * docutils/frontend.py: @@ -113,6 +115,7 @@ Specific: - Added a "rawsource" attribute to the ``Text`` class, for text before backslash-escape resolution. + - Support for new transform system. * docutils/statemachine.py: @@ -173,6 +176,7 @@ Specific: ``Body.parse_field_body()`` out of ``Body.field()``, overridden in ``ExtensionOptions``. - Improved definition list term/classifier parsing. + - Added warnings for unknown directives. * docutils/parsers/rst/tableparser.py: @@ -187,6 +191,7 @@ Specific: - Added ``flag()``, ``unchanged()``, ``path()``, ``nonnegative_int()``, and ``choice()`` directive option helper functions. + - Added warnings for unknown directives. * docutils/parsers/rst/directives/body.py: Added to project. Contains the "topic", "line-block", and "parsed-literal" directives. @@ -218,6 +223,11 @@ Specific: - 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). + +* docutils/transforms/__init__.py: + + - Added ``Transformer`` class. * docutils/transforms/frontmatter.py: @@ -351,6 +361,9 @@ Specific: * 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/directives.txt: - Added directives: "topic", "sectnum", "target-notes", @@ -421,6 +434,7 @@ Specific: - Added style for "address" elements. - Removed "a.footnote-reference" style; doing it with ```` now. - Improved field list rendering. + - Vertical whitespace improvements. * tools/stylesheets/pep.css: diff --git a/README.txt b/README.txt index da44b00d1..d9bc76dc4 100644 --- a/README.txt +++ b/README.txt @@ -83,6 +83,8 @@ Project Files & Directories * COPYING.txt: Copyright details for non-public-domain files (most are PD). +* FAQ.txt: Docutils Frequently Asked Questions. + * HISTORY.txt: Release notes for the current and previous project releases. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e7bcf670a..4e0a6739d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -102,6 +102,9 @@ General for the ``default_transforms`` class attribute and an ``add_transforms()`` method. + - The ``Transformer`` class could host all universal transforms in + its ``default_transforms`` attribute. + - How to handle ``pending`` elements? Perhaps a ``Transformer.add_pending(pending, priority=None)`` method? Just call it from ``nodes.document.note_pending()``. Need to @@ -109,7 +112,20 @@ General - Who creates a ``Transformer`` object? Attach it to the ``document`` object? Needs to be accessible when instantiating - other components? Or when "runtime initializing" them. + other components? Or when "runtime initializing" them? + + a) ``core.Publisher`` creates a ``Transformer`` object, + initializes it from components (reader, parser, writer, + source, destination), and attaches it to ``document`` (via + ``options``]?). + + b) ``document`` is given a ``Transformer`` object + (``document.transformer``) in ``utils.new_document``. + ``Publisher`` populates ``document.transformer`` from + components after the ``self.reader.read`` call returns (be + sure to use ``self.reader.parser``, not ``self.parser``). + ``document.transformer.apply_all`` is called before + ``self.writer.write``. - Should components initialize the ``Transformer`` object (add ``self.add_transforms()`` calls to components' ``__init__``), or @@ -140,12 +156,12 @@ General | docutils.core.Publisher, | | docutils.core.publish() | +--------------------------+ - / | \ - / | \ - 1,3,5 / 6 | \ 7 - +--------+ +-------------+ +--------+ - | READER | ====> | TRANSFORMER | ===> | WRITER | - +--------+ +-------------+ +--------+ + / | \ + / | \ + 1,3,5 / 6 | \ 7 + +--------+ +-------------+ +--------+ + | READER | ---> | TRANSFORMER | ====> | WRITER | + +--------+ +-------------+ +--------+ / \\ | / \\ | 2 / 4 \\ 8 | @@ -172,7 +188,7 @@ General * Add object numbering and object references (tables & figures). - We'll need _`persistent sequences`, such as chapter numbers. See + We may need _`persistent sequences`, such as chapter numbers. See `OpenOffice.org XML`_ "fields". Should the sequences be automatic or manual (user-specifyable)? @@ -355,6 +371,8 @@ General Writers now), and thus have associated option/setting specs and transforms. +* ``docutils.Component`` + Documentation ------------- diff --git a/docs/howto/rst-directives.txt b/docs/howto/rst-directives.txt index a1f40e973..5e30e4334 100644 --- a/docs/howto/rst-directives.txt +++ b/docs/howto/rst-directives.txt @@ -168,10 +168,19 @@ directive function itself. Register the Directive ====================== -Register the new directive in ``directives/__init__.py``, in the +Register the new directive in +``docutils/parsers/rst/directives/__init__.py``, in the ``_directive_registry`` dictionary. This allows the reStructuredText parser to find and use the directive. +Add an entry to ``docutils/parsers/rst/languages/en.py`` for the +directive, mapping the English name to the canonical name (both +lowercase). Usually the English name and the canonical name are the +same. + +Please check for and update any other language modules for languages +in which you are proficient. + Examples ======== diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index f162c7a9a..0d5e0da34 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -32,7 +32,9 @@ directives = { #'imagemap': 'imagemap', 'image': 'image', 'figure': 'figure', - #'raw': 'raw', + 'include': 'include', + 'raw': 'raw', + 'replace': 'replace', 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/test/test_parsers/test_rst/test_directives/test_unknown.py b/test/test_parsers/test_rst/test_directives/test_unknown.py index fa73541ef..bd0f433ab 100755 --- a/test/test_parsers/test_rst/test_directives/test_unknown.py +++ b/test/test_parsers/test_rst/test_directives/test_unknown.py @@ -30,16 +30,28 @@ totest['unknown'] = [ """, """\ + + + No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". + Trying "reStructuredText-unknown-directive" as canonical directive name. Unknown directive type "reStructuredText-unknown-directive". .. reStructuredText-unknown-directive:: + + + No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". + Trying "reStructuredText-unknown-directive" as canonical directive name. Unknown directive type "reStructuredText-unknown-directive". .. reStructuredText-unknown-directive:: argument + + + No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". + Trying "reStructuredText-unknown-directive" as canonical directive name. Unknown directive type "reStructuredText-unknown-directive". diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 7a1c9c7a1..84d87a33d 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -174,6 +174,10 @@ No blank line after. Substitution definition "empty" missing contents. .. |empty| + + + No directive entry for "directive" in module "docutils.parsers.rst.languages.en". + Trying "directive" as canonical directive name. Unknown directive type "directive". -- cgit v1.2.1 From 7ea9d986a30d37a766caaee5fb531955ab6c38c8 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 02:26:11 +0000 Subject: backtrack a bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@812 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 61610416a..2a0636fd3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -746,7 +746,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'li', '')) if len(node): node[0].set_class('first') - node[-1].set_class('last') def depart_list_item(self, node): self.body.append('\n') -- cgit v1.2.1 From 1e0205793925c196788496c92e954daa70ab077b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 02:55:28 +0000 Subject: Allow for Unicode string I/O with explicit "unicode" encoding (*not* ``None``). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@813 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index c78bb4f17..94a19f431 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -213,7 +213,7 @@ class StringInput(Input): def read(self, reader): """Decode and return the source string.""" - if self.options.input_encoding is None: + if self.options.input_encoding.lower() == 'unicode': return self.source else: return self.decode(self.source) @@ -229,7 +229,7 @@ class StringOutput(Output): def write(self, data): """Encode `data`, store it in `self.destination`, and return it.""" - if self.options.output_encoding is None: + if self.options.output_encoding.lower() == 'unicode': self.destination = data else: self.destination = data.encode(self.options.output_encoding) -- cgit v1.2.1 From f4d1adc624df8cf3f7924f587ab4d750cb662ac7 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 02:56:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@814 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 2fc9ace9b..b9439f186 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -85,7 +85,7 @@ Specific: - Try to get path/stream name automatically in ``FileInput`` & ``FileOutput``. - Added defaults for source & destination paths. - - Allow for Unicode string I/O. + - Allow for Unicode string I/O with an explicit "unicode" encoding. * docutils/nodes.py: -- cgit v1.2.1 From a91984c003e1f1ddff4cb4a6ff885381b0d6c155 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 17 Oct 2002 03:25:29 +0000 Subject: Removed "Representation of Horizontal Rules" to spec/rst/alternatives.txt. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@815 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 100 --------------------------------------------------- 1 file changed, 100 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 75f57ef1c..a0eeba191 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -3408,106 +3408,6 @@ strong_, substitution_definition_, substitution_reference_, subtitle_, target_, term_, title_, version_ ----------------------- - Miscellaneous Topics ----------------------- - -Representation of Horizontal Rules -================================== - -Having added the "horizontal rule" construct to the `reStructuredText -Markup Specification`_, a decision had to be made as to how to reflect -the construct in the implementation of the document tree. Given this -source:: - - Document - ======== - - Paragraph 1 - - -------- - - Paragraph 2 - -The horizontal rule indicates a "transition" (in prose terms) or the -start of a new "division". Before implementation, the parsed document -tree would be:: - - -
    - - Document - <paragraph> - Paragraph 1 - -------- <--- error here - <paragraph> - Paragraph 2 - -There are several possibilities for the implementation: - -1. Implement horizontal rules as "divisions" or segments. A - "division" is a title-less, non-hierarchical section. The first - try at an implementation looked like this:: - - <document> - <section name="document"> - <title> - Document - <paragraph> - Paragraph 1 - <division> - <paragraph> - Paragraph 2 - - But the two paragraphs are really at the same level; they shouldn't - appear to be at different levels. There's really an invisible - "first division". The horizontal rule splits the document body - into two segments, which should be treated uniformly. - -2. Treating "divisions" uniformly brings us to the second - possibility:: - - <document> - <section name="document"> - <title> - Document - <division> - <paragraph> - Paragraph 1 - <division> - <paragraph> - Paragraph 2 - - With this change, documents and sections will directly contain - divisions and sections, but not body elements. Only divisions will - directly contain body elements. Even without a horizontal rule - anywhere, the body elements of a document or section would be - contained within a division element. This makes the document tree - deeper. This is similar to the way HTML_ treats document contents: - grouped within a ``<body>`` element. - -3. Implement them as "transitions", empty elements:: - - <document> - <section name="document"> - <title> - Document - <paragraph> - Paragraph 1 - <transition> - <paragraph> - Paragraph 2 - - A transition would be a "point element", not containing anything, - only identifying a point within the document structure. This keeps - the document tree flatter, but the idea of a "point element" like - "transition" smells bad. A transition isn't a thing itself, it's - the space between two divisions. However, transitions are a - practical solution. - -Solution 3 was chosen for incorporation into the document tree model. - - .. Local Variables: -- cgit v1.2.1 From 696b91c5403b0d61ee00a69eb5427f03fa387a20 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 17 Oct 2002 03:26:03 +0000 Subject: updated/fixedAdded "Doctree Representation of Transitions" from spec/doctree.txt. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@816 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index f90320a03..b8a5aca29 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1622,6 +1622,105 @@ be left up to the author? Perhaps if the syntax is *allowed* but its use strongly *discouraged*, for aesthetic reasons? Or would that just be hypocritical? Dilemma. + +Doctree Representation of Transitions +===================================== + +(Although not reStructuredText-specific, this section fits best in +this document.) + +Having added the "horizontal rule" construct to the `reStructuredText +Markup Specification`_, a decision had to be made as to how to reflect +the construct in the implementation of the document tree. Given this +source:: + + Document + ======== + + Paragraph 1 + + -------- + + Paragraph 2 + +The horizontal rule indicates a "transition" (in prose terms) or the +start of a new "division". Before implementation, the parsed document +tree would be:: + + <document> + <section name="document"> + <title> + Document + <paragraph> + Paragraph 1 + -------- <--- error here + <paragraph> + Paragraph 2 + +There are several possibilities for the implementation: + +1. Implement horizontal rules as "divisions" or segments. A + "division" is a title-less, non-hierarchical section. The first + try at an implementation looked like this:: + + <document> + <section name="document"> + <title> + Document + <paragraph> + Paragraph 1 + <division> + <paragraph> + Paragraph 2 + + But the two paragraphs are really at the same level; they shouldn't + appear to be at different levels. There's really an invisible + "first division". The horizontal rule splits the document body + into two segments, which should be treated uniformly. + +2. Treating "divisions" uniformly brings us to the second + possibility:: + + <document> + <section name="document"> + <title> + Document + <division> + <paragraph> + Paragraph 1 + <division> + <paragraph> + Paragraph 2 + + With this change, documents and sections will directly contain + divisions and sections, but not body elements. Only divisions will + directly contain body elements. Even without a horizontal rule + anywhere, the body elements of a document or section would be + contained within a division element. This makes the document tree + deeper. This is similar to the way HTML_ treats document contents: + grouped within a ``<body>`` element. + +3. Implement them as "transitions", empty elements:: + + <document> + <section name="document"> + <title> + Document + <paragraph> + Paragraph 1 + <transition> + <paragraph> + Paragraph 2 + + A transition would be a "point element", not containing anything, + only identifying a point within the document structure. This keeps + the document tree flatter, but the idea of a "point element" like + "transition" smells bad. A transition isn't a thing itself, it's + the space between two divisions. However, transitions are a + practical solution. + +Solution 3 was chosen for incorporation into the document tree model. + .. Local Variables: -- cgit v1.2.1 From e81838bcc05fa68f2e8005050fbdf74aedc6386f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 17 Oct 2002 03:26:29 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@817 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index b9439f186..89cc67e60 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -330,6 +330,8 @@ Specific: - Wrote descriptions of all common attributes and parameter entities. Filled in introductory material. - Working through the element descriptions: 33 down, 50 to go. + - Removed "Representation of Horizontal Rules" to + spec/rst/alternatives.txt. * spec/docutils.dtd: @@ -364,6 +366,11 @@ Specific: * spec/howto/i18n.txt: Docutils Internationalization. Added to project. +* spec/rst/alternatives.txt: + + - Added "Doctree Representation of Transitions" from + spec/doctree.txt. + * spec/rst/directives.txt: - Added directives: "topic", "sectnum", "target-notes", -- cgit v1.2.1 From 904a224b8e6591a78892cefe18463d2a875f6167 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 17 Oct 2002 03:32:57 +0000 Subject: fixed references git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@818 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 2 ++ docs/ref/doctree.txt | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index b8a5aca29..05327c71b 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1721,6 +1721,8 @@ There are several possibilities for the implementation: Solution 3 was chosen for incorporation into the document tree model. +.. _HTML: http://www.w3.org/MarkUp/ + .. Local Variables: diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index a0eeba191..5332ab96e 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -2694,7 +2694,11 @@ elements, dividing a section into untitled divisions. A transition may not begin or end a section or document, nor may two transitions be immediately adjacent. -See `Representation of Horizontal Rules`_ below. +See `Doctree Representation of Transitions`__ in `A Record of +reStructuredText Syntax Alternatives`__. + +__ rst/alternatives.txt#doctree-representation-of-transitions +__ rst/alternatives.txt Details -- cgit v1.2.1 From a47fca125f6ebfaefa64347df50173d08f5b7f0c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 04:37:48 +0000 Subject: Fixed string I/O encoding bug; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@821 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 94a19f431..68ea19c88 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -23,9 +23,9 @@ class Input: default_source_path = None - def __init__(self, options, source=None, source_path=None): - self.options = options - """An option values object with "input_encoding" and "output_encoding" + def __init__(self, settings, source=None, source_path=None): + self.settings = settings + """A settings object with "input_encoding" and "output_encoding" attributes (typically a `docutils.optik.Values` object).""" self.source = source @@ -54,7 +54,7 @@ class Input: locale.setlocale(locale.LC_ALL, '') """ - encodings = [self.options.input_encoding, 'utf-8'] + encodings = [self.settings.input_encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) except: @@ -89,9 +89,9 @@ class Output: default_destination_path = None - def __init__(self, options, destination=None, destination_path=None): - self.options = options - """An option values object with "input_encoding" and "output_encoding" + def __init__(self, settings, destination=None, destination_path=None): + self.settings = settings + """A settings object with "input_encoding" and "output_encoding" attributes (typically a `docutils.optik.Values` object).""" self.destination = destination @@ -117,7 +117,7 @@ class FileInput(Input): Input for single, simple file-like objects. """ - def __init__(self, options, source=None, source_path=None, autoclose=1): + def __init__(self, settings, source=None, source_path=None, autoclose=1): """ :Parameters: - `source`: either a file-like object (which is read directly), or @@ -126,7 +126,7 @@ class FileInput(Input): - `autoclose`: close automatically after read (boolean); always false if `sys.stdin` is the source. """ - Input.__init__(self, options, source, source_path) + Input.__init__(self, settings, source, source_path) self.autoclose = autoclose if source is None: if source_path: @@ -157,7 +157,7 @@ class FileOutput(Output): Output for single, simple file-like objects. """ - def __init__(self, options, destination=None, destination_path=None, + def __init__(self, settings, destination=None, destination_path=None, autoclose=1): """ :Parameters: @@ -169,7 +169,7 @@ class FileOutput(Output): - `autoclose`: close automatically after write (boolean); always false if `sys.stdout` is the destination. """ - Output.__init__(self, options, destination, destination_path) + Output.__init__(self, settings, destination, destination_path) self.opened = 1 self.autoclose = autoclose if destination is None: @@ -190,7 +190,7 @@ class FileOutput(Output): def write(self, data): """Encode `data`, write it to a single file, and return it.""" - output = data.encode(self.options.output_encoding) + output = data.encode(self.settings.output_encoding) if not self.opened: self.open() self.destination.write(output) @@ -213,7 +213,8 @@ class StringInput(Input): def read(self, reader): """Decode and return the source string.""" - if self.options.input_encoding.lower() == 'unicode': + if self.settings.input_encoding \ + and self.settings.input_encoding.lower() == 'unicode': return self.source else: return self.decode(self.source) @@ -229,10 +230,11 @@ class StringOutput(Output): def write(self, data): """Encode `data`, store it in `self.destination`, and return it.""" - if self.options.output_encoding.lower() == 'unicode': + if self.settings.output_encoding \ + and self.settings.output_encoding.lower() == 'unicode': self.destination = data else: - self.destination = data.encode(self.options.output_encoding) + self.destination = data.encode(self.settings.output_encoding) return self.destination -- cgit v1.2.1 From ddf130508e6c446a3d2f7afbd5fba383acffc2b6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 04:43:18 +0000 Subject: Fixed a bug in ``relative_path()``; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@822 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/docutils/utils.py b/docutils/utils.py index 2f2c4c9f1..bbd08c6a2 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -237,14 +237,14 @@ class BadOptionDataError(ExtensionOptionError): pass class DuplicateOptionError(ExtensionOptionError): pass -def extract_extension_options(field_list, option_spec): +def extract_extension_options(field_list, options_spec): """ Return a dictionary mapping extension option names to converted values. :Parameters: - `field_list`: A flat field list without field arguments, where each field body consists of a single paragraph only. - - `option_spec`: Dictionary mapping known option names to a + - `options_spec`: Dictionary mapping known option names to a conversion function such as `int` or `float`. :Exceptions: @@ -257,7 +257,7 @@ def extract_extension_options(field_list, option_spec): missing data, bad quotes, etc.). """ option_list = extract_options(field_list) - option_dict = assemble_option_dict(option_list, option_spec) + option_dict = assemble_option_dict(option_list, options_spec) return option_dict def extract_options(field_list): @@ -292,14 +292,14 @@ def extract_options(field_list): option_list.append((name, data)) return option_list -def assemble_option_dict(option_list, option_spec): +def assemble_option_dict(option_list, options_spec): """ Return a mapping of option names to values. :Parameters: - `option_list`: A list of (name, value) pairs (the output of `extract_options()`). - - `option_spec`: Dictionary mapping known option names to a + - `options_spec`: Dictionary mapping known option names to a conversion function such as `int` or `float`. :Exceptions: @@ -310,7 +310,7 @@ def assemble_option_dict(option_list, option_spec): """ options = {} for name, value in option_list: - convertor = option_spec[name] # raises KeyError if unknown + convertor = options_spec[name] # raises KeyError if unknown if options.has_key(name): raise DuplicateOptionError('duplicate option "%s"' % name) try: @@ -372,12 +372,12 @@ def normalize_name(name): """Return a case- and whitespace-normalized name.""" return ' '.join(name.lower().split()) -def new_document(source, options=None): - if options is None: - options = frontend.OptionParser().get_default_values() - reporter = Reporter(source, options.report_level, options.halt_level, - options.warning_stream, options.debug) - document = nodes.document(options, reporter, source=source) +def new_document(source, settings=None): + if settings is None: + settings = frontend.OptionParser().get_default_values() + reporter = Reporter(source, settings.report_level, settings.halt_level, + settings.warning_stream, settings.debug) + document = nodes.document(settings, reporter, source=source) document.note_source(source) return document @@ -398,8 +398,10 @@ def relative_path(source, target): """ source_parts = os.path.abspath(source or '').split(os.sep) target_parts = os.path.abspath(target).split(os.sep) - if source_parts[:1] != target_parts[:1]: - # Nothing in common between paths. Return absolute path. + # Check first 2 parts because '/dir'.split('/') == ['', 'dir']: + if source_parts[:2] != target_parts[:2]: + # Nothing in common between paths. + # Return absolute path, using '/' for URLs: return '/'.join(target_parts) source_parts.reverse() target_parts.reverse() -- cgit v1.2.1 From 7a48b3972754ebd5e339322f77b3119c895fffa1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 04:45:18 +0000 Subject: Fixed path handling in "include" and "raw" directives. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@823 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 58af1336f..3bd088e39 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -9,20 +9,25 @@ __docformat__ = 'reStructuredText' import sys +import os.path from urllib2 import urlopen, URLError -from docutils import nodes, statemachine +from docutils import nodes, statemachine, utils from docutils.parsers.rst import directives, states def include(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Include a reST file as part of the content of this reST file.""" + source_dir = os.path.dirname( + os.path.abspath(state.document.current_source)) path = ''.join(arguments[0].splitlines()) if path.find(' ') != -1: error = state_machine.reporter.error( '"%s" directive path contains whitespace.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] + path = os.path.normpath(os.path.join(source_dir, path)) + path = utils.relative_path(None, path) try: include_file = open(path) except IOError, error: @@ -78,8 +83,12 @@ def raw(name, arguments, options, content, lineno, 'specified for the "%s" directive.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] + source_dir = os.path.dirname( + os.path.abspath(state.document.current_source)) + path = os.path.normpath(os.path.join(source_dir, options['file'])) + path = utils.relative_path(None, path) try: - raw_file = open(options['file']) + raw_file = open(path) except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), @@ -87,7 +96,7 @@ def raw(name, arguments, options, content, lineno, return [severe] text = raw_file.read() raw_file.close() - attributes['source'] = options['file'] + attributes['source'] = path elif options.has_key('url'): try: raw_file = urlopen(options['url']) -- cgit v1.2.1 From be8b4a7a7f9dc8ed02f5fb25b5920364602b3b80 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 04:48:00 +0000 Subject: Progress on ``Transformer`` class; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@824 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 51 ++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 328d246e7..34aa7911d 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -58,11 +58,12 @@ class Transform: apply to the document as a whole, `startnode` is not set (i.e. its value is `None`).""" - self.language = languages.get_language(document.options.language_code) + self.language = languages.get_language( + document.settings.language_code) """Language module local to this document.""" - def transform(self): - """Override to transform the document tree.""" + def apply(self): + """Override to apply the transform to the document tree.""" raise NotImplementedError('subclass must override this method') @@ -72,31 +73,59 @@ class Transformer(TransformSpec): The Transformer class records and applies transforms to documents. """ - def __init__(self): + from docutils.transforms import universal + + default_transforms = (universal.Decorations, + universal.FinalChecks, + universal.Messages) + + def __init__(self, document): self.transforms = [] """Queue of transforms to apply.""" self.applying = None """Boolean: am I now applying tranforms?""" - def add_transform(self, transform_class, priority=None): + self.document = document + """The `nodes.document` object this Transformer is attached to.""" + + def add_transform(self, transform_class, priority=None, component=None): if priority is None: priority = transform_class.priority - self.transforms.append((priority, transform_class, None)) + self.transforms.append((priority, transform_class, None, component)) if self.applying: self.transforms.sort() - def add_transforms(self, transform_list): + def add_transforms(self, transform_list, component=None): for transform_class in transform_list: - self.transforms.append((transform_class.priority, transform_class, - None)) + self.transforms.append( + (transform_class.priority, transform_class, None, component)) if self.applying: self.transforms.sort() - def add_pending(self, pending, priority=None): + def add_pending(self, pending, priority=None, component=None): transform_class = pending.transform if priority is None: priority = transform_class.priority - self.transforms.append((priority, transform_class, pending)) + self.transforms.append( + (priority, transform_class, pending, component)) if self.applying: self.transforms.sort() + + def populate_from_components(self, components): + for component in components: + if component is None: + continue + self.add_transforms(component.default_transforms, + component=component) + + def apply_transforms(self): + self.applying = 1 + self.transforms.sort() + while self.transforms: + priority, transform_class, pending, component \ + = self.transforms.pop(0) + transform = transform_class(self.document, component, + startnode=pending) + transform.apply() + self.applying = None -- cgit v1.2.1 From afeedfb343c2904e9357997d2a50f8f3cabb2568 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 04:55:21 +0000 Subject: Refactored names (options -> settings; .transform() -> .apply(); etc.); updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@825 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 29 +++++-- docs/dev/todo.txt | 51 ++++++------- docs/peps/pep-0258.txt | 7 +- docs/user/tools.txt | 45 ++++++----- docutils/__init__.py | 37 +++++---- docutils/core.py | 89 ++++++++++++---------- docutils/frontend.py | 54 ++++++------- docutils/nodes.py | 8 +- docutils/parsers/rst/__init__.py | 4 +- docutils/parsers/rst/states.py | 13 ++-- docutils/readers/__init__.py | 10 +-- docutils/readers/pep.py | 4 +- docutils/transforms/components.py | 2 +- docutils/transforms/frontmatter.py | 4 +- docutils/transforms/parts.py | 6 +- docutils/transforms/peps.py | 10 +-- docutils/transforms/references.py | 8 +- docutils/transforms/universal.py | 39 +++++----- docutils/writers/__init__.py | 7 +- docutils/writers/docutils_xml.py | 10 +-- docutils/writers/html4css1.py | 37 ++++----- docutils/writers/pep_html.py | 36 ++++----- test/DocutilsTestSupport.py | 38 ++++----- .../test_rst/test_directives/test_include.py | 2 +- .../test_rst/test_directives/test_raw.py | 2 +- tools/buildhtml.py | 71 ++++++++--------- tools/docutils-xml.py | 4 +- tools/html.py | 4 +- tools/pep.py | 5 +- tools/pep2html.py | 24 +++--- tools/publish.py | 4 +- tools/quicktest.py | 6 +- 32 files changed, 357 insertions(+), 313 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 89cc67e60..135af4abe 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -41,7 +41,22 @@ Changes Since 0.2 General: -- Changed "attribute" to "option" for directives/extensions. +* 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: @@ -51,18 +66,20 @@ Specific: - 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 ``OptionSpec`` out of ``Component``; separately useful. + - 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). * docutils/core.py: - Made ``publish()`` a bit more convenient. - Generalized ``Publisher.set_io``. + - Renamed ``publish()`` to ``publish_cmdline()``. * docutils/frontend.py: @@ -70,10 +87,10 @@ Specific: - Fixed bug with absolute paths & ``--config``. - Set non-command-line defaults in ``OptionParser.__init__()``: ``_source`` & ``_destination``. - - Distributed ``relative_path_options`` to components; updated + - 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_options``). + global ``relative_path_settings``). - Added ``--expose-internal-attribute`` option. * docutils/io.py: @@ -304,7 +321,7 @@ Specific: - Added a "silent" setting for ``buildhtml.py``. - Added a "Getting Help" section. - Rearranged the structure. - - Kept up to date, with new command-line options etc. + - Kept up to date, with new settings, command-line options etc. * docs/rst/quickstart.txt: @@ -408,7 +425,7 @@ Specific: - Fixed bug with absolute paths & ``--config``. - Updated for new I/O classes. - Added some exception handling. - - Separated publishers' option defaults; prevents interference. + - Separated publishers' setting defaults; prevents interference. * tools/pep-html-template: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4e0a6739d..e6d202e9a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -117,7 +117,7 @@ General a) ``core.Publisher`` creates a ``Transformer`` object, initializes it from components (reader, parser, writer, source, destination), and attaches it to ``document`` (via - ``options``]?). + ``settings``]?). b) ``document`` is given a ``Transformer`` object (``document.transformer``) in ``utils.new_document``. @@ -147,27 +147,25 @@ General - Document transform priorities. - - Change ``Transform.transform()`` to ``Transform.apply()``? - Updated project dataflow model under consideration for PEP 258:: - +--------------------------+ - | Docutils: | - | docutils.core.Publisher, | - | docutils.core.publish() | - +--------------------------+ - / | \ - / | \ - 1,3,5 / 6 | \ 7 - +--------+ +-------------+ +--------+ - | READER | ---> | TRANSFORMER | ====> | WRITER | - +--------+ +-------------+ +--------+ - / \\ | - / \\ | - 2 / 4 \\ 8 | - +-------+ +--------+ +--------+ - | INPUT | | PARSER | | OUTPUT | - +-------+ +--------+ +--------+ + +---------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish_*() | + +---------------------------+ + / | \ + / | \ + 1,3,5 / 6 | \ 7 + +--------+ +-------------+ +--------+ + | READER | ----> | TRANSFORMER | ====> | WRITER | + +--------+ +-------------+ +--------+ + / \\ | + / \\ | + 2 / 4 \\ 8 | + +-------+ +--------+ +--------+ + | INPUT | | PARSER | | OUTPUT | + +-------+ +--------+ +--------+ * @@@ Break up ``references.Hyperlinks`` into multiple smaller transforms. @@ -337,8 +335,6 @@ General As I said earlier in chapter :chapter:`objects`, the reference count gets increased every time a binding is made. -* Change all occurrences of "options" to "settings"? - * Add functional testing to Docutils: Readers, Writers, front ends. * Changes to sandbox/davidg/infrastructure/docutils-update? @@ -355,9 +351,9 @@ General the very least, there ought to be error checking higher up in the call chain. [Aahz] - ``Publisher.set_options`` requires that all components be set up + ``Publisher.get_settings`` requires that all components be set up before it's called. Perhaps the I/O *objects* shouldn't be set, but - I/O *classes*. Then options are set up (``.set_options``), and + I/O *classes*. Then options are set up (``.set_options``), and ``Publisher.set_io`` (or equivalent code) is called with source & destination paths, creating the I/O objects. @@ -371,7 +367,7 @@ General Writers now), and thus have associated option/setting specs and transforms. -* ``docutils.Component`` +* Documentation @@ -1076,7 +1072,8 @@ HTML Writer ----------- * @@ Construct a _`templating system`, as in ht2html/yaptu, using - directives and substitutions for dynamic stuff. + directives and substitutions for dynamic stuff. Or a specialized + writer to generate .ht & links.h files for ht2html? * Add more support for <link> elements, especially for navigation bars. @@ -1123,7 +1120,7 @@ Front-End Tools apart. * Parameterize help text & defaults somehow? Perhaps a callback? Or - initialize ``cmdline_options`` in ``__init__`` or ``init_options``? + initialize ``settings_spec`` in ``__init__`` or ``init_options``? * Disable common options that don't apply? diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 15a3317cb..f385cebb6 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -94,8 +94,8 @@ format and writing the formatted data to its destination I/O. Calling the "publish" function (or instantiating a "Publisher" object) with component names will result in default behavior. For custom -behavior (setting component options), create custom component objects -first, and pass *them* to publish/Publisher. +behavior (customizing component settings), create custom component +objects first, and pass *them* to publish/Publisher. Readers @@ -324,7 +324,8 @@ Docutils Package Structure convenience function "publish()". See `Publisher`_ above. - Module "docutils.frontend" provides command-line and option - processing for Docutils front-end tools. + processing for Docutils front-end tools, and runtime settings + support for programmatic use. - Module "docutils.io" provides a uniform API for low-level input and output. See `Input/Output`_ above. diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 0cf585f6e..7e1f597bd 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -321,19 +321,20 @@ options is listed in `Configuration File Entries`_ below. Configuration File Entries -------------------------- -The entry names listed below may be specified in `configuration -files`_. Hyphens may be used in place of underscores in entry names. -Some knowledge of Python_ is assumed for some attributes. +Names in the first column of the table below are runtime settings. +Most may be specified in `configuration files`_, where hyphens may be +used in place of underscores. Some knowledge of Python_ is assumed +for some attributes. ==================== ================================================ -Config Entry Name Description +Setting/Config Entry Description ==================== ================================================ -expose_internals (Hidden option, for development use only.) List - of internal attribues to expose as external +expose_internals List of internal attribues to expose as external attributes (with "internal:" namespace prefix). Default: don't (None). Options: - ``--expose-internal-attribute``. + ``--expose-internal-attribute`` (hidden, for + development use only). -------------------- ------------------------------------------------ compact_lists (HTML Writer.) Remove extra vertical whitespace between items of bullet lists and enumerated @@ -368,13 +369,13 @@ debug Report debug-level system messages. Default: don't (None). Options: ``--debug, --no-debug``. -------------------- ------------------------------------------------ -dump_internals (Hidden option, for development use only.) At - the end of processing, print out all internal +dump_internals At the end of processing, print out all internal attributes of the document (``document.__dict__``). Default: don't (None). Options: - ``--dump-internals``. + ``--dump-internals`` (hidden, for development + use only). -------------------- ------------------------------------------------ embed_stylesheet (HTML Writer.) Embed the stylesheet in the output HTML file. The stylesheet file must be @@ -430,12 +431,11 @@ newlines (XML Writer.) Generate XML with newlines before Default: don't (None). Options: ``--newlines``. -------------------- ------------------------------------------------ -no_random (PEP/HTML Writer; hidden option.) Workaround - for platforms which core-dump on "``import - random``". +no_random (PEP/HTML Writer.) Workaround for platforms + which core-dump on "``import random``". Default: random enabled (None). Options: - ``--no-random``. + ``--no-random`` (hidden). -------------------- ------------------------------------------------ output_encoding Default: UTF-8. Options: ``--output-encoding, -o``. @@ -552,16 +552,21 @@ warning_stream Path to a file for the output of system messages ---------------------------------------------------------------------- _directories (``buildhtml.py`` front end.) List of paths to source directories, set from positional - arguments. Default: current working directory - (None). No command-line options. + arguments. + + Default: current working directory (None). No + command-line options. -------------------- ------------------------------------------------ _destination Path to output destination, set from positional - arguments. Default: stdout (None). No - command-line options. + arguments. + + Default: stdout (None). No command-line + options. -------------------- ------------------------------------------------ _source Path to input source, set from positional - arguments. Default: stdin (None). No - command-line options. + arguments. + + Default: stdin (None). No command-line options. ==================== ================================================ .. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html diff --git a/docutils/__init__.py b/docutils/__init__.py index a52dbb51d..7461d2f42 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,7 +55,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.5' +__version__ = '0.2.6' """``major.minor.micro`` version number. The ``micro`` number is bumped any time there's a change in the API incompatible with one of the front ends.""" @@ -64,30 +64,34 @@ class ApplicationError(StandardError): pass class DataError(ApplicationError): pass -class OptionSpec: +class SettingsSpec: """ - Runtime option specification base class. + Runtime setting specification base class. - OptionSpec subclass objects used by `docutils.frontend.OptionParser`. + SettingsSpec subclass objects used by `docutils.frontend.OptionParser`. """ - cmdline_options = () - """Command-line option specification. Override in subclasses. + settings_spec = () + """Runtime settings specification. Override in subclasses. - One or more sets of option group title, description, and a list/tuple of - tuples: ``('help text', [list of option strings], {keyword arguments})``. - Group title and/or description may be `None`; no group title implies no - group, just a list of single options.""" + Specifies runtime settings and associated command-line options, as used by + `docutils.frontend.OptionParser`. This tuple contains one or more sets of + option group title, description, and a list/tuple of tuples: ``('help + text', [list of option strings], {keyword arguments})``. Group title + and/or description may be `None`; no group title implies no group, just a + list of single options. Runtime settings names are derived implicitly + from long option names ("--a-setting" becomes ``settings.a_setting``) or + explicitly from the "destination" keyword argument.""" - option_default_overrides = None - """A dictionary of auxiliary defaults, to override defaults for options + settings_default_overrides = None + """A dictionary of auxiliary defaults, to override defaults for settings defined in other components. Override in subclasses.""" - relative_path_options = () - """Options containing filesystem paths. Override in subclasses. + relative_path_settings = () + """Settings containing filesystem paths. Override in subclasses. - Options listed here are to be interpreted relative to the current working + Settings listed here are to be interpreted relative to the current working directory.""" @@ -100,9 +104,10 @@ class TransformSpec: """ default_transforms = () + """Transforms required by this class. Override in subclasses.""" -class Component(OptionSpec, TransformSpec): +class Component(SettingsSpec, TransformSpec): """Base class for Docutils components.""" diff --git a/docutils/core.py b/docutils/core.py index c243df22d..1e363fee5 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -29,7 +29,7 @@ class Publisher: def __init__(self, reader=None, parser=None, writer=None, source=None, source_class=io.FileInput, destination=None, destination_class=io.FileOutput, - options=None): + settings=None): """ Initial setup. If any of `reader`, `parser`, or `writer` are not specified, the corresponding ``set_...`` method should be called with @@ -57,9 +57,9 @@ class Publisher: self.destination_class = destination_class """The class for dynamically created destination objects.""" - self.options = options + self.settings = settings """An object containing Docutils settings as instance attributes. - Set by `self.process_command_line()` or `self.set_options()`.""" + Set by `self.process_command_line()` or `self.get_settings()`.""" def set_reader(self, reader_name, parser, parser_name): """Set `self.reader` by name.""" @@ -73,35 +73,36 @@ class Publisher: self.writer = writer_class() def setup_option_parser(self, usage=None, description=None, - option_spec=None, **defaults): + settings_spec=None, **defaults): option_parser = OptionParser( - components=(option_spec, self.parser, self.reader, self.writer), + components=(settings_spec, self.parser, self.reader, self.writer), usage=usage, description=description) config = ConfigParser() config.read_standard_files() - config_options = config.get_section('options') - frontend.make_paths_absolute(config_options, - option_parser.relative_path_options) - defaults.update(config_options) + config_settings = config.get_section('options') + frontend.make_paths_absolute(config_settings, + option_parser.relative_path_settings) + defaults.update(config_settings) option_parser.set_defaults(**defaults) return option_parser - def set_options(self, usage=None, description=None, - option_spec=None, **defaults): + def get_settings(self, usage=None, description=None, + settings_spec=None, **defaults): """ - Set and return default option values (keyword arguments). + Set and return default settings (overrides in `defaults` keyword + argument). Set components first (`self.set_reader` & `self.set_writer`). - Explicitly setting options disables command line option processing - from `self.publish()`. + Explicitly setting `self.settings` disables command line option + processing from `self.publish()`. """ option_parser = self.setup_option_parser(usage, description, - option_spec, **defaults) - self.options = option_parser.get_default_values() - return self.options + settings_spec, **defaults) + self.settings = option_parser.get_default_values() + return self.settings def process_command_line(self, argv=None, usage=None, description=None, - option_spec=None, **defaults): + settings_spec=None, **defaults): """ Pass an empty list to `argv` to avoid reading `sys.argv` (the default). @@ -109,32 +110,32 @@ class Publisher: Set components first (`self.set_reader` & `self.set_writer`). """ option_parser = self.setup_option_parser(usage, description, - option_spec, **defaults) + settings_spec, **defaults) if argv is None: argv = sys.argv[1:] - self.options = option_parser.parse_args(argv) + self.settings = option_parser.parse_args(argv) def set_io(self): if self.source is None: - self.source = self.source_class(self.options, - source_path=self.options._source) + self.source = self.source_class(self.settings, + source_path=self.settings._source) if self.destination is None: self.destination = self.destination_class( - self.options, destination_path=self.options._destination) + self.settings, destination_path=self.settings._destination) def publish(self, argv=None, usage=None, description=None, - option_spec=None): + settings_spec=None): """ - Process command line options and arguments (if `self.options` not + Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return `self.writer`'s output. """ - if self.options is None: - self.process_command_line(argv, usage, description, option_spec) + if self.settings is None: + self.process_command_line(argv, usage, description, settings_spec) self.set_io() - document = self.reader.read(self.source, self.parser, self.options) + document = self.reader.read(self.source, self.parser, self.settings) output = self.writer.write(document, self.destination) - if self.options.dump_internals: + if self.settings.dump_internals: from pprint import pformat print >>sys.stderr, pformat(document.__dict__) return output @@ -144,18 +145,26 @@ default_usage = '%prog [options] [<source> [<destination>]]' default_description = ('Reads from <source> (default is stdin) and writes to ' '<destination> (default is stdout).') -def publish(reader=None, reader_name='standalone', - parser=None, parser_name='restructuredtext', - writer=None, writer_name='pseudoxml', - argv=None, usage=default_usage, description=default_description, - option_spec=None, options=None): - """ - A convenience function for file I/O front ends; set up & run a - `Publisher`. - """ - pub = Publisher(reader, parser, writer, options=options) +def publish_cmdline(reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='pseudoxml', + argv=None, usage=default_usage, + description=default_description, + settings_spec=None, settings=None): + """Set up & run a `Publisher`. For command-line front ends.""" + pub = Publisher(reader, parser, writer, settings=settings) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: pub.set_writer(writer_name) - pub.publish(argv, usage, description, option_spec) + pub.publish(argv, usage, description, settings_spec) + +def publish_file(): + """ + Set up & run a `Publisher`. For programmatic use with file-like I/O. + """ + +def publish_string(): + """ + Set up & run a `Publisher`. For programmatic use with string I/O. + """ diff --git a/docutils/frontend.py b/docutils/frontend.py index f99c3f667..609926e40 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -10,7 +10,8 @@ Command-line and common processing for Docutils front-end tools. Exports the following classes: - `OptionParser`: Standard Docutils command-line processing. -- `Values`: Option values; objects are simple structs (``object.attribute``). +- `Values`: Runtime settings; objects are simple structs + (``object.attribute``). - `ConfigParser`: Standard Docutils config file processing. """ @@ -43,7 +44,7 @@ def read_config_file(option, opt, value, parser): config_parser = ConfigParser() config_parser.read(value) settings = config_parser.get_section('options') - make_paths_absolute(settings, parser.relative_path_options, + make_paths_absolute(settings, parser.relative_path_settings, os.path.dirname(value)) parser.values.__dict__.update(settings) @@ -52,7 +53,7 @@ def make_paths_absolute(pathdict, keys, base_path=None): Interpret filesystem path settings relative to the `base_path` given. Paths are values in `pathdict` whose keys are in `keys`. Get `keys` from - `OptionParser.relative_path_options`. + `OptionParser.relative_path_settings`. """ if base_path is None: base_path = os.getcwd() @@ -62,16 +63,16 @@ def make_paths_absolute(pathdict, keys, base_path=None): os.path.abspath(os.path.join(base_path, pathdict[key]))) -class OptionParser(optik.OptionParser, docutils.OptionSpec): +class OptionParser(optik.OptionParser, docutils.SettingsSpec): """ - Parser for command-line and library use. The `cmdline_options` - specification here and in other Docutils components are merged to - build the set of command-line options for this process. + Parser for command-line and library use. The `settings_spec` + specification here and in other Docutils components are merged to build + the set of command-line options and runtime settings for this process. - Common options (defined below) and component-specific options must - not conflict. Short options are reserved for common options, and - components are restrict to using long options. + Common settings (defined below) and component-specific settings must not + conflict. Short options are reserved for common settings, and components + are restrict to using long options. """ threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split() @@ -80,7 +81,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5} """Lookup table for --report and --halt threshold values.""" - cmdline_options = ( + settings_spec = ( 'General Docutils Options', None, (('Include a "Generated by Docutils" credit and link at the end ' @@ -161,7 +162,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): ' Default is "en" (English).', ['--language', '-l'], {'dest': 'language_code', 'default': 'en', 'metavar': '<name>'}), - ('Read configuration options from <file>, if it exists.', + ('Read configuration settings from <file>, if it exists.', ['--config'], {'metavar': '<file>', 'type': 'string', 'action': 'callback', 'callback': read_config_file}), ("Show this program's version number and exit.", @@ -175,11 +176,11 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): (optik.SUPPRESS_HELP, ['--expose-internal-attribute'], {'action': 'append', 'dest': 'expose_internals'}),)) - """Command-line options common to all Docutils front ends. Option specs - specific to individual Docutils components are also used (see - `populate_from_components()`).""" + """Runtime settings and command-line options common to all Docutils front + ends. Setting specs specific to individual Docutils components are also + used (see `populate_from_components()`).""" - relative_path_options = ('warning_stream',) + relative_path_settings = ('warning_stream',) version_template = '%%prog (Docutils %s)' % docutils.__version__ """Default version message.""" @@ -187,7 +188,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): def __init__(self, components=(), *args, **kwargs): """ `components` is a list of Docutils components each containing a - ``.cmdline_options`` attribute. `defaults` is a mapping of option + ``.settings_spec`` attribute. `defaults` is a mapping of setting default overrides. """ optik.OptionParser.__init__( @@ -199,11 +200,11 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): *args, **kwargs) if not self.version: self.version = self.version_template - # Internal settings with no defaults from option specifications; + # Internal settings with no defaults from settings specifications; # initialize manually: self.set_defaults(_source=None, _destination=None) # Make an instance copy (it will be modified): - self.relative_path_options = list(self.relative_path_options) + self.relative_path_settings = list(self.relative_path_settings) self.populate_from_components(tuple(components) + (self,)) def populate_from_components(self, components): @@ -211,10 +212,11 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): if component is None: continue i = 0 - cmdline_options = component.cmdline_options - self.relative_path_options.extend(component.relative_path_options) - while i < len(cmdline_options): - title, description, option_spec = cmdline_options[i:i+3] + settings_spec = component.settings_spec + self.relative_path_settings.extend( + component.relative_path_settings) + while i < len(settings_spec): + title, description, option_spec = settings_spec[i:i+3] if title: group = optik.OptionGroup(self, title, description) self.add_option_group(group) @@ -225,8 +227,8 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): **kwargs) i += 3 for component in components: - if component and component.option_default_overrides: - self.defaults.update(component.option_default_overrides) + if component and component.settings_default_overrides: + self.defaults.update(component.settings_default_overrides) def check_values(self, values, args): if hasattr(values, 'report_level'): @@ -234,7 +236,7 @@ class OptionParser(optik.OptionParser, docutils.OptionSpec): if hasattr(values, 'halt_level'): values.halt_level = self.check_threshold(values.halt_level) values._source, values._destination = self.check_args(args) - make_paths_absolute(values.__dict__, self.relative_path_options, + make_paths_absolute(values.__dict__, self.relative_path_settings, os.getcwd()) return values diff --git a/docutils/nodes.py b/docutils/nodes.py index c95c514ca..b61b21761 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -602,7 +602,7 @@ class Labeled: class document(Root, Structural, Element): - def __init__(self, options, reporter, *args, **kwargs): + def __init__(self, settings, reporter, *args, **kwargs): Element.__init__(self, *args, **kwargs) self.current_source = None @@ -611,8 +611,8 @@ class document(Root, Structural, Element): self.current_line = None """Line number (1-based) of `current_source`.""" - self.options = options - """Command-line or internal option data record.""" + self.settings = settings + """Runtime settings data record.""" self.reporter = reporter """System message generator.""" @@ -908,7 +908,7 @@ class document(Root, Structural, Element): self.current_source = source def copy(self): - return self.__class__(self.options, self.reporter, + return self.__class__(self.settings, self.reporter, **self.attributes) diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index c8077de48..82e8c59af 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -57,7 +57,7 @@ class Parser(docutils.parsers.Parser): supported = ('restructuredtext', 'rst', 'rest', 'restx', 'rtxt', 'rstx') """Aliases this parser supports.""" - cmdline_options = ( + settings_spec = ( 'reStructuredText Parser Options', None, (('Recognize and link to PEP references (like "PEP 258").', @@ -87,6 +87,6 @@ class Parser(docutils.parsers.Parser): initial_state=self.initial_state, debug=debug) inputlines = docutils.statemachine.string2lines( - inputstring, tab_width=document.options.tab_width, + inputstring, tab_width=document.settings.tab_width, convert_whitespace=1) self.statemachine.run(inputlines, document, inliner=self.inliner) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 27784dc27..6600391ff 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -145,11 +145,12 @@ class RSTStateMachine(StateMachineWS): StateMachine, and return the resulting document. """ - self.language = languages.get_language(document.options.language_code) + self.language = languages.get_language( + document.settings.language_code) self.match_titles = match_titles if inliner is None: inliner = Inliner() - inliner.init_customizations(document.options) + inliner.init_customizations(document.settings) self.memo = Stuff(document=document, reporter=document.reporter, language=self.language, @@ -431,12 +432,12 @@ class Inliner: """List of (pattern, bound method) tuples, used by `self.implicit_inline`.""" - def init_customizations(self, options): - """Option-based customizations; run when parsing begins.""" - if options.pep_references: + def init_customizations(self, settings): + """Setting-based customizations; run when parsing begins.""" + if settings.pep_references: self.implicit_dispatch.append((self.patterns.pep, self.pep_reference)) - if options.rfc_references: + if settings.rfc_references: self.implicit_dispatch.append((self.patterns.rfc, self.rfc_reference)) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 1903fcd35..44e6fe76c 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -28,7 +28,7 @@ class Reader(Component): """ transforms = () - """Ordered tuple of transform classes (each with a ``transform()`` + """Ordered tuple of transform classes (each with an ``apply()`` method). Populated by subclasses. `Reader.transform()` instantiates & runs them.""" @@ -59,11 +59,11 @@ class Reader(Component): parser_class = parsers.get_parser_class(parser_name) self.parser = parser_class() - def read(self, source, parser, options): + def read(self, source, parser, settings): self.source = source if not self.parser: self.parser = parser - self.options = options + self.settings = settings # May modify self.parser, depending on input: self.input = self.source.read(self) self.parse() @@ -85,11 +85,11 @@ class Reader(Component): for xclass in (universal.first_reader_transforms + tuple(self.transforms) + universal.last_reader_transforms): - xclass(self.document, self).transform() + xclass(self.document, self).apply() def new_document(self): """Create and return a new empty document tree (root node).""" - document = utils.new_document(self.source.source_path, self.options) + document = utils.new_document(self.source.source_path, self.settings) return document diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b1b514886..7492331c8 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -25,7 +25,7 @@ class Reader(standalone.Reader): supported = ('pep',) """Contexts this reader supports.""" - cmdline_options = ( + settings_spec = ( 'PEP Reader Option Defaults', 'The --pep-references and --rfc-references options (for the ' 'reStructuredText parser) are on by default.', @@ -38,7 +38,7 @@ class Reader(standalone.Reader): references.Footnotes, references.Hyperlinks,) - option_default_overrides = {'pep_references': 1, 'rfc_references': 1} + settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} def __init__(self, parser, parser_name): """`parser` should be ``None``.""" diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index 6b0c2648c..7bb4e959d 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -40,7 +40,7 @@ class Filter(Transform): it will be deleted from the output of all other writers. """ - def transform(self): + def apply(self): pending = self.startnode component_type = pending.stage.split()[-1] # 'reader' or 'writer' component_name = pending.details[component_type] diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index c3b5bca83..f8d4869c5 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -102,7 +102,7 @@ class DocTitle(Transform): after the title(s). """ - def transform(self): + def apply(self): if self.promote_document_title(): self.promote_document_subtitle() @@ -225,7 +225,7 @@ class DocInfo(Transform): expansion text changes only if the file name changes.) """ - def transform(self): + def apply(self): document = self.document index = document.first_child_not_matching_class( nodes.PreBibliographic) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index bbb27245a..8bf0d2946 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -31,7 +31,7 @@ class SectNum(Transform): be used. """ - def transform(self): + def apply(self): self.maxdepth = self.startnode.details.get('depth', sys.maxint) self.startnode.parent.remove(self.startnode) self.update_section_numbers(self.document) @@ -69,7 +69,7 @@ class Contents(Transform): startnode is replaced by the table of contents "topic"). """ - def transform(self): + def apply(self): topic = nodes.topic(CLASS='contents') title = self.startnode.details['title'] if self.startnode.details.has_key('local'): @@ -95,7 +95,7 @@ class Contents(Transform): if self.startnode.details.has_key('backlinks'): self.backlinks = self.startnode.details['backlinks'] else: - self.backlinks = self.document.options.toc_backlinks + self.backlinks = self.document.settings.toc_backlinks contents = self.build_contents(startnode) if len(contents): topic += contents diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index f7cea6953..91d59bf72 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -38,7 +38,7 @@ class Headers(Transform): (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'), (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),) - def transform(self): + def apply(self): if not len(self.document): raise DataError('Document tree is empty.') header = self.document[0] @@ -136,7 +136,7 @@ class Contents(Transform): the RFC 2822 header. """ - def transform(self): + def apply(self): pending = nodes.pending(parts.Contents, 'first writer', {'title': None}) self.document.insert(1, pending) @@ -150,7 +150,7 @@ class TargetNotes(Transform): target footnote insertion transform at the end, and run the transform. """ - def transform(self): + def apply(self): doc = self.document i = len(doc) - 1 refsect = copyright = None @@ -170,7 +170,7 @@ class TargetNotes(Transform): doc.append(refsect) pending = nodes.pending(references.TargetNotes, 'immediate', {}) refsect.append(pending) - pending.transform(doc, self, pending).transform() + pending.transform(doc, self, pending).apply() class PEPZero(Transform): @@ -179,7 +179,7 @@ class PEPZero(Transform): Special processing for PEP 0. """ - def transform(self): + def apply(self): visitor = PEPZeroSpecial(self.document) self.document.walk(visitor) self.startnode.parent.remove(self.startnode) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index cc073e9c7..96bd48942 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -28,7 +28,7 @@ class Hyperlinks(Transform): """Resolve the various types of hyperlink targets and references.""" - def transform(self): + def apply(self): self.resolve_chained_targets() self.resolve_anonymous() self.resolve_indirect() @@ -472,7 +472,7 @@ class Footnotes(Transform): u'\u2663', # club suit ♣ ] - def transform(self): + def apply(self): self.autofootnote_labels = [] startnum = self.document.autofootnote_start self.document.autofootnote_start = self.number_footnotes(startnum) @@ -635,7 +635,7 @@ class Substitutions(Transform): <image alt="biohazard" uri="biohazard.png"> """ - def transform(self): + def apply(self): defs = self.document.substitution_defs for refname, refs in self.document.substitution_refs.items(): for ref in refs: @@ -665,7 +665,7 @@ class TargetNotes(Transform): Transform.__init__(self, document, component, startnode) self.notes = {} - def transform(self): + def apply(self): nodelist = [] for target in self.document.external_targets: name = target.get('name') diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 3ba62ecef..de52c3bb3 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -32,7 +32,7 @@ class Decorations(Transform): Populate a document's decoration element (header, footer). """ - def transform(self): + def apply(self): header = self.generate_header() footer = self.generate_footer() if header or footer: @@ -53,24 +53,25 @@ class Decorations(Transform): def generate_footer(self): # @@@ Text is hard-coded for now. # Should be made dynamic (language-dependent). - options = self.document.options - if options.generator or options.datestamp or options.source_link \ - or options.source_url: + settings = self.document.settings + if settings.generator or settings.datestamp or settings.source_link \ + or settings.source_url: text = [] - if options.source_link and options._source or options.source_url: - if options.source_url: - source = options.source_url + if settings.source_link and settings._source \ + or settings.source_url: + if settings.source_url: + source = settings.source_url else: - source = utils.relative_path(options._destination, - options._source) + source = utils.relative_path(settings._destination, + settings._source) text.extend([ nodes.reference('', 'View document source', refuri=source), nodes.Text('.\n')]) - if options.datestamp: - datestamp = time.strftime(options.datestamp, time.gmtime()) + if settings.datestamp: + datestamp = time.strftime(settings.datestamp, time.gmtime()) text.append(nodes.Text('Generated on: ' + datestamp + '.\n')) - if options.generator: + if settings.generator: text.extend([ nodes.Text('Generated by '), nodes.reference('', 'Docutils', refuri= @@ -93,7 +94,7 @@ class Messages(Transform): of the document. """ - def transform(self): + def apply(self): unfiltered = self.document.transform_messages threshold = self.document.reporter['writer'].report_level messages = [] @@ -115,7 +116,7 @@ class TestMessages(Transform): Append all post-parse system messages to the end of the document. """ - def transform(self): + def apply(self): for msg in self.document.transform_messages: if not msg.parent: self.document += msg @@ -129,10 +130,10 @@ class FinalChecks(Transform): - Check for dangling references (incl. footnote & citation). """ - def transform(self): + def apply(self): visitor = FinalCheckVisitor(self.document) self.document.walk(visitor) - if self.document.options.expose_internals: + if self.document.settings.expose_internals: visitor = InternalAttributeExposer(self.document) self.document.walk(visitor) @@ -170,7 +171,7 @@ class InternalAttributeExposer(nodes.GenericNodeVisitor): def __init__(self, document): nodes.GenericNodeVisitor.__init__(self, document) - self.internal_attributes = document.options.expose_internals + self.internal_attributes = document.settings.expose_internals def default_visit(self, node): for att in self.internal_attributes: @@ -194,11 +195,11 @@ class Pending(Transform): 'last reader', 'first writer', and 'last writer'. Overriden in subclasses (below).""" - def transform(self): + def apply(self): for pending in self.document.pending: if pending.stage == self.stage: pending.transform(self.document, self.component, - pending).transform() + pending).apply() class FirstReaderPending(Pending): diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 42bdeb8ce..0a8eb6917 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -39,7 +39,7 @@ class Writer(Component): """`docutils.io` IO object; where to write the document.""" transforms = () - """Ordered list of transform classes (each with a ``transform()`` method). + """Ordered list of transform classes (each with an ``apply()`` method). Populated by subclasses. `Writer.transform()` instantiates & runs them.""" def __init__(self): @@ -50,7 +50,8 @@ class Writer(Component): def write(self, document, destination): self.document = document - self.language = languages.get_language(document.options.language_code) + self.language = languages.get_language( + document.settings.language_code) self.destination = destination self.transform() self.translate() @@ -62,7 +63,7 @@ class Writer(Component): for xclass in (universal.first_writer_transforms + tuple(self.transforms) + universal.last_writer_transforms): - xclass(self.document, self).transform() + xclass(self.document, self).apply() def translate(self): """ diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 14b218dcd..e5de9c48c 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -20,7 +20,7 @@ class Writer(writers.Writer): supported = ('xml',) """Formats this writer supports.""" - cmdline_options = ( + settings_spec = ( '"Docutils XML" Writer Options', 'Warning: these options may adversely affect whitespace; use them ' 'only for reading convenience.', @@ -41,14 +41,14 @@ class Writer(writers.Writer): generator = '<!-- Generated by Docutils %s -->\n' def translate(self): - options = self.document.options + settings = self.document.settings indent = newline = '' - if options.newlines: + if settings.newlines: newline = '\n' - if options.indents: + if settings.indents: newline = '\n' indent = ' ' - output_prefix = [self.xml_declaration % options.output_encoding, + output_prefix = [self.xml_declaration % settings.output_encoding, self.doctype, self.generator % docutils.__version__] docnode = self.document.asdom().childNodes[0] diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2a0636fd3..8b58778f6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -30,7 +30,7 @@ class Writer(writers.Writer): supported = ('html', 'html4css1', 'xhtml') """Formats this writer supports.""" - cmdline_options = ( + settings_spec = ( 'HTML-Specific Options', None, (('Specify a stylesheet URL, used verbatim. Default is ' @@ -68,7 +68,7 @@ class Writer(writers.Writer): ['--no-compact-lists'], {'dest': 'compact_lists', 'action': 'store_false'}),)) - relative_path_options = ('stylesheet_path',) + relative_path_settings = ('stylesheet_path',) output = None """Final translated form of `document`.""" @@ -130,7 +130,8 @@ class HTMLTranslator(nodes.NodeVisitor): child with 'class="first"' if it is a paragraph. The stylesheet sets the top margin to 0 for these paragraphs. - The ``--no-compact-lists`` option disables list whitespace optimization. + The ``no_compact_lists`` setting (``--no-compact-lists`` command-line + option) disables list whitespace optimization. """ xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' @@ -151,16 +152,16 @@ class HTMLTranslator(nodes.NodeVisitor): def __init__(self, document): nodes.NodeVisitor.__init__(self, document) - self.options = options = document.options - self.language = languages.get_language(options.language_code) + self.settings = settings = document.settings + self.language = languages.get_language(settings.language_code) self.head_prefix = [ - self.xml_declaration % options.output_encoding, + self.xml_declaration % settings.output_encoding, self.doctype, - self.html_head % options.language_code, - self.content_type % options.output_encoding, + self.html_head % settings.language_code, + self.content_type % settings.output_encoding, self.generator % docutils.__version__] self.head = [] - if options.embed_stylesheet: + if settings.embed_stylesheet: stylesheet = self.get_stylesheet_reference(os.getcwd()) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] @@ -181,13 +182,13 @@ class HTMLTranslator(nodes.NodeVisitor): self.in_docinfo = None def get_stylesheet_reference(self, relative_to=None): - options = self.options - if options.stylesheet_path: + settings = self.settings + if settings.stylesheet_path: if relative_to == None: - relative_to = options._destination - return utils.relative_path(relative_to, options.stylesheet_path) + relative_to = settings._destination + return utils.relative_path(relative_to, settings.stylesheet_path) else: - return options.stylesheet + return settings.stylesheet def astext(self): return ''.join(self.head_prefix + self.head + self.stylesheet @@ -311,7 +312,7 @@ class HTMLTranslator(nodes.NodeVisitor): old_compact_simple = self.compact_simple self.context.append((self.compact_simple, self.compact_p)) self.compact_p = None - self.compact_simple = (self.options.compact_lists and + self.compact_simple = (self.settings.compact_lists and (self.compact_simple or self.topic_class == 'contents' or self.check_simple_list(node))) @@ -539,7 +540,7 @@ class HTMLTranslator(nodes.NodeVisitor): old_compact_simple = self.compact_simple self.context.append((self.compact_simple, self.compact_p)) self.compact_p = None - self.compact_simple = (self.options.compact_lists and + self.compact_simple = (self.settings.compact_lists and (self.compact_simple or self.topic_class == 'contents' or self.check_simple_list(node))) @@ -625,7 +626,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.footnote_backrefs(node) def footnote_backrefs(self, node): - if self.options.footnote_backlinks and node.hasattr('backrefs'): + if self.settings.footnote_backlinks and node.hasattr('backrefs'): backrefs = node['backrefs'] if len(backrefs) == 1: self.context.append('') @@ -654,7 +655,7 @@ class HTMLTranslator(nodes.NodeVisitor): href = '#' + node['refid'] elif node.has_key('refname'): href = '#' + self.document.nameids[node['refname']] - format = self.options.footnote_references + format = self.settings.footnote_references if format == 'brackets': suffix = '[' self.context.append(']') diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 69c0492bc..c535f8c79 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -19,7 +19,7 @@ from docutils.writers import html4css1 class Writer(html4css1.Writer): - cmdline_options = html4css1.Writer.cmdline_options + ( + settings_spec = html4css1.Writer.settings_spec + ( 'PEP/HTML-Specific Options', 'The HTML --footnote-references option is set to "brackets" by ' 'default.', @@ -47,9 +47,9 @@ class Writer(html4css1.Writer): (optik.SUPPRESS_HELP, ['--no-random'], {'action': 'store_true'}),)) - option_default_overrides = {'footnote_references': 'brackets'} + settings_default_overrides = {'footnote_references': 'brackets'} - relative_path_options = ('pep_stylesheet_path', 'pep_template') + relative_path_settings = ('pep_stylesheet_path', 'pep_template') def __init__(self): html4css1.Writer.__init__(self) @@ -57,16 +57,16 @@ class Writer(html4css1.Writer): def translate(self): html4css1.Writer.translate(self) - options = self.document.options - template = open(options.pep_template).read() + settings = self.document.settings + template = open(settings.pep_template).read() # Substitutions dict for template: subs = {} - subs['encoding'] = options.output_encoding + subs['encoding'] = settings.output_encoding subs['version'] = docutils.__version__ subs['stylesheet'] = ''.join(self.stylesheet) - pyhome = options.python_home + pyhome = settings.python_home subs['pyhome'] = pyhome - subs['pephome'] = options.pep_home + subs['pephome'] = settings.pep_home if pyhome == '..': subs['pepindex'] = '.' else: @@ -75,7 +75,7 @@ class Writer(html4css1.Writer): header = self.document[index] pepnum = header[0][1].astext() subs['pep'] = pepnum - if options.no_random: + if settings.no_random: subs['banner'] = 0 else: import random @@ -94,18 +94,18 @@ class Writer(html4css1.Writer): class HTMLTranslator(html4css1.HTMLTranslator): def get_stylesheet_reference(self, relative_to=None): - options = self.options + settings = self.settings if relative_to == None: - relative_to = options._destination - if options.pep_stylesheet_path: + relative_to = settings._destination + if settings.pep_stylesheet_path: return utils.relative_path(relative_to, - options.pep_stylesheet_path) - elif options.pep_stylesheet: - return options.pep_stylesheet - elif options._stylesheet_path: - return utils.relative_path(relative_to, options.stylesheet_path) + settings.pep_stylesheet_path) + elif settings.pep_stylesheet: + return settings.pep_stylesheet + elif settings._stylesheet_path: + return utils.relative_path(relative_to, settings.stylesheet_path) else: - return options.stylesheet + return settings.stylesheet def depart_field_list(self, node): html4css1.HTMLTranslator.depart_field_list(self, node) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 6e9c804e5..7d7252184 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -249,11 +249,12 @@ class TransformTestCase(CustomTestCase): cases that have nothing to do with the input and output of the transform. """ - options = frontend.OptionParser(components=(rst.Parser,)).get_default_values() - options.report_level = 1 - options.halt_level = 5 - options.debug = package_unittest.debug - options.warning_stream = DevNull() + option_parser = frontend.OptionParser(components=(rst.Parser,)) + settings = option_parser.get_default_values() + settings.report_level = 1 + settings.halt_level = 5 + settings.debug = package_unittest.debug + settings.warning_stream = DevNull() def __init__(self, *args, **kwargs): self.transforms = kwargs['transforms'] @@ -271,13 +272,13 @@ class TransformTestCase(CustomTestCase): def test_transforms(self): if self.run_in_debugger: pdb.set_trace() - document = utils.new_document('test data', self.options) + document = utils.new_document('test data', self.settings) document.reporter.attach_observer(document.note_parse_message) self.parser.parse(self.input, document) document.reporter.detach_observer(document.note_parse_message) document.reporter.attach_observer(document.note_transform_message) for transformClass in (self.transforms + universal.test_transforms): - transformClass(document, self).transform() + transformClass(document, self).apply() output = document.pformat() self.compare_output(self.input, output, self.expected) @@ -287,12 +288,12 @@ class TransformTestCase(CustomTestCase): print '\n', self.id print '-' * 70 print self.input - document = utils.new_document('test data', self.options) + document = utils.new_document('test data', self.settings) self.parser.parse(self.input, document) print '-' * 70 print document.pformat() for transformClass in self.transforms: - transformClass(document).transform() + transformClass(document).apply() output = document.pformat() print '-' * 70 print output @@ -312,15 +313,16 @@ class ParserTestCase(CustomTestCase): parser = rst.Parser() """Parser shared by all ParserTestCases.""" - options = frontend.OptionParser(components=(parser,)).get_default_values() - options.report_level = 5 - options.halt_level = 5 - options.debug = package_unittest.debug + option_parser = frontend.OptionParser(components=(parser,)) + settings = option_parser.get_default_values() + settings.report_level = 5 + settings.halt_level = 5 + settings.debug = package_unittest.debug def test_parser(self): if self.run_in_debugger: pdb.set_trace() - document = utils.new_document('test data', self.options) + document = utils.new_document('test data', self.settings) self.parser.parse(self.input, document) output = document.pformat() self.compare_output(self.input, output, self.expected) @@ -372,10 +374,10 @@ class PEPParserTestCase(ParserTestCase): """Parser shared by all PEPParserTestCases.""" option_parser = frontend.OptionParser(components=(parser, pep.Reader)) - options = option_parser.get_default_values() - options.report_level = 5 - options.halt_level = 5 - options.debug = package_unittest.debug + settings = option_parser.get_default_values() + settings.report_level = 5 + settings.halt_level = 5 + settings.debug = package_unittest.debug class PEPParserTestSuite(ParserTestSuite): diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index cad84c7e0..4a32309b2 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -71,7 +71,7 @@ A paragraph. This file is used by ``test_include.py``. <paragraph> A paragraph. -""" % include1], +""" % DocutilsTestSupport.utils.relative_path(None, include1)], ["""\ Let's test the parse context. diff --git a/test/test_parsers/test_rst/test_directives/test_raw.py b/test/test_parsers/test_rst/test_directives/test_raw.py index 54f3892d0..cbce2f50d 100755 --- a/test/test_parsers/test_rst/test_directives/test_raw.py +++ b/test/test_parsers/test_rst/test_directives/test_raw.py @@ -43,7 +43,7 @@ totest['raw'] = [ <document source="test data"> <raw format="html" source="%s" xml:space="preserve"> <p>This file is used by <tt>test_raw.py</tt>.</p> -""" % raw1], +""" % DocutilsTestSupport.utils.relative_path(None, raw1)], ["""\ .. raw:: html :file: rawfile.html diff --git a/tools/buildhtml.py b/tools/buildhtml.py index 8375cd844..9b10a8f96 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -36,15 +36,15 @@ description = ('Generates .html from all the .txt files (including PEPs) ' 'in each <directory> (default is the current directory).') -class OptionSpec(docutils.OptionSpec): +class SettingsSpec(docutils.SettingsSpec): """ - Command-line options for the ``buildhtml.py`` front end. + Runtime settings & command-line options for the front end. """ # Can't be included in OptionParser below because we don't want to # override the base class. - cmdline_options = ( + settings_spec = ( 'Build-HTML Options', None, (('Recursively scan subdirectories for files to process. This is ' @@ -88,7 +88,7 @@ class Builder: def __init__(self): self.publishers = { - '': Struct(components=(OptionSpec, pep.Reader, rst.Parser, + '': Struct(components=(SettingsSpec, pep.Reader, rst.Parser, pep_html.Writer), setup=None), '.txt': Struct(components=(rst.Parser, standalone.Reader, @@ -109,17 +109,18 @@ class Builder: Each publisher (combination of parser, reader, and writer) may have its own configuration defaults, which must be kept separate from those - of the other publishers. Option defaults are combined with the config - file settings and command-line options by `self.get_options()`. + of the other publishers. Setting defaults are combined with the + config file settings and command-line options by + `self.get_settings()`. """ for name, publisher in self.publishers.items(): option_parser = OptionParser( components=publisher.components, usage=usage, description=description) publisher.option_parser = option_parser - publisher.option_defaults = option_parser.get_default_values() - frontend.make_paths_absolute(publisher.option_defaults.__dict__, - option_parser.relative_path_options) + publisher.setting_defaults = option_parser.get_default_values() + frontend.make_paths_absolute(publisher.setting_defaults.__dict__, + option_parser.relative_path_settings) if publisher.setup: publisher.setup() config_parser = frontend.ConfigParser() @@ -127,32 +128,32 @@ class Builder: self.config_settings = config_parser.get_section('options') frontend.make_paths_absolute( self.config_settings, - self.publishers[''].option_parser.relative_path_options) - self.cmdline_options = self.publishers[''].option_parser.parse_args( + self.publishers[''].option_parser.relative_path_settings) + self.settings_spec = self.publishers[''].option_parser.parse_args( values=frontend.Values()) # no defaults; just the cmdline opts - self.initial_options = self.get_options('') + self.initial_settings = self.get_settings('') - def get_options(self, publisher_name, directory=None): + def get_settings(self, publisher_name, directory=None): """ - Return an option values object, from multiple sources. + Return a settings object, from multiple sources. - Copy the option defaults, overlay the startup config file settings, + Copy the setting defaults, overlay the startup config file settings, then the local config file settings, then the command-line options. Assumes the current directory has been set. """ publisher = self.publishers[publisher_name] - options = copy.deepcopy(publisher.option_defaults) - options.__dict__.update(self.config_settings) + settings = copy.deepcopy(publisher.setting_defaults) + settings.__dict__.update(self.config_settings) if directory: config_parser = frontend.ConfigParser() config_parser.read(os.path.join(directory, 'docutils.conf')) local_config = config_parser.get_section('options') frontend.make_paths_absolute( - local_config, publisher.option_parser.relative_path_options, + local_config, publisher.option_parser.relative_path_settings, directory) - options.__dict__.update(local_config) - options.__dict__.update(self.cmdline_options.__dict__) - return options + settings.__dict__.update(local_config) + settings.__dict__.update(self.settings_spec.__dict__) + return settings def setup_html_publisher(self): pub = core.Publisher() @@ -162,18 +163,18 @@ class Builder: self.html_publisher = pub def run(self, directory=None, recurse=1): - recurse = recurse and self.initial_options.recurse + recurse = recurse and self.initial_settings.recurse if directory: self.directories = [directory] - elif self.cmdline_options._directories: - self.directories = self.cmdline_options._directories + elif self.settings_spec._directories: + self.directories = self.settings_spec._directories else: self.directories = [os.getcwd()] for directory in self.directories: os.path.walk(directory, self.visit, recurse) def visit(self, recurse, directory, names): - if not self.initial_options.silent: + if not self.initial_settings.silent: print >>sys.stderr, '/// Processing directory:', directory sys.stderr.flush() peps_found = 0 @@ -189,17 +190,17 @@ class Builder: del names[:] def process_txt(self, directory, name): - options = self.get_options('.txt', directory) - options._source = os.path.normpath(os.path.join(directory, name)) - options._destination = options._source[:-4]+'.html' + settings = self.get_settings('.txt', directory) + settings._source = os.path.normpath(os.path.join(directory, name)) + settings._destination = settings._source[:-4]+'.html' pub = self.html_publisher - pub.options = options - if not self.initial_options.silent: + pub.settings = settings + if not self.initial_settings.silent: print >>sys.stderr, ' ::: Processing .txt:', name sys.stderr.flush() - pub.source = io.FileInput(options, source_path=options._source) + pub.source = io.FileInput(settings, source_path=settings._source) pub.destination = io.FileOutput( - options, destination_path=options._destination) + settings, destination_path=settings._destination) try: pub.publish() except ApplicationError, error: @@ -207,16 +208,16 @@ class Builder: % (error.__class__.__name__, error)) def process_peps(self, directory): - options = self.get_options('PEPs', directory) + settings = self.get_settings('PEPs', directory) old_directory = os.getcwd() os.chdir(directory) - if self.initial_options.silent: + if self.initial_settings.silent: argv = ['-q'] else: print >>sys.stderr, ' ::: Processing PEPs:' sys.stderr.flush() argv = [] - pep2html.docutils_options = options + pep2html.docutils_settings = settings try: pep2html.main(argv) except Exception, error: diff --git a/tools/docutils-xml.py b/tools/docutils-xml.py index 688a38786..42c879cc8 100755 --- a/tools/docutils-xml.py +++ b/tools/docutils-xml.py @@ -16,10 +16,10 @@ try: except: pass -from docutils.core import publish, default_description +from docutils.core import publish_cmdline, default_description description = ('Generates Docutils-native XML from standalone ' 'reStructuredText sources. ' + default_description) -publish(writer_name='xml', description=description) +publish_cmdline(writer_name='xml', description=description) diff --git a/tools/html.py b/tools/html.py index 81c34ab4b..98293b3a1 100755 --- a/tools/html.py +++ b/tools/html.py @@ -16,10 +16,10 @@ try: except: pass -from docutils.core import publish, default_description +from docutils.core import publish_cmdline, default_description description = ('Generates (X)HTML documents from standalone reStructuredText ' 'sources. ' + default_description) -publish(writer_name='html', description=description) +publish_cmdline(writer_name='html', description=description) diff --git a/tools/pep.py b/tools/pep.py index e44eabe18..4c38980b6 100755 --- a/tools/pep.py +++ b/tools/pep.py @@ -17,10 +17,11 @@ try: except: pass -from docutils.core import publish, default_description +from docutils.core import publish_cmdline, default_description description = ('Generates (X)HTML from reStructuredText-format PEP files. ' + default_description) -publish(reader_name='pep', writer_name='pep_html', description=description) +publish_cmdline(reader_name='pep', writer_name='pep_html', + description=description) diff --git a/tools/pep2html.py b/tools/pep2html.py index c0a4fc31d..2cc7434e9 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -41,7 +41,7 @@ import random import time REQUIRES = {'python': '2.2', - 'docutils': '0.2.4'} + 'docutils': '0.2.6'} PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' @@ -280,9 +280,9 @@ def fixfile(inpath, input_lines, outfile): print >> outfile, '</html>' -docutils_options = None -"""Option value object used by Docutils. Can be set by the client application -when this module is imported.""" +docutils_settings = None +"""Runtime settings object used by Docutils. Can be set by the client +application when this module is imported.""" def fix_rst_pep(inpath, input_lines, outfile): from docutils import core, io @@ -290,17 +290,17 @@ def fix_rst_pep(inpath, input_lines, outfile): pub.set_reader(reader_name='pep', parser_name='restructuredtext', parser=None) pub.set_writer(writer_name='pep_html') - if docutils_options: - options = docutils_options - pub.options = options + if docutils_settings: + settings = docutils_settings + pub.settings = settings else: - options = pub.set_options() - options._source = inpath - options._destination = outfile.name + settings = pub.get_settings() + settings._source = inpath + settings._destination = outfile.name pub.source = io.StringInput( - options, source=''.join(input_lines), source_path=inpath) + settings, source=''.join(input_lines), source_path=inpath) pub.destination = io.FileOutput( - options, destination=outfile, destination_path=outfile.name, + settings, destination=outfile, destination_path=outfile.name, autoclose=0) pub.publish() diff --git a/tools/publish.py b/tools/publish.py index 75de3a141..d360cd124 100755 --- a/tools/publish.py +++ b/tools/publish.py @@ -16,10 +16,10 @@ try: except: pass -from docutils.core import publish, default_description +from docutils.core import publish_cmdline, default_description description = ('Generates pseudo-XML from standalone reStructuredText ' 'sources (for testing purposes). ' + default_description) -publish(description=description) +publish_cmdline(description=description) diff --git a/tools/quicktest.py b/tools/quicktest.py index 1ee77b3c4..83b5a622b 100755 --- a/tools/quicktest.py +++ b/tools/quicktest.py @@ -193,11 +193,11 @@ Use the next dialog to build a command line: def main(): # process cmdline arguments: inputFile, outputFile, outputFormat, optargs = getArgs() - options = OptionParser(components=(Parser,)).get_default_values() - options.debug = optargs['debug'] + settings = OptionParser(components=(Parser,)).get_default_values() + settings.debug = optargs['debug'] parser = Parser() input = inputFile.read() - document = new_document(inputFile.name, options) + document = new_document(inputFile.name, settings) parser.parse(input, document) output = format(outputFormat, input, document, optargs) outputFile.write(output) -- cgit v1.2.1 From 18c39f24ba6a4c6d170d750b2d8476d8e896adf1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:39:31 +0000 Subject: Bumped version to 0.2.7 for new ``docutils.core.publish_*`` convenience functions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@827 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 7461d2f42..f7ebd564d 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,7 +55,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.6' +__version__ = '0.2.7' """``major.minor.micro`` version number. The ``micro`` number is bumped any time there's a change in the API incompatible with one of the front ends.""" -- cgit v1.2.1 From a4736ddfb3d1836db095e199f39842d995657938 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:40:19 +0000 Subject: Rearranged the parameters of ``publish_cmdline()`` and improved its docstring. Added ``publish_file()`` and ``publish_string()``. Factored ``Publisher.set_source()`` and ``.set_destination()`` out of ``.set_io``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@828 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 167 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 150 insertions(+), 17 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 1e363fee5..5d6927099 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -5,11 +5,11 @@ # Copyright: This module has been placed in the public domain. """ -Calling the `publish` convenience function (or instantiating a +Calling the ``publish_*`` convenience functions (or instantiating a `Publisher` object) with component names will result in default behavior. For custom behavior (setting component options), create custom component objects first, and pass *them* to -`publish`/`Publisher`. +``publish_*``/`Publisher`. """ __docformat__ = 'reStructuredText' @@ -115,23 +115,41 @@ class Publisher: argv = sys.argv[1:] self.settings = option_parser.parse_args(argv) - def set_io(self): + def set_io(self, source_path=None, destination_path=None): if self.source is None: - self.source = self.source_class(self.settings, - source_path=self.settings._source) + self.set_source(source_path=source_path) if self.destination is None: - self.destination = self.destination_class( - self.settings, destination_path=self.settings._destination) + self.set_destination(destination_path=destination_path) + + def set_source(self, source=None, source_path=None): + if source_path is None: + source_path = self.settings._source + else: + self.settings._source = source_path + self.source = self.source_class(self.settings, source=source, + source_path=source_path) + + def set_destination(self, destination=None, destination_path=None): + if destination_path is None: + destination_path = self.settings._destination + else: + self.settings._destination = destination_path + self.destination = self.destination_class( + self.settings, destination=destination, + destination_path=destination_path) def publish(self, argv=None, usage=None, description=None, - settings_spec=None): + settings_spec=None, settings_overrides=None): """ Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return `self.writer`'s output. """ if self.settings is None: - self.process_command_line(argv, usage, description, settings_spec) + self.process_command_line(argv, usage, description, settings_spec, + **(settings_overrides or {})) + elif settings_overrides: + self.settings._update(settings_overrides, 'loose') self.set_io() document = self.reader.read(self.source, self.parser, self.settings) output = self.writer.write(document, self.destination) @@ -148,23 +166,138 @@ default_description = ('Reads from <source> (default is stdin) and writes to ' def publish_cmdline(reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', - argv=None, usage=default_usage, - description=default_description, - settings_spec=None, settings=None): - """Set up & run a `Publisher`. For command-line front ends.""" + settings=None, settings_spec=None, + settings_overrides=None, argv=None, + usage=default_usage, description=default_description): + """ + Set up & run a `Publisher`. For command-line front ends. + + Parameters: + + - `reader`: A `docutils.readers.Reader` object. + - `reader_name`: Name or alias of the Reader class to be instantiated if + no `reader` supplied. + - `parser`: A `docutils.parsers.Parser` object. + - `parser_name`: Name or alias of the Parser class to be instantiated if + no `parser` supplied. + - `writer`: A `docutils.writers.Writer` object. + - `writer_name`: Name or alias of the Writer class to be instantiated if + no `writer` supplied. + - `settings`: Runtime settings object. + - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` + subclass. Used only if no `settings` specified. + - `settings_overrides`: A dictionary containing program-specific overrides + of component settings. + - `argv`: Command-line argument list to use instead of ``sys.argv[1:]``. + - `usage`: Usage string, output if there's a problem parsing the command + line. + - `description`: Program description, output for the "--help" option + (along with command-line option descriptions). + """ pub = Publisher(reader, parser, writer, settings=settings) if reader is None: pub.set_reader(reader_name, parser, parser_name) if writer is None: pub.set_writer(writer_name) - pub.publish(argv, usage, description, settings_spec) + pub.publish(argv, usage, description, settings_spec, settings_overrides) -def publish_file(): +def publish_file(source=None, source_path=None, + destination=None, destination_path=None, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, settings_overrides=None): """ Set up & run a `Publisher`. For programmatic use with file-like I/O. + + Parameters: + + - `source`: A file-like object (must have "read" and "close" methods). + - `source_path`: Path to the input file. Opened if no `source` supplied. + If neither `source` nor `source_path` are supplied, `sys.stdin` is used. + - `destination`: A file-like object (must have "write" and "close" + methods). + - `destination_path`: Path to the input file. Opened if no `destination` + supplied. If neither `destination` nor `destination_path` are supplied, + `sys.stdout` is used. + - `reader`: A `docutils.readers.Reader` object. + - `reader_name`: Name or alias of the Reader class to be instantiated if + no `reader` supplied. + - `parser`: A `docutils.parsers.Parser` object. + - `parser_name`: Name or alias of the Parser class to be instantiated if + no `parser` supplied. + - `writer`: A `docutils.writers.Writer` object. + - `writer_name`: Name or alias of the Writer class to be instantiated if + no `writer` supplied. + - `settings`: Runtime settings object. + - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` + subclass. Used only if no `settings` specified. + - `settings_overrides`: A dictionary containing program-specific overrides + of component settings. """ + pub = Publisher(reader, parser, writer, settings=settings) + if reader is None: + pub.set_reader(reader_name, parser, parser_name) + if writer is None: + pub.set_writer(writer_name) + if settings is None: + settings = pub.get_settings(settings_spec=settings_spec) + if settings_overrides: + settings._update(settings_overrides, 'loose') + pub.set_source(source, source_path) + pub.set_destination(destination, destination_path) + pub.publish() -def publish_string(): +def publish_string(source, source_path=None, destination_path=None, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, + settings_overrides=None): """ - Set up & run a `Publisher`. For programmatic use with string I/O. + Set up & run a `Publisher`, and return the string output. + For programmatic use with string I/O. + + For encoded string output, be sure to set the "output_encoding" setting to + the desired encoding. Set it to "unicode" for Unicode string output. + + Parameters: + + - `source`: An input string; required. This can be an encoded 8-big + string (in which case the "input_encoding" setting should be set) or a + Unicode string (in which case set the "input_encoding" setting to + "unicode"). + - `source_path`: Path to the file or object that produced `source`; + optional. Only used for diagnostic output. + - `destination_path`: Path to the file or object which will receive the + output; optional. Used for determining relative paths (stylesheets, + source links, etc.). + - `reader`: A `docutils.readers.Reader` object. + - `reader_name`: Name or alias of the Reader class to be instantiated if + no `reader` supplied. + - `parser`: A `docutils.parsers.Parser` object. + - `parser_name`: Name or alias of the Parser class to be instantiated if + no `parser` supplied. + - `writer`: A `docutils.writers.Writer` object. + - `writer_name`: Name or alias of the Writer class to be instantiated if + no `writer` supplied. + - `settings`: Runtime settings object. + - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec` + subclass. Used only if no `settings` specified. + - `settings_overrides`: A dictionary containing program-specific overrides + of component settings. """ + pub = Publisher(reader, parser, writer, settings=settings, + source_class=io.StringInput, + destination_class=io.StringOutput) + if reader is None: + pub.set_reader(reader_name, parser, parser_name) + if writer is None: + pub.set_writer(writer_name) + if settings is None: + settings = pub.get_settings(settings_spec=settings_spec) + if settings_overrides: + settings._update(settings_overrides, 'loose') + pub.set_source(source, source_path) + pub.set_destination(destination_path=destination_path) + return pub.publish() -- cgit v1.2.1 From cf50c56c8bf3977410ed8c8ca864b6bcf5b10d99 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:41:45 +0000 Subject: Made special "unicode" encoding general (but it will only work for strings or Unicode StringIO). Added ``Output.encode()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@829 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 68ea19c88..02f392460 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -54,6 +54,9 @@ class Input: locale.setlocale(locale.LC_ALL, '') """ + if self.settings.input_encoding \ + and self.settings.input_encoding.lower() == 'unicode': + return unicode(data) encodings = [self.settings.input_encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) @@ -110,6 +113,13 @@ class Output: def write(self, data): raise NotImplementedError + def encode(self, data): + if self.settings.output_encoding \ + and self.settings.output_encoding.lower() == 'unicode': + return data + else: + return data.encode(self.settings.output_encoding or '') + class FileInput(Input): @@ -190,7 +200,7 @@ class FileOutput(Output): def write(self, data): """Encode `data`, write it to a single file, and return it.""" - output = data.encode(self.settings.output_encoding) + output = self.encode(data) if not self.opened: self.open() self.destination.write(output) @@ -209,15 +219,11 @@ class StringInput(Input): Direct string input. """ - default_source_path = 'string input' + default_source_path = '<string>' def read(self, reader): """Decode and return the source string.""" - if self.settings.input_encoding \ - and self.settings.input_encoding.lower() == 'unicode': - return self.source - else: - return self.decode(self.source) + return self.decode(self.source) class StringOutput(Output): @@ -226,15 +232,11 @@ class StringOutput(Output): Direct string output. """ - default_destination_path = 'string output' + default_destination_path = '<string>' def write(self, data): """Encode `data`, store it in `self.destination`, and return it.""" - if self.settings.output_encoding \ - and self.settings.output_encoding.lower() == 'unicode': - self.destination = data - else: - self.destination = data.encode(self.settings.output_encoding) + self.destination = self.encode(data) return self.destination -- cgit v1.2.1 From a3d5874e951e34373fc39ac5dc502ec4ef01d89e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:44:47 +0000 Subject: Renamed ``Stuff`` to ``Struct``. Fixed a bug. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@830 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 6600391ff..06c6cb1c1 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -28,7 +28,7 @@ the reStructuredText parser. It defines the following: - `SpecializedText`: Superclass for continuation lines of Text-variants. - `Definition`: Second line of potential definition_list_item. - `Line`: Second line of overlined section title or transition marker. - - `Stuff`: An auxiliary collection class. + - `Struct`: An auxiliary collection class. :Exception classes: - `MarkupError` @@ -120,9 +120,9 @@ class ParserError(ApplicationError): pass class MarkupMismatch(Exception): pass -class Stuff: +class Struct: - """Stores a bunch of stuff for dotted-attribute access.""" + """Stores data attributes for dotted-attribute access.""" def __init__(self, **keywordargs): self.__dict__.update(keywordargs) @@ -151,12 +151,12 @@ class RSTStateMachine(StateMachineWS): if inliner is None: inliner = Inliner() inliner.init_customizations(document.settings) - self.memo = Stuff(document=document, - reporter=document.reporter, - language=self.language, - title_styles=[], - section_level=0, - inliner=inliner) + self.memo = Struct(document=document, + reporter=document.reporter, + language=self.language, + title_styles=[], + section_level=0, + inliner=inliner) self.document = self.memo.document self.attach_observer(self.document.note_state_machine_change) self.reporter = self.memo.reporter @@ -524,7 +524,7 @@ class Inliner: ) ] ) - patterns = Stuff( + patterns = Struct( initial=build_regexp(parts), emphasis=re.compile(non_whitespace_escape_before + r'(\*)' + end_string_suffix), @@ -903,13 +903,13 @@ class Body(RSTState): Generic classifier of the first line of a block. """ - enum = Stuff() + enum = Struct() """Enumerated list parsing information.""" enum.formatinfo = { - 'parens': Stuff(prefix='(', suffix=')', start=1, end=-1), - 'rparen': Stuff(prefix='', suffix=')', start=0, end=-1), - 'period': Stuff(prefix='', suffix='.', start=0, end=-1)} + 'parens': Struct(prefix='(', suffix=')', start=1, end=-1), + 'rparen': Struct(prefix='', suffix=')', start=0, end=-1), + 'period': Struct(prefix='', suffix='.', start=0, end=-1)} enum.formats = enum.formatinfo.keys() enum.sequences = ['arabic', 'loweralpha', 'upperalpha', 'lowerroman', 'upperroman'] # ORDERED! @@ -1449,10 +1449,10 @@ class Body(RSTState): return row - explicit = Stuff() + explicit = Struct() """Patterns and constants used for explicit markup recognition.""" - explicit.patterns = Stuff( + explicit.patterns = Struct( target=re.compile(r""" ( _ # anonymous target @@ -1903,10 +1903,7 @@ class Body(RSTState): try: return method(self, expmatch) except MarkupError, (message, lineno): # never reached? - errors.append( - self.reporter.warning( - '%s: %s' % (detail.__class__.__name__, message), - line=lineno)) + errors.append(self.reporter.warning(message, line=lineno)) break nodelist, blank_finish = self.comment(match) return nodelist + errors, blank_finish -- cgit v1.2.1 From de2bc738f537152627ba07db4e59ba60df792a5f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:45:29 +0000 Subject: Improved layout of <pre> HTML source. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@831 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8b58778f6..bd7372bec 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -258,11 +258,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_address(self, node): self.visit_docinfo_item(node, 'address', meta=None) - self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='address')) + self.body.append(self.starttag(node, 'pre', CLASS='address')) def depart_address(self, node): - self.body.append('</pre>\n') + self.body.append('\n</pre>\n') self.depart_docinfo_item() def visit_admonition(self, node, name): @@ -485,11 +484,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</td></tr>\n') def visit_doctest_block(self, node): - self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='doctest-block')) + self.body.append(self.starttag(node, 'pre', CLASS='doctest-block')) def depart_doctest_block(self, node): - self.body.append('</pre>\n') + self.body.append('\n</pre>\n') def visit_document(self, node): self.body.append(self.starttag(node, 'div', CLASS='document')) @@ -737,11 +735,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</div>\n') def visit_line_block(self, node): - self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='line-block')) + self.body.append(self.starttag(node, 'pre', CLASS='line-block')) def depart_line_block(self, node): - self.body.append('</pre>\n') + self.body.append('\n</pre>\n') def visit_list_item(self, node): self.body.append(self.starttag(node, 'li', '')) @@ -769,11 +766,10 @@ class HTMLTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_literal_block(self, node): - self.body.append(self.starttag(node, 'pre', suffix='', - CLASS='literal-block')) + self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) def depart_literal_block(self, node): - self.body.append('</pre>\n') + self.body.append('\n</pre>\n') def visit_meta(self, node): self.head.append(self.starttag(node, 'meta', **node.attributes)) -- cgit v1.2.1 From 6c098e17d8e414894609dab0c4e5f08634db81b8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:46:56 +0000 Subject: Updated for new ``publish_file()`` convenience function; simplified. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@832 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/buildhtml.py | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/tools/buildhtml.py b/tools/buildhtml.py index 9b10a8f96..9486229de 100755 --- a/tools/buildhtml.py +++ b/tools/buildhtml.py @@ -89,14 +89,11 @@ class Builder: def __init__(self): self.publishers = { '': Struct(components=(SettingsSpec, pep.Reader, rst.Parser, - pep_html.Writer), - setup=None), + pep_html.Writer)), '.txt': Struct(components=(rst.Parser, standalone.Reader, - html4css1.Writer), - setup=self.setup_html_publisher), + html4css1.Writer)), 'PEPs': Struct(components=(rst.Parser, pep.Reader, - pep_html.Writer), - setup=None)} + pep_html.Writer))} """Publisher-specific settings. Key '' is for the front-end script itself. ``self.publishers[''].components`` must contain a superset of all components used by individual publishers.""" @@ -121,8 +118,6 @@ class Builder: publisher.setting_defaults = option_parser.get_default_values() frontend.make_paths_absolute(publisher.setting_defaults.__dict__, option_parser.relative_path_settings) - if publisher.setup: - publisher.setup() config_parser = frontend.ConfigParser() config_parser.read_standard_files() self.config_settings = config_parser.get_section('options') @@ -155,13 +150,6 @@ class Builder: settings.__dict__.update(self.settings_spec.__dict__) return settings - def setup_html_publisher(self): - pub = core.Publisher() - pub.set_reader(reader_name='standalone', - parser_name='restructuredtext', parser=None) - pub.set_writer(writer_name='html') - self.html_publisher = pub - def run(self, directory=None, recurse=1): recurse = recurse and self.initial_settings.recurse if directory: @@ -193,16 +181,16 @@ class Builder: settings = self.get_settings('.txt', directory) settings._source = os.path.normpath(os.path.join(directory, name)) settings._destination = settings._source[:-4]+'.html' - pub = self.html_publisher - pub.settings = settings if not self.initial_settings.silent: print >>sys.stderr, ' ::: Processing .txt:', name sys.stderr.flush() - pub.source = io.FileInput(settings, source_path=settings._source) - pub.destination = io.FileOutput( - settings, destination_path=settings._destination) try: - pub.publish() + core.publish_file(source_path=settings._source, + destination_path=settings._destination, + reader_name='standalone', + parser_name='restructuredtext', + writer_name='html', + settings=settings) except ApplicationError, error: print >>sys.stderr, (' Error (%s): %s' % (error.__class__.__name__, error)) -- cgit v1.2.1 From e649ed80f03f669e7a18b1a2412240dff931a6a9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:47:35 +0000 Subject: Updated for new ``publish_string()`` convenience function. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@833 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index 2cc7434e9..fe78026f4 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -41,7 +41,7 @@ import random import time REQUIRES = {'python': '2.2', - 'docutils': '0.2.6'} + 'docutils': '0.2.7'} PROGRAM = sys.argv[0] RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' PEPURL = 'pep-%04d.html' @@ -286,23 +286,15 @@ application when this module is imported.""" def fix_rst_pep(inpath, input_lines, outfile): from docutils import core, io - pub = core.Publisher() - pub.set_reader(reader_name='pep', parser_name='restructuredtext', - parser=None) - pub.set_writer(writer_name='pep_html') - if docutils_settings: - settings = docutils_settings - pub.settings = settings - else: - settings = pub.get_settings() - settings._source = inpath - settings._destination = outfile.name - pub.source = io.StringInput( - settings, source=''.join(input_lines), source_path=inpath) - pub.destination = io.FileOutput( - settings, destination=outfile, destination_path=outfile.name, - autoclose=0) - pub.publish() + output = core.publish_string( + source=''.join(input_lines), + source_path=inpath, + destination_path=outfile.name, + reader_name='pep', + parser_name='restructuredtext', + writer_name='pep_html', + settings=docutils_settings) + outfile.write(output) def get_pep_type(input_lines): -- cgit v1.2.1 From e1118b87d660565cdafe0f321adf2bd2fcbe03e9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 18 Oct 2002 23:49:58 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@834 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 15 +++++++++++++-- docs/dev/todo.txt | 6 ++++-- docs/peps/pep-0258.txt | 11 ++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 135af4abe..06cefe38b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -74,12 +74,18 @@ Specific: - 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. * docutils/core.py: - Made ``publish()`` a bit more convenient. - Generalized ``Publisher.set_io``. - - Renamed ``publish()`` to ``publish_cmdline()``. + - 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``. * docutils/frontend.py: @@ -102,7 +108,8 @@ Specific: - Try to get path/stream name automatically in ``FileInput`` & ``FileOutput``. - Added defaults for source & destination paths. - - Allow for Unicode string I/O with an explicit "unicode" encoding. + - Allow for Unicode I/O with an explicit "unicode" encoding. + - Added ``Output.encode()``. * docutils/nodes.py: @@ -194,6 +201,7 @@ Specific: ``ExtensionOptions``. - Improved definition list term/classifier parsing. - Added warnings for unknown directives. + - Renamed ``Stuff`` to ``Struct``. * docutils/parsers/rst/tableparser.py: @@ -304,6 +312,7 @@ Specific: - 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. * docutils/writers/pep_html.py: @@ -426,11 +435,13 @@ Specific: - 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. + - Updated for new ``publish_string()`` convenience function. * tools/pep2html.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e6d202e9a..7f42eab5d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -367,7 +367,8 @@ General Writers now), and thus have associated option/setting specs and transforms. -* +* Multiple file I/O suggestion from Michael Hudson: use a file-like + object or something you can iterate over to get file-like objects. Documentation @@ -1038,7 +1039,8 @@ If the processed document is written to multiple files (possibly in a directory tree), it will need to be split up. References will have to be adjusted. -(HTML only? For now, yes.) +(HTML only? Initially, yes. Eventually, anything should be +splittable.) Navigation diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index f385cebb6..7fa848911 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -176,11 +176,12 @@ reStructuredText markup. It is implemented in the Transforms ---------- -Transforms change the document tree from one form to another, add to -the tree, or prune it. Transforms are run by Reader and Writer -objects. Some transforms are Reader-specific, some are -Parser-specific, and others are Writer-specific. The choice and order -of transforms is specified in the Reader and Writer objects. +Transforms are applied to the document tree to change it from one form +to another, to add to the tree, or to prune it. Transforms are +applied by Reader and Writer objects. Some transforms are +Reader-specific, some are Parser-specific, and others are +Writer-specific. The choice and order of transforms is specified in +the Reader and Writer objects. Each transform is a class in a module in the ``docutils/transforms/`` package, a subclass of docutils.tranforms.Transform. -- cgit v1.2.1 From 17c3ca36527dee68dfbe7076fb54866ff2b2be51 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 22 Oct 2002 01:02:55 +0000 Subject: Fixed attribute typo in <colspec>. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@837 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index bd7372bec..77884a430 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -380,7 +380,7 @@ class HTMLTranslator(nodes.NodeVisitor): for node in self.colspecs: colwidth = int(node['colwidth'] * 100.0 / width + 0.5) self.body.append(self.emptytag(node, 'col', - colwidth='%i%%' % colwidth)) + width='%i%%' % colwidth)) self.colspecs = [] def visit_comment(self, node, -- cgit v1.2.1 From a8529d5c7ba55461db6427c9858ca7f21c18464c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 23 Oct 2002 01:07:40 +0000 Subject: Removed "a.target" style. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@840 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 3 --- tools/stylesheets/pep.css | 3 --- 2 files changed, 6 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index b929f6503..2e1fddb9e 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -14,9 +14,6 @@ Default cascading style sheet for the HTML output of Docutils. .last { margin-bottom: 0 } -a.target { - color: blue } - a.toc-backref { text-decoration: none ; color: black } diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 8cc2a13fb..08274817d 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -49,9 +49,6 @@ Default cascading style sheet for the PEP HTML output of Docutils. font-weight: bold ; margin-bottom: 0em } -a.target { - color: blue } - a.toc-backref { text-decoration: none ; color: black } -- cgit v1.2.1 From 45517c8b55bcc6a6723576bfb620772ab471601a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 23 Oct 2002 01:10:23 +0000 Subject: Added reasons for ``nodes.SkipNode`` exceptions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@841 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 77884a430..851df03e3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -387,6 +387,7 @@ class HTMLTranslator(nodes.NodeVisitor): sub=re.compile('-(?=-)').sub): """Escape double-dashes in comment text.""" self.body.append('<!-- %s -->\n' % sub('- ', node.astext())) + # Content already processed: raise nodes.SkipNode def visit_contact(self, node): @@ -749,6 +750,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</li>\n') def visit_literal(self, node): + """Process text to prevent tokens from wrapping.""" self.body.append(self.starttag(node, 'tt', '', CLASS='literal')) text = node.astext() for token in self.words_and_spaces.findall(text): @@ -763,6 +765,7 @@ class HTMLTranslator(nodes.NodeVisitor): # Protect runs of multiple spaces; the last space can wrap: self.body.append(' ' * (len(token) - 1) + ' ') self.body.append('</tt>') + # Content already processed: raise nodes.SkipNode def visit_literal_block(self, node): @@ -870,8 +873,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_raw(self, node): - if node.has_key('format') and node['format'] == 'html': + if node.get('format') == 'html': self.body.append(node.astext()) + # Keep non-HTML raw text out of output: raise nodes.SkipNode def visit_reference(self, node): @@ -920,6 +924,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</strong>') def visit_substitution_definition(self, node): + """Internal only.""" raise nodes.SkipNode def visit_substitution_reference(self, node): @@ -933,6 +938,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_system_message(self, node): if node['level'] < self.document.reporter['writer'].report_level: + # Level is too low to display: raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) self.body.append('<p class="system-message-title">') -- cgit v1.2.1 From 99fbfbba88293ef1c07f4b96cc0cf9a75dc28849 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:35:43 +0000 Subject: Added "--dump-pseudo-xml", "--dump-settings", and "--dump-transforms" hidden options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@842 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 25 +++++++++++++++++++++++-- docutils/frontend.py | 9 +++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 7e1f597bd..3e499b93b 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -369,14 +369,35 @@ debug Report debug-level system messages. Default: don't (None). Options: ``--debug, --no-debug``. -------------------- ------------------------------------------------ -dump_internals At the end of processing, print out all internal +dump_internals At the end of processing, write all internal attributes of the document - (``document.__dict__``). + (``document.__dict__``) to stderr. Default: don't (None). Options: ``--dump-internals`` (hidden, for development use only). -------------------- ------------------------------------------------ +dump_pseudo_xml At the end of processing, write the pseudo-XML + representation of the document to stderr. + + Default: don't (None). Options: + ``--dump-pseudo-xml`` (hidden, for development + use only). +-------------------- ------------------------------------------------ +dump_settings At the end of processing, write all Docutils + settings to stderr. + + Default: don't (None). Options: + ``--dump-settings`` (hidden, for development use + only). +-------------------- ------------------------------------------------ +dump_transforms At the end of processing, write a list of all + transforms applied to the document to stderr. + + Default: don't (None). Options: + ``--dump-transforms`` (hidden, for development + use only). +-------------------- ------------------------------------------------ embed_stylesheet (HTML Writer.) Embed the stylesheet in the output HTML file. The stylesheet file must be accessible during processing. The stylesheet is diff --git a/docutils/frontend.py b/docutils/frontend.py index 609926e40..3c13f094e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -170,9 +170,18 @@ class OptionParser(optik.OptionParser, docutils.SettingsSpec): ('Show this help message and exit.', ['--help', '-h'], {'action': 'help'}), # Hidden options, for development use only: + (optik.SUPPRESS_HELP, + ['--dump-settings'], + {'action': 'store_true'}), (optik.SUPPRESS_HELP, ['--dump-internals'], {'action': 'store_true'}), + (optik.SUPPRESS_HELP, + ['--dump-transforms'], + {'action': 'store_true'}), + (optik.SUPPRESS_HELP, + ['--dump-pseudo-xml'], + {'action': 'store_true'}), (optik.SUPPRESS_HELP, ['--expose-internal-attribute'], {'action': 'append', 'dest': 'expose_internals'}),)) -- cgit v1.2.1 From 85e63d722ab2413ecc1a9de5b878bb7b83079a95 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:36:14 +0000 Subject: Added ``Component.component_type`` attribute. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@843 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index f7ebd564d..eab752cd2 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -111,6 +111,9 @@ class Component(SettingsSpec, TransformSpec): """Base class for Docutils components.""" + component_type = None + """Override in subclasses.""" + supported = () """Names for this component. Override in subclasses.""" @@ -118,8 +121,7 @@ class Component(SettingsSpec, TransformSpec): """ Is `format` supported by this component? - To be used by transforms to ask the component (Reader or Writer) - controlling the transform if that component supports a certain input - context or output format. + 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 -- cgit v1.2.1 From 04715867f21e8f700fe73c1409e7c69daa6d4cf2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:37:00 +0000 Subject: Added ``Publisher.apply_transforms()`` method. Added support for "--dump-pseudo-xml", "--dump-settings", and "--dump-transforms" hidden options. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@844 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docutils/core.py b/docutils/core.py index 5d6927099..14e794c7e 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -74,6 +74,7 @@ class Publisher: def setup_option_parser(self, usage=None, description=None, settings_spec=None, **defaults): + #@@@ Add self.source & self.destination to components in future? option_parser = OptionParser( components=(settings_spec, self.parser, self.reader, self.writer), usage=usage, description=description) @@ -138,6 +139,12 @@ class Publisher: self.settings, destination=destination, destination_path=destination_path) + def apply_transforms(self, document): + document.transformer.populate_from_components( + (self.source, self.reader, self.reader.parser, self.writer, + self.destination)) + document.transformer.apply_transforms() + def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None): """ @@ -152,10 +159,24 @@ class Publisher: self.settings._update(settings_overrides, 'loose') self.set_io() document = self.reader.read(self.source, self.parser, self.settings) + self.apply_transforms(document) output = self.writer.write(document, self.destination) + if self.settings.dump_settings: + from pprint import pformat + print >>sys.stderr, '\n::: Docutils settings:' + print >>sys.stderr, pformat(self.settings.__dict__) if self.settings.dump_internals: from pprint import pformat + print >>sys.stderr, '\n::: Docutils internals:' print >>sys.stderr, pformat(document.__dict__) + if self.settings.dump_transforms: + from pprint import pformat + print >>sys.stderr, '\n::: Transforms applied:' + print >>sys.stderr, pformat(document.transformer.applied) + if self.settings.dump_pseudo_xml: + print >>sys.stderr, '\n::: Pseudo-XML:' + print >>sys.stderr, document.pformat().encode( + 'raw_unicode_escape') return output -- cgit v1.2.1 From 9d7e709e41310a49d0753fe62cac709fefffdb72 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:38:59 +0000 Subject: Completed transform reform. Reworked ``pending`` elements. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@845 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index b61b21761..8659759e8 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -679,9 +679,6 @@ class document(Root, Structural, Element): self.citations = [] """List of citation nodes.""" - self.pending = [] - """List of pending elements.""" - self.autofootnote_start = 1 """Initial auto-numbered footnote number.""" @@ -697,8 +694,9 @@ class document(Root, Structural, Element): self.transform_messages = [] """System messages generated while applying transforms.""" - self.transformer = None - """`docutils.transforms.Transformer` object.""" + import docutils.transforms + self.transformer = docutils.transforms.Transformer(self) + """Storage for transforms to be applied to this document.""" self.document = self @@ -892,8 +890,8 @@ class document(Root, Structural, Element): self.substitution_refs.setdefault( subref['refname'], []).append(subref) - def note_pending(self, pending): - self.pending.append(pending) + def note_pending(self, pending, priority=None): + self.transformer.add_pending(pending, priority) def note_parse_message(self, message): self.parse_messages.append(message) @@ -1070,8 +1068,9 @@ class pending(Special, Invisible, PreBibliographic, Element): The "pending" element is used to encapsulate a pending operation: the operation (transform), the point at which to apply it, and any data it requires. Only the pending operation's location within the document is - stored in the public document tree; the operation itself and its data are - stored in internal instance attributes. + stored in the public document tree (by the "pending" object itself); the + operation and its data are stored in the "pending" object's internal + instance attributes. For example, say you want a table of contents in your reStructuredText document. The easiest way to specify where to put it is from within the @@ -1080,24 +1079,18 @@ class pending(Special, Invisible, PreBibliographic, Element): .. contents:: But the "contents" directive can't do its work until the entire document - has been parsed (and possibly transformed to some extent). So the - directive code leaves a placeholder behind that will trigger the second - phase of the its processing, something like this:: + has been parsed and possibly transformed to some extent. So the directive + code leaves a placeholder behind that will trigger the second phase of the + its processing, something like this:: <pending ...public attributes...> + internal attributes - Use `document.note_pending()` to append the "pending" node to - `document.pending`, so that a later stage of processing can easily run all - pending transforms. The processign stage must also be specified (one of - "first reader", "last reader", "first writer", or "last writer"). - - Pending transforms will be triggered by the transform subclasses of - ``docutils.transforms.universal.Pending``. These transforms are called by - ``docutils.readers.Reader.transform()`` and - ``docutils.readers.Writer.transform()``. + Use `document.note_pending()` so that the + `docutils.transforms.Transformer` stage of processing can run all pending + transforms. """ - def __init__(self, transform, stage, details, + def __init__(self, transform, details=None, rawsource='', *children, **attributes): Element.__init__(self, rawsource, *children, **attributes) @@ -1105,10 +1098,7 @@ class pending(Special, Invisible, PreBibliographic, Element): """The `docutils.transforms.Transform` class implementing the pending operation.""" - self.stage = stage - """The stage of processing when the function will be called.""" - - self.details = details + self.details = details or {} """Detail data (dictionary) required by the pending operation.""" def pformat(self, indent=' ', level=0): @@ -1116,7 +1106,6 @@ class pending(Special, Invisible, PreBibliographic, Element): '.. internal attributes:', ' .transform: %s.%s' % (self.transform.__module__, self.transform.__name__), - ' .stage: %r' % self.stage, ' .details:'] details = self.details.items() details.sort() @@ -1138,8 +1127,8 @@ class pending(Special, Invisible, PreBibliographic, Element): for line in internals])) def copy(self): - return self.__class__(self.transform, self.stage, self.details, - **self.attributes) + return self.__class__(self.transform, self.details, self.rawsource, + **self.attribuates) class raw(Special, Inline, PreBibliographic, FixedTextElement): -- cgit v1.2.1 From 2586836579f852ed06ddaad9f4933e3e2b8a6af5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:40:03 +0000 Subject: Added ``Parser.finish_parse()`` method; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@846 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/__init__.py b/docutils/parsers/__init__.py index b5717e0d3..5b1e964be 100644 --- a/docutils/parsers/__init__.py +++ b/docutils/parsers/__init__.py @@ -15,14 +15,22 @@ from docutils import Component class Parser(Component): + component_type = 'parser' + def parse(self, inputstring, document): """Override to parse `inputstring` into document tree `document`.""" raise NotImplementedError('subclass must override this method') def setup_parse(self, inputstring, document): - """Initial setup, used by `parse()`.""" + """Initial parse setup. Call at start of `self.parse()`.""" self.inputstring = inputstring self.document = document + document.reporter.attach_observer(document.note_parse_message) + + def finish_parse(self): + """Finalize parse details. Call at end of `self.parse()`.""" + self.document.reporter.detach_observer( + self.document.note_parse_message) _parser_aliases = { -- cgit v1.2.1 From 3e8c56e56bd1d9c62e125da837698dff2b11718f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:41:19 +0000 Subject: Detect bad column spans in "simple" tables. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@847 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/tableparser.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 3ef7e7d68..6b2ffe3ee 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -377,6 +377,7 @@ class SimpleTableParser(TableParser): self.block[-1] = self.block[-1].replace('=', '-') self.head_body_sep = None self.columns = [] + self.border_end = None self.table = [] self.done = [-1] * len(block[0]) self.rowseps = {0: [0]} @@ -390,7 +391,8 @@ class SimpleTableParser(TableParser): job. """ # Top border must fully describe all table columns. - self.columns = self.parse_columns(self.block[0]) + self.columns = self.parse_columns(self.block[0], 0) + self.border_end = self.columns[-1][1] firststart, firstend = self.columns[0] block = self.block[1:] offset = 0 @@ -412,7 +414,7 @@ class SimpleTableParser(TableParser): # Accumulate lines of incomplete row. rowlines.append((line.rstrip(), offset)) - def parse_columns(self, line): + def parse_columns(self, line, offset): """ Given a column span underline, return a list of (begin, end) pairs. """ @@ -427,6 +429,9 @@ class SimpleTableParser(TableParser): end = len(line) cols.append((begin, end)) if self.columns: + if cols[-1][1] != self.border_end: + raise TableMarkupError('Column span incomplete at line ' + 'offset %s.' % offset) # Allow for an unbounded rightmost column: cols[-1] = (cols[-1][0], self.columns[-1][1]) return cols @@ -457,10 +462,6 @@ class SimpleTableParser(TableParser): text from each line, and check for text in column margins. Finally, adjust for insigificant whitespace. """ - if spanline: - columns = self.parse_columns(spanline[0]) - else: - columns = self.columns[:] while lines and not lines[-1][0]: lines.pop() # Remove blank trailing lines. if lines: @@ -470,6 +471,10 @@ class SimpleTableParser(TableParser): else: # No new row, just blank lines. return + if spanline: + columns = self.parse_columns(*spanline) + else: + columns = self.columns[:] row = self.init_row(columns, offset) # "Infinite" value for a dummy last column's beginning, used to # check for text overflow: -- cgit v1.2.1 From f426b617ed5f1cb5727fc5cd8cfd1befff548744 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:42:58 +0000 Subject: Completed transform reform; removed ``transform()`` method; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@848 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 17 +---------------- docutils/writers/__init__.py | 17 ++--------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 44e6fe76c..413983777 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -27,10 +27,7 @@ class Reader(Component): `parse()`, and `transform()`. Call `read()` to process a document. """ - transforms = () - """Ordered tuple of transform classes (each with an ``apply()`` - method). Populated by subclasses. `Reader.transform()` - instantiates & runs them.""" + component_type = 'reader' def __init__(self, parser, parser_name): """ @@ -67,26 +64,14 @@ class Reader(Component): # May modify self.parser, depending on input: self.input = self.source.read(self) self.parse() - self.transform() return self.document def parse(self): """Parse `self.input` into a document tree.""" self.document = document = self.new_document() - document.reporter.attach_observer(document.note_parse_message) self.parser.parse(self.input, document) - document.reporter.detach_observer(document.note_parse_message) document.current_source = document.current_line = None - def transform(self): - """Run all of the transforms defined for this Reader.""" - self.document.reporter.attach_observer( - self.document.note_transform_message) - for xclass in (universal.first_reader_transforms - + tuple(self.transforms) - + universal.last_reader_transforms): - xclass(self.document, self).apply() - def new_document(self): """Create and return a new empty document tree (root node).""" document = utils.new_document(self.source.source_path, self.settings) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 0a8eb6917..675c45f18 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -29,6 +29,8 @@ class Writer(Component): Call `write()` to process a document. """ + component_type = 'writer' + document = None """The document to write.""" @@ -38,33 +40,18 @@ class Writer(Component): destination = None """`docutils.io` IO object; where to write the document.""" - transforms = () - """Ordered list of transform classes (each with an ``apply()`` method). - Populated by subclasses. `Writer.transform()` instantiates & runs them.""" - def __init__(self): """Initialize the Writer instance.""" - self.transforms = list(self.transforms) - """Instance copy of `Writer.transforms`; may be modified by client.""" - def write(self, document, destination): self.document = document self.language = languages.get_language( document.settings.language_code) self.destination = destination - self.transform() self.translate() output = self.destination.write(self.output) return output - def transform(self): - """Run all of the transforms defined for this Writer.""" - for xclass in (universal.first_writer_transforms - + tuple(self.transforms) - + universal.last_writer_transforms): - xclass(self.document, self).apply() - def translate(self): """ Override to do final document tree translation. -- cgit v1.2.1 From 3af1c5ceb828ce4322d32cccbd91b09d52010cc9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:44:28 +0000 Subject: Split ``references.Hyperlinks`` into multiple transforms. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@849 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/pep.py | 16 ++++++++++------ docutils/readers/standalone.py | 14 +++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 7492331c8..2c2715b0f 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -31,12 +31,16 @@ class Reader(standalone.Reader): 'reStructuredText parser) are on by default.', ()) - transforms = (references.Substitutions, - peps.Headers, - peps.Contents, - peps.TargetNotes, - references.Footnotes, - references.Hyperlinks,) + default_transforms = (references.Substitutions, + peps.Headers, + peps.Contents, + references.ChainedTargets, + references.AnonymousHyperlinks, + references.IndirectHyperlinks, + peps.TargetNotes, + references.Footnotes, + references.ExternalTargets, + references.InternalTargets,) settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 0eca2e7da..d7c5c8828 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -25,8 +25,12 @@ class Reader(readers.Reader): document = None """A single document tree.""" - transforms = (references.Substitutions, - frontmatter.DocTitle, - frontmatter.DocInfo, - references.Footnotes, - references.Hyperlinks,) + default_transforms = (references.Substitutions, + frontmatter.DocTitle, + frontmatter.DocInfo, + references.ChainedTargets, + references.AnonymousHyperlinks, + references.IndirectHyperlinks, + references.Footnotes, + references.ExternalTargets, + references.InternalTargets,) -- cgit v1.2.1 From 74d3adf49780948eb723c003bf604c016f6433d1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:45:07 +0000 Subject: Split ``Hyperlinks`` into multiple transforms. Fixed ``TargetNotes`` (indirect links to external targets now work). Completed transform reform; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@850 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 406 ++++++++++++++++++++------------------ 1 file changed, 213 insertions(+), 193 deletions(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 96bd48942..c757f39d3 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -5,12 +5,7 @@ # Copyright: This module has been placed in the public domain. """ -Transforms for resolving references: - -- `Hyperlinks`: Used to resolve hyperlink targets and references. -- `Footnotes`: Resolve footnote numbering and references. -- `Substitutions`: Resolve substitutions. -- `TargetNotes`: Create footnotes for external targets. +Transforms for resolving references. """ __docformat__ = 'reStructuredText' @@ -24,49 +19,113 @@ from docutils.transforms import TransformError, Transform indices = xrange(sys.maxint) -class Hyperlinks(Transform): +class ChainedTargets(Transform): - """Resolve the various types of hyperlink targets and references.""" + """ + Attributes "refuri" and "refname" are migrated from the final direct + target up the chain of contiguous adjacent internal targets, using + `ChainedTargetResolver`. + """ - def apply(self): - self.resolve_chained_targets() - self.resolve_anonymous() - self.resolve_indirect() - self.resolve_external_targets() - self.resolve_internal_targets() + default_priority = 420 - def resolve_chained_targets(self): - """ - Attributes "refuri" and "refname" are migrated from the final direct - target up the chain of contiguous adjacent internal targets, using - `ChainedTargetResolver`. - """ + def apply(self): visitor = ChainedTargetResolver(self.document) self.document.walk(visitor) - def resolve_anonymous(self): - """ - Link anonymous references to targets. Given:: +class ChainedTargetResolver(nodes.SparseNodeVisitor): + + """ + Copy reference attributes up the length of a hyperlink target chain. + + "Chained targets" are multiple adjacent internal hyperlink targets which + "point to" an external or indirect target. After the transform, all + chained targets will effectively point to the same place. + + Given the following ``document`` as input:: + + <document> + <target id="a" name="a"> + <target id="b" name="b"> + <target id="c" name="c" refuri="http://chained.external.targets"> + <target id="d" name="d"> <paragraph> - <reference anonymous="1"> - internal - <reference anonymous="1"> - external - <target anonymous="1" id="id1"> - <target anonymous="1" id="id2" refuri="http://external"> + I'm known as "d". + <target id="e" name="e"> + <target id="id1"> + <target id="f" name="f" refname="d"> - Corresponding references are linked via "refid" or resolved via - "refuri":: + ``ChainedTargetResolver(document).walk()`` will transform the above into:: + <document> + <target id="a" name="a" refuri="http://chained.external.targets"> + <target id="b" name="b" refuri="http://chained.external.targets"> + <target id="c" name="c" refuri="http://chained.external.targets"> + <target id="d" name="d"> <paragraph> - <reference anonymous="1" refid="id1"> - text - <reference anonymous="1" refuri="http://external"> - external - <target anonymous="1" id="id1"> - <target anonymous="1" id="id2" refuri="http://external"> - """ + I'm known as "d". + <target id="e" name="e" refname="d"> + <target id="id1" refname="d"> + <target id="f" name="f" refname="d"> + """ + + def unknown_visit(self, node): + pass + + def visit_target(self, node): + if node.hasattr('refuri'): + attname = 'refuri' + call_if_named = self.document.note_external_target + elif node.hasattr('refname'): + attname = 'refname' + call_if_named = self.document.note_indirect_target + elif node.hasattr('refid'): + attname = 'refid' + call_if_named = None + else: + return + attval = node[attname] + index = node.parent.index(node) + for i in range(index - 1, -1, -1): + sibling = node.parent[i] + if not isinstance(sibling, nodes.target) \ + or sibling.hasattr('refuri') \ + or sibling.hasattr('refname') \ + or sibling.hasattr('refid'): + break + sibling[attname] = attval + if sibling.hasattr('name') and call_if_named: + call_if_named(sibling) + + +class AnonymousHyperlinks(Transform): + + """ + Link anonymous references to targets. Given:: + + <paragraph> + <reference anonymous="1"> + internal + <reference anonymous="1"> + external + <target anonymous="1" id="id1"> + <target anonymous="1" id="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" id="id1"> + <target anonymous="1" id="id2" refuri="http://external"> + """ + + default_priority = 440 + + def apply(self): if len(self.document.anonymous_refs) \ != len(self.document.anonymous_targets): msg = self.document.reporter.error( @@ -92,56 +151,62 @@ class Hyperlinks(Transform): self.document.note_refid(ref) target.referenced = 1 - def resolve_indirect(self): - """ - 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"> - """ + +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) @@ -246,22 +311,28 @@ class Hyperlinks(Transform): self.resolve_indirect_references(ref) target.referenced = 1 - def resolve_external_targets(self): - """ - Given:: - <paragraph> - <reference refname="direct external"> - direct external - <target id="id1" name="direct external" refuri="http://direct"> +class ExternalTargets(Transform): + + """ + Given:: - The "refname" attribute is replaced by the direct "refuri" attribute:: + <paragraph> + <reference refname="direct external"> + direct external + <target id="id1" name="direct external" refuri="http://direct"> - <paragraph> - <reference refuri="http://direct"> - 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.external_targets: if target.hasattr('refuri') and target.hasattr('name'): name = target['name'] @@ -284,23 +355,29 @@ class Hyperlinks(Transform): ref.resolved = 1 target.referenced = 1 - def resolve_internal_targets(self): - """ - Given:: - <paragraph> - <reference refname="direct internal"> - direct internal - <target id="id1" name="direct internal"> +class InternalTargets(Transform): + + """ + Given:: - The "refname" attribute is replaced by "refid" linking to the target's - "id":: + <paragraph> + <reference refname="direct internal"> + direct internal + <target id="id1" name="direct internal"> - <paragraph> - <reference refid="id1"> - 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"> + """ + + default_priority = 660 + + def apply(self): for target in self.document.internal_targets: if target.hasattr('refuri') or target.hasattr('refid') \ or not target.hasattr('name'): @@ -326,71 +403,6 @@ class Hyperlinks(Transform): target.referenced = 1 -class ChainedTargetResolver(nodes.SparseNodeVisitor): - - """ - Copy reference attributes up the length of a hyperlink target chain. - - "Chained targets" are multiple adjacent internal hyperlink targets which - "point to" an external or indirect target. After the transform, all - chained targets will effectively point to the same place. - - Given the following ``document`` as input:: - - <document> - <target id="a" name="a"> - <target id="b" name="b"> - <target id="c" name="c" refuri="http://chained.external.targets"> - <target id="d" name="d"> - <paragraph> - I'm known as "d". - <target id="e" name="e"> - <target id="id1"> - <target id="f" name="f" refname="d"> - - ``ChainedTargetResolver(document).walk()`` will transform the above into:: - - <document> - <target id="a" name="a" refuri="http://chained.external.targets"> - <target id="b" name="b" refuri="http://chained.external.targets"> - <target id="c" name="c" refuri="http://chained.external.targets"> - <target id="d" name="d"> - <paragraph> - I'm known as "d". - <target id="e" name="e" refname="d"> - <target id="id1" refname="d"> - <target id="f" name="f" refname="d"> - """ - - def unknown_visit(self, node): - pass - - def visit_target(self, node): - if node.hasattr('refuri'): - attname = 'refuri' - call_if_named = self.document.note_external_target - elif node.hasattr('refname'): - attname = 'refname' - call_if_named = self.document.note_indirect_target - elif node.hasattr('refid'): - attname = 'refid' - call_if_named = None - else: - return - attval = node[attname] - index = node.parent.index(node) - for i in range(index - 1, -1, -1): - sibling = node.parent[i] - if not isinstance(sibling, nodes.target) \ - or sibling.hasattr('refuri') \ - or sibling.hasattr('refname') \ - or sibling.hasattr('refid'): - break - sibling[attname] = attval - if sibling.hasattr('name') and call_if_named: - call_if_named(sibling) - - class Footnotes(Transform): """ @@ -452,6 +464,8 @@ class Footnotes(Transform): ignored. """ + default_priority = 620 + autofootnote_labels = None """Keep track of unlabeled autonumbered footnotes.""" @@ -635,6 +649,10 @@ class Substitutions(Transform): <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 for refname, refs in self.document.substitution_refs.items(): @@ -661,11 +679,12 @@ class TargetNotes(Transform): footnote references after each reference. """ - def __init__(self, document, component, startnode=None): - Transform.__init__(self, document, component, startnode) - self.notes = {} + default_priority = 540 + """The TargetNotes transform has to be applied after `IndirectHyperlinks` + but before `Footnotes`.""" def apply(self): + notes = {} nodelist = [] for target in self.document.external_targets: name = target.get('name') @@ -675,26 +694,25 @@ class TargetNotes(Transform): refs = self.document.refnames.get(name, []) if not refs: continue - footnote = self.make_target_footnote(target, refs) - if not self.notes.has_key(target['refuri']): - self.notes[target['refuri']] = footnote + footnote = self.make_target_footnote(target, refs, notes) + if not notes.has_key(target['refuri']): + notes[target['refuri']] = footnote nodelist.append(footnote) if len(self.document.anonymous_targets) \ == len(self.document.anonymous_refs): for target, ref in zip(self.document.anonymous_targets, self.document.anonymous_refs): if target.hasattr('refuri'): - footnote = self.make_target_footnote(target, [ref]) - if not self.notes.has_key(target['refuri']): - self.notes[target['refuri']] = footnote + footnote = self.make_target_footnote(target, [ref], notes) + if not notes.has_key(target['refuri']): + notes[target['refuri']] = footnote nodelist.append(footnote) self.startnode.parent.replace(self.startnode, nodelist) - # @@@ what about indirect links to external targets? - def make_target_footnote(self, target, refs): + def make_target_footnote(self, target, refs, notes): refuri = target['refuri'] - if self.notes.has_key(refuri): # duplicate? - footnote = self.notes[refuri] + if notes.has_key(refuri): # duplicate? + footnote = notes[refuri] footnote_name = footnote['name'] else: # original footnote = nodes.footnote() @@ -709,6 +727,8 @@ class TargetNotes(Transform): 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) self.document.note_autofootnote_ref(refnode) -- cgit v1.2.1 From cb678b87cdec6c2fc503cccf524b48bc80950edd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:45:58 +0000 Subject: Completed transform reform; removed ``Pending`` transform classes & data; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@852 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 69 +++++----------------------------------- 1 file changed, 8 insertions(+), 61 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index de52c3bb3..65fc0cb4a 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -12,9 +12,6 @@ Transforms needed by most or all documents: `nodes.document.transform_messages`. - `TestMessages`: Like `Messages`, used on test runs. - `FinalReferences`: Resolve remaining references. -- `Pending`: Execute pending transforms (abstract base class; - `FirstReaderPending`, `LastReaderPending`, `FirstWriterPending`, and - `LastWriterPending` are its concrete subclasses). """ __docformat__ = 'reStructuredText' @@ -32,6 +29,8 @@ class Decorations(Transform): Populate a document's decoration element (header, footer). """ + default_priority = 820 + def apply(self): header = self.generate_header() footer = self.generate_footer() @@ -94,6 +93,8 @@ class Messages(Transform): of the document. """ + default_priority = 860 + def apply(self): unfiltered = self.document.transform_messages threshold = self.document.reporter['writer'].report_level @@ -116,6 +117,8 @@ class TestMessages(Transform): Append all post-parse system messages to the end of the document. """ + default_priority = 890 + def apply(self): for msg in self.document.transform_messages: if not msg.parent: @@ -130,6 +133,8 @@ class FinalChecks(Transform): - Check for dangling references (incl. footnote & citation). """ + default_priority = 840 + def apply(self): visitor = FinalCheckVisitor(self.document) self.document.walk(visitor) @@ -178,61 +183,3 @@ class InternalAttributeExposer(nodes.GenericNodeVisitor): value = getattr(node, att, None) if value is not None: node['internal:' + att] = value - - -class Pending(Transform): - - """ - Base class for the execution of pending transforms. - - `nodes.pending` element objects each contain a "stage" attribute; the - stage of the pending element must match the `stage` of this transform. - """ - - stage = None - """The stage of processing applicable to this transform; match with - `nodes.pending.stage`. Possible values include 'first reader', - 'last reader', 'first writer', and 'last writer'. Overriden in - subclasses (below).""" - - def apply(self): - for pending in self.document.pending: - if pending.stage == self.stage: - pending.transform(self.document, self.component, - pending).apply() - - -class FirstReaderPending(Pending): - - stage = 'first reader' - - -class LastReaderPending(Pending): - - stage = 'last reader' - - -class FirstWriterPending(Pending): - - stage = 'first writer' - - -class LastWriterPending(Pending): - - stage = 'last writer' - - -test_transforms = (TestMessages,) -"""Universal transforms to apply to the raw document when testing.""" - -first_reader_transforms = (FirstReaderPending,) -"""Universal transforms to apply before any other Reader transforms.""" - -last_reader_transforms = (LastReaderPending, Decorations) -"""Universal transforms to apply after all other Reader transforms.""" - -first_writer_transforms = (FirstWriterPending,) -"""Universal transforms to apply before any other Writer transforms.""" - -last_writer_transforms = (LastWriterPending, FinalChecks, Messages) -"""Universal transforms to apply after all other Writer transforms.""" -- cgit v1.2.1 From 1ecb8a1bf993d41cb606a26ca5168809bd75412b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:51:10 +0000 Subject: Completed transform reform; updated. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@853 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 107 ++++++++++++++++++++++++------------- docutils/transforms/components.py | 26 +++++---- docutils/transforms/frontmatter.py | 4 ++ docutils/transforms/parts.py | 20 +++---- docutils/transforms/peps.py | 17 ++++-- test/DocutilsTestSupport.py | 11 ++-- 6 files changed, 119 insertions(+), 66 deletions(-) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 34aa7911d..24cc4771f 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -40,7 +40,10 @@ class Transform: Docutils transform component abstract base class. """ - def __init__(self, document, component, startnode=None): + 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. """ @@ -48,11 +51,6 @@ class Transform: self.document = document """The document tree to transform.""" - self.component = component - """The Docutils component running this transform. Transforms can - query their controlling components with calls to - `docutils.Component.supports()`.""" - 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 @@ -70,7 +68,8 @@ class Transform: class Transformer(TransformSpec): """ - The Transformer class records and applies transforms to documents. + Stores transforms (`Transform` classes) and applies them to document + trees. Also keeps track of components by component type name. """ from docutils.transforms import universal @@ -78,54 +77,90 @@ class Transformer(TransformSpec): default_transforms = (universal.Decorations, universal.FinalChecks, universal.Messages) + """These transforms are applied to all document trees.""" def __init__(self, document): self.transforms = [] - """Queue of transforms to apply.""" - - self.applying = None - """Boolean: am I now applying tranforms?""" + """List of transforms to apply. Each item is a 3-tuple: + ``(priority string, transform class, pending node or None)``.""" self.document = document """The `nodes.document` object this Transformer is attached to.""" - def add_transform(self, transform_class, priority=None, component=None): + 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): + """ + Store a single transform. Use `priority` to override the default. + """ if priority is None: - priority = transform_class.priority - self.transforms.append((priority, transform_class, None, component)) - if self.applying: - self.transforms.sort() + priority = transform_class.default_priority + priority_string = self.get_priority_string(priority) + self.transforms.append((priority_string, transform_class, None)) + self.sorted = 0 - def add_transforms(self, transform_list, component=None): + def add_transforms(self, transform_list): + """Store multiple transforms, with default priorities.""" for transform_class in transform_list: - self.transforms.append( - (transform_class.priority, transform_class, None, component)) - if self.applying: - self.transforms.sort() + 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, component=None): + 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.priority - self.transforms.append( - (priority, transform_class, pending, component)) - if self.applying: - self.transforms.sort() + 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. + """ + self.add_transforms(self.default_transforms) for component in components: if component is None: continue - self.add_transforms(component.default_transforms, - component=component) + self.add_transforms(component.default_transforms) + self.components[component.component_type] = component + self.sorted = 0 def apply_transforms(self): - self.applying = 1 - self.transforms.sort() + """Apply all of the stored transforms, in priority order.""" + self.document.reporter.attach_observer( + self.document.note_transform_message) while self.transforms: - priority, transform_class, pending, component \ - = self.transforms.pop(0) - transform = transform_class(self.document, component, - startnode=pending) + 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 = self.transforms.pop() + transform = transform_class(self.document, startnode=pending) transform.apply() - self.applying = None + self.applied.append((priority, transform_class, pending)) diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index 7bb4e959d..8f4a267e1 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -25,26 +25,30 @@ 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 a key matching the dependency component - type (e.g. ``details['writer']`` for a "pending" element whose ``stage`` - attribute is 'last writer'). The value is the name of a specific format - or context of that component (e.g. ``details['writer'] = 'html'``). If - the Docutils component which called this transform supports that format or - context, the "pending" element is replaced by the contents of + 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 supporting the "html" format will include the "meta" element; - it will be deleted from the output of all other writers. + 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.stage.split()[-1] # 'reader' or 'writer' - component_name = pending.details[component_type] - if self.component.supports(component_name): + component_type = pending.details['component'] # 'reader' or 'writer' + format = pending.details['format'] + component = self.document.transformer.components[component_type] + if component.supports(format): pending.parent.replace(pending, pending.details['nodes']) else: pending.parent.remove(pending) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index f8d4869c5..86cae9854 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -102,6 +102,8 @@ class DocTitle(Transform): after the title(s). """ + default_priority = 320 + def apply(self): if self.promote_document_title(): self.promote_document_subtitle() @@ -225,6 +227,8 @@ class DocInfo(Transform): expansion text changes only if the file name changes.) """ + default_priority = 340 + def apply(self): document = self.document index = document.first_child_not_matching_class( diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 8bf0d2946..05747183e 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -6,9 +6,6 @@ """ Transforms related to document parts. - -- `Contents`: Used to build a table of contents. -- `SectNum`: Used to automatically number the section titles. """ __docformat__ = 'reStructuredText' @@ -23,14 +20,17 @@ from docutils.transforms import TransformError, Transform class SectNum(Transform): """ - This 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. + 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', sys.maxint) self.startnode.parent.remove(self.startnode) @@ -69,6 +69,8 @@ class Contents(Transform): startnode is replaced by the table of contents "topic"). """ + default_priority = 720 + def apply(self): topic = nodes.topic(CLASS='contents') title = self.startnode.details['title'] diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 91d59bf72..db1cdf47f 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -31,6 +31,8 @@ class Headers(Transform): Process fields in a PEP's initial RFC-2822 header. """ + default_priority = 360 + pep_url = 'pep-%04d.html' pep_cvs_url = ('http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/' 'python/nondist/peps/pep-%04d.txt') @@ -74,7 +76,7 @@ class Headers(Transform): 'header.') if pep == 0: # Special processing for PEP 0. - pending = nodes.pending(PEPZero, 'last reader', {}) + pending = nodes.pending(PEPZero) self.document.insert(1, pending) self.document.note_pending(pending) for field in header: @@ -136,9 +138,10 @@ class Contents(Transform): the RFC 2822 header. """ + default_priority = 380 + def apply(self): - pending = nodes.pending(parts.Contents, 'first writer', - {'title': None}) + pending = nodes.pending(parts.Contents, {'title': None}) self.document.insert(1, pending) self.document.note_pending(pending) @@ -150,6 +153,8 @@ class TargetNotes(Transform): target footnote insertion transform at the end, and run the transform. """ + default_priority = 520 + def apply(self): doc = self.document i = len(doc) - 1 @@ -168,9 +173,9 @@ class TargetNotes(Transform): doc.insert(copyright, refsect) else: doc.append(refsect) - pending = nodes.pending(references.TargetNotes, 'immediate', {}) + pending = nodes.pending(references.TargetNotes) refsect.append(pending) - pending.transform(doc, self, pending).apply() + self.document.note_pending(pending, 0) class PEPZero(Transform): @@ -179,6 +184,8 @@ class PEPZero(Transform): Special processing for PEP 0. """ + default_priority =760 + def apply(self): visitor = PEPZeroSpecial(self.document) self.document.walk(visitor) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 7d7252184..822a45946 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -273,12 +273,13 @@ class TransformTestCase(CustomTestCase): if self.run_in_debugger: pdb.set_trace() document = utils.new_document('test data', self.settings) - document.reporter.attach_observer(document.note_parse_message) self.parser.parse(self.input, document) - document.reporter.detach_observer(document.note_parse_message) - document.reporter.attach_observer(document.note_transform_message) - for transformClass in (self.transforms + universal.test_transforms): - transformClass(document, self).apply() + # Don't do a ``populate_from_components()`` because that would + # enable the Transformer's default transforms. + document.transformer.add_transforms(self.transforms) + document.transformer.add_transform(universal.TestMessages) + document.transformer.components['writer'] = self + document.transformer.apply_transforms() output = document.pformat() self.compare_output(self.input, output, self.expected) -- cgit v1.2.1 From f70da4a859aed7187bb6c4a183a8827ff4cbb58f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:51:28 +0000 Subject: Brought up to date. Many changes. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@854 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0258.txt | 465 +++++++++++++++++++++++++++---------------------- 1 file changed, 254 insertions(+), 211 deletions(-) diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 7fa848911..e7df5dc04 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -20,7 +20,7 @@ This PEP documents design issues and implementation details for Docutils, a Python Docstring Processing System (DPS). The rationale and high-level concepts of a DPS are documented in PEP 256, "Docstring Processing System Framework" [#PEP-256]_. Also see PEP 256 for a -"Roadmap to the Doctring PEPs". +"Roadmap to the Docstring PEPs". Docutils is being designed modularly so that any of its components can be replaced easily. In addition, Docutils is not limited to the @@ -39,63 +39,65 @@ documentation. Docutils Project Model ====================== -:: - - +--------------------------+ - | Docutils: | - | docutils.core.Publisher, | - | docutils.core.publish() | - +--------------------------+ - / \ - / \ - 1,3,5,7 / \ 8,10 - +--------+ +--------+ - | READER | =========================> | WRITER | - +--------+ +--------+ - / || \ / \ - / || \ / \ - 2 / 4 || \ 6 9 / \ 11 - +-----+ +--------+ +-------------+ +------------+ +-----+ - | I/O | | PARSER |...| reader | | writer | | I/O | - +-----+ +--------+ | transforms | | transforms | +-----+ - | | | | - | - docinfo | | - system | - | - titles | | messages | - | - linking | | - final | - | - lookups | | checks | - | - reader- | | - writer- | - | specific | | specific | - | - parser- | | - etc. | - | specific | +------------+ - | - layout | - | (stylist) | - | - etc. | - +-------------+ - -The numbers indicate the path a document's data takes through the -code. Double-width lines between reader & parser and between reader & -writer indicate that data sent along these paths should be standard -(pure & unextended) Docutils doc trees. Single-width lines signify -that internal tree extensions or completely unrelated representations -are possible, but they must be supported at both ends. +Project components and data flow:: + + +---------------------------+ + | Docutils: | + | docutils.core.Publisher, | + | docutils.core.publish_*() | + +---------------------------+ + / | \ + / | \ + 1,3,5 / 6 | \ 7 + +--------+ +-------------+ +--------+ + | READER | ----> | TRANSFORMER | ====> | WRITER | + +--------+ +-------------+ +--------+ + / \\ | + / \\ | + 2 / 4 \\ 8 | + +-------+ +--------+ +--------+ + | INPUT | | PARSER | | OUTPUT | + +-------+ +--------+ +--------+ + +The numbers above each component indicate the path a document's data +takes. Double-width lines between Reader & Parser and between +Transformer & Writer indicate that data sent along these paths should +be standard (pure & unextended) Docutils doc trees. Single-width +lines signify that internal tree extensions or completely unrelated +representations are possible, but they must be supported at both ends. Publisher --------- The ``docutils.core`` module contains a "Publisher" facade class and -"publish" convenience function. Publisher encapsulates the high-level -logic of a Docutils system. The ``Publisher.publish()`` method first -calls its Reader, which reads data from its source I/O, parses and -transforms the data, and returns it. ``Publisher.publish()`` then -passes the resulting document tree to its Writer, which further -transforms the document before translating it to the final output -format and writing the formatted data to its destination I/O. +several convenience functions: "publish_cmdline()" (for command-line +front ends), "publish_file()" (for programmatic use with file-like +I/O), and "publish_string()" (for programmatic use with string I/O). +The Publisher class encapsulates the high-level logic of a Docutils +system. The Publisher class has overall responsibility for +processing, controlled by the ``Publisher.publish()`` method: + +1. Set up internal settings (may include config files & command-line + options) and I/O objects. + +2. Call the Reader object to read data from the source Input object + and parse the data with the Parser object. A document object is + returned. + +3. Set up and apply transforms via the Transformer object attached to + the document. + +4. Call the Writer object which translates the document to the final + output format and writes the formatted data to the destination + Output object. Depending on the Output object, the output may be + returned from the Writer, and then from the ``publish()`` method. Calling the "publish" function (or instantiating a "Publisher" object) with component names will result in default behavior. For custom behavior (customizing component settings), create custom component -objects first, and pass *them* to publish/Publisher. +objects first, and pass *them* to the Publisher or ``publish_*`` +convenience functions. Readers @@ -104,9 +106,6 @@ Readers Readers understand the input context (where the data is coming from), send the whole input or discrete "chunks" to the parser, and provide the context to bind the chunks together back into a cohesive whole. -Using transforms_, Readers also resolve references, footnote numbers, -interpreted text processing, and anything else that requires -context-sensitive computation. Each reader is a module or package exporting a "Reader" class with a "read" method. The base "Reader" class can be found in the @@ -118,40 +117,40 @@ still incomplete) will be able to determine the parser on its own. Responsibilities: -- Get input text from the source I/O. +* Get input text from the source I/O. -- Pass the input text to the parser, along with a fresh doctree root. - -- Run transforms over the doctree(s). +* Pass the input text to the parser, along with a fresh `document + tree`_ root. Examples: -- Standalone (Raw/Plain): Just read a text file and process it. +* Standalone (Raw/Plain): Just read a text file and process it. The reader needs to be told which parser to use. The "Standalone Reader" has been implemented in module ``docutils.readers.standalone``. -- Python Source: See `Python Source Reader`_ below. This Reader is +* Python Source: See `Python Source Reader`_ below. This Reader is currently in development in the Docutils sandbox. -- Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. +* Email: RFC-822 headers, quoted excerpts, signatures, MIME parts. -- PEP: RFC-822 headers, "PEP xxxx" and "RFC xxxx" conversion to URIs. +* PEP: RFC-822 headers, "PEP xxxx" and "RFC xxxx" conversion to URIs. The "PEP Reader" has been implemented in module ``docutils.readers.pep``; see PEP 287 and PEP 12. -- Wiki: Global reference lookups of "wiki links" incorporated into +* Wiki: Global reference lookups of "wiki links" incorporated into transforms. (CamelCase only or unrestricted?) Lazy indentation? -- Web Page: As standalone, but recognize meta fields as meta tags. +* Web Page: As standalone, but recognize meta fields as meta tags. Support for templates of some sort? (After ``<body>``, before ``</body>``?) -- FAQ: Structured "question & answer(s)" constructs. +* FAQ: Structured "question & answer(s)" constructs. -- Compound document: Merge chapters into a book. Master TOC file? +* Compound document: Merge chapters into a book. Master manifest + file? Parsers @@ -172,56 +171,78 @@ Example: The only parser implemented so far is for the reStructuredText markup. It is implemented in the ``docutils/parsers/rst/`` package. +The development and integration of other parsers is possible and +encouraged. -Transforms ----------- -Transforms are applied to the document tree to change it from one form -to another, to add to the tree, or to prune it. Transforms are -applied by Reader and Writer objects. Some transforms are -Reader-specific, some are Parser-specific, and others are -Writer-specific. The choice and order of transforms is specified in -the Reader and Writer objects. +.. _transforms: + +Transformer +----------- + +The Transformer class, in ``docutils/transforms/__init__.py``, stores +transforms and applies them to documents. A transformer object is +attached to every new document tree. The Publisher_ calls +``Transformer.apply_transforms()`` to apply all stored transforms to +the document tree. Transforms change the document tree from one form +to another, add to the tree, or prune it. Transforms resolve +references and footnote numbers, processing interpreted text, and do +other context-sensitive processing. + +Some transforms are specific to components (Readers, Parser, Writers, +Input, Output). Standard component-specific transforms are specified +in the ``default_transforms`` attribute of component classes. After +the Reader has finished processing, the Publisher_ calls the +Transformer object's "populate_from_components" method with a list of +components. Each transform is a class in a module in the ``docutils/transforms/`` -package, a subclass of docutils.tranforms.Transform. +package, a subclass of ``docutils.tranforms.Transform``. Transform +classes each have a ``default_priority`` attribute which is used by +the Transformer to apply transforms in order. The default priority +can be overridden when adding transforms to the Transformer object. -Responsibilities: +Transformer responsibilities: + +* Apply transforms to the document tree, in priority order. + +* Store a mapping of component type name ('reader', 'writer', etc.) to + component objects. These are used by certain transforms (such as + "components.Filter") to determine suitability. + +Transform responsibilities: -- Modify a doctree in-place, either purely transforming one structure +* Modify a doctree in-place, either purely transforming one structure into another, or adding new structures based on the doctree and/or external data. -Examples (in the ``docutils/transforms/`` package): +Examples of transforms (in the ``docutils/transforms/`` package): -- frontmatter.DocInfo: Conversion of document metadata (bibliographic +* frontmatter.DocInfo: Conversion of document metadata (bibliographic information). -- references.Hyperlinks: Resolution of hyperlinks. +* references.AnonymousHyperlinks: Resolution of anonymous references + to corresponding targets. -- parts.Contents: Generates a table of contents for a document. +* parts.Contents: Generates a table of contents for a document. -- document.Merger: Combining multiple populated doctrees into one (not - yet implemented or fully understood). +* document.Merger: Combining multiple populated doctrees into one. + (Not yet implemented or fully understood.) -- document.Splitter: Splits a document into a tree-structure of +* document.Splitter: Splits a document into a tree-structure of subdocuments, perhaps by section. It will have to transform references appropriately. (Neither implemented not remotely understood.) -- universal.Pending: Handles transforms that must be executed at - specific stages of processing. - -- components.Filter: Includes or excludes elements which depend on a - specific Docutils component (triggered by the universal.Pending - transform). +* components.Filter: Includes or excludes elements which depend on a + specific Docutils component. Writers ------- Writers produce the final output (HTML, XML, TeX, etc.). Writers -translate the internal document tree structure into the final data +translate the internal `document tree`_ structure into the final data format, possibly running Writer-specific transforms_ first. By the time the document gets to the Writer, it should be in final @@ -236,34 +257,34 @@ Each writer is a module or package exporting a "Writer" class with a Responsibilities: -- Translate doctree(s) into specific output formats. +* Translate doctree(s) into specific output formats. - Transform references into format-native forms. -- Write the translated output to the destination I/O. +* Write the translated output to the destination I/O. Examples: -- XML: Various forms, such as: +* XML: Various forms, such as: - - DocBook (being implemented in the Docutils sandbox). + - Docutils XML (an expression of the internal document tree, + implemented as ``docutils.writers.docutils_xml``). - - Raw doctree XML (accessible via "``doctree.asdom().toxml()``"; no - Writer component implemented yet). + - DocBook (being implemented in the Docutils sandbox). -- HTML (XHTML implemented as ``docutils.writers.html4css1``). +* HTML (XHTML implemented as ``docutils.writers.html4css1``). -- PDF (a ReportLabs interface is being developed in the Docutils +* PDF (a ReportLabs interface is being developed in the Docutils sandbox). -- TeX +* TeX (a LaTeX Writer is being implemented in the sandbox). -- Docutils-native pseudo-XML (implemented as +* Docutils-native pseudo-XML (implemented as ``docutils.writers.pseudoxml``, used for testing). -- Plain text +* Plain text -- reStructuredText? +* reStructuredText? Input/Output @@ -271,69 +292,78 @@ Input/Output I/O classes provide a uniform API for low-level input and output. Subclasses will exist for a variety of input/output mechanisms. +However, they can be considered an implementation detail. Most +applications should be satisfied using one of the convenience +functions associated with the Publisher_. I/O classes are currently in the preliminary stages; there's a lot of work yet to be done. Issues: -- Looking at the list of writers, it seems that only HTML would - require anything other than monolithic output. Perhaps "Writer" - variants, one for each output distribution type? +* How to represent multi-file input (files & directories) in the API? -- How to represent a multi-file document (files & directories) in the - API? +* How to represent multi-file output? Perhaps "Writer" variants, one + for each output distribution type? Or Output objects with + associated transforms? Responsibilities: -- Read data from the input source and/or write data to the output - destination. +* Read data from the input source (Input objects) or write data to the + output destination (Output objects). Examples of input sources: -- A single file on disk or a stream (implemented as +* A single file on disk or a stream (implemented as ``docutils.io.FileInput``). -- Multiple files on disk (``MultiFileInput``?). +* Multiple files on disk (``MultiFileInput``?). -- Python source files: modules and packages. +* Python source files: modules and packages. -- Python strings, as received from a client application +* Python strings, as received from a client application (implemented as ``docutils.io.StringInput``). Examples of output destinations: -- A single file on disk or a stream (implemented as +* A single file on disk or a stream (implemented as ``docutils.io.FileOutput``). -- A tree of directories and files on disk. +* A tree of directories and files on disk. -- A Python string, returned to a client application (implemented as +* A Python string, returned to a client application (implemented as ``docutils.io.StringOutput``). -- A single tree-shaped data structure in memory. +* No output; useful for programmatic applications where only a portion + of the normal output is to be used (implemented as + ``docutils.io.NullOutput``). -- Some other set of data structures in memory. +* A single tree-shaped data structure in memory. + +* Some other set of data structures in memory. Docutils Package Structure ========================== -- Package "docutils". +* Package "docutils". - - Class "Component" is a base class for Docutils components. + - Module "__init__.py" contains: class "Component", a base class for + Docutils components; class "SettingsSpec", a base class for + specifying runtime settings (used by docutils.frontend); and class + "TransformSpec", a base class for specifying transforms. - Module "docutils.core" contains facade class "Publisher" and - convenience function "publish()". See `Publisher`_ above. + convenience functions. See `Publisher`_ above. - - Module "docutils.frontend" provides command-line and option - processing for Docutils front-end tools, and runtime settings - support for programmatic use. + - Module "docutils.frontend" provides runtime settings support, for + programmatic use and front-end tools (including configuration file + support, and command-line argument and option processing). - Module "docutils.io" provides a uniform API for low-level input and output. See `Input/Output`_ above. - Module "docutils.nodes" contains the Docutils document tree - element class library plus Visitor pattern base classes. See - `Document Tree`_ below. + element class library plus tree-traversal Visitor pattern base + classes. See `Document Tree`_ below. - Module "docutils.optik" provides option parsing and command-line help; from Greg Ward's http://optik.sf.net/ project, included for @@ -343,8 +373,9 @@ Docutils Package Structure routines. - Module "docutils.statemachine" contains a finite state machine - specialized for regular-expression-based text filters. The - reStructuredText parser implementation is based on this module. + specialized for regular-expression-based text filters and parsers. + The reStructuredText parser implementation is based on this + module. - Module "docutils.urischemes" contains a mapping of known URI schemes ("http", "ftp", "mail", etc.). @@ -378,7 +409,7 @@ Docutils Package Structure Proposals). - Readers to be added for: Python source code (structure & - docstrings), PEPs, email, FAQ, and perhaps Wiki and others. + docstrings), email, FAQ, and perhaps Wiki and others. See `Readers`_ above. @@ -388,20 +419,26 @@ Docutils Package Structure by name. Class "Writer" is the base class of specific writers. (``docutils/writers/__init__.py``) - - Module "docutils.writers.pseudoxml" is a simple internal - document tree writer; it writes indented pseudo-XML. - - Module "docutils.writers.html4css1" is a simple HyperText Markup Language document tree writer for HTML 4.01 and CSS1. + - Module "docutils.writers.docutils_xml" writes the internal + document tree in XML form. + + - Module "docutils.writers.pseudoxml" is a simple internal + document tree writer; it writes indented pseudo-XML. + - Writers to be added: HTML 3.2 or 4.01-loose, XML (various forms, - such as DocBook and the raw internal doctree), PDF, TeX, - plaintext, reStructuredText, and perhaps others. + such as DocBook), PDF, TeX, plaintext, reStructuredText, and + perhaps others. See `Writers`_ above. - Package "docutils.transforms": tree transform classes. + - Class "Transformer" stores transforms and applies them to + document trees. (``docutils/transforms/__init__.py``) + - Class "Transform" is the base class of specific transforms. (``docutils/transforms/__init__.py``) @@ -425,7 +462,8 @@ Docutils Package Structure Front-End Tools =============== -See `Docutils Front-End Tools`_. +The ``tools/`` directory contains several front ends for common +Docutils processing. See `Docutils Front-End Tools`_ for details. .. _Docutils Front-End Tools: http://docutils.sf.net/docs/tools.html @@ -435,31 +473,34 @@ Document Tree A single intermediate data structure is used internally by Docutils, in the interfaces between components; it is defined in the -docutils.nodes module. It is not required that this data structure be -used *internally* by any of the components, just *between* components. +``docutils.nodes`` module. It is not required that this data +structure be used *internally* by any of the components, just +*between* components as outlined in the diagram in the `Docutils +Project Model`_ above. Custom node types are allowed, provided that either (a) a transform converts them to standard Docutils nodes before they reach the Writer proper, or (b) the custom node is explicitly supported by certain Writers, and is wrapped in a filtered "pending" node. An example of -condition A is the `Python Source Reader`_ (see below), where a +condition (a) is the `Python Source Reader`_ (see below), where a "stylist" transform converts custom nodes. The HTML ``<meta>`` tag is -an example of condition B; it is supported by the HTML Writer but not -by others. The reStructuredText "meta" directive creates a "pending" -node, which contains knowledge that the embedded "meta" node can only -be handled by HTML-compatible writers. The "pending" node is resolved -by the "transforms.components.Filter" transform, which checks that the -calling writer supports HTML; if it doesn't, the "meta" node is -removed from the document. +an example of condition (b); it is supported by the HTML Writer but +not by others. The reStructuredText "meta" directive creates a +"pending" node, which contains knowledge that the embedded "meta" node +can only be handled by HTML-compatible writers. The "pending" node is +resolved by the ``docutils.transforms.components.Filter`` transform, +which checks that the calling writer supports HTML; if it doesn't, the +"pending" node (and enclosed "meta" node) is removed from the +document. The document tree data structure is similar to a DOM tree, but with specific node names (classes) instead of DOM's generic nodes. The schema is documented in an XML DTD (eXtensible Markup Language Document Type Definition), which comes in two parts: -- the Docutils Generic DTD, docutils.dtd_, and +* the Docutils Generic DTD, docutils.dtd_, and -- the OASIS Exchange Table Model, soextbl.dtd_. +* the OASIS Exchange Table Model, soextbl.dtd_. The DTD defines a rich set of elements, suitable for many input and output formats. The DTD retains all information necessary to @@ -476,23 +517,23 @@ When the parser encounters an error in markup, it inserts a system message (DTD element "system_message"). There are five levels of system messages: -- Level-0, "DEBUG": an internal reporting issue. There is no effect +* Level-0, "DEBUG": an internal reporting issue. There is no effect on the processing. Level-0 system messages are handled separately from the others. -- Level-1, "INFO": a minor issue that can be ignored. There is little +* Level-1, "INFO": a minor issue that can be ignored. There is little or no effect on the processing. Typically level-1 system messages are not reported. -- Level-2, "WARNING": an issue that should be addressed. If ignored, +* Level-2, "WARNING": an issue that should be addressed. If ignored, there may be minor problems with the output. Typically level-2 system messages are reported but do not halt processing -- Level-3, "ERROR": a major issue that should be addressed. If +* Level-3, "ERROR": a major issue that should be addressed. If ignored, the output will contain unpredictable errors. Typically level-3 system messages are reported but do not halt processing -- Level-4, "SEVERE": a critical error that must be addressed. +* Level-4, "SEVERE": a critical error that must be addressed. Typically level-4 system messages are turned into exceptions which halt processing. If ignored, the output will contain severe errors. @@ -520,11 +561,11 @@ Processing Model This model will evolve over time, incorporating experience and discoveries. -1. The PySource Reader uses an I/O class to read in some Python - packages and modules, into a tree of strings. +1. The PySource Reader uses an Input class to read in Python packages + and modules, into a tree of strings. 2. The Python modules are parsed, converting the tree of strings into - a tree of abstract syntax trees. + a tree of abstract syntax trees with docstring nodes. 3. The abstract syntax trees are converted into an internal representation of the packages/modules. Docstrings are extracted, @@ -535,7 +576,7 @@ discoveries. Docutils doctrees. 5. PySource assembles all the individual docstrings' doctrees into a - Python-specific custom Docutils tree parallelling the + Python-specific custom Docutils tree paralleling the package/module/class structure; this is a custom Reader-specific internal representation (see the `Docutils Python Source DTD`_). Namespaces must be merged: Python identifiers, hyperlink targets. @@ -544,37 +585,38 @@ discoveries. identifiers are resolved according to the Python namespace lookup rules. See `Identifier Cross-References`_ below. -7. A "Stylist" transform is applied to the custom doctree, custom - nodes are rendered using standard nodes as primitives, and a - standard document tree is emitted. See `Stylist Transforms`_ - below. +7. A "Stylist" transform is applied to the custom doctree (by the + Transformer_), custom nodes are rendered using standard nodes as + primitives, and a standard document tree is emitted. See `Stylist + Transforms`_ below. -8. Other transforms are applied to the standard doctree. +8. Other transforms are applied to the standard doctree by the + Transformer_. 9. The standard doctree is sent to a Writer, which translates the document into a concrete format (HTML, PDF, etc.). -10. The Writer uses an I/O class to write the resulting data to its +10. The Writer uses an Output class to write the resulting data to its destination (disk file, directories and files, etc.). AST Mining ---------- -Abstract Syntax Tree mining code will be written that scans a parsed -Python module, and returns an ordered tree containing the names, -docstrings (including attribute and additional docstrings; see below), -and additional info (in parentheses below) of all of the following -objects: - -- packages -- modules -- module attributes (+ initial values) -- classes (+ inheritance) -- class attributes (+ initial values) -- instance attributes (+ initial values) -- methods (+ parameters & defaults) -- functions (+ parameters & defaults) +Abstract Syntax Tree mining code will be written (or adapted) that +scans a parsed Python module, and returns an ordered tree containing +the names, docstrings (including attribute and additional docstrings; +see below), and additional info (in parentheses below) of all of the +following objects: + +* packages +* modules +* module attributes (+ initial values) +* classes (+ inheritance) +* class attributes (+ initial values) +* instance attributes (+ initial values) +* methods (+ parameters & defaults) +* functions (+ parameters & defaults) (Extract comments too? For example, comments at the start of a module would be a good place for bibliographic field lists.) @@ -582,7 +624,7 @@ would be a good place for bibliographic field lists.) In order to evaluate interpreted text cross-references, namespaces for each of the above will also be required. -See python-dev/docstring-develop thread "AST mining", started on +See the python-dev/docstring-develop thread "AST mining", started on 2001-08-14. @@ -595,12 +637,11 @@ Docstring Extraction Rules documented, only identifiers listed in "``__all__``" are examined for docstrings. - b) In the absense of "``__all__``", all identifiers are examined, + b) In the absence of "``__all__``", all identifiers are examined, except those whose names are private (names begin with "_" but don't begin and end with "__"). - c) 1a and 1b can be overridden by a parameter or command-line - option. + c) 1a and 1b can be overridden by runtime settings. 2. Where: @@ -619,7 +660,8 @@ Docstring Extraction Rules docstrings in (a) and (b) will be recognized, extracted, and concatenated. See `Additional Docstrings`_ below. - d) @@@ 2.2-style "properties" with attribute docstrings? + d) @@@ 2.2-style "properties" with attribute docstrings? Wait for + syntax? 3. How: @@ -632,7 +674,7 @@ Docstring Extraction Rules examine an imported module, such as comments and the order of definitions. - - Docstrings are to be recognized in places where the bytecode + - Docstrings are to be recognized in places where the byte-code compiler ignores string literal expressions (2b and 2c above), meaning importing the module will lose these docstrings. @@ -645,7 +687,7 @@ Docstring Extraction Rules limitations must be lived with. Since attribute docstrings and additional docstrings are ignored by -the Python bytecode compiler, no namespace pollution or runtime bloat +the Python byte-code compiler, no namespace pollution or runtime bloat will result from their use. They are not assigned to ``__doc__`` or to any other attribute. The initial parsing of a module may take a slight performance hit. @@ -657,7 +699,7 @@ Attribute Docstrings (This is a simplified version of PEP 224 [#PEP-224]_.) A string literal immediately following an assignment statement is -interpreted by the docstring extration machinery as the docstring of +interpreted by the docstring extraction machinery as the docstring of the target of the assignment statement, under the following conditions: @@ -669,7 +711,7 @@ conditions: b) At the top level of a class definition: a class attribute. c) At the top level of the "``__init__``" method definition of a - class: an instance attribute. + class: an instance attribute. (@@@ ``__new__`` methods?) Since each of the above contexts are at the top level (i.e., in the outermost suite of a definition), it may be necessary to place @@ -688,7 +730,7 @@ conditions: b) For context 1c above, the target must be of the form "``self.attrib``", where "``self``" matches the "``__init__``" method's first parameter (the instance parameter) and "attrib" - is a simple indentifier as in 3a. + is a simple identifier as in 3a. Blank lines may be used after attribute docstrings to emphasize the connection between the assignment and the docstring. @@ -715,25 +757,25 @@ Additional Docstrings Many programmers would like to make extensive use of docstrings for API documentation. However, docstrings do take up space in the -running program, so some of these programmers are reluctant to "bloat -up" their code. Also, not all API documentation is applicable to -interactive environments, where ``__doc__`` would be displayed. - -The docstring processing system's extraction tools will concatenate -all string literal expressions which appear at the beginning of a -definition or after a simple assignment. Only the first strings in -definitions will be available as ``__doc__``, and can be used for -brief usage text suitable for interactive sessions; subsequent string -literals and all attribute docstrings are ignored by the Python -bytecode compiler and may contain more extensive API information. +running program, so some programmers are reluctant to "bloat up" their +code. Also, not all API documentation is applicable to interactive +environments, where ``__doc__`` would be displayed. + +Docutils' docstring extraction tools will concatenate all string +literal expressions which appear at the beginning of a definition or +after a simple assignment. Only the first strings in definitions will +be available as ``__doc__``, and can be used for brief usage text +suitable for interactive sessions; subsequent string literals and all +attribute docstrings are ignored by the Python byte-code compiler and +may contain more extensive API information. Example:: def function(arg): """This is __doc__, function's docstring.""" """ - This is an additional docstring, ignored by the bytecode - compiler, but extracted by the Docutils. + This is an additional docstring, ignored by the byte-code + compiler, but extracted by Docutils. """ pass @@ -756,13 +798,13 @@ Example:: 1. Should we search for docstrings after a ``__future__`` statement? Very ugly. - 2. Redefine ``__future__`` statements to allow multiple preceeding + 2. Redefine ``__future__`` statements to allow multiple preceding string literals? 3. Or should we not even worry about this? There probably shouldn't be ``__future__`` statements in production code, after - all. Will modules with ``__future__`` statements simply have to - put up with the single-docstring limitation? + all. Perhaps modules with ``__future__`` statements will simply + have to put up with the single-docstring limitation. Choice of Docstring Format @@ -779,7 +821,8 @@ format being used, a case-insensitive string matching the input parser's module or package name (i.e., the same name as required to "import" the module or package), or a registered alias. If no ``__docformat__`` is specified, the default format is "plaintext" for -now; this may be changed to the standard format once determined. +now; this may be changed to the standard format if one is ever +established. The ``__docformat__`` string may contain an optional second field, separated from the format name (first field) by a single space: a @@ -821,17 +864,17 @@ when necessary. For example (using reStructuredText markup):: """ Extend `Storer.__init__()` to keep track of instances. - Keep count in `self.instances`, data in `self.data`. + Keep count in `Keeper.instances`, data in `self.data`. """ Storer.__init__(self) - self.instances += 1 + Keeper.instances += 1 self.data = [] """Store data in a list, most recent last.""" - def storedata(self, data): + def store_data(self, data): """ - Extend `Storer.storedata()`; append new `data` to a + Extend `Storer.store_data()`; append new `data` to a list (in `self.data`). """ self.data = data @@ -843,12 +886,12 @@ references to the definitions of the identifiers themselves. Stylist Transforms ------------------ -Stylist transforms are specialized transforms specific to a Reader. -The PySource Reader doesn't have to make any decisions as to style; it -just produces a logically constructed document tree, parsed and -linked, including custom node types. Stylist transforms understand -the custom nodes created by the Reader and convert them into standard -Docutils nodes. +Stylist transforms are specialized transforms specific to the PySource +Reader. The PySource Reader doesn't have to make any decisions as to +style; it just produces a logically constructed document tree, parsed +and linked, including custom node types. Stylist transforms +understand the custom nodes created by the Reader and convert them +into standard Docutils nodes. Multiple Stylist transforms may be implemented and one can be chosen at runtime (through a "--style" or "--stylist" command-line option). -- cgit v1.2.1 From f8c63e4e07ebdcf7c41888c4f9f3ffe4e701a7a3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 00:54:03 +0000 Subject: Added to project. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@855 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/transforms.txt | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 docs/ref/transforms.txt diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt new file mode 100644 index 000000000..92e85179c --- /dev/null +++ b/docs/ref/transforms.txt @@ -0,0 +1,113 @@ +===================== + Docutils Transforms +===================== + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + + +.. contents:: + + +For background about transforms and the Transformer object, see `PEP +258`_. + +.. _PEP 258: pep-0258.html#transformer + + +Transforms Listed in Priority Order +=================================== + +============================== ====================== ======== +Transform: module.Class Added By Priority +============================== ====================== ======== +references.Substitutions standalone (r) 220 + + pep (r) + +frontmatter.DocTitle standalone (r) 320 + +frontmatter.DocInfo standalone (r) 340 + +peps.Headers pep (r) 360 + +peps.Contents pep (r) 380 + +references.ChainedTargets standalone (r) 420 + + pep (r) + +references.AnonymousHyperlinks standalone (r) 440 + + pep (r) + +references.IndirectHyperlinks standalone (r) 460 + + pep (r) + +peps.TargetNotes pep (r) 520 + +references.TargetNotes peps.TargetNotes (t) 0 + + "target-notes" (d) 540 + +references.Footnotes standalone (r) 620 + + pep (r) + +references.ExternalTargets standalone (r) 640 + + pep (r) + +references.InternalTargets standalone (r) 660 + + pep (r) + +parts.SectNum "sectnum" (d) 710 + +parts.Contents "contents" (d) 720 + + peps.Contents (t) + +peps.PEPZero pep.Headers (t) 760 + +components.Filter "meta" (d) 780 + +universal.Decorations all Readers 820 + +universal.FinalChecks all Writers 840 + +universal.Messages all Writers 860 + +universal.TestMessages DocutilsTestSupport 890 +============================== ====================== ======== + +Legend: + +* (r): Reader +* (d): Directive +* (t): Transform + + +Transform Priority Range Categories +=================================== + +==== ==== ================================================ + Priority Category +---------- ------------------------------------------------ +From To +==== ==== ================================================ + 0 immediate execution (added by another transform) +---------- ------------------------------------------------ + 1 99 unused + 100 199 very early (non-standard) + 200 299 very early + 300 399 early + 400 699 main + 700 799 late + 800 899 very late + 900 999 very late (non-standard) +==== ==== ================================================ -- cgit v1.2.1 From a714d9a65946eaec2c775e27e24159ce65ce10a1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 01:01:53 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@856 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 44 +++++++--- docs/dev/todo.txt | 98 +--------------------- docs/ref/rst/restructuredtext.txt | 6 +- docutils/io.py | 9 +- docutils/parsers/rst/__init__.py | 1 + docutils/parsers/rst/directives/html.py | 6 +- docutils/parsers/rst/directives/parts.py | 5 +- docutils/parsers/rst/directives/references.py | 2 +- .../test_rst/test_directives/test_contents.py | 7 -- .../test_rst/test_directives/test_meta.py | 40 ++++----- test/test_parsers/test_rst/test_tables.py | 80 ++++++++++++++++++ test/test_transforms/test_contents.py | 3 +- test/test_transforms/test_filter.py | 3 +- test/test_transforms/test_hyperlinks.py | 11 ++- test/test_transforms/test_messages.py | 2 +- test/test_transforms/test_sectnum.py | 5 +- 16 files changed, 167 insertions(+), 155 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 06cefe38b..1c65aba44 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -27,7 +27,8 @@ and related projects: Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, Tavis Rudd, Ollie Rutherfurd, Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van - Rossum, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka + Rossum, Greg Ward, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, + Moshe Zadka Thank you! @@ -67,7 +68,7 @@ Specific: - 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`` + - 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. @@ -76,6 +77,7 @@ Specific: - 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. * docutils/core.py: @@ -86,18 +88,22 @@ Specific: - 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. * docutils/frontend.py: - Check for & exit on identical source & destination paths. - - Fixed bug with absolute paths & ``--config``. + - 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`` option. + - Added "--expose-internal-attribute", "--dump-pseudo-xml", + "--dump-settings", and "--dump-transforms" hidden options. * docutils/io.py: @@ -140,6 +146,7 @@ Specific: - Added a "rawsource" attribute to the ``Text`` class, for text before backslash-escape resolution. - Support for new transform system. + - Reworked ``pending`` element. * docutils/statemachine.py: @@ -172,6 +179,10 @@ Specific: - Fixed a bug in ``relative_path()``. - Added support for improved diagnostics. +* docutils/parser/__init__.py: + + - Added ``Parser.finish_parse()`` method. + * docutils/parser/rst/__init__.py: - Added options: "--pep-references", "--rfc-references", @@ -207,6 +218,8 @@ Specific: - 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. @@ -242,6 +255,7 @@ Specific: - Added support for the observer pattern from ``utils.Reporter``, in ``Reader.parse`` and ``Reader.transform``. + - Removed ``Reader.transform()`` method. * docutils/readers/pep.py: @@ -252,7 +266,7 @@ Specific: * docutils/transforms/__init__.py: - - Added ``Transformer`` class. + - Added ``Transformer`` class and completed transform reform. * docutils/transforms/frontmatter.py: @@ -274,10 +288,16 @@ Specific: * docutils/transforms/references.py: - Added the ``TargetNotes`` generic transform. + - Split ``Hyperlinks`` into multiple transforms. * docutils/transforms/universal.py: - - Added support for the ``--expose-internal-attributes`` option. + - 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: @@ -313,6 +333,7 @@ Specific: - 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>. * docutils/writers/pep_html.py: @@ -384,6 +405,8 @@ Specific: * 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 @@ -430,8 +453,8 @@ Specific: * tools/buildhtml.py: - - Added ``--silent`` option. - - Fixed bug with absolute paths & ``--config``. + - 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. @@ -439,7 +462,7 @@ Specific: * tools/pep-html-template: - - Allow for ``--embed-stylesheet``. + - Allow for "--embed-stylesheet". - Added Docutils version to "generator" meta tag. - Updated for new ``publish_string()`` convenience function. @@ -455,7 +478,7 @@ Specific: * tools/quicktest.py: - - Added ``-V``/``--version`` option. + - Added "-V"/"--version" option. * tools/stylesheets/default.css: Moved into the stylesheets directory. @@ -470,6 +493,7 @@ Specific: - 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: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 7f42eab5d..e70026510 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -79,101 +79,6 @@ General * Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? -* @@@ Transforms need a priority system. The "first reader" ... - "last writer" system is no longer adequate for pending transforms. - For example, the ``references.TargetNotes`` transform needs to run - after ``references.Hyperlinks.resolve_indirect()`` but before - ``references.Footnotes``. - - Ideas: - - - Add a ``Transformer`` class that registers and executes - transforms. - - - Class contains a queue, with entries ``(priority, transform, - pending=None)``. - - - Perhaps ``Transformer.add_transform(transform, priority=None)``, - where ``priority`` can be used to override the transform class' - ``default_priority`` class attribute (used if ``None``). - - - Perhaps a ``Transformer.add_transforms(transform_list)`` method - for quick population. ``docutils.Component`` could be the host - for the ``default_transforms`` class attribute and an - ``add_transforms()`` method. - - - The ``Transformer`` class could host all universal transforms in - its ``default_transforms`` attribute. - - - How to handle ``pending`` elements? Perhaps a - ``Transformer.add_pending(pending, priority=None)`` method? - Just call it from ``nodes.document.note_pending()``. Need to - re-sort the queue whenever a new transform is added. - - - Who creates a ``Transformer`` object? Attach it to the - ``document`` object? Needs to be accessible when instantiating - other components? Or when "runtime initializing" them? - - a) ``core.Publisher`` creates a ``Transformer`` object, - initializes it from components (reader, parser, writer, - source, destination), and attaches it to ``document`` (via - ``settings``]?). - - b) ``document`` is given a ``Transformer`` object - (``document.transformer``) in ``utils.new_document``. - ``Publisher`` populates ``document.transformer`` from - components after the ``self.reader.read`` call returns (be - sure to use ``self.reader.parser``, not ``self.parser``). - ``document.transformer.apply_all`` is called before - ``self.writer.write``. - - - Should components initialize the ``Transformer`` object (add - ``self.add_transforms()`` calls to components' ``__init__``), or - should the ``Transformer`` initialize itself, accessing the - transform lists of the components? - - - Pass a ``Transformer`` object at component instantiation time? - - - Transform classes can have ``priority`` class attributes. - Each transform could have a unique priority. Use a look-up table? - No, that would require too many imports to construct. - - - Priorities can be numeric. Integers (0..100? 0..999? - 100..999? 0..9999?)? Floats (would be easier to squeeze in new - ones)? - - - Priorities can be strings. Numeric (000..999? 100..999? - 0000..9999?)? Alphanumeric (a..z? 1, 1a, 1b, ...?)? - - - Document transform priorities. - - Updated project dataflow model under consideration for PEP 258:: - - +---------------------------+ - | Docutils: | - | docutils.core.Publisher, | - | docutils.core.publish_*() | - +---------------------------+ - / | \ - / | \ - 1,3,5 / 6 | \ 7 - +--------+ +-------------+ +--------+ - | READER | ----> | TRANSFORMER | ====> | WRITER | - +--------+ +-------------+ +--------+ - / \\ | - / \\ | - 2 / 4 \\ 8 | - +-------+ +--------+ +--------+ - | INPUT | | PARSER | | OUTPUT | - +-------+ +--------+ +--------+ - -* @@@ Break up ``references.Hyperlinks`` into multiple smaller - transforms. - -* Make it easier to say, "Here's a reStructuredText string; give me - HTML." Maybe ``core.publish_string()``; rename ``core.publish`` to - ``core.publish_file()``? - * Standalone Reader: Implement an option to turn off the DocTitle transform? @@ -487,6 +392,9 @@ Miscellaneous ideas: vice-versa: backlinks from the colorized source files to the API docs! +* In summaries, use the first *sentence* of a docstring if the first + line is not followed by a blank line. + reStructuredText Parser ----------------------- diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 642aace28..00445956c 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1254,9 +1254,9 @@ Simple Tables Simple tables provide a compact and easy to type but limited row-oriented table representation for simple data sets. Cell contents are typically single paragraphs, although arbitrary body elements may -be represented in most cells. Simple tables allow multi-line rows and -column spans, but not row spans. See `Grid Tables`_ above for a -complete table representation. +be represented in most cells. Simple tables allow multi-line rows (in +all but the first column) and column spans, but not row spans. See +`Grid Tables`_ above for a complete table representation. Simple tables are described with horizontal borders made up of "=" and "-" characters. The equals sign ("=") is used for top and bottom diff --git a/docutils/io.py b/docutils/io.py index 02f392460..de8af4582 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -13,14 +13,17 @@ __docformat__ = 'reStructuredText' import sys import locale +from docutils import TransformSpec -class Input: +class Input(TransformSpec): """ Abstract base class for input wrappers. """ + component_type = 'input' + default_source_path = None def __init__(self, settings, source=None, source_path=None): @@ -84,12 +87,14 @@ class Input: % ', '.join([repr(enc) for enc in encodings if enc])) -class Output: +class Output(TransformSpec): """ Abstract base class for output wrappers. """ + component_type = 'output' + default_destination_path = None def __init__(self, settings, destination=None, destination_path=None): diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 82e8c59af..ad60a319d 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -90,3 +90,4 @@ class Parser(docutils.parsers.Parser): inputstring, tab_width=document.settings.tab_width, convert_whitespace=1) self.statemachine.run(inputlines, document, inliner=self.inliner) + self.finish_parse() diff --git a/docutils/parsers/rst/directives/html.py b/docutils/parsers/rst/directives/html.py index 88675c284..a6e656994 100644 --- a/docutils/parsers/rst/directives/html.py +++ b/docutils/parsers/rst/directives/html.py @@ -60,8 +60,10 @@ class MetaBody(states.SpecializedBody): indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) node = self.meta() - pending = nodes.pending(components.Filter, 'first writer', - {'writer': 'html', 'nodes': [node]}) + pending = nodes.pending(components.Filter, + {'component': 'writer', + 'format': 'html', + 'nodes': [node]}) node['content'] = ' '.join(indented) if not indented: line = self.state_machine.line diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 9512b835d..e4ca8d3df 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -34,8 +34,7 @@ def contents(name, arguments, options, content, lineno, else: messages = [] title = None - pending = nodes.pending(parts.Contents, 'first writer', {'title': title}, - block_text) + pending = nodes.pending(parts.Contents, {'title': title}, block_text) pending.details.update(options) state_machine.document.note_pending(pending) return [pending] + messages @@ -48,7 +47,7 @@ contents.options = {'depth': directives.nonnegative_int, def sectnum(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Automatic section numbering.""" - pending = nodes.pending(parts.SectNum, 'last reader', {}) + pending = nodes.pending(parts.SectNum) pending.details.update(options) state_machine.document.note_pending(pending) return [pending] diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py index 815bc1477..92966140f 100644 --- a/docutils/parsers/rst/directives/references.py +++ b/docutils/parsers/rst/directives/references.py @@ -17,7 +17,7 @@ from docutils.transforms import references def target_notes(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Target footnote generation.""" - pending = nodes.pending(references.TargetNotes, 'first reader', {}) + pending = nodes.pending(references.TargetNotes) state_machine.document.note_pending(pending) nodelist = [pending] return nodelist diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index fbd7c517c..de5913708 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -28,7 +28,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: title: None """], @@ -40,7 +39,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: title: <title> @@ -55,7 +53,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: title: <title> @@ -71,7 +68,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: title: <title> @@ -87,7 +83,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: title: <title> @@ -107,7 +102,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: depth: 2 local: None @@ -139,7 +133,6 @@ totest['contents'] = [ <pending> .. internal attributes: .transform: docutils.transforms.parts.Contents - .stage: 'first writer' .details: backlinks: None depth: 2 diff --git a/test/test_parsers/test_rst/test_directives/test_meta.py b/test/test_parsers/test_rst/test_directives/test_meta.py index 9e2e29232..ecfedd721 100755 --- a/test/test_parsers/test_rst/test_directives/test_meta.py +++ b/test/test_parsers/test_rst/test_directives/test_meta.py @@ -30,19 +30,19 @@ totest['meta'] = [ <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="The reStructuredText plaintext markup language" name="description"> - writer: 'html' <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="plaintext,markup language" name="keywords"> - writer: 'html' """], ["""\ .. meta:: @@ -54,19 +54,19 @@ totest['meta'] = [ <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="An amusing story" lang="en" name="description"> - writer: 'html' <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="Un histoire amusant" lang="fr" name="description"> - writer: 'html' """], ["""\ .. meta:: @@ -77,11 +77,11 @@ totest['meta'] = [ <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"> - writer: 'html' """], ["""\ .. meta:: @@ -93,11 +93,11 @@ totest['meta'] = [ <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="content over multiple lines" name="name"> - writer: 'html' """], ["""\ Paragraph @@ -112,11 +112,11 @@ Paragraph <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="content" name="name"> - writer: 'html' """], ["""\ .. meta:: @@ -165,11 +165,11 @@ Paragraph <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="content" name="name"> - writer: 'html' <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Invalid meta directive. @@ -190,19 +190,19 @@ Paragraph <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="content" name="name"> - writer: 'html' <pending> .. internal attributes: .transform: docutils.transforms.components.Filter - .stage: 'first writer' .details: + component: 'writer' + format: 'html' nodes: <meta content="content" name="name"> - writer: 'html' <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Invalid meta directive. diff --git a/test/test_parsers/test_rst/test_tables.py b/test/test_parsers/test_rst/test_tables.py index c188a4214..d0d1d1317 100755 --- a/test/test_parsers/test_rst/test_tables.py +++ b/test/test_parsers/test_rst/test_tables.py @@ -1063,6 +1063,86 @@ A table with many row separators. <entry> <entry> """], +["""\ +== =========== =========== +1 Span columns 2 & 3 +-- ------------------------ +2 Span columns 2 & 3 + ------------------------ +3 +== =========== =========== + +== =========== =========== +1 Span cols 1&2 but not 3 +--------------- ----------- +2 Span cols 1&2 but not 3 +--------------- +3 no spans here +== =========== =========== + +== =========== =========== +1 Not a span Not a span + ----------- ----------- +2 +== =========== =========== +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Malformed table. + Text in column margin at line offset 3. + <literal_block xml:space="preserve"> + == =========== =========== + 1 Span columns 2 & 3 + -- ------------------------ + 2 Span columns 2 & 3 + ------------------------ + 3 + == =========== =========== + <system_message level="3" line="9" source="test data" type="ERROR"> + <paragraph> + Malformed table. + Column span incomplete at line offset 4. + <literal_block xml:space="preserve"> + == =========== =========== + 1 Span cols 1&2 but not 3 + --------------- ----------- + 2 Span cols 1&2 but not 3 + --------------- + 3 no spans here + == =========== =========== + <table> + <tgroup cols="3"> + <colspec colwidth="2"> + <colspec colwidth="11"> + <colspec colwidth="11"> + <tbody> + <row> + <entry> + <paragraph> + 1 + <entry> + <system_message level="4" line="20" source="test data" type="SEVERE"> + <paragraph> + Unexpected section title. + <literal_block xml:space="preserve"> + Not a span + ----------- + <entry> + <system_message level="4" line="20" source="test data" type="SEVERE"> + <paragraph> + Unexpected section title. + <literal_block xml:space="preserve"> + Not a span + ----------- + <row> + <entry> + <paragraph> + 2 + <entry> + <entry> +"""], ] diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 8618f4a20..024d5ee4c 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -12,7 +12,6 @@ Tests for `docutils.transforms.parts.Contents` (via """ from __init__ import DocutilsTestSupport -from docutils.transforms.universal import LastReaderPending, FirstWriterPending from docutils.transforms.references import Substitutions from docutils.parsers.rst import Parser @@ -25,7 +24,7 @@ def suite(): totest = {} -totest['tables_of_contents'] = ((Substitutions, FirstWriterPending), [ +totest['tables_of_contents'] = ((Substitutions,), [ ["""\ .. contents:: diff --git a/test/test_transforms/test_filter.py b/test/test_transforms/test_filter.py index 53b3246cb..009600d81 100644 --- a/test/test_transforms/test_filter.py +++ b/test/test_transforms/test_filter.py @@ -11,7 +11,6 @@ Tests for docutils.transforms.components.Filter. """ from __init__ import DocutilsTestSupport -from docutils.transforms.universal import FirstWriterPending from docutils.parsers.rst import Parser @@ -23,7 +22,7 @@ def suite(): totest = {} -totest['meta'] = ((FirstWriterPending,), [ +totest['meta'] = ((), [ ["""\ .. meta:: :description: The reStructuredText plaintext markup language diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 6fd3c1d5c..89cf6c946 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -11,7 +11,8 @@ Tests for docutils.transforms.references.Hyperlinks. """ from __init__ import DocutilsTestSupport -from docutils.transforms.references import Hyperlinks +from docutils.transforms.references import ChainedTargets, \ + AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, InternalTargets from docutils.parsers.rst import Parser @@ -25,7 +26,9 @@ totest = {} # Exhaustive listing of hyperlink variations: every combination of # target/reference, direct/indirect, internal/external, and named/anonymous. -totest['exhaustive_hyperlinks'] = ((Hyperlinks,), [ +totest['exhaustive_hyperlinks'] = ((ChainedTargets, AnonymousHyperlinks, + IndirectHyperlinks, ExternalTargets, + InternalTargets,), [ ["""\ direct_ external @@ -226,7 +229,9 @@ __ ztarget_ """], ]) -totest['hyperlinks'] = ((Hyperlinks,), [ +totest['hyperlinks'] = ((ChainedTargets, AnonymousHyperlinks, + IndirectHyperlinks, ExternalTargets, + InternalTargets,), [ ["""\ .. _internal hyperlink: diff --git a/test/test_transforms/test_messages.py b/test/test_transforms/test_messages.py index 60c768f76..75325bc96 100755 --- a/test/test_transforms/test_messages.py +++ b/test/test_transforms/test_messages.py @@ -24,7 +24,7 @@ def suite(): totest = {} -totest['system_message_sections'] = ((Substitutions, Messages,), [ +totest['system_message_sections'] = ((Substitutions, Messages), [ ["""\ This |unknown substitution| will generate a system message, thanks to the ``Substitutions`` transform. The ``Messages`` transform will diff --git a/test/test_transforms/test_sectnum.py b/test/test_transforms/test_sectnum.py index c4d275539..543deac16 100644 --- a/test/test_transforms/test_sectnum.py +++ b/test/test_transforms/test_sectnum.py @@ -12,8 +12,6 @@ Tests for `docutils.transforms.parts.SectNum` (via """ from __init__ import DocutilsTestSupport -from docutils.transforms.universal import LastReaderPending, \ - FirstWriterPending from docutils.transforms.references import Substitutions from docutils.parsers.rst import Parser @@ -26,8 +24,7 @@ def suite(): totest = {} -totest['section_numbers'] = ((Substitutions, LastReaderPending, - FirstWriterPending), [ +totest['section_numbers'] = ((Substitutions,), [ ["""\ .. sectnum:: -- cgit v1.2.1 From 35a1beda765cd44715a9ea7c4064d71b1abbcf1e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 23:33:52 +0000 Subject: minor updates & fixes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@859 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- docs/dev/todo.txt | 5 ++- docs/howto/rst-directives.txt | 10 ++---- docs/peps/pep-0256.txt | 4 +-- docs/peps/pep-0258.txt | 8 ++--- docs/peps/pep-0287.txt | 2 +- docs/ref/transforms.txt | 76 ++++++++++++++++++------------------------- docutils/core.py | 4 +-- docutils/transforms/peps.py | 7 ++-- setup.py | 3 +- 10 files changed, 53 insertions(+), 68 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 1c65aba44..46404e757 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -25,7 +25,7 @@ and related projects: Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, Edward Loper, Dallas Mahrt, Ken Manheimer, Skip Montanaro, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, - Tavis Rudd, Ollie Rutherfurd, Kenichi Sato, Ueli Schlaepfer, + Tavis Rudd, Oliver Rutherfurd, Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van Rossum, Greg Ward, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e70026510..f198f9560 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -296,9 +296,8 @@ Implementation Docs - Transforms -* Document the ``pending`` elements, how they're generated and when - they're triggered ("first reader", "last writer", etc.; priority - system due to be reworked, as noted above). +* Document the ``pending`` elements, how they're generated and what + they do. * Document the transforms (perhaps in docstrings?): how they're used, what they do, dependencies & order considerations. diff --git a/docs/howto/rst-directives.txt b/docs/howto/rst-directives.txt index 5e30e4334..377ca31ad 100644 --- a/docs/howto/rst-directives.txt +++ b/docs/howto/rst-directives.txt @@ -313,8 +313,8 @@ code:: else: messages = [] title = None - pending = nodes.pending(parts.Contents, 'first writer', - {'title': title}, block_text) + pending = nodes.pending(parts.Contents, {'title': title}, + block_text) pending.details.update(options) state_machine.document.note_pending(pending) return [pending] + messages @@ -345,8 +345,4 @@ Aspects of note include: options, effectively communicating the options forward. The actual table of contents processing is performed by a transform, ``docutils.transforms.parts.Contents``, after the rest of the - document has been parsed. [#]_ - -.. [#] Please note that the priority system for transforms, indicated - above by ``'first writer'`` in the call to the ``nodes.pending`` - class, is due for an overhaul. + document has been parsed. diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index 8dc00f72e..198ebd9d8 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -34,8 +34,8 @@ The concepts of a DPS framework are presented independently of implementation details. -Roadmap to the Doctring PEPs -============================ +Road Map to the Doctring PEPs +============================= There are many aspects to docstring processing. The "Docstring PEPs" have broken up the issues in order to deal with each of them in diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index e7df5dc04..1a0968ecf 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -20,7 +20,7 @@ This PEP documents design issues and implementation details for Docutils, a Python Docstring Processing System (DPS). The rationale and high-level concepts of a DPS are documented in PEP 256, "Docstring Processing System Framework" [#PEP-256]_. Also see PEP 256 for a -"Roadmap to the Docstring PEPs". +"Road Map to the Docstring PEPs". Docutils is being designed modularly so that any of its components can be replaced easily. In addition, Docutils is not limited to the @@ -192,9 +192,9 @@ other context-sensitive processing. Some transforms are specific to components (Readers, Parser, Writers, Input, Output). Standard component-specific transforms are specified in the ``default_transforms`` attribute of component classes. After -the Reader has finished processing, the Publisher_ calls the -Transformer object's "populate_from_components" method with a list of -components. +the Reader has finished processing, the Publisher_ calls +``Transformer.populate_from_components()`` with a list of components +and all default transforms are stored. Each transform is a class in a module in the ``docutils/transforms/`` package, a subclass of ``docutils.tranforms.Transform``. Transform diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 4b4ed4e44..af790a53e 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -25,7 +25,7 @@ what-you-see-is-what-you-get plaintext markup syntax. Only the low-level syntax of docstrings is addressed here. This PEP is not concerned with docstring semantics or processing at all (see -PEP 256 for a "Roadmap to the Doctring PEPs"). Nor is it an attempt +PEP 256 for a "Road Map to the Doctring PEPs"). Nor is it an attempt to deprecate pure plaintext docstrings, which are always going to be legitimate. The reStructuredText markup is an alternative for those who want more expressive docstrings. diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 92e85179c..a5564f042 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -21,84 +21,70 @@ For background about transforms and the Transformer object, see `PEP Transforms Listed in Priority Order =================================== -============================== ====================== ======== -Transform: module.Class Added By Priority -============================== ====================== ======== -references.Substitutions standalone (r) 220 +============================== ============================ ======== +Transform: module.Class Added By Priority +============================== ============================ ======== +references.Substitutions standalone (r), pep (r) 220 - pep (r) +frontmatter.DocTitle standalone (r) 320 -frontmatter.DocTitle standalone (r) 320 +frontmatter.DocInfo standalone (r) 340 -frontmatter.DocInfo standalone (r) 340 +peps.Headers pep (r) 360 -peps.Headers pep (r) 360 +peps.Contents pep (r) 380 -peps.Contents pep (r) 380 +references.ChainedTargets standalone (r), pep (r) 420 -references.ChainedTargets standalone (r) 420 +references.AnonymousHyperlinks standalone (r), pep (r) 440 - pep (r) +references.IndirectHyperlinks standalone (r), pep (r) 460 -references.AnonymousHyperlinks standalone (r) 440 +peps.TargetNotes pep (r) 520 - pep (r) +references.TargetNotes peps.TargetNotes (t/p) 0 -references.IndirectHyperlinks standalone (r) 460 +references.TargetNotes "target-notes" (d/p) 540 - pep (r) +references.Footnotes standalone (r), pep (r) 620 -peps.TargetNotes pep (r) 520 +references.ExternalTargets standalone (r), pep (r) 640 -references.TargetNotes peps.TargetNotes (t) 0 +references.InternalTargets standalone (r), pep (r) 660 - "target-notes" (d) 540 +parts.SectNum "sectnum" (d/p) 710 -references.Footnotes standalone (r) 620 +parts.Contents "contents" (d/p), 720 + peps.Contents (t/p) - pep (r) +peps.PEPZero pep.Headers (t/p) 760 -references.ExternalTargets standalone (r) 640 +components.Filter "meta" (d/p) 780 - pep (r) +universal.Decorations Transformer 820 -references.InternalTargets standalone (r) 660 +universal.FinalChecks Transformer 840 - pep (r) +universal.Messages Transformer 860 -parts.SectNum "sectnum" (d) 710 +universal.TestMessages DocutilsTestSupport 890 +============================== ============================ ======== -parts.Contents "contents" (d) 720 - - peps.Contents (t) - -peps.PEPZero pep.Headers (t) 760 - -components.Filter "meta" (d) 780 - -universal.Decorations all Readers 820 - -universal.FinalChecks all Writers 840 - -universal.Messages all Writers 860 - -universal.TestMessages DocutilsTestSupport 890 -============================== ====================== ======== - -Legend: +Key: * (r): Reader * (d): Directive * (t): Transform +* (/p): Via a "pending" node Transform Priority Range Categories =================================== ==== ==== ================================================ - Priority Category + Priority ---------- ------------------------------------------------ -From To +From To Category ==== ==== ================================================ 0 immediate execution (added by another transform) ---------- ------------------------------------------------ diff --git a/docutils/core.py b/docutils/core.py index 14e794c7e..900498b9e 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -163,11 +163,11 @@ class Publisher: output = self.writer.write(document, self.destination) if self.settings.dump_settings: from pprint import pformat - print >>sys.stderr, '\n::: Docutils settings:' + print >>sys.stderr, '\n::: Runtime settings:' print >>sys.stderr, pformat(self.settings.__dict__) if self.settings.dump_internals: from pprint import pformat - print >>sys.stderr, '\n::: Docutils internals:' + print >>sys.stderr, '\n::: Document internals:' print >>sys.stderr, pformat(document.__dict__) if self.settings.dump_transforms: from pprint import pformat diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index db1cdf47f..fe82175b8 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -160,18 +160,21 @@ class TargetNotes(Transform): i = len(doc) - 1 refsect = copyright = None while i >= 0 and isinstance(doc[i], nodes.section): - if 'references' in doc[i][0].astext().lower().split(): + title_words = doc[i][0].astext().lower().split() + if 'references' in title_words: refsect = doc[i] break - if 'copyright' in doc[i][0].astext().lower().split(): + elif 'copyright' in title_words: copyright = i i -= 1 if not refsect: refsect = nodes.section() refsect += nodes.title('', 'References') 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) diff --git a/setup.py b/setup.py index 636619bb6..c58ab1725 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,8 @@ def do_setup(): 'docutils.transforms', 'docutils.languages', 'docutils.parsers', 'docutils.parsers.rst', 'docutils.parsers.rst.directives', - 'docutils.parsers.rst.languages']) + 'docutils.parsers.rst.languages'], + scripts = ['tools/html.py'] ) return dist if __name__ == '__main__' : -- cgit v1.2.1 From 1e65626e89a45d8790785c66aede0800c3f85804 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 24 Oct 2002 23:42:49 +0000 Subject: undo; oops git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@860 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index c58ab1725..636619bb6 100755 --- a/setup.py +++ b/setup.py @@ -17,8 +17,7 @@ def do_setup(): 'docutils.transforms', 'docutils.languages', 'docutils.parsers', 'docutils.parsers.rst', 'docutils.parsers.rst.directives', - 'docutils.parsers.rst.languages'], - scripts = ['tools/html.py'] ) + 'docutils.parsers.rst.languages']) return dist if __name__ == '__main__' : -- cgit v1.2.1 From 0e08813dff384af5edcd26e1cce8005f904f0cc7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 29 Oct 2002 03:49:35 +0000 Subject: Updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@865 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep2html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pep2html.py b/tools/pep2html.py index fe78026f4..6e031d72c 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -285,7 +285,7 @@ docutils_settings = None application when this module is imported.""" def fix_rst_pep(inpath, input_lines, outfile): - from docutils import core, io + from docutils import core output = core.publish_string( source=''.join(input_lines), source_path=inpath, -- cgit v1.2.1 From b35f28af244723b3fe955654857fcfb58e07d49b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 30 Oct 2002 02:28:42 +0000 Subject: Made "context" a parameter to ``StateMachine.run()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@866 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 63f35c741..19c357d06 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -172,7 +172,7 @@ class StateMachine: state.unlink() self.states = None - def run(self, input_lines, input_offset=0): + def run(self, input_lines, input_offset=0, context=None): """ Run the state machine on `input_lines`. Return results (a list). @@ -190,6 +190,7 @@ class StateMachine: - `input_lines`: a list of strings without newlines. - `input_offset`: the line offset of `input_lines` from the beginning of the file. + - `context`: application-specific storage. """ self.runtime_init() self.input_lines = input_lines @@ -199,7 +200,6 @@ class StateMachine: if self.debug: print >>sys.stderr, ('\nStateMachine.run: input_lines:\n| %s' % '\n| '.join(self.input_lines)) - context = None transitions = None results = [] state = self.get_state() -- cgit v1.2.1 From 2f2d626dab262d2fb0beae7a505b9d8b40cba68c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 30 Oct 2002 02:29:33 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@867 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 46404e757..285ce6b25 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -169,6 +169,7 @@ Specific: changes. - Added ``strip_top`` parameter to ``StateMachineWS.get_first_known_indented``. + - Made ``context`` a parameter to ``StateMachine.run()``. * docutils/utils.py: -- cgit v1.2.1 From d01273dd782b4d075ed6e29b6860819dad338490 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 31 Oct 2002 02:36:58 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@868 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 3e499b93b..870f90a6a 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -542,7 +542,7 @@ stylesheet (HTML Writer.) CSS stylesheet URL, used Default: "default.css". Options: ``--stylesheet``. -------------------- ------------------------------------------------ -stylesheet-path (HTML Writer.) Path to CSS stylesheet [#pwd]_. +stylesheet_path (HTML Writer.) Path to CSS stylesheet [#pwd]_. Overrides "stylesheet" URL option (``--stylesheet``). Path is adjusted relative to the output HTML file. -- cgit v1.2.1 From b4f387efe3f819802be5bdbcecc3e420f244a0b2 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 31 Oct 2002 02:38:00 +0000 Subject: Now flagged as errors: transitions at the beginning or end of sections, empty sections (except title), and empty documents. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@869 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 60 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 06c6cb1c1..ebfee3430 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -163,8 +163,16 @@ class RSTStateMachine(StateMachineWS): self.node = document results = StateMachineWS.run(self, input_lines, input_offset) assert results == [], 'RSTStateMachine.run() results should be empty!' + self.check_document() self.node = self.memo = None # remove unneeded references + def check_document(self): + """Check for illegal structure: empty document.""" + if len(self.document) == 0: + error = self.reporter.error( + 'Document empty; must have contents.', line=0) + self.document += error + class NestedStateMachine(StateMachineWS): @@ -344,27 +352,53 @@ class RSTState(StateWS): memo = self.memo mylevel = memo.section_level memo.section_level += 1 - sectionnode = nodes.section() - self.parent += sectionnode + section_node = nodes.section() + self.parent += section_node textnodes, title_messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) name = normalize_name(titlenode.astext()) - sectionnode['name'] = name - sectionnode += titlenode - sectionnode += messages - sectionnode += title_messages - self.document.note_implicit_target(sectionnode, sectionnode) + section_node['name'] = name + section_node += titlenode + section_node += messages + section_node += title_messages + self.document.note_implicit_target(section_node, section_node) offset = self.state_machine.line_offset + 1 absoffset = self.state_machine.abs_line_offset() + 1 newabsoffset = self.nested_parse( self.state_machine.input_lines[offset:], input_offset=absoffset, - node=sectionnode, match_titles=1) + node=section_node, match_titles=1) self.goto_line(newabsoffset) + self.check_section(section_node) if memo.section_level <= mylevel: # can't handle next section? raise EOFError # bubble up to supersection # reset section_level; next pass will detect it properly memo.section_level = mylevel + def check_section(self, section): + """ + Check for illegal structure: empty section, misplaced transitions. + """ + lineno = section.line + if len(section) <= 1: + error = self.reporter.error( + 'Section empty; must have contents.', line=lineno) + section += error + return + if not isinstance(section[0], nodes.title): # shouldn't ever happen + error = self.reporter.error( + 'First element of section must be a title.', line=lineno) + section.insert(0, error) + if isinstance(section[1], nodes.transition): + error = self.reporter.error( + 'Section may not begin with a transition.', + line=section[1].line) + section.insert(1, error) + if len(section) > 2 and isinstance(section[-1], nodes.transition): + error = self.reporter.error( + 'Section may not end with a transition.', + line=section[-1].line) + section += error + def paragraph(self, lines, lineno): """ Return a list (paragraph & messages) & a boolean: literal_block next? @@ -2446,31 +2480,35 @@ class Line(SpecializedText): if len(marker) < 4: self.state_correction(context) if self.eofcheck: # ignore EOFError with sections + lineno = self.state_machine.abs_line_number() - 1 transition = nodes.transition(context[0]) + transition.line = lineno self.parent += transition msg = self.reporter.error( 'Document or section may not end with a transition.', - line=self.state_machine.abs_line_number() - 1) + line=lineno) self.parent += msg self.eofcheck = 1 return [] def blank(self, match, context, next_state): """Transition marker.""" + lineno = self.state_machine.abs_line_number() - 1 marker = context[0].strip() if len(marker) < 4: self.state_correction(context) transition = nodes.transition(marker) + transition.line = lineno if len(self.parent) == 0: msg = self.reporter.error( 'Document or section may not begin with a transition.', - line=self.state_machine.abs_line_number() - 1) + line=lineno) self.parent += msg elif isinstance(self.parent[-1], nodes.transition): msg = self.reporter.error( 'At least one body element must separate transitions; ' 'adjacent transitions not allowed.', - line=self.state_machine.abs_line_number() - 1) + line=lineno) self.parent += msg self.parent += transition return [], 'Body', [] -- cgit v1.2.1 From 8dbfd4ae1deaa77beabe3af8fe87067f7650d535 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 31 Oct 2002 02:38:54 +0000 Subject: Added default parameter values to ``Reader.__init__()`` to make instantiation easier. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@870 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 2 +- docutils/readers/pep.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 413983777..b75db5159 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -29,7 +29,7 @@ class Reader(Component): component_type = 'reader' - def __init__(self, parser, parser_name): + def __init__(self, parser=None, parser_name='restructuredtext'): """ Initialize the Reader instance. diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 2c2715b0f..38d09f8c7 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -44,7 +44,7 @@ class Reader(standalone.Reader): settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} - def __init__(self, parser, parser_name): + def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" if parser is None: parser = rst.Parser(rfc2822=1, inliner=Inliner()) -- cgit v1.2.1 From 15e81d9c0111d33107133b79089a21561e398ed9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 31 Oct 2002 02:43:26 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@871 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 29 ++++++----- docs/dev/todo.txt | 22 ++++++-- docs/peps/pep-0258.txt | 5 +- .../test_rst/test_directives/test_include.py | 28 ++++++++++ test/test_parsers/test_rst/test_section_headers.py | 25 +++++++++ test/test_parsers/test_rst/test_transitions.py | 59 ++++++++++++++++++++++ 6 files changed, 149 insertions(+), 19 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 285ce6b25..47bc64170 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -17,18 +17,18 @@ on the Docutils project, knowingly or not, in terms of encouragement, suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: - Aahz, David Ascher, Fred Bremmer, Simon Budig, Brett Cannon, Adam - Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim Fulton, Peter - Funk, Jorge Gonzalez, Engelbert Gruber, Simon Hefti, Doug - Hellmann, Juergen Hermann, Jeremy Hylton, Tony Ibbs, Alan Jaffray, - Dmitry Jemerov, Richard Jones, Garth Kidd, Daniel Larsson, - Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, Edward Loper, - Dallas Mahrt, Ken Manheimer, Skip Montanaro, Paul Moore, Michel - Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, - Tavis Rudd, Oliver Rutherfurd, Kenichi Sato, Ueli Schlaepfer, - Gunnar Schwant, tav, Bob Tolbert, Laurence Tratt, Guido van - Rossum, Greg Ward, Barry Warsaw, Edward Welbourne, Ka-Ping Yee, - Moshe Zadka + Aahz, David Ascher, Fred Bremmer, Ian Bicking, Simon Budig, Brett + Cannon, Adam Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim + Fulton, Peter Funk, Jorge Gonzalez, Engelbert Gruber, Simon Hefti, + Doug Hellmann, Juergen Hermann, Jeremy Hylton, Tony Ibbs, Alan + Jaffray, Dmitry Jemerov, Richard Jones, Garth Kidd, Daniel + Larsson, Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, + Edward Loper, Dallas Mahrt, Ken Manheimer, Skip Montanaro, Paul + Moore, Michel Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, + Mark Pilgrim, Brett g Porter, Tavis Rudd, Oliver Rutherfurd, + Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, + Laurence Tratt, Guido van Rossum, Greg Ward, Barry Warsaw, Edward + Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -214,6 +214,8 @@ Specific: - 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. * docutils/parsers/rst/tableparser.py: @@ -221,7 +223,6 @@ Specific: tables. - Detect bad column spans in "simple" tables. - * docutils/parsers/rst/directives: Updated all directive functions to new API. @@ -257,6 +258,8 @@ Specific: - 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. * docutils/readers/pep.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f198f9560..4a554f715 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -45,6 +45,19 @@ Bugs whitespace and punctuation as markup delimiters, which may not be applicable in these languages. +* @@@ The "include" directive screws up with multiple adjacent + includes of sections. Also, sections must be self-contained (i.e., + a section can't start in an included file and end in the parent + file, because of nested parsing). (Thanks to Brett g Porter for a + bug report that led to this one.) + + Possible solution: Instead of nested parsing, how about replacing + the list of strings for the state machine with an iterator which can + handle multiple files? New files could be inserted, and callbacks + called (observers notified) when the file changes. See + docutils-develop 2002-10-30, subject 'problem with the "include" + directive'. + General ------- @@ -65,10 +78,11 @@ General pollution. Ask opinions on whether or not Docutils should recognize & use them. -* In reader.get_reader_class (& parser & writer too), should we be - importing "standalone" or "docutils.readers.standalone"? (This would - avoid importing top-level modules if the module name is not in - docutils/readers. Potential nastiness.) +* In ``docutils.readers.get_reader_class`` (& ``parsers`` & + ``writers`` too), should we be importing "standalone" or + "docutils.readers.standalone"? (This would avoid importing + top-level modules if the module name is not in docutils/readers. + Potential nastiness.) * Perhaps store a _`name-to-id mapping file`? This could be stored permanently, read by subsequent processing runs, and updated with diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 1a0968ecf..2ad422d75 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -199,8 +199,9 @@ and all default transforms are stored. Each transform is a class in a module in the ``docutils/transforms/`` package, a subclass of ``docutils.tranforms.Transform``. Transform classes each have a ``default_priority`` attribute which is used by -the Transformer to apply transforms in order. The default priority -can be overridden when adding transforms to the Transformer object. +the Transformer to apply transforms in order (low to high). The +default priority can be overridden when adding transforms to the +Transformer object. Transformer responsibilities: diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index 4a32309b2..ff6df8d2e 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -121,6 +121,34 @@ A paragraph. <paragraph> A paragraph. """], +["""\ +Include Test +============ + +.. include:: %s + +\\ + +.. include:: %s + +A paragraph. +""" % (include1, include1), +"""\ +"""], +["""\ +Include Test +============ + +.. include:: %s + +---------- + +.. include:: %s + +A paragraph. +""" % (include1, include1), +"""\ +"""], ] diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index 7b92edaa9..79c885f7b 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -816,6 +816,8 @@ Hi ... Yo ... + +Ho """, """\ <document source="test data"> @@ -829,6 +831,29 @@ Yo <section id="yo" name="yo"> <title> Yo + <paragraph> + Ho +"""], +["""\ +Empty Section +============= +""", +"""\ +<document source="test data"> + <section id="empty-section" name="empty section"> + <title> + Empty Section + <system_message level="3" line="2" source="test data" type="ERROR"> + <paragraph> + Section empty; must have contents. +"""], +["""\ +""", +"""\ +<document source="test data"> + <system_message level="3" line="0" source="test data" type="ERROR"> + <paragraph> + Document empty; must have contents. """], ] diff --git a/test/test_parsers/test_rst/test_transitions.py b/test/test_parsers/test_rst/test_transitions.py index ca7aee5f4..3e8a63e91 100755 --- a/test/test_parsers/test_rst/test_transitions.py +++ b/test/test_parsers/test_rst/test_transitions.py @@ -153,6 +153,65 @@ Paragraph <paragraph> Paragraph """], +["""\ +Sections with transitions at beginning and end. + +Section 1 +========= + +---------- + +Illegal transitions. + +---------- + +Section 2 +========= + +---------- +""", +"""\ +<document source="test data"> + <paragraph> + Sections with transitions at beginning and end. + <section id="section-1" name="section 1"> + <title> + Section 1 + <system_message level="3" line="6" source="test data" type="ERROR"> + <paragraph> + Section may not begin with a transition. + <transition> + <paragraph> + Illegal transitions. + <transition> + <system_message level="3" line="10" source="test data" type="ERROR"> + <paragraph> + Section may not end with a transition. + <section id="section-2" name="section 2"> + <title> + Section 2 + <system_message level="3" line="15" source="test data" type="ERROR"> + <paragraph> + Section may not begin with a transition. + <transition> + <system_message level="3" line="15" source="test data" type="ERROR"> + <paragraph> + Document or section may not end with a transition. +"""], +["""\ +---------- + +Document beginning with a transition. +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <paragraph> + Document beginning with a transition. +"""], ] -- cgit v1.2.1 From 8509a0c4f9cd7c689e78429828906bf0f099377f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Nov 2002 23:10:02 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@878 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_directives/test_include.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index ff6df8d2e..d2b2191d5 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -127,8 +127,6 @@ Include Test .. include:: %s -\\ - .. include:: %s A paragraph. -- cgit v1.2.1 From cd4490bf85dd03ebe0e60f6cdd55d779cf111ffd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Nov 2002 23:23:49 +0000 Subject: Added ``Publisher.set_components()`` method; support for ``publish_*()`` conveninece functions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@879 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 900498b9e..fa99df483 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -72,6 +72,16 @@ class Publisher: writer_class = writers.get_writer_class(writer_name) self.writer = writer_class() + def set_components(self, reader_name, parser_name, writer_name): + if self.reader is None: + self.set_reader(reader_name, self.parser, parser_name) + if self.parser is None: + if self.reader.parser is None: + self.reader.set_parser(parser_name) + self.parser = self.reader.parser + if self.writer is None: + self.set_writer(writer_name) + def setup_option_parser(self, usage=None, description=None, settings_spec=None, **defaults): #@@@ Add self.source & self.destination to components in future? @@ -216,10 +226,7 @@ def publish_cmdline(reader=None, reader_name='standalone', (along with command-line option descriptions). """ pub = Publisher(reader, parser, writer, settings=settings) - if reader is None: - pub.set_reader(reader_name, parser, parser_name) - if writer is None: - pub.set_writer(writer_name) + pub.set_components(reader_name, parser_name, writer_name) pub.publish(argv, usage, description, settings_spec, settings_overrides) def publish_file(source=None, source_path=None, @@ -257,10 +264,7 @@ def publish_file(source=None, source_path=None, of component settings. """ pub = Publisher(reader, parser, writer, settings=settings) - if reader is None: - pub.set_reader(reader_name, parser, parser_name) - if writer is None: - pub.set_writer(writer_name) + pub.set_components(reader_name, parser_name, writer_name) if settings is None: settings = pub.get_settings(settings_spec=settings_spec) if settings_overrides: @@ -280,14 +284,14 @@ def publish_string(source, source_path=None, destination_path=None, For programmatic use with string I/O. For encoded string output, be sure to set the "output_encoding" setting to - the desired encoding. Set it to "unicode" for Unicode string output. + the desired encoding. Set it to "unicode" for unencoded Unicode string + output. Parameters: - - `source`: An input string; required. This can be an encoded 8-big - string (in which case the "input_encoding" setting should be set) or a - Unicode string (in which case set the "input_encoding" setting to - "unicode"). + - `source`: An input string; required. This can be an encoded 8-bit + string (set the "input_encoding" setting to the correct encoding) or a + Unicode string (set the "input_encoding" setting to "unicode"). - `source_path`: Path to the file or object that produced `source`; optional. Only used for diagnostic output. - `destination_path`: Path to the file or object which will receive the @@ -311,10 +315,7 @@ def publish_string(source, source_path=None, destination_path=None, pub = Publisher(reader, parser, writer, settings=settings, source_class=io.StringInput, destination_class=io.StringOutput) - if reader is None: - pub.set_reader(reader_name, parser, parser_name) - if writer is None: - pub.set_writer(writer_name) + pub.set_components(reader_name, parser_name, writer_name) if settings is None: settings = pub.get_settings(settings_spec=settings_spec) if settings_overrides: -- cgit v1.2.1 From 9b6399c61cdd1c032bfb71ce1d46ed293bdc94fa Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Nov 2002 23:34:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@880 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 47bc64170..ebb258a7f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -91,6 +91,8 @@ Specific: - 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. * docutils/frontend.py: -- cgit v1.2.1 From 6f29cffd10c80e604b5298fbecf046c2c9657cc6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Nov 2002 04:28:21 +0000 Subject: Replaced stilted section example with abstract output. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@882 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickstart.txt | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index c40c67cdd..5426e9c93 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -269,24 +269,30 @@ underline style are deemed to be at the same level:: Chapter 2 Title =============== -results in: - -.. sorry, I change the heading style here, but it's only an example :) - -Chapter 1 Title -~~~~~~~~~~~~~~~ - -Section 1.1 Title -''''''''''''''''' - -Subsection 1.1.1 Title -"""""""""""""""""""""" - -Section 1.2 Title -''''''''''''''''' - -Chapter 2 Title -~~~~~~~~~~~~~~~ +This results in the following structure, illustrated by simplified +pseudo-XML:: + + <section> + <title> + Chapter 1 Title + <section> + <title> + Section 1.1 Title + <section> + <title> + Subsection 1.1.1 Title + <section> + <title> + Section 1.2 Title + <section> + <title> + Chapter 2 Title + +(Pseudo-XML uses indentation for nesting and has no end-tags. It's +not possible to show actual processed output, as in the other +examples, because sections cannot exist inside block quotes. For a +concrete example, compare the section structure of this document's +source text and processed output.) Note that section headers are available as link targets, just using their name. To link to the Lists_ heading, I write "``Lists_``". If -- cgit v1.2.1 From bbff5bae14890845feab785b384f2893ffcd18f9 Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Nov 2002 15:40:28 +0000 Subject: + add sk.py to docutils/languages. + added missing labels to docutils/languages/de.py and sv.py (none swedish). + changed de directives to lowercase. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@887 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/de.py | 4 +++ docutils/languages/sk.py | 60 ++++++++++++++++++++++++++++++++++++ docutils/languages/sv.py | 1 + docutils/parsers/rst/languages/de.py | 24 +++++++-------- 4 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 docutils/languages/sk.py diff --git a/docutils/languages/de.py b/docutils/languages/de.py index b6068da2a..e5968dae3 100644 --- a/docutils/languages/de.py +++ b/docutils/languages/de.py @@ -17,11 +17,13 @@ labels = { 'author': 'Autor', 'authors': 'Autoren', 'organization': 'Organisation', + 'address': 'Adresse', 'contact': 'Kontakt', 'version': 'Version', 'revision': 'Revision', 'status': 'Status', 'date': 'Datum', + 'dedication': 'Widmung', 'copyright': 'Copyright', 'abstract': 'Zusammenfassung', 'attention': 'Achtung!', @@ -40,12 +42,14 @@ bibliographic_fields = { 'autor': nodes.author, 'autoren': nodes.authors, 'organisation': nodes.organization, + 'adresse': nodes.address, 'kontakt': nodes.contact, 'version': nodes.version, 'revision': nodes.revision, 'status': nodes.status, 'datum': nodes.date, 'copyright': nodes.copyright, + 'widmung': nodes.topic, 'zusammenfassung': nodes.topic} """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" diff --git a/docutils/languages/sk.py b/docutils/languages/sk.py new file mode 100644 index 000000000..4e18e0885 --- /dev/null +++ b/docutils/languages/sk.py @@ -0,0 +1,60 @@ +""" +:Author: Miroslav Vako +:Contact: zemiak@zoznam.sk +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +Slovak-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +labels = { + 'author': 'Autor', + 'authors': 'Autori', + 'organization': 'Organizcia', + 'address': 'Adresa', + 'contact': 'Kontakt', + 'version': 'Verzia', + 'revision': 'Revzia', + 'status': 'Stav', + 'date': 'Dtum', + 'copyright': 'Copyright', + 'dedication': 'Venovanie', + 'abstract': 'Abstraktne', + 'attention': 'Pozor!', + 'caution': 'Opatrne!', + 'danger': '!NEBEZPEENSTVO!', + 'error': 'Chyba', + 'hint': 'Rada', + 'important': 'Dleit', + 'note': 'Poznmka', + 'tip': 'Tip', + 'warning': 'Varovanie', + 'contents': 'Obsah'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + '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} +"""Field name (lowcased) to node class name mapping for bibliographic fields +(field_list).""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 97fbcd470..0a99015c9 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -18,6 +18,7 @@ labels = { 'author': u'F\u00f6rfattare', 'authors': u'F\u00f6rfattare', 'organization': u'Organisation', + 'address': u'Address', # BUG no swedish spoken here. 'contact': u'Kontakt', 'version': u'Version', 'revision': u'Revision', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index e381a18a2..f05e032a6 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -13,16 +13,16 @@ __docformat__ = 'reStructuredText' directives = { - 'Achtung': 'attention', - 'Vorsicht': 'caution', - 'Gefahr': 'danger', - 'Fehler': 'error', - 'Hinweis': 'hint', - 'Wichtig': 'important', - 'Notiz': 'note', - 'Tip': 'tip', - 'Warnung': 'warning', - 'Topic': 'topic', # Inhalt, Thema or berbegriff + 'achtung': 'attention', + 'vorsicht': 'caution', + 'gefahr': 'danger', + 'fehler': 'error', + 'hinweis': 'hint', + 'wichtig': 'important', + 'notiz': 'note', + 'tip': 'tip', + 'warnung': 'warning', + 'topic': 'topic', # Inhalt, Thema or berbegriff 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', #'questions': 'questions', @@ -30,10 +30,10 @@ directives = { #'faq': 'questions', 'meta': 'meta', #'imagemap': 'imagemap', - 'Bild': 'image', + 'bild': 'image', 'figure': 'figure', # also Bild ? #'raw': 'raw', - 'Inhalt': 'contents', + 'inhalt': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', 'target-notes': 'target-notes', -- cgit v1.2.1 From da2b8ff94991bde4ca2cd83c689c4d4fc8cd0ffe Mon Sep 17 00:00:00 2001 From: chodorowski <chodorowski@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Nov 2002 15:46:06 +0000 Subject: Translated "address". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@889 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 0a99015c9..6c1c7706c 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -18,7 +18,7 @@ labels = { 'author': u'F\u00f6rfattare', 'authors': u'F\u00f6rfattare', 'organization': u'Organisation', - 'address': u'Address', # BUG no swedish spoken here. + 'address': u'Adress', 'contact': u'Kontakt', 'version': u'Version', 'revision': u'Revision', -- cgit v1.2.1 From 866e3c5f8c6d15d2b5c343577bb65d54e92edf23 Mon Sep 17 00:00:00 2001 From: chodorowski <chodorowski@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Nov 2002 15:52:35 +0000 Subject: Added 'adress' -> nodes.addres for bibliographic fields. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@890 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 6c1c7706c..19af12daa 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -42,6 +42,7 @@ labels = { bibliographic_fields = { u'f\u00f6rfattare': nodes.authors, u'organisation': nodes.organization, + u'adress': nodes.address, u'kontakt': nodes.contact, u'version': nodes.version, u'revision': nodes.revision, -- cgit v1.2.1 From bfda82c68d90e66574bc4c7907920848e2858aef Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Nov 2002 02:29:25 +0000 Subject: ASCII-only in Python code. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@893 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/i18n.txt | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/docs/howto/i18n.txt b/docs/howto/i18n.txt index 9aeda9f6a..f9a33d334 100644 --- a/docs/howto/i18n.txt +++ b/docs/howto/i18n.txt @@ -31,14 +31,6 @@ have to be added to the project: one for Docutils itself (the `Docutils Language Module`_) and one for the reStructuredText parser (the `reStructuredText Language Module`_). -Language modules are named using a case-insensitive language -identifier as defined in `RFC 1766`_. A typical language identifier -consists of a 2-letter language code from `ISO 639`_ (3-letter codes -can be used if no 2-letter code exists; RFC 1766 is currently being -revised to allow 3-letter codes). If no language identifier is -specified, the default is "en" for English. Examples of module names -include ``en.py``, ``fr.py``, and ``ja.py`` - .. [#] If anything in Docutils is insufficiently parameterized, it should be considered a bug. Please report bugs to the Docutils project bug tracker on SourceForge at @@ -47,10 +39,42 @@ include ``en.py``, ``fr.py``, and ``ja.py`` .. _Docutils: http://docutils.sourceforge.net/ .. _Introduction to i18n: http://www.debian.org/doc/manuals/intro-i18n/ + + +Language Module Names +===================== + +Language modules are named using a case-insensitive language +identifier as defined in `RFC 1766`_. A typical language identifier +consists of a 2-letter language code from `ISO 639`_ (3-letter codes +can be used if no 2-letter code exists; RFC 1766 is currently being +revised to allow 3-letter codes). If no language identifier is +specified, the default is "en" for English. Examples of module names +include ``en.py``, ``fr.py``, and ``ja.py`` + .. _RFC 1766: http://www.faqs.org/rfcs/rfc1766.html .. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html +Python Code +=========== + +All Python code in Docutils will be ASCII-only. In language modules, +Unicode-escapes will have to be used for non-ASCII characters. +Although it may be possible for some developers to store non-ASCII +characters directly in strings, it will cause problems for other +developers whose locales are set up differently. + +`PEP 263`_ introduces source code encodings to Python modules, +implemented beginning in Python 2.3. Until PEP 263 is fully +implemented as a well-established convention, proven robust in daily +use, and the tools (editors, CVS, email, etc.) recognize this +convention, Docutils shall remain conservative. + +As mentioned in the note above, developers are invited to explore +"gettext" and other i18n technologies. + + Docutils Language Module ======================== -- cgit v1.2.1 From b2f5d8df179415896167ddbf22d25cdd12769758 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Nov 2002 02:30:01 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@894 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4a554f715..d0c6f691d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -111,7 +111,7 @@ General We need to name the objects: - - "name" attribute for the "figure" directive? :: + - "name" option for the "figure" directive? :: .. figure:: image.png :name: image's name @@ -128,7 +128,7 @@ General False True ===== ===== - This would also allow other attributes to be set, like border + This would also allow other options to be set, like border styles. The same technique could be used for other objects. - The object could also be done this way:: @@ -669,21 +669,21 @@ Directives * Allow directives to be added at run-time? -* Use the language module for directive attribute names? +* Use the language module for directive option names? -* Implement attributes on existing directives: +* Implement options on existing directives: - _`images.image`: "border"? - _`parts.sectnum`: "start", "local"? - A "local" attribute could enable numbering for sections from a + A "local" option could enable numbering for sections from a certain point down, and sections in the rest of the document are not numbered. For example, a reference section of a manual might be numbered, but not the rest. OTOH, an all-or-nothing approach would probably be enough. - The "start" attribute will specify the sequence set to use at the + The "start" option will specify the sequence set to use at the same time as the starting value, for the first part of the section number (i.e., section, not subsection). For example:: @@ -714,6 +714,9 @@ Directives suppress contents display for sections in a branch from that point down. Or a new directive, like "prune-contents"? + - _`misc.include`: "encoding" option? Take default from runtime + settings. Use Input component to read it in? + * Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The directive name itself could be the same as the @@ -763,7 +766,7 @@ Directives - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & Answers. Implement as a generic two-column marked list? As a standalone (non-directive) construct? (Is the markup ambiguous?) - Add support to parts.contents (optional attribute "qa" done). + Add support to parts.contents. New elements would be required. Perhaps:: -- cgit v1.2.1 From 5aed03bda74ab6f155bd07ddba18d32d89f0deab Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Nov 2002 02:47:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@895 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index d0c6f691d..646991646 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1108,6 +1108,9 @@ least important): * 4 spaces per indentation level. No tabs. Indent continuation lines according to the Emacs python-mode standard. +* Use only ASCII, no 8-bit strings. See `Docutils + Internationalization`_. + * No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is O.K.). @@ -1131,6 +1134,7 @@ least important): .. _Style Guide for Python Code: http://www.python.org/peps/pep-0008.html .. _Docstring Conventions: http://www.python.org/peps/pep-0257.html +.. _Docutils Internationalization: howto/i18n.html#python-code Copyrights and Licensing -- cgit v1.2.1 From ac321a3311501b2c173075dd284c1cb36f4ed33b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Nov 2002 02:47:56 +0000 Subject: link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@896 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/i18n.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/howto/i18n.txt b/docs/howto/i18n.txt index f9a33d334..3e9cc0f89 100644 --- a/docs/howto/i18n.txt +++ b/docs/howto/i18n.txt @@ -74,6 +74,8 @@ convention, Docutils shall remain conservative. As mentioned in the note above, developers are invited to explore "gettext" and other i18n technologies. +.. _PEP 263: http://www.python.org/peps/pep-0263.html + Docutils Language Module ======================== -- cgit v1.2.1 From 55970b7661292e2494bf92109f38c4a3f90de7ed Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Nov 2002 01:47:19 +0000 Subject: small fixes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@899 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 08274817d..9ff72b162 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -22,7 +22,8 @@ Default cascading style sheet for the PEP HTML output of Docutils. .navigation .navicon { width: 150px ; - height: 35 } + height: 35 ; + margin-bottom: 0em } .navigation .textlinks { padding-left: 1em ; @@ -42,7 +43,7 @@ Default cascading style sheet for the PEP HTML output of Docutils. .rfc2822 td { text-align: left } -.rfc2822 th { +.rfc2822 th.field-name { text-align: right ; font-family: sans-serif ; padding-right: 0.5em ; -- cgit v1.2.1 From 2c6aa283bb09769bc8f2e19fa716f789b3f7d16f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Nov 2002 01:48:26 +0000 Subject: Added "auto-generated file" comment. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@900 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-html-template | 5 +++++ tools/pep2html.py | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/tools/pep-html-template b/tools/pep-html-template index 5549c5d6d..3f4bbdd40 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -1,4 +1,9 @@ <?xml version="1.0" encoding="%(encoding)s"?> +<!-- +This HTML is auto-generated. DO NOT EDIT THIS FILE! If you are writing a new +PEP, see http://www.python.org/peps/pep-0001.html for instructions and links +to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! +--> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en"> <head> diff --git a/tools/pep2html.py b/tools/pep2html.py index 6e031d72c..c74de27db 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -54,6 +54,12 @@ HOST = "www.python.org" # host for update HDIR = "/ftp/ftp.python.org/pub/www.python.org/peps" # target host directory LOCALVARS = "Local Variables:" +COMMENT = """<!-- +This HTML is auto-generated. DO NOT EDIT THIS FILE! If you are writing a new +PEP, see http://www.python.org/peps/pep-0001.html for instructions and links +to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! +-->""" + # The generated HTML doesn't validate -- you cannot use <hr> and <h3> inside # <pre> tags. But if I change that, the result doesn't look very nice... DTD = ('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"\n' @@ -132,6 +138,7 @@ def fixfile(inpath, input_lines, outfile): basename = os.path.basename(inpath) infile = iter(input_lines) # convert plaintext pep to minimal XHTML markup + print >> outfile, COMMENT print >> outfile, DTD print >> outfile, '<html>' print >> outfile, '<head>' -- cgit v1.2.1 From f290510ad2f164c0ef773ca098eae21274bcbd9f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Nov 2002 01:53:07 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@901 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 17 +++++++++++++++++ docs/user/tools.txt | 16 ++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 646991646..c35b210f5 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -58,6 +58,17 @@ Bugs docutils-develop 2002-10-30, subject 'problem with the "include" directive'. +* From Engelbert Gruber:: + + tools/html.py -l de README.txt donotcare.html + ... + File ".../docutils/parsers/rst/languages/__init__.py", line + 19, in get_language + module = __import__(language_code, globals(), locals()) + ImportError: No module named de + + Shouldn't cause a traceback; just return ``None``. + General ------- @@ -289,6 +300,10 @@ General * Multiple file I/O suggestion from Michael Hudson: use a file-like object or something you can iterate over to get file-like objects. +* Language modules: in accented languages it may be useful to have + both accented and unaccented entries in the ``bibliographic_fields`` + mapping for versatility. + Documentation ------------- @@ -1004,6 +1019,8 @@ HTML Writer * Add more support for <link> elements, especially for navigation bars. +* Make the admonitions more distinctive and varied. + Front-End Tools --------------- diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 870f90a6a..b5bbfdf99 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -329,13 +329,6 @@ for some attributes. ==================== ================================================ Setting/Config Entry Description ==================== ================================================ -expose_internals List of internal attribues to expose as external - attributes (with "internal:" namespace prefix). - - Default: don't (None). Options: - ``--expose-internal-attribute`` (hidden, for - development use only). --------------------- ------------------------------------------------ compact_lists (HTML Writer.) Remove extra vertical whitespace between items of bullet lists and enumerated lists, when list items are "simple" (i.e., all @@ -402,11 +395,18 @@ embed_stylesheet (HTML Writer.) Embed the stylesheet in the output HTML file. The stylesheet file must be accessible during processing. The stylesheet is embedded inside a comment, so it must not - contain the text "--" (two hyphens). + contain the text "``--``" (two hyphens). Default: link, don't embed (None). Options: ``--embed-stylesheet, --link-stylesheet``. -------------------- ------------------------------------------------ +expose_internals List of internal attribues to expose as external + attributes (with "internal:" namespace prefix). + + Default: don't (None). Options: + ``--expose-internal-attribute`` (hidden, for + development use only). +-------------------- ------------------------------------------------ footnote_backlinks Enable or disable backlinks from footnotes and citations to their references. -- cgit v1.2.1 From 3ac51a6c7a0d119945d87d3634d6fca261562a8e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Nov 2002 02:39:59 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@902 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sv.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/languages/sv.py b/docutils/languages/sv.py index 19af12daa..c96f2c99d 100644 --- a/docutils/languages/sv.py +++ b/docutils/languages/sv.py @@ -40,6 +40,7 @@ labels = { """Mapping of node class name to label text.""" bibliographic_fields = { + # 'Author' and 'Authors' identical in Swedish; assume the plural: u'f\u00f6rfattare': nodes.authors, u'organisation': nodes.organization, u'adress': nodes.address, -- cgit v1.2.1 From 6b524e8a1b83734a01deda7fe8e15c13f2cdec9e Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Nov 2002 08:29:08 +0000 Subject: + add directives and todo. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@903 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index f05e032a6..9cd35fa15 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -22,7 +22,7 @@ directives = { 'notiz': 'note', 'tip': 'tip', 'warnung': 'warning', - 'topic': 'topic', # Inhalt, Thema or berbegriff + 'topic': 'topic', # berbegriff 'line-block': 'line-block', 'parsed-literal': 'parsed-literal', #'questions': 'questions', @@ -31,8 +31,11 @@ directives = { 'meta': 'meta', #'imagemap': 'imagemap', 'bild': 'image', - 'figure': 'figure', # also Bild ? - #'raw': 'raw', + 'abbildung': 'figure', + 'raw': 'raw', # unbearbeitet + 'include': 'include', # einfgen, "fge ein" would be more like a command. + # einfgung would be the noun. + 'replace': 'replace', # ersetzen, ersetze 'inhalt': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', -- cgit v1.2.1 From 7cd7af54b57b79f893d016e447ece46a0c3e03f8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:25:27 +0000 Subject: *I* didn't write it! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@907 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/de.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 9cd35fa15..25e6c4dd6 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -1,5 +1,5 @@ -# Author: David Goodger -# Contact: goodger@users.sourceforge.net +# Author: Engelbert Gruber +# Contact: grubert@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ # Copyright: This module has been placed in the public domain. -- cgit v1.2.1 From 5157f1e2679a577144a6edaeb0d9e9a7e305eba9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:26:22 +0000 Subject: Bumped version to 0.2.8 because of the internal parser switch from plain lists to the docutils.statemachine.StringList objects. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@908 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index eab752cd2..9c1f2569f 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -55,9 +55,12 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.2.7' -"""``major.minor.micro`` version number. The ``micro`` number is bumped any -time there's a change in the API incompatible with one of the front ends.""" +__version__ = '0.2.8' +"""``major.minor.micro`` version number. The micro number is bumped any time +there's a change in the API incompatible with one of the front ends. The +minor number is bumped whenever there is a project release. The major number +will be bumped when the project is complete, and perhaps if there is a major +change in the design.""" class ApplicationError(StandardError): pass -- cgit v1.2.1 From a9e6a15d0af83b21577891ecbb706a8ac657db4a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:27:29 +0000 Subject: Added to project; French mappings by Stefane Fermigier. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@909 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/fr.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 docutils/languages/fr.py diff --git a/docutils/languages/fr.py b/docutils/languages/fr.py new file mode 100644 index 000000000..cd3f40bc5 --- /dev/null +++ b/docutils/languages/fr.py @@ -0,0 +1,60 @@ +# Author: Stefane Fermigier +# Contact: sf@fermigier.com +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +French-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import nodes + + +labels = { + 'author': 'Auteur', + 'authors': 'Auteurs', + 'organization': 'Organisation', + 'address': 'Adresse', + 'contact': 'Contact', + 'version': 'Version', + 'revision': 'R\u00e9vision', + 'status': 'Statut', + 'date': 'Date', + 'copyright': 'Copyright', + 'dedication': 'D\u00e9dicace', + 'abstract': 'R\u00e9sum\u00e9', + 'attention': 'Attention!', + 'caution': 'Avertissement!', + 'danger': '!DANGER!', + 'error': 'Erreur', + 'hint': 'Indication', + 'important': 'Important', + 'note': 'Note', + 'tip': 'Astuce', + 'warning': 'Avertissement', + 'contents': 'Contenu'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + 'auteur': nodes.author, + 'auteurs': nodes.authors, + 'organisation': nodes.organization, + 'adresse': nodes.address, + 'contact': nodes.contact, + 'version': nodes.version, + 'r\u00e9vision': nodes.revision, + 'status': nodes.status, + 'date': nodes.date, + 'copyright': nodes.copyright, + 'd\u00e9dicace': nodes.topic, + 'r\u00e9sum\u00e9': nodes.topic} +"""Field name (lowcased) to node class name mapping for bibliographic fields +(field_list).""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" -- cgit v1.2.1 From 44fd54469a2e923e85e4c86007ae47e6b67c8c96 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:28:01 +0000 Subject: Unicode escape patch from Miroslav Vasko. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@910 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/sk.py | 80 ++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/docutils/languages/sk.py b/docutils/languages/sk.py index 4e18e0885..49372d7ad 100644 --- a/docutils/languages/sk.py +++ b/docutils/languages/sk.py @@ -1,10 +1,10 @@ -""" -:Author: Miroslav Vako -:Contact: zemiak@zoznam.sk -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. +# :Author: Miroslav Vasko +# :Contact: zemiak@zoznam.sk +# :Revision: $Revision$ +# :Date: $Date$ +# :Copyright: This module has been placed in the public domain. +""" Slovak-language mappings for language-dependent features of Docutils. """ @@ -15,43 +15,43 @@ from docutils import nodes labels = { - 'author': 'Autor', - 'authors': 'Autori', - 'organization': 'Organizcia', - 'address': 'Adresa', - 'contact': 'Kontakt', - 'version': 'Verzia', - 'revision': 'Revzia', - 'status': 'Stav', - 'date': 'Dtum', - 'copyright': 'Copyright', - 'dedication': 'Venovanie', - 'abstract': 'Abstraktne', - 'attention': 'Pozor!', - 'caution': 'Opatrne!', - 'danger': '!NEBEZPEENSTVO!', - 'error': 'Chyba', - 'hint': 'Rada', - 'important': 'Dleit', - 'note': 'Poznmka', - 'tip': 'Tip', - 'warning': 'Varovanie', - 'contents': 'Obsah'} + 'author': u'Autor', + 'authors': u'Autori', + 'organization': u'Organiz\u00E1cia', + 'address': u'Adresa', + 'contact': u'Kontakt', + 'version': u'Verzia', + 'revision': u'Rev\u00EDzia', + 'status': u'Stav', + 'date': u'D\u00E1tum', + 'copyright': u'Copyright', + 'dedication': u'Venovanie', + 'abstract': u'Abstraktne', + 'attention': u'Pozor!', + 'caution': u'Opatrne!', + 'danger': u'!NEBEZPE\u010cENSTVO!', + 'error': u'Chyba', + 'hint': u'Rada', + 'important': u'D\u00F4le\u017Eit\u00E9', + 'note': u'Pozn\u00E1mka', + 'tip': u'Tip', + 'warning': u'Varovanie', + 'contents': u'Obsah'} """Mapping of node class name to label text.""" bibliographic_fields = { - '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} + u'autor': nodes.author, + u'autori': nodes.authors, + u'organiz\u00E1cia': nodes.organization, + u'adresa': nodes.address, + u'kontakt': nodes.contact, + u'verzia': nodes.version, + u'rev\u00EDzia': nodes.revision, + u'stav': nodes.status, + u'D\u00E1tum': nodes.date, + u'copyright': nodes.copyright, + u'venovanie': nodes.topic, + u'abstraktne': nodes.topic} """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" -- cgit v1.2.1 From 660034ddbe25f092221cb4fc0aa286dfe5724aab Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:28:38 +0000 Subject: Removed ``document.note_state_machine_change`` & revised ``.note_source``; updates for statemachine. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@911 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 8659759e8..c9670796e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -899,11 +899,12 @@ class document(Root, Structural, Element): def note_transform_message(self, message): self.transform_messages.append(message) - def note_state_machine_change(self, state_machine): - self.current_line = state_machine.abs_line_number() - - def note_source(self, source): + def note_source(self, source, offset): self.current_source = source + if offset is None: + self.current_line = offset + else: + self.current_line = offset + 1 def copy(self): return self.__class__(self.settings, self.reporter, -- cgit v1.2.1 From 42233c8cbb5e89ce57ad0705aca74eae61346622 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:29:22 +0000 Subject: Simplified "include" directive code. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@912 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 3bd088e39..3ff9eb93f 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -45,13 +45,7 @@ def include(name, arguments, options, content, lineno, else: include_lines = statemachine.string2lines(include_text, convert_whitespace=1) - current_source = state.document.current_source - state.document.note_source(path) - state.memo.reporter.source = path - state.nested_parse(include_lines, 0, node=state_machine.node, - match_titles=state_machine.match_titles) - state.document.note_source(current_source) - state.memo.reporter.source = current_source + state_machine.insert_input(include_lines, path) return [] include.arguments = (1, 0, 1) -- cgit v1.2.1 From 39148f8101ca745fbf08dc91862537dc5b8a1668 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:30:20 +0000 Subject: Updated for ``statemachine.StringList``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@913 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 72 ++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index ebfee3430..9c4eeafab 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -157,11 +157,12 @@ class RSTStateMachine(StateMachineWS): title_styles=[], section_level=0, inliner=inliner) - self.document = self.memo.document - self.attach_observer(self.document.note_state_machine_change) + self.document = document + self.attach_observer(document.note_source) self.reporter = self.memo.reporter self.node = document - results = StateMachineWS.run(self, input_lines, input_offset) + results = StateMachineWS.run(self, input_lines, input_offset, + input_source=document['source']) assert results == [], 'RSTStateMachine.run() results should be empty!' self.check_document() self.node = self.memo = None # remove unneeded references @@ -190,7 +191,7 @@ class NestedStateMachine(StateMachineWS): self.match_titles = match_titles self.memo = memo self.document = memo.document - self.attach_observer(self.document.note_state_machine_change) + self.attach_observer(self.document.note_source) self.reporter = memo.reporter self.node = node results = StateMachineWS.run(self, input_lines, input_offset) @@ -260,12 +261,16 @@ class RSTState(StateWS): state_machine_class = self.nested_sm if state_machine_kwargs is None: state_machine_kwargs = self.nested_sm_kwargs + block_length = len(block) state_machine = state_machine_class(debug=self.debug, **state_machine_kwargs) state_machine.run(block, input_offset, memo=self.memo, node=node, match_titles=match_titles) state_machine.unlink() - return state_machine.abs_line_offset() + new_offset = state_machine.abs_line_offset() + # Adjustment for block if modified in nested parse: + self.state_machine.next_line(len(block) - block_length) + return new_offset def nested_list_parse(self, block, input_offset, node, initial_state, blank_finish, @@ -1270,10 +1275,12 @@ class Body(RSTState): return [], next_state, [] def option_list_item(self, match): + offset = self.state_machine.abs_line_offset() options = self.parse_option_marker(match) indented, indent, line_offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) if not indented: # not an option list item + self.goto_line(offset) raise statemachine.TransitionCorrection('text') option_group = nodes.option_group('', *options) description = nodes.description('\n'.join(indented)) @@ -1366,10 +1373,11 @@ class Body(RSTState): try: block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: - block, lineno = instance.args + block, source, lineno = instance.args messages.append(self.reporter.error('Unexpected indentation.', - line=lineno)) + source=source, line=lineno)) blank_finish = 0 + block.disconnect() width = len(block[0].strip()) for i in range(len(block)): block[i] = block[i].strip() @@ -1649,7 +1657,9 @@ class Body(RSTState): self.state_machine.get_first_known_indented(match.end(), strip_indent=0) blocktext = (match.string[:match.end()] + '\n'.join(block)) - block = [escape2null(line) for line in block] + block.disconnect() + for i in range(len(block)): + block[i] = escape2null(block[i]) escaped = block[0].rstrip() blockindex = 0 while 1: @@ -1667,6 +1677,8 @@ class Body(RSTState): if not block[0]: del block[0] offset += 1 + while block and not block[-1].strip(): + block.pop() subname = subdefmatch.group('name') name = normalize_name(subname) substitutionnode = nodes.substitution_definition( @@ -1674,11 +1686,9 @@ class Body(RSTState): substitutionnode.line = lineno if block: block[0] = block[0].strip() - newabsoffset, blank_finish = self.nested_list_parse( + new_abs_offset, blank_finish = self.nested_list_parse( block, input_offset=offset, node=substitutionnode, initial_state='SubstitutionDef', blank_finish=blank_finish) - self.state_machine.previous_line( - len(block) + offset - newabsoffset - 1) i = 0 for node in substitutionnode[:]: if not (isinstance(node, nodes.Inline) or @@ -1692,7 +1702,7 @@ class Body(RSTState): 'Substitution definition "%s" empty or invalid.' % subname, nodes.literal_block(blocktext, blocktext), line=lineno) - self.parent += msg + return [msg], blank_finish else: del substitutionnode['alt'] self.document.note_substitution_def( @@ -1702,8 +1712,7 @@ class Body(RSTState): msg = self.reporter.warning( 'Substitution definition "%s" missing contents.' % subname, nodes.literal_block(blocktext, blocktext), line=lineno) - self.parent += msg - return [], blank_finish + return [msg], blank_finish def directive(self, match, **option_presets): type_name = match.group(1) @@ -1722,8 +1731,9 @@ class Body(RSTState): Parameters: - - `directive_fn`: The function implementing the directive. Must have - function attributes ``arguments``, ``options``, and ``content``. + - `directive_fn`: The function implementing the directive. Uses + function attributes ``arguments``, ``options``, and/or ``content`` + if present. - `match`: A regular expression match object which matched the first line of the directive. @@ -1753,10 +1763,10 @@ class Body(RSTState): block_text = '\n'.join(self.state_machine.input_lines[ initial_line_offset : self.state_machine.line_offset + 1]) if indented and not indented[0].strip(): - indented.pop(0) + indented.trim_start() line_offset += 1 while indented and not indented[-1].strip(): - indented.pop() + indented.trim_end() if indented and (argument_spec or option_spec): for i in range(len(indented)): if not indented[i].strip(): @@ -1771,7 +1781,7 @@ class Body(RSTState): content_offset = line_offset arg_block = [] while content and not content[0].strip(): - content.pop(0) + content.trim_start() content_offset += 1 try: if option_spec: @@ -1790,7 +1800,7 @@ class Body(RSTState): result = directive_fn( type_name, arguments, options, content, lineno, content_offset, block_text, self, self.state_machine) - return result, blank_finish + return result, blank_finish or self.state_machine.is_next_line_blank() def parse_directive_options(self, option_presets, option_spec, arg_block): options = option_presets.copy() @@ -1875,6 +1885,8 @@ class Body(RSTState): return [nodes.comment()], 1 # "A tiny but practical wart." indented, indent, offset, blank_finish = \ self.state_machine.get_first_known_indented(match.end()) + while indented and not indented[-1].strip(): + indented.trim_end() text = '\n'.join(indented) return [nodes.comment(text, text)], blank_finish @@ -2059,7 +2071,8 @@ class RFC2822Body(Body): def rfc2822_field(self, match): name = match.string[:match.string.find(':')] indented, indent, line_offset, blank_finish = \ - self.state_machine.get_first_known_indented(match.end()) + self.state_machine.get_first_known_indented(match.end(), + until_blank=1) fieldnode = nodes.field() fieldnode += nodes.field_name(name, name) fieldbody = nodes.field_body('\n'.join(indented)) @@ -2213,7 +2226,7 @@ class ExtensionOptions(FieldList): def parse_field_body(self, indented, offset, node): """Override `Body.parse_field_body` for simpler parsing.""" lines = [] - for line in indented + ['']: + for line in list(indented) + ['']: if line.strip(): lines.append(line) elif lines: @@ -2240,6 +2253,8 @@ class Explicit(SpecializedBody): self.blank_finish = blank_finish return [], next_state, [] + blank = SpecializedBody.invalid_input + class SubstitutionDef(Body): @@ -2353,9 +2368,10 @@ class Text(RSTState): try: block = self.state_machine.get_text_block(flush_left=1) except statemachine.UnexpectedIndentationError, instance: - block, lineno = instance.args - msg = self.reporter.error('Unexpected indentation.', line=lineno) - lines = context + block + block, source, lineno = instance.args + msg = self.reporter.error('Unexpected indentation.', + source=source, line=lineno) + lines = context + list(block) paragraph, literalnext = self.paragraph(lines, startline) self.parent += paragraph self.parent += msg @@ -2373,7 +2389,7 @@ class Text(RSTState): self.state_machine.get_indented() nodelist = [] while indented and not indented[-1].strip(): - indented.pop() + indented.trim_end() if indented: data = '\n'.join(indented) nodelist.append(nodes.literal_block(data, data)) @@ -2388,8 +2404,8 @@ class Text(RSTState): def definition_list_item(self, termline): indented, indent, line_offset, blank_finish = \ self.state_machine.get_indented() - definitionlistitem = nodes.definition_list_item('\n'.join(termline - + indented)) + definitionlistitem = nodes.definition_list_item( + '\n'.join(termline + list(indented))) termlist, messages = self.term( termline, self.state_machine.abs_line_number() - 1) definitionlistitem += termlist -- cgit v1.2.1 From 10a51bd456b22e1bedc9721a00c1854e17260d78 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:31:13 +0000 Subject: Removed bogus aliases. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@914 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index b75db5159..70960b210 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -78,12 +78,7 @@ class Reader(Component): return document -_reader_aliases = { - 'rst': 'standalone', - 'rest': 'standalone', - 'restx': 'standalone', - 'rtxt': 'standalone', - 'restructuredtext': 'standalone'} +_reader_aliases = {} def get_reader_class(reader_name): """Return the Reader class from the `reader_name` module.""" -- cgit v1.2.1 From 5dc3617bbe58ef3bbf00aae5f5b5dd4d74afb8a4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:32:08 +0000 Subject: Added ``ViewList`` & ``StringList`` classes, to allow synchronized updating of parent lists from slices (child lists). ``extract_indented()`` becomes ``StringList.get_indented()``. Added ``StateMachine.insert_input()``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@915 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 510 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 409 insertions(+), 101 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 19c357d06..076a9df2f 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -14,6 +14,8 @@ this module defines the following classes: - `StateWS`, a state superclass for use with `StateMachineWS` - `SearchStateMachine`, uses `re.search()` instead of `re.match()` - `SearchStateMachineWS`, uses `re.search()` instead of `re.match()` +- `ViewList`, extends standard Python lists. +- `StringList`, string-specific ViewList. Exception classes: @@ -31,7 +33,7 @@ Exception classes: Functions: - `string2lines()`: split a multi-line string into a list of one-line strings -- `extract_indented()`: return indented lines with minimum indentation removed + How To Use This Module ====================== @@ -136,7 +138,8 @@ class StateMachine: """ self.input_lines = None - """List of strings (without newlines). Filled by `self.run()`.""" + """`StringList` of input lines (without newlines). + Filled by `self.run()`.""" self.input_offset = 0 """Offset of `self.input_lines` from the beginning of the file.""" @@ -172,7 +175,8 @@ class StateMachine: state.unlink() self.states = None - def run(self, input_lines, input_offset=0, context=None): + def run(self, input_lines, input_offset=0, context=None, + input_source=None): """ Run the state machine on `input_lines`. Return results (a list). @@ -187,19 +191,24 @@ class StateMachine: Parameters: - - `input_lines`: a list of strings without newlines. + - `input_lines`: a list of strings without newlines, or `StringList`. - `input_offset`: the line offset of `input_lines` from the beginning of the file. - `context`: application-specific storage. + - `input_source`: name or path of source of `input_lines`. """ self.runtime_init() - self.input_lines = input_lines + if isinstance(input_lines, StringList): + self.input_lines = input_lines + else: + self.input_lines = StringList(input_lines, source=input_source) self.input_offset = input_offset self.line_offset = -1 self.current_state = self.initial_state if self.debug: - print >>sys.stderr, ('\nStateMachine.run: input_lines:\n| %s' % - '\n| '.join(self.input_lines)) + print >>sys.stderr, ( + '\nStateMachine.run: input_lines (line_offset=%s):\n| %s' + % (self.line_offset, '\n| '.join(self.input_lines))) transitions = None results = [] state = self.get_state() @@ -213,8 +222,12 @@ class StateMachine: try: self.next_line() if self.debug: - print >>sys.stderr, ('\nStateMachine.run: line:\n' - '| %s' % self.line) + source, offset = self.input_lines.info( + self.line_offset) + print >>sys.stderr, ( + '\nStateMachine.run: line (source=%r, ' + 'offset=%r):\n| %s' + % (source, offset, self.line)) context, next_state, result = self.check_line( context, state, transitions) except EOFError: @@ -234,7 +247,7 @@ class StateMachine: print >>sys.stderr, ( '\nStateMachine.run: TransitionCorrection to ' 'state "%s", transition %s.' - % (state.__class__.__name, transitions[0])) + % (state.__class__.__name__, transitions[0])) continue except StateCorrection, exception: self.previous_line() # back up for another try @@ -337,6 +350,14 @@ class StateMachine: """Return line number of current line (counting from 1).""" return self.line_offset + self.input_offset + 1 + def insert_input(self, input_lines, source): + self.input_lines.insert(self.line_offset + 1, '', + source='internal padding') + self.input_lines.insert(self.line_offset + 1, '', + source='internal padding') + self.input_lines.insert(self.line_offset + 2, + StringList(input_lines, source)) + def get_text_block(self, flush_left=0): """ Return a contiguous block of text. @@ -345,17 +366,15 @@ class StateMachine: indented line is encountered before the text block ends (with a blank line). """ - block = [] - for line in self.input_lines[self.line_offset:]: - if not line.strip(): - break - if flush_left and (line[0] == ' '): - self.next_line(len(block) - 1) # advance to last line of block - raise UnexpectedIndentationError(block, - self.abs_line_number() + 1) - block.append(line) - self.next_line(len(block) - 1) # advance to last line of block - return block + try: + block = self.input_lines.get_text_block(self.line_offset, + flush_left) + self.next_line(len(block) - 1) + return block + except UnexpectedIndentationError, error: + block, source, lineno = error + self.next_line(len(block) - 1) # advance to last line of block + raise def check_line(self, context, state, transitions=None): """ @@ -386,10 +405,6 @@ class StateMachine: % (state.__class__.__name__, transitions)) for name in transitions: pattern, method, next_state = state.transitions[name] - if self.debug: - print >>sys.stderr, ( - '\nStateMachine.check_line: Trying transition "%s" ' - 'in state "%s".' % (name, state.__class__.__name__)) match = self.match(pattern) if match: if self.debug: @@ -399,6 +414,10 @@ class StateMachine: % (name, state.__class__.__name__)) return method(match, context, next_state) else: + if self.debug: + print >>sys.stderr, ( + '\nStateMachine.check_line: No match in state "%s".' + % state.__class__.__name__) return state.no_match(context, transitions) def match(self, pattern): @@ -445,8 +464,8 @@ class StateMachine: def attach_observer(self, observer): """ - The `observer` parameter is a function or bound method which takes one - argument, ``self`` (this StateMachine object). + The `observer` parameter is a function or bound method which takes two + arguments, the source and offset of the current line. """ self.observers.append(observer) @@ -455,7 +474,11 @@ class StateMachine: def notify_observers(self): for observer in self.observers: - observer(self) + try: + info = self.input_lines.info(self.line_offset) + except IndexError: + info = (None, None) + observer(*info) class State: @@ -762,12 +785,12 @@ class StateMachineWS(StateMachine): - whether or not it finished with a blank line. """ offset = self.abs_line_offset() - indented, indent, blank_finish = extract_indented( - self.input_lines[self.line_offset:], until_blank, strip_indent) + indented, indent, blank_finish = self.input_lines.get_indented( + self.line_offset, until_blank, strip_indent) if indented: self.next_line(len(indented) - 1) # advance to last indented line while indented and not indented[0].strip(): - indented.pop(0) + indented.trim_start() offset += 1 return indented, indent, offset, blank_finish @@ -793,24 +816,12 @@ class StateMachineWS(StateMachine): - whether or not it finished with a blank line. """ offset = self.abs_line_offset() - indented = [self.line[indent:]] - for line in self.input_lines[self.line_offset + 1:]: - if line[:indent].strip(): - blank_finish = not indented[-1].strip() and len(indented) > 1 - break - if until_blank and line.strip(): - blank_finish = 1 - break - if strip_indent: - indented.append(line[indent:]) - else: - indented.append(line) - else: - blank_finish = 1 - if indented: - self.next_line(len(indented) - 1) # advance to last indented line + indented, indent, blank_finish = self.input_lines.get_indented( + self.line_offset, until_blank, strip_indent, + block_indent=indent) + self.next_line(len(indented) - 1) # advance to last indented line while indented and not indented[0].strip(): - indented.pop(0) + indented.trim_start() offset += 1 return indented, offset, blank_finish @@ -837,14 +848,13 @@ class StateMachineWS(StateMachine): - whether or not it finished with a blank line. """ offset = self.abs_line_offset() - indented = [self.line[indent:]] - indented[1:], indent, blank_finish = extract_indented( - self.input_lines[self.line_offset + 1:], until_blank, - strip_indent) + indented, indent, blank_finish = self.input_lines.get_indented( + self.line_offset, until_blank, strip_indent, + first_indent=indent) self.next_line(len(indented) - 1) # advance to last indented line if strip_top: while indented and not indented[0].strip(): - indented.pop(0) + indented.trim_start() offset += 1 return indented, indent, offset, blank_finish @@ -1023,6 +1033,352 @@ class SearchStateMachineWS(_SearchOverride, StateMachineWS): pass +class ViewList: + + """ + List with extended functionality: slices of ViewList objects are child + lists, linked to their parents. Changes made to a child list also affect + the parent list. A child list is effectively a "view" (in the SQL sense) + of the parent list. Changes to parent lists, however, do *not* affect + active child lists. If a parent list is changed, any active child lists + should be recreated. + + The start and end of the slice can be trimmed using the `trim_start()` and + `trim_end()` methods, without affecting the parent list. The link between + child and parent lists can be broken by calling `disconnect()` on the + child list. + + Also, ViewList objects keep track of the source & offset of each item. + This information is accessible via the `source()`, `offset()`, and + `info()` methods. + """ + + def __init__(self, initlist=None, source=None, items=None, + parent=None, parent_offset=None): + self.data = [] + """The actual list of data, flattened from various sources.""" + + self.items = [] + """A list of (source, offset) pairs, same length as `self.data`: the + source of each line and the offset of each line from the beginning of + its source.""" + + self.parent = parent + """The parent list.""" + + self.parent_offset = parent_offset + """Offset of this list from the beginning of the parent list.""" + + if isinstance(initlist, ViewList): + self.data = initlist.data[:] + self.items = initlist.items[:] + elif initlist is not None: + self.data = list(initlist) + if items: + self.items = items + else: + self.items = [(source, i) for i in range(len(initlist))] + assert len(self.data) == len(self.items), 'data mismatch' + + def __str__(self): + return str(self.data) + + def __repr__(self): + return '%s(%s, items=%s)' % (self.__class__.__name__, + self.data, self.items) + + def __lt__(self, other): return self.data < self.__cast(other) + def __le__(self, other): return self.data <= self.__cast(other) + def __eq__(self, other): return self.data == self.__cast(other) + def __ne__(self, other): return self.data != self.__cast(other) + def __gt__(self, other): return self.data > self.__cast(other) + def __ge__(self, other): return self.data >= self.__cast(other) + def __cmp__(self, other): return cmp(self.data, self.__cast(other)) + + def __cast(self, other): + if isinstance(other, ViewList): + return other.data + else: + return other + + def __contains__(self, item): return item in self.data + def __len__(self): return len(self.data) + + def __getitem__(self, i): + try: + return self.data[i] + except TypeError: + assert i.step is None, 'cannot handle slice with stride' + return self.__class__(self.data[i.start:i.stop], + items=self.items[i.start:i.stop], + parent=self, parent_offset=i.start) + + def __setitem__(self, i, item): + try: + self.data[i] = item + if self.parent: + self.parent[i + self.parent_offset] = item + except TypeError: + assert i.step is None, 'cannot handle slice with stride' + if not isinstance(item, ViewList): + raise TypeError('assigning non-ViewList to ViewList slice') + self.data[i.start:i.stop] = item.data + self.items[i.start:i.stop] = item.items + assert len(self.data) == len(self.items), 'data mismatch' + if self.parent: + self.parent[i.start + self.parent_offset + : i.stop + self.parent_offset] = item + + def __delitem__(self, i): + try: + del self.data[i] + del self.items[i] + if self.parent: + del self.parent[i + self.parent_offset] + except TypeError: + assert i.step is None, 'cannot handle slice with stride' + del self.data[i.start:i.stop] + del self.items[i.start:i.stop] + if self.parent: + del self.parent[i.start + self.parent_offset + : i.stop + self.parent_offset] + + def __add__(self, other): + if isinstance(other, ViewList): + return self.__class__(self.data + other.data, + items=(self.items + other.items)) + else: + raise TypeError('adding non-ViewList to a ViewList') + + def __radd__(self, other): + if isinstance(other, ViewList): + return self.__class__(other.data + self.data, + items=(other.items + self.items)) + else: + raise TypeError('adding ViewList to a non-ViewList') + + def __iadd__(self, other): + if isinstance(other, ViewList): + self.data += other.data + else: + raise TypeError('argument to += must be a ViewList') + return self + + def __mul__(self, n): + return self.__class__(self.data * n, items=(self.items * n)) + + __rmul__ = __mul__ + + def __imul__(self, n): + self.data *= n + self.items *= n + return self + + def extend(self, other): + if not isinstance(other, ViewList): + raise TypeError('extending a ViewList with a non-ViewList') + if self.parent: + self.parent.insert(len(self.data) + self.parent_offset, other) + self.data.extend(other.data) + self.items.extend(other.items) + + def append(self, item, source=None, offset=0): + if source is None: + self.extend(item) + else: + if self.parent: + self.parent.insert(len(self.data) + self.parent_offset, item, + source, offset) + self.data.append(item) + self.items.append((source, offset)) + + def insert(self, i, item, source=None, offset=0): + if source is None: + if not isinstance(item, ViewList): + raise TypeError('inserting non-ViewList with no source given') + self.data[i:i] = item.data + self.items[i:i] = item.items + if self.parent: + index = (len(self.data) + i) % len(self.data) + self.parent.insert(index + self.parent_offset, item) + else: + self.data.insert(i, item) + self.items.insert(i, (source, offset)) + if self.parent: + index = (len(self.data) + i) % len(self.data) + self.parent.insert(index + self.parent_offset, item, + source, offset) + + def pop(self, i=-1): + if self.parent: + index = (len(self.data) + i) % len(self.data) + self.parent.pop(index + self.parent_offset) + self.items.pop(i) + return self.data.pop(i) + + def trim_start(self, n=1): + """ + Remove items from the start of the list, without touching the parent. + """ + if n > len(self.data): + raise IndexError("Size of trim too large; can't trim %s items " + "from a list of size %s." % (n, len(self.data))) + elif n < 0: + raise IndexError('Trim size must be >= 0.') + del self.data[:n] + del self.items[:n] + if self.parent: + self.parent_offset += n + + def trim_end(self, n=1): + """ + Remove items from the end of the list, without touching the parent. + """ + if n > len(self.data): + raise IndexError("Size of trim too large; can't trim %s items " + "from a list of size %s." % (n, len(self.data))) + elif n < 0: + raise IndexError('Trim size must be >= 0.') + del self.data[-n:] + del self.items[-n:] + + def remove(self, item): + index = self.index(item) + del self[index] + + def count(self, item): return self.data.count(item) + def index(self, item): return self.data.index(item) + + def reverse(self): + self.data.reverse() + self.items.reverse() + self.parent = None + + def sort(self, *args): + tmp = zip(self.data, self.items) + tmp.sort(*args) + self.data = [entry[0] for entry in tmp] + self.items = [entry[1] for entry in tmp] + self.parent = None + + def info(self, i): + """Return source & offset for index `i`.""" + try: + return self.items[i] + except IndexError: + if i == len(self.data): # Just past the end + return self.items[i - 1][0], None + else: + raise + + def source(self, i): + """Return source for index `i`.""" + return self.info(i)[0] + + def offset(self, i): + """Return offset for index `i`.""" + return self.info(i)[1] + + def disconnect(self): + """Break link between this list and parent list.""" + self.parent = None + + +class StringList(ViewList): + + """A `ViewList` with string-specific methods.""" + + def strip_indent(self, length, start=0, end=sys.maxint): + """ + Strip `length` characters off the beginning of each item, in-place, + from index `start` to `end`. No whitespace-checking is done on the + stripped text. Does not affect slice parent. + """ + self.data[start:end] = [line[length:] + for line in self.data[start:end]] + + def get_text_block(self, start, flush_left=0): + """ + Return a contiguous block of text. + + If `flush_left` is true, raise `UnexpectedIndentationError` if an + indented line is encountered before the text block ends (with a blank + line). + """ + end = start + last = len(self.data) + while end < last: + line = self.data[end] + if not line.strip(): + break + if flush_left and (line[0] == ' '): + source, offset = self.info(end) + raise UnexpectedIndentationError(self[start:end], source, + offset + 1) + end += 1 + return self[start:end] + + def get_indented(self, start=0, until_blank=0, strip_indent=1, + block_indent=None, first_indent=None): + """ + Extract and return a StringList of indented lines of text. + + Collect all lines with indentation, determine the minimum indentation, + remove the minimum indentation from all indented lines (unless + `strip_indent` is false), and return them. All lines up to but not + including the first unindented line will be returned. + + :Parameters: + - `start`: The index of the first line to examine. + - `until_blank`: Stop collecting at the first blank line if true. + - `strip_indent`: Strip common leading indent if true (default). + - `block_indent`: The indent of the entire block, if known. + - `first_indent`: The indent of the first line, if known. + + :Return: + - a StringList of indented lines with mininum indent removed; + - the amount of the indent; + - a boolean: did the indented block finish with a blank line or EOF? + """ + indent = block_indent # start with None if unknown + end = start + if block_indent is not None and first_indent is None: + first_indent = block_indent + if first_indent is not None: + end += 1 + last = len(self.data) + while end < last: + line = self.data[end] + if line and (line[0] != ' ' + or (block_indent is not None + and line[:block_indent].strip())): + # Line not indented or insufficiently indented. + # Block finished properly iff the last indented line blank: + blank_finish = ((end > start) + and not self.data[end - 1].strip()) + break + stripped = line.lstrip() + if not stripped: # blank line + if until_blank: + blank_finish = 1 + break + elif block_indent is None: + line_indent = len(line) - len(stripped) + if indent is None: + indent = line_indent + else: + indent = min(indent, line_indent) + end += 1 + else: + blank_finish = 1 # block ends at end of lines + block = self[start:end] + if first_indent is not None and block: + block.data[0] = block.data[0][first_indent:] + if indent and strip_indent: + block.strip_indent(indent, start=(first_indent is not None)) + return block, indent or 0, blank_finish + + class StateMachineError(Exception): pass class UnknownStateError(StateMachineError): pass class DuplicateStateError(StateMachineError): pass @@ -1070,54 +1426,6 @@ def string2lines(astring, tab_width=8, convert_whitespace=0, astring = whitespace.sub(' ', astring) return [s.expandtabs(tab_width) for s in astring.splitlines()] -def extract_indented(lines, until_blank=0, strip_indent=1): - """ - Extract and return a list of indented lines of text. - - Collect all lines with indentation, determine the minimum indentation, - remove the minimum indentation from all indented lines (unless - `strip_indent` is false), and return them. All lines up to but not - including the first unindented line will be returned. - - :Parameters: - - `lines`: a list of one-line strings without newlines. - - `until_blank`: Stop collecting at the first blank line if true (1). - - `strip_indent`: Strip common leading indent if true (1, default). - - :Return: - - a list of indented lines with mininum indent removed; - - the amount of the indent; - - whether or not the block finished with a blank line or at the end of - `lines`. - """ - source = [] - indent = None - for line in lines: - if line and line[0] != ' ': # line not indented - # block finished properly iff the last indented line was blank - blank_finish = len(source) and not source[-1].strip() - break - stripped = line.lstrip() - if until_blank and not stripped: # blank line - blank_finish = 1 - break - source.append(line) - if not stripped: # blank line - continue - lineindent = len(line) - len(stripped) - if indent is None: - indent = lineindent - else: - indent = min(indent, lineindent) - else: - blank_finish = 1 # block ends at end of lines - if indent: - if strip_indent: - source = [s[indent:] for s in source] - return source, indent, blank_finish - else: - return [], 0, blank_finish - def _exception_data(): """ Return exception information: -- cgit v1.2.1 From 5f2af13120e6a2a7e8dffeb228dc74e87f57ea7d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:34:54 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@916 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_viewlist.py | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 test/test_viewlist.py diff --git a/test/test_viewlist.py b/test/test_viewlist.py new file mode 100644 index 000000000..3ddf1fcf1 --- /dev/null +++ b/test/test_viewlist.py @@ -0,0 +1,166 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for the ViewList class from statemachine.py. +""" + +import unittest +import sys +import re +from DocutilsTestSupport import statemachine + + +class ViewListTests(unittest.TestCase): + + a_list = list('abcdefg') + b_list = list('AEIOU') + c_list = list('XYZ') + + def setUp(self): + self.a = statemachine.ViewList(self.a_list, 'a') + self.b = statemachine.ViewList(self.b_list, 'b') + self.c = statemachine.ViewList(self.c_list, 'c') + + def test_lists(self): + self.assertEqual(self.a, self.a_list) + self.assertEqual(str(self.a), str(self.a_list)) + self.assertEqual(self.b, self.b_list) + self.assertEqual(self.c, self.c_list) + self.assertEqual(self.a.items, + zip('a' * len(self.a_list), range(len(self.a_list)))) + + def test_get_slice(self): + a = self.a[1:-1] + a_list = self.a_list[1:-1] + self.assertEqual(a, a_list) + self.assertEqual(a.items, + zip('a' * len(a_list), range(1, len(a_list) + 1))) + self.assertEqual(a.parent, self.a) + + def test_set_slice(self): + a = statemachine.ViewList(self.a[:]) + s = a[2:-2] + s[2:2] = self.b + s_list = self.a_list[2:-2] + s_list[2:2] = self.b_list + self.assertEqual(s, s_list) + self.assertEqual(s, a[2:-2]) + self.assertEqual(s.items, a[2:-2].items) + + def test_del_slice(self): + a = statemachine.ViewList(self.a[:]) + s = a[2:] + s_list = self.a_list[2:] + del s[3:5] + del s_list[3:5] + self.assertEqual(s, s_list) + self.assertEqual(s, a[2:]) + self.assertEqual(s.items, a[2:].items) + + def test_insert(self): + a_list = self.a_list[:] + a_list.insert(2, 'Q') + a_list[4:4] = self.b_list + a = self.a[:] + self.assert_(isinstance(a, statemachine.ViewList)) + a.insert(2, 'Q', 'runtime') + a.insert(4, self.b) + self.assertEqual(a, a_list) + self.assertEqual(a.info(2), ('runtime', 0)) + self.assertEqual(a.info(5), ('b', 1)) + + def test_append(self): + a_list = self.a_list[:] + a_list.append('Q') + a_list.extend(self.b_list) + a = statemachine.ViewList(self.a) + a.append('Q', 'runtime') + a.append(self.b) + self.assertEqual(a, a_list) + self.assertEqual(a.info(len(self.a)), ('runtime', 0)) + self.assertEqual(a.info(-2), ('b', len(self.b) - 2)) + + def test_extend(self): + a_list = self.a_list[:] + a_list.extend(self.b_list) + a = statemachine.ViewList(self.a) + a.extend(self.b) + self.assertEqual(a, a_list) + self.assertEqual(a.info(len(self.a) + 1), ('b', 1)) + + def test_view(self): + a = statemachine.ViewList(self.a[:]) + a.insert(4, self.b) + s = a[2:-2] + s.insert(5, self.c) + self.assertEqual(s, a[2:-2]) + self.assertEqual(s.items, a[2:-2].items) + s.pop() + self.assertEqual(s, a[2:-2]) + self.assertEqual(s.items, a[2:-2].items) + s.remove('X') + self.assertEqual(s, a[2:-2]) + self.assertEqual(s.items, a[2:-2].items) + + def test_trim(self): + a = statemachine.ViewList(self.a[:]) + s = a[1:-1] + s.trim_start(1) + self.assertEquals(a, self.a) + self.assertEquals(s, a[2:-1]) + s.trim_end(1) + self.assertEquals(a, self.a) + self.assertEquals(s, a[2:-2]) + + +# print +# print a +# print s +# print a.items +# print s.items + + +class StringList(unittest.TestCase): + + text = """\ +This is some +example text. + + Here is some + indented text. + +Unindented text. +""" + + indented_string = """\ + a + literal + block""" + + + def setUp(self): + self.a_list = self.text.splitlines(1) + self.a = statemachine.StringList(self.a_list, 'a') + + def test_strip_indent(self): + s = self.a[3:5] + s.strip_indent(4) + self.assertEqual(s, [line.lstrip() for line in self.a_list[3:5]]) + + def test_get_indented(self): + self.assertEquals(self.a.get_indented(), + ([], 0, 0)) + block = statemachine.StringList( + statemachine.string2lines(self.indented_string)) + self.assertEquals(block.get_indented(), + ([s[6:] for s in block], 6, 1)) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.1 From 47e460c659b1e295d43604762eff2e9147d7df6c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 01:38:11 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@917 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 38 +++++++++---- docs/dev/todo.txt | 7 +++ docs/peps/pep-0258.txt | 3 +- docutils/parsers/rst/tableparser.py | 4 +- docutils/utils.py | 2 +- .../test_rst/test_directives/test_include.py | 65 ++++++++++++++++++++-- test/test_parsers/test_rst/test_substitutions.py | 7 --- test/test_readers/test_pep/test_rfc2822.py | 24 ++++++++ test/test_statemachine.py | 18 +----- tools/pep2html.py | 2 - tools/stylesheets/pep.css | 3 +- 11 files changed, 128 insertions(+), 45 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ebb258a7f..054b0d6a3 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -18,17 +18,18 @@ suggestions, criticism, bug reports, code contributions, tasty treats, and related projects: Aahz, David Ascher, Fred Bremmer, Ian Bicking, Simon Budig, Brett - Cannon, Adam Chodorowski, Fred Drake, Dethe Elza, fantasai, Jim - Fulton, Peter Funk, Jorge Gonzalez, Engelbert Gruber, Simon Hefti, - Doug Hellmann, Juergen Hermann, Jeremy Hylton, Tony Ibbs, Alan - Jaffray, Dmitry Jemerov, Richard Jones, Garth Kidd, Daniel - Larsson, Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, - Edward Loper, Dallas Mahrt, Ken Manheimer, Skip Montanaro, Paul + Cannon, Adam Chodorowski, Fred Drake, Dethe Elza, fantasai, + Stefane Fermigier, Jim Fulton, Peter Funk, Jorge Gonzalez, + Engelbert Gruber, Simon Hefti, Doug Hellmann, Juergen Hermann, + Michael Hudson, Jeremy Hylton, Tony Ibbs, Alan Jaffray, Dmitry + Jemerov, Richard Jones, Andreas Jung, Garth Kidd, Daniel Larsson, + Marc-Andre Lemburg, Julien Letessier, Wolfgang Lipp, Edward Loper, + Dallas Mahrt, Ken Manheimer, Vasko Miroslav, Skip Montanaro, Paul Moore, Michel Pelletier, Sam Penrose, Tim Peters, Pearu Peterson, Mark Pilgrim, Brett g Porter, Tavis Rudd, Oliver Rutherfurd, Kenichi Sato, Ueli Schlaepfer, Gunnar Schwant, tav, Bob Tolbert, - Laurence Tratt, Guido van Rossum, Greg Ward, Barry Warsaw, Edward - Welbourne, Ka-Ping Yee, Moshe Zadka + Laurence Tratt, Guido van Rossum, Martin von Loewis, Greg Ward, + Barry Warsaw, Edward Welbourne, Ka-Ping Yee, Moshe Zadka Thank you! @@ -78,6 +79,8 @@ Specific: - 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. * docutils/core.py: @@ -141,14 +144,14 @@ Specific: - Converted variations on ``node.parent = self`` to ``self.setup_child(node)``. - Added ``document.current_source`` & ``.current_line`` - attributes, and ``.note_state_machine_change`` & - ``.note_source`` observer methods. + 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. + - * docutils/statemachine.py: @@ -172,6 +175,9 @@ Specific: - 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()``. * docutils/utils.py: @@ -182,6 +188,12 @@ Specific: - Fixed a bug in ``relative_path()``. - Added support for improved diagnostics. +* docutils/languages/fr.py: Added to project; French mappings by + Stefane Fermigier. + +* docutils/languages/sk.py: Added to project; Slovak mappings by + Miroslav Vasko. + * docutils/parser/__init__.py: - Added ``Parser.finish_parse()`` method. @@ -218,6 +230,7 @@ Specific: - 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``. * docutils/parsers/rst/tableparser.py: @@ -255,6 +268,9 @@ Specific: * docutils/parsers/rst/directives/references.py: Added to project. Contains the "target-notes" directive. +* docutils/parsers/rst/languages/de.py: Added to project; German + mappings by Engelbert Gruber. + * docutils/readers/__init__.py: - Added support for the observer pattern from ``utils.Reporter``, in @@ -351,6 +367,7 @@ Specific: - 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: @@ -481,6 +498,7 @@ Specific: - Updated for new I/O classes. - Added ``check_requirements()`` & ``pep_type_error()``. - Added some exception handling. + - Added a "DO NOT EDIT THIS FILE" comment to generated HTML. * tools/quicktest.py: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c35b210f5..8848d1208 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -304,6 +304,13 @@ General both accented and unaccented entries in the ``bibliographic_fields`` mapping for versatility. +* Add a "--strict-language" option & setting: no English fallback for + language-dependent features. + +* Add an "--input-language" option & setting? Specify a different + language module for input (bibliographic fields, directives) than + for output ("--language"). + Documentation ------------- diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 2ad422d75..e9df3c9a5 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -455,7 +455,8 @@ Docutils Package Structure - Function "get_language(language_code)", returns matching language module. (``docutils/languages/__init__.py``) - - Module "docutils.languages.en" (English). + - Modules: en.py (English), de.py (German), fr.py (French), sk.py + (Slovak), sv.py (Swedish). - Other languages to be added. diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 6b2ffe3ee..35b52e578 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -131,7 +131,7 @@ class GridTableParser(TableParser): head_body_separator_pat = re.compile(r'\+=[=+]+=\+ *$') def setup(self, block): - self.block = block[:] # make a copy; it may be modified + self.block = list(block) # make a copy; it may be modified self.bottom = len(block) - 1 self.right = len(block[0]) - 1 self.head_body_sep = None @@ -371,7 +371,7 @@ class SimpleTableParser(TableParser): span_pat = re.compile('-[ -]*$') def setup(self, block): - self.block = block[:] # make a copy; it will be modified + self.block = list(block) # make a copy; it will be modified # Convert top & bottom borders to column span underlines: self.block[0] = self.block[0].replace('=', '-') self.block[-1] = self.block[-1].replace('=', '-') diff --git a/docutils/utils.py b/docutils/utils.py index bbd08c6a2..a216e114a 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -378,7 +378,7 @@ def new_document(source, settings=None): reporter = Reporter(source, settings.report_level, settings.halt_level, settings.warning_stream, settings.debug) document = nodes.document(settings, reporter, source=source) - document.note_source(source) + document.note_source(source, -1) return document def clean_rcs_keywords(paragraph, keyword_substitutions): diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index d2b2191d5..613ecae39 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -21,6 +21,7 @@ def suite(): mydir = os.path.dirname(suite.func_code.co_filename) include1 = os.path.join(mydir, 'include1.txt') +include1rel = DocutilsTestSupport.utils.relative_path(None, include1) include2 = os.path.join(mydir, 'include2.txt') totest = {} @@ -47,8 +48,8 @@ A paragraph. <literal> test_include.py . - <paragraph> - A paragraph. + <paragraph> + A paragraph. """], ["""\ Include Test @@ -71,7 +72,7 @@ A paragraph. This file is used by ``test_include.py``. <paragraph> A paragraph. -""" % DocutilsTestSupport.utils.relative_path(None, include1)], +""" % include1rel], ["""\ Let's test the parse context. @@ -132,7 +133,32 @@ Include Test A paragraph. """ % (include1, include1), """\ -"""], +<document source="test data"> + <section id="include-test" name="include test"> + <title> + Include Test + <section dupname="inclusion 1" id="inclusion-1"> + <title> + Inclusion 1 + <paragraph> + This file is used by + <literal> + test_include.py + . + <section dupname="inclusion 1" id="id1"> + <title> + Inclusion 1 + <system_message backrefs="id1" level="1" line="2" source="%s" type="INFO"> + <paragraph> + Duplicate implicit target name: "inclusion 1". + <paragraph> + This file is used by + <literal> + test_include.py + . + <paragraph> + A paragraph. +""" % include1rel], ["""\ Include Test ============ @@ -146,7 +172,36 @@ Include Test A paragraph. """ % (include1, include1), """\ -"""], +<document source="test data"> + <section id="include-test" name="include test"> + <title> + Include Test + <section dupname="inclusion 1" id="inclusion-1"> + <title> + Inclusion 1 + <paragraph> + This file is used by + <literal> + test_include.py + . + <transition> + <system_message level="3" line="12" source="test data" type="ERROR"> + <paragraph> + Section may not end with a transition. + <section dupname="inclusion 1" id="id1"> + <title> + Inclusion 1 + <system_message backrefs="id1" level="1" line="2" source="%s" type="INFO"> + <paragraph> + Duplicate implicit target name: "inclusion 1". + <paragraph> + This file is used by + <literal> + test_include.py + . + <paragraph> + A paragraph. +""" % include1rel], ] diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 84d87a33d..498439a09 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -200,13 +200,6 @@ No blank line after. .. |invalid 2| there's no directive here With some block quote text, line 1. And some more, line 2. - <system_message level="2" line="12" source="test data" type="WARNING"> - <paragraph> - Explicit markup ends without a blank line; unexpected unindent. - <block_quote> - <paragraph> - With some block quote text, line 1. - And some more, line 2. <system_message level="2" line="15" source="test data" type="WARNING"> <paragraph> Substitution definition "invalid 3" empty or invalid. diff --git a/test/test_readers/test_pep/test_rfc2822.py b/test/test_readers/test_pep/test_rfc2822.py index 13d1c96ea..f13de16d2 100644 --- a/test/test_readers/test_pep/test_rfc2822.py +++ b/test/test_readers/test_pep/test_rfc2822.py @@ -260,6 +260,30 @@ Version: Version <field_body> """], +["""\ +Authors: Me + + Myself and I +Version: +""", +"""\ +<document source="test data"> + <field_list class="rfc2822"> + <field> + <field_name> + Authors + <field_body> + <paragraph> + Me + <block_quote> + <paragraph> + Myself and I + <system_message level="2" line="4" source="test data" type="WARNING"> + <paragraph> + Block quote ends without a blank line; unexpected unindent. + <paragraph> + Version: +"""], ] if __name__ == '__main__': diff --git a/test/test_statemachine.py b/test/test_statemachine.py index 4ff5993fb..4ca2a0144 100755 --- a/test/test_statemachine.py +++ b/test/test_statemachine.py @@ -157,7 +157,7 @@ class SMWSTests(unittest.TestCase): self.assertEquals(len(self.sm.states['MockState'].transitions), 4) def test_get_indented(self): - self.sm.input_lines = testtext + self.sm.input_lines = statemachine.StringList(testtext) self.sm.line_offset = -1 self.sm.next_line(3) indented, offset, good = self.sm.get_known_indented(2) @@ -182,7 +182,7 @@ class SMWSTests(unittest.TestCase): self.failUnless(good) def test_get_text_block(self): - self.sm.input_lines = testtext + self.sm.input_lines = statemachine.StringList(testtext) self.sm.line_offset = -1 self.sm.next_line() textblock = self.sm.get_text_block() @@ -192,7 +192,7 @@ class SMWSTests(unittest.TestCase): self.assertEquals(textblock, testtext[2:4]) def test_get_text_block_flush_left(self): - self.sm.input_lines = testtext + self.sm.input_lines = statemachine.StringList(testtext) self.sm.line_offset = -1 self.sm.next_line() textblock = self.sm.get_text_block(flush_left=1) @@ -274,22 +274,10 @@ class MiscTests(unittest.TestCase): s2l_string = "hello\tthere\thow are\tyou?\n\tI'm fine\tthanks.\n" s2l_expected = ['hello there how are you?', " I'm fine thanks."] - indented_string = """\ - a - literal - block""" - def test_string2lines(self): self.assertEquals(statemachine.string2lines(self.s2l_string), self.s2l_expected) - def test_extract_indented(self): - block = statemachine.string2lines(self.indented_string) - self.assertEquals(statemachine.extract_indented(block), - ([s[6:] for s in block], 6, 1)) - self.assertEquals(statemachine.extract_indented(self.s2l_expected), - ([], 0, 0)) - if __name__ == '__main__': unittest.main() diff --git a/tools/pep2html.py b/tools/pep2html.py index c74de27db..deb65c813 100755 --- a/tools/pep2html.py +++ b/tools/pep2html.py @@ -243,8 +243,6 @@ def fixfile(inpath, input_lines, outfile): if line.strip() == LOCALVARS: break if line[0].strip(): - if line.strip() == LOCALVARS: - break if not need_pre: print >> outfile, '</pre>' print >> outfile, '<h3>%s</h3>' % line.strip() diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index 9ff72b162..5f055d2b9 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -22,8 +22,7 @@ Default cascading style sheet for the PEP HTML output of Docutils. .navigation .navicon { width: 150px ; - height: 35 ; - margin-bottom: 0em } + height: 35 } .navigation .textlinks { padding-left: 1em ; -- cgit v1.2.1 From 482f7623f06aa1f55b5f09198a78254fd6f11ff1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Nov 2002 22:04:42 +0000 Subject: Fixed meta tags. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@922 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-html-template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/pep-html-template b/tools/pep-html-template index 3f4bbdd40..4434e269e 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -7,8 +7,8 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en"> <head> - <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s"> - <meta name="generator" content="Docutils %(version)s: http://docutils.sourceforge.net/"> + <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" /> + <meta name="generator" content="Docutils %(version)s: http://docutils.sourceforge.net/" /> <title>PEP %(pep)s -- %(title)s %(stylesheet)s -- cgit v1.2.1 From 0b5556688eb293cdd373a5cf0cd3ee5af5842b8a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 8 Nov 2002 22:06:30 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@923 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 8 +++--- docs/dev/todo.txt | 41 +++++++++++++++++------------ docutils/parsers/rst/directives/__init__.py | 17 ++++++------ 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 05327c71b..c5c859c50 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1356,8 +1356,8 @@ Currently reStructuredText has two hyperlink syntax variations: * Anonymous hyperlinks (in current reStructuredText):: - This is a named reference__ of one word ("reference"). Here is - a `phrase reference`__. Phrase references may even cross `line + This is an anonymous reference__. Here is an anonymous + `phrase reference`__. Phrase references may even cross `line boundaries`__. __ http://www.example.org/reference/ @@ -1380,13 +1380,13 @@ syntaxes for hyperlinks: * First, ``"reference text":URL``:: - This is a named "reference":http://www.example.org/reference/ + This is a "reference":http://www.example.org/reference/ of one word ("reference"). Here is a "phrase reference":http://www.example.org/phrase_reference/. * Second, ``"reference text", http://example.com/absolute_URL``:: - This is a named "reference", http://www.example.org/reference/ + This is a "reference", http://www.example.org/reference/ of one word ("reference"). Here is a "phrase reference", http://www.example.org/phrase_reference/. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 8848d1208..3b53930eb 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -45,19 +45,6 @@ Bugs whitespace and punctuation as markup delimiters, which may not be applicable in these languages. -* @@@ The "include" directive screws up with multiple adjacent - includes of sections. Also, sections must be self-contained (i.e., - a section can't start in an included file and end in the parent - file, because of nested parsing). (Thanks to Brett g Porter for a - bug report that led to this one.) - - Possible solution: Instead of nested parsing, how about replacing - the list of strings for the state machine with an iterator which can - handle multiple files? New files could be inserted, and callbacks - called (observers notified) when the file changes. See - docutils-develop 2002-10-30, subject 'problem with the "include" - directive'. - * From Engelbert Gruber:: tools/html.py -l de README.txt donotcare.html @@ -309,7 +296,23 @@ General * Add an "--input-language" option & setting? Specify a different language module for input (bibliographic fields, directives) than - for output ("--language"). + for output. The "--language" option would set both input & output + languages. + +* Auto-generate reference tables for language-dependent features? + Could be generated from the source modules. A special command-line + option could be added to Docutils front ends to do this. (Idea from + Engelbert Gruber.) + +* Add a "test_language.py" module to the test suite. Engelbert Gruber + has started one. See docutils-develop, 2002-11-05, article + "language set testing". + + Idea: the "test_language.py" module could test all languages when + run by "alltests.py", and it could accept a language name argument + if run as a script, like this:: + + test_language.py de Documentation @@ -613,10 +616,10 @@ __ rst/alternatives.html#or-not-to-do first blank line ends it) where every line begins with the same non-alphanumeric non-whitespace character. -* @@@ Decide whether or not to implement Simon Budig's "inline - external targets" syntax idea, and if so, how? +* @@@ Decide whether or not to implement Simon Budig's _`inline + external targets` syntax idea, and if so, how? - - As a regular directive affecting its indented text block:: + - As a regular directive affecting only its text block (indented):: .. inline-urls:: @@ -643,6 +646,10 @@ __ rst/alternatives.html#or-not-to-do - Or as a full-blown addition to the spec & parser. + The full discussion is here__. + + __ rst/alternatives.html#inline-external-targets + * Add support for pragma (syntax-altering) directives. * Remove leading numbers from section titles for implicit link names? diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 034a88e64..14f10e3f7 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -131,20 +131,19 @@ def directive(directive_name, language_module, document): try: canonicalname = language_module.directives[normname] except (KeyError, AttributeError): - warning = document.reporter.warning( - 'No directive entry for "%s" in module "%s".' - % (directive_name, language_module.__name__), - line=document.current_line) + msg_text = ('No directive entry for "%s" in module "%s".' + % (directive_name, language_module.__name__)) try: - # Try English as a fallback: canonicalname = _fallback_language_module.directives[normname] - warning[-1] += nodes.Text( - 'Using English fallback for directive "%s".' % directive_name) + msg_text += ('\nUsing English fallback for directive "%s".' + % directive_name) except KeyError: - warning[-1] += nodes.Text( - 'Trying "%s" as canonical directive name.' % directive_name) + msg_text += ('\nTrying "%s" as canonical directive name.' + % directive_name) # The canonical name should be an English name, but just in case: canonicalname = normname + warning = document.reporter.warning( + msg_text, line=document.current_line) messages.append(warning) try: modulename, functionname = _directive_registry[canonicalname] -- cgit v1.2.1 From f8b508ad727e1ec8ed1b6c72f169adcfe8aeac07 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 9 Nov 2002 02:56:00 +0000 Subject: *** empty log message *** git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@924 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/problems.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt index 25fda8136..cead7b5b8 100644 --- a/docs/dev/rst/problems.txt +++ b/docs/dev/rst/problems.txt @@ -281,6 +281,7 @@ definition (this distinguishes definition lists from block quotes). Literal Blocks ============== + The StructuredText_ specification has literal blocks indicated by 'example', 'examples', or '::' ending the preceding paragraph. STNG only recognizes '::'; 'example'/'examples' are not implemented. This -- cgit v1.2.1 From 180a8ae0dba23e223f1d0e70645e9eeb92d582c2 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 9 Nov 2002 20:58:34 +0000 Subject: typo caught by GvR git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@926 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/peps/pep-0256.txt | 4 ++-- docs/peps/pep-0287.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index 198ebd9d8..bad386391 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -34,8 +34,8 @@ The concepts of a DPS framework are presented independently of implementation details. -Road Map to the Doctring PEPs -============================= +Road Map to the Docstring PEPs +============================== There are many aspects to docstring processing. The "Docstring PEPs" have broken up the issues in order to deal with each of them in diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index af790a53e..c6e48901b 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -25,7 +25,7 @@ what-you-see-is-what-you-get plaintext markup syntax. Only the low-level syntax of docstrings is addressed here. This PEP is not concerned with docstring semantics or processing at all (see -PEP 256 for a "Road Map to the Doctring PEPs"). Nor is it an attempt +PEP 256 for a "Road Map to the Docstring PEPs"). Nor is it an attempt to deprecate pure plaintext docstrings, which are always going to be legitimate. The reStructuredText markup is an alternative for those who want more expressive docstrings. -- cgit v1.2.1 From f6ee688991dabc8826b6cc203758900113a3995a Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 12 Nov 2002 00:51:03 +0000 Subject: removed illegal attributes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@930 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/pep-html-template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pep-html-template b/tools/pep-html-template index 4434e269e..6b42976c5 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -11,7 +11,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! PEP %(pep)s -- %(title)s %(stylesheet)s - +

    +
    +

    2.21   List Tables

    +

    Here's a list table exercising all features:

    + + +++++ + + + + + + + + + + + + + + + + + + + + +
    list table with integral header
    TreatQuantityDescription
    Albatross2.99On a stick!
    Crunchy Frog1.49If we took the bones out, it wouldn't be +crunchy, now would it?
    Gannet Ripple1.99On a stick!
    +
    -

    3   Error Handling

    +

    3   Error Handling

    Any errors caught during processing will generate system messages.

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    @@ -870,17 +904,17 @@ section, "Docutils System Messages":

    System Message: ERROR/3 (functional/input/data/standard.txt, line 98); backlink

    Undefined substitution referenced: "problematic".
    -
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 352); backlink

    +
    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 352); backlink

    Unknown target name: "5".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 361); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 361); backlink

    Unknown target name: "nonexistent".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 386); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 386); backlink

    Unknown target name: "hyperlink reference without a target".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 399); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 399); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/test/functional/input/data/list_table.txt b/test/functional/input/data/list_table.txt new file mode 100644 index 000000000..632285e36 --- /dev/null +++ b/test/functional/input/data/list_table.txt @@ -0,0 +1,24 @@ +List Tables +----------- + +Here's a list table exercising all features: + +.. list-table:: list table with integral header + :class: test + :widths: 10 20 30 + :header-rows: 1 + :stub-columns: 1 + + * - Treat + - Quantity + - Description + * - Albatross + - 2.99 + - On a stick! + * - Crunchy Frog + - 1.49 + - If we took the bones out, it wouldn't be + crunchy, now would it? + * - Gannet Ripple + - 1.99 + - On a stick! diff --git a/test/functional/input/standalone_rst_html4css1.txt b/test/functional/input/standalone_rst_html4css1.txt index 68f9de864..3847a089e 100644 --- a/test/functional/input/standalone_rst_html4css1.txt +++ b/test/functional/input/standalone_rst_html4css1.txt @@ -2,4 +2,5 @@ .. include:: data/table_colspan.txt .. include:: data/table_rowspan.txt .. include:: data/table_complex.txt +.. include:: data/list_table.txt .. include:: data/errors.txt diff --git a/test/test_parsers/test_rst/test_directives/test_tables.py b/test/test_parsers/test_rst/test_directives/test_tables.py index a38e8b343..da88510e7 100755 --- a/test/test_parsers/test_rst/test_directives/test_tables.py +++ b/test/test_parsers/test_rst/test_directives/test_tables.py @@ -116,6 +116,7 @@ else: .. csv-table:: inline with integral header :widths: 10, 20, 30 :header-rows: 1 + :stub-columns: 1 "Treat", "Quantity", "Description" "Albatross", 2.99, "On a stick!" @@ -129,7 +130,7 @@ else: inline with integral header <tgroup cols="3"> - <colspec colwidth="10"> + <colspec colwidth="10" stub="1"> <colspec colwidth="20"> <colspec colwidth="30"> <thead> @@ -815,6 +816,7 @@ totest['list-table'] = [ .. list-table:: list table with integral header :widths: 10 20 30 :header-rows: 1 + :stub-columns: 1 * - Treat - Quantity @@ -836,7 +838,7 @@ totest['list-table'] = [ <title> list table with integral header <tgroup cols="3"> - <colspec colwidth="10"> + <colspec colwidth="10" stub="1"> <colspec colwidth="20"> <colspec colwidth="30"> <thead> @@ -949,6 +951,44 @@ totest['list-table'] = [ \n\ * - ":widths:" option doesn\'t match columns """], +["""\ +.. list-table:: + :stub-columns: 3 + + * - column 1 + - column 2 +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + 3 stub column(s) specified but only 2 columns(s) of data supplied ("list-table" directive). + <literal_block xml:space="preserve"> + .. list-table:: + :stub-columns: 3 + \n\ + * - column 1 + - column 2 +"""], +["""\ +.. list-table:: + :stub-columns: 2 + + * - column 1 + - column 2 +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Insufficient data supplied (2 columns(s)); no data remaining for table body, required by "list-table" directive. + <literal_block xml:space="preserve"> + .. list-table:: + :stub-columns: 2 + \n\ + * - column 1 + - column 2 +"""], ] -- cgit v1.2.1 From bc1a6ae4d6953fd1ddea43891c531049377473c9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 03:22:18 +0000 Subject: improve docs/ref/rst/directives.html field list rendering git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3166 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/docutils.conf b/tools/docutils.conf index a838c2325..ccddb0db7 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -7,6 +7,7 @@ generator: on [html4css1 writer] # These entries affect HTML output: stylesheet-path: stylesheets/default.css +field-name-limit: 25 [pep_html writer] # These entries affect reStructuredText-style PEPs: -- cgit v1.2.1 From b1958c72c8cc1e3bd8c3239cac80a139cd5fb411 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 03:23:51 +0000 Subject: 20 is enough git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3167 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docutils.conf b/tools/docutils.conf index ccddb0db7..9f218d3bf 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -7,7 +7,7 @@ generator: on [html4css1 writer] # These entries affect HTML output: stylesheet-path: stylesheets/default.css -field-name-limit: 25 +field-name-limit: 20 [pep_html writer] # These entries affect reStructuredText-style PEPs: -- cgit v1.2.1 From d6ab28097870eadae43ea8975d984a27a2ee0379 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 03:29:10 +0000 Subject: fixed mistaken indentation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3168 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 8be376eb6..3de9832db 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -486,6 +486,8 @@ Rubric :Directive Options: Possible. :Directive Content: None. +.. + rubric n. 1. a title, heading, or the like, in a manuscript, book, statute, etc., written or printed in red or otherwise distinguished from the rest of the text. ... -- cgit v1.2.1 From 8cc8a7b68db6775d44db53403e23a72111f2e4bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 03:39:52 +0000 Subject: added syntax idea for table stubs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3169 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 08c94bbbb..50b13392b 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1696,7 +1696,7 @@ Issues: Description - On a stick! - If we took the bones out, it wouldn't be - crunchy, now would it? + crunchy, now would it? * A syntax for stubs in ASCII-art tables is easy to imagine:: @@ -1706,6 +1706,16 @@ Issues: | body row 1, column 1 || column 2 | column 3 | +------------------------++------------+----------+ + Or this idea from Nick Moffitt:: + + +-----+---+---+ + | XOR # T | F | + +=====+===+===+ + | T # F | T | + +-----+---+---+ + | F # T | F | + +-----+---+---+ + Auto-Enumerated Lists ===================== @@ -2102,7 +2112,7 @@ __ http://thread.gmane.org/gmane.text.docutils.devel/1386 1. References and targets take this form:: - targetname_ + targetname_ .. _targetname: stuff @@ -2203,7 +2213,7 @@ __ http://thread.gmane.org/gmane.text.docutils.devel/1386 ".. comment::" would violate that. The goals of reStructuredText are many, and they conflict. Determining the right set of goals and finding solutions that best fit is done on a case-by-case - basis. + basis. Even readability is has two aspects. Being readable without any prior knowledge is one. Being as easily read in raw form as in -- cgit v1.2.1 From 729bd558dd73911547be889a6c8c991870e65b5f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 04:06:56 +0000 Subject: added new idea for compact definition lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3170 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/enthought-plan.txt | 52 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/docs/dev/enthought-plan.txt b/docs/dev/enthought-plan.txt index f73342fa4..e37bb0ded 100644 --- a/docs/dev/enthought-plan.txt +++ b/docs/dev/enthought-plan.txt @@ -388,7 +388,8 @@ Where the classifier part is optional. Ideas for improvements: term : classifier one : two : three ... definition -2. We could allow the definition on the same line as the term. +2. We could allow the definition on the same line as the term, using + some embedded/inline markup: * "--" could be used, but only in limited and well-known contexts:: @@ -411,7 +412,42 @@ Where the classifier part is optional. Ideas for improvements: This syntax has advantages. Equals signs lend themselves to the connotation of "definition". And whereas one or two equals signs are commonly used in program code, three equals signs in a row - have no conflicting meanings that I know of. + have no conflicting meanings that I know of. (Update: there + *are* uses out there.) + + The problem with this approach is that using inline markup for + structure is inherently ambiguous in reStructuredText. For + example, writing *about* definition lists would be difficult:: + + ``term === definition`` is an example of a compact definition list item + + The parser checks for structural markup before it does inline + markup processing. But the "===" should be protected by its inline + literal context. + +3. We could allow the definition on the same line as the term, using + structural markup. A variation on bullet lists would work well:: + + : term :: definition + : another term :: and a definition that + wraps across lines + + Some ambiguity remains:: + + : term ``containing :: double colons`` :: definition + + But the likelihood of such cases is negligible, and they can be + covered in the documentation. + + Other possibilities for the definition delimiter include:: + + : term : classifier -- definition + : term : classifier --- definition + : term : classifier : : definition + : term : classifier === definition + +The third idea currently has the best chance of being adopted and +implemented. Recommendation @@ -425,13 +461,13 @@ Combining these ideas, the function definition becomes:: Wang (1992). :Parameters: - temperature : sequence === Temperature in degrees Celsius - pressure : sequence === Pressure in MPa - api : sequence === Stock tank oil API - specific_gravity : sequence === Specific gravity of gas at - STP, default is .56 + : temperature : sequence :: Temperature in degrees Celsius + : pressure : sequence :: Pressure in MPa + : api : sequence :: Stock tank oil API + : specific_gravity : sequence :: Specific gravity of gas at + STP, default is .56 :Returns: - max_gor : sequence === Maximum dissolved gas in liters/liter + : max_gor : sequence :: Maximum dissolved gas in liters/liter :Description: This estimate is based on equations given by Mavko, Mukerji, and Dvorkin, (1998, pp. 218-219, or 2003, p. 236) obtained originally from Batzle and Wang (1992). -- cgit v1.2.1 From a9cb01249ed3351c1e3ba36caa9fc45d0522b842 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 15:26:16 +0000 Subject: merged reporter-categories branch into trunk: removed docutils.utils.Reporter.categories, docutils.utils.ConditionSet, and all references to them, to simplify error reporting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3171 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 20 +++---- docutils/parsers/rst/__init__.py | 3 +- docutils/transforms/universal.py | 4 +- docutils/utils.py | 120 +++++++++++---------------------------- docutils/writers/html4css1.py | 2 +- docutils/writers/latex2e.py | 2 +- test/test_utils.py | 81 -------------------------- 7 files changed, 48 insertions(+), 184 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index d347d9dda..e6bb52fac 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -111,8 +111,8 @@ class Node: ``visit`` implementation for each `Node` subclass encountered. """ visitor.document.reporter.debug( - 'calling dispatch_visit for %s' % self.__class__.__name__, - category='nodes.Node.walk') + 'docutils.nodes.Node.walk calling dispatch_visit for %s' + % self.__class__.__name__) try: visitor.dispatch_visit(self) except (SkipChildren, SkipNode): @@ -138,8 +138,8 @@ class Node: """ call_depart = 1 visitor.document.reporter.debug( - 'calling dispatch_visit for %s' % self.__class__.__name__, - category='nodes.Node.walkabout') + 'docutils.nodes.Node.walkabout calling dispatch_visit for %s' + % self.__class__.__name__) try: try: visitor.dispatch_visit(self) @@ -157,8 +157,8 @@ class Node: pass if call_depart: visitor.document.reporter.debug( - 'calling dispatch_departure for %s' % self.__class__.__name__, - category='nodes.Node.walkabout') + 'docutils.nodes.Node.walkabout calling dispatch_departure ' + 'for %s' % self.__class__.__name__) visitor.dispatch_departure(self) def traverse(self, condition=None, @@ -1409,8 +1409,8 @@ class NodeVisitor: node_name = node.__class__.__name__ method = getattr(self, 'visit_' + node_name, self.unknown_visit) self.document.reporter.debug( - 'calling %s for %s' % (method.__name__, node_name), - category='nodes.NodeVisitor.dispatch_visit') + 'docutils.nodes.NodeVisitor.dispatch_visit calling %s for %s' + % (method.__name__, node_name)) return method(node) def dispatch_departure(self, node): @@ -1422,8 +1422,8 @@ class NodeVisitor: node_name = node.__class__.__name__ method = getattr(self, 'depart_' + node_name, self.unknown_departure) self.document.reporter.debug( - 'calling %s for %s' % (method.__name__, node_name), - category='nodes.NodeVisitor.dispatch_departure') + 'docutils.nodes.NodeVisitor.dispatch_departure calling %s for %s' + % (method.__name__, node_name)) return method(node) def unknown_visit(self, node): diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 8d7935be6..30825d7c4 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -144,11 +144,10 @@ class Parser(docutils.parsers.Parser): def parse(self, inputstring, document): """Parse `inputstring` and populate `document`, a document tree.""" self.setup_parse(inputstring, document) - debug = document.reporter[''].debug self.statemachine = states.RSTStateMachine( state_classes=self.state_classes, initial_state=self.initial_state, - debug=debug) + debug=document.reporter.debug_flag) inputlines = docutils.statemachine.string2lines( inputstring, tab_width=document.settings.tab_width, convert_whitespace=1) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 7d8a796cc..c77d72df8 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -97,7 +97,7 @@ class Messages(Transform): def apply(self): unfiltered = self.document.transform_messages - threshold = self.document.reporter['writer'].report_level + threshold = self.document.reporter.report_level messages = [] for msg in unfiltered: if msg['level'] >= threshold and not msg.parent: @@ -130,7 +130,7 @@ class SystemMessageFilterVisitor(nodes.SparseNodeVisitor): pass def visit_system_message(self, node): - if node['level'] < self.document.reporter['writer'].report_level: + if node['level'] < self.document.reporter.report_level: node.parent.remove(node) diff --git a/docutils/utils.py b/docutils/utils.py index 848e231fe..c61aedd4e 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -39,27 +39,14 @@ class Reporter: There is typically one Reporter object per process. A Reporter object is instantiated with thresholds for reporting (generating warnings) and halting processing (raising exceptions), a switch to turn debug output on - or off, and an I/O stream for warnings. These are stored in the default - reporting category, '' (zero-length string). - - Multiple reporting categories [#]_ may be set, each with its own reporting - and halting thresholds, debugging switch, and warning stream - (collectively a `ConditionSet`). Categories are hierarchical dotted-name - strings that look like attribute references: 'spam', 'spam.eggs', - 'neeeow.wum.ping'. The 'spam' category is the ancestor of - 'spam.bacon.eggs'. Unset categories inherit stored conditions from their - closest ancestor category that has been set. - - When a system message is generated, the stored conditions from its - category (or ancestor if unset) are retrieved. The system message level - is compared to the thresholds stored in the category, and a warning or - error is generated as appropriate. Debug messages are produced iff the - stored debug switch is on. Message output is sent to the stored warning - stream if not set to ''. - - The default category is '' (empty string). By convention, Writers should - retrieve reporting conditions from the 'writer' category (which, unless - explicitly set, defaults to the conditions of the default category). + or off, and an I/O stream for warnings. These are stored as instance + attributes. + + When a system message is generated, its level is compared to the stored + thresholds, and a warning or error is generated as appropriate. Debug + messages are produced iff the stored debug switch is on, independently of + other thresholds. Message output is sent to the stored warning stream if + not set to ''. The Reporter class also employs a modified form of the "Observer" pattern [GoF95]_ to track system messages generated. The `attach_observer` method @@ -67,9 +54,6 @@ class Reporter: accepts system messages. The observer can be removed with `detach_observer`, and another added in its place. - .. [#] The concept of "categories" was inspired by the log4j project: - http://jakarta.apache.org/log4j/. - .. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA, 1995. @@ -81,10 +65,7 @@ class Reporter: def __init__(self, source, report_level, halt_level, stream=None, debug=0, encoding='ascii', error_handler='replace'): """ - Initialize the `ConditionSet` forthe `Reporter`'s default category. - :Parameters: - - `source`: The path to or description of the source data. - `report_level`: The level at or above which warning output will be sent to `stream`. @@ -101,6 +82,23 @@ class Reporter: self.source = source """The path to or description of the source data.""" + self.encoding = encoding + """The character encoding for the stderr output.""" + + self.error_handler = error_handler + """The character encoding error handler.""" + + self.debug_flag = debug + """Show debug (level=0) system messages?""" + + self.report_level = report_level + """The level at or above which warning output will be sent + to `self.stream`.""" + + self.halt_level = halt_level + """The level at or above which `SystemMessage` exceptions + will be raised, halting execution.""" + if stream is None: stream = sys.stderr elif type(stream) in (StringType, UnicodeType): @@ -111,15 +109,8 @@ class Reporter: elif type(stream) == UnicodeType: stream = open(stream.encode(), 'w') - self.encoding = encoding - """The character encoding for the stderr output.""" - - self.error_handler = error_handler - """The character encoding error handler.""" - - self.categories = {'': ConditionSet(debug, report_level, halt_level, - stream)} - """Mapping of category names to conditions. Default category is ''.""" + self.stream = stream + """Where warning output is sent.""" self.observers = [] """List of bound methods or functions to call with each system_message @@ -128,26 +119,6 @@ class Reporter: self.max_level = -1 """The highest level system message generated so far.""" - def set_conditions(self, category, report_level, halt_level, - stream=None, debug=0): - if stream is None: - stream = sys.stderr - self.categories[category] = ConditionSet(debug, report_level, - halt_level, stream) - - def unset_conditions(self, category): - if category and self.categories.has_key(category): - del self.categories[category] - - __delitem__ = unset_conditions - - def get_conditions(self, category): - while not self.categories.has_key(category): - category = category[:category.rfind('.') + 1][:-1] - return self.categories[category] - - __getitem__ = get_conditions - def attach_observer(self, observer): """ The `observer` parameter is a function or bound method which takes one @@ -169,9 +140,6 @@ class Reporter: Raise an exception or generate a warning if appropriate. """ attributes = kwargs.copy() - category = kwargs.get('category', '') - if kwargs.has_key('category'): - del attributes['category'] if kwargs.has_key('base_node'): source, line = get_source_line(kwargs['base_node']) del attributes['base_node'] @@ -183,16 +151,13 @@ class Reporter: msg = nodes.system_message(message, level=level, type=self.levels[level], *children, **attributes) - debug, report_level, halt_level, stream = self[category].astuple() - if (level >= report_level or debug and level == 0) and stream: + if self.stream and (level >= self.report_level + or self.debug_flag and level == 0): msgtext = msg.astext().encode(self.encoding, self.error_handler) - if category: - print >>stream, msgtext, '[%s]' % category - else: - print >>stream, msgtext - if level >= halt_level: + print >>self.stream, msgtext + if level >= self.halt_level: raise SystemMessage(msg, level) - if level > 0 or debug: + if level > 0 or self.debug_flag: self.notify_observers(msg) self.max_level = max(level, self.max_level) return msg @@ -203,7 +168,7 @@ class Reporter: effect on the processing. Level-0 system messages are handled separately from the others. """ - if self.categories[''].debug: + if self.debug_flag: return self.system_message(0, *args, **kwargs) def info(self, *args, **kwargs): @@ -236,25 +201,6 @@ class Reporter: return self.system_message(4, *args, **kwargs) -class ConditionSet: - - """ - A set of two thresholds (`report_level` & `halt_level`), a switch - (`debug`), and an I/O stream (`stream`), corresponding to one `Reporter` - category. - """ - - def __init__(self, debug, report_level, halt_level, stream): - self.debug = debug - self.report_level = report_level - self.halt_level = halt_level - self.stream = stream - - def astuple(self): - return (self.debug, self.report_level, self.halt_level, - self.stream) - - class ExtensionOptionError(DataError): pass class BadOptionError(ExtensionOptionError): pass class BadOptionDataError(ExtensionOptionError): pass diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 27442e6ca..0ed0f1544 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1174,7 +1174,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</sup>') def visit_system_message(self, node): - if node['level'] < self.document.reporter['writer'].report_level: + if node['level'] < self.document.reporter.report_level: # Level is too low to display: raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 1a488d88d..f756f1e39 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1822,7 +1822,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_system_message(self, node): - if node['level'] < self.document.reporter['writer'].report_level: + if node['level'] < self.document.reporter.report_level: raise nodes.SkipNode def depart_system_message(self, node): diff --git a/test/test_utils.py b/test/test_utils.py index 7077757ba..006495ac9 100755 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -123,87 +123,6 @@ class QuietReporterTests(unittest.TestCase): self.assertEquals(self.stream.getvalue(), '') -class ReporterCategoryTests(unittest.TestCase): - - stream = StringIO.StringIO() - - def setUp(self): - self.stream.seek(0) - self.stream.truncate() - self.reporter = utils.Reporter('test data', 2, 4, self.stream, 1) - self.reporter.set_conditions('lemon', 1, 3, self.stream, 0) - - def test_getset(self): - self.reporter.set_conditions('test', 5, 5, None, 0) - self.assertEquals(self.reporter.get_conditions('other').astuple(), - (1, 2, 4, self.stream)) - self.assertEquals(self.reporter.get_conditions('test').astuple(), - (0, 5, 5, sys.stderr)) - self.assertEquals(self.reporter.get_conditions('test.dummy').astuple(), - (0, 5, 5, sys.stderr)) - self.reporter.set_conditions('test.dummy.spam', 1, 2, self.stream, 1) - self.assertEquals( - self.reporter.get_conditions('test.dummy.spam').astuple(), - (1, 1, 2, self.stream)) - self.assertEquals(self.reporter.get_conditions('test.dummy').astuple(), - (0, 5, 5, sys.stderr)) - self.assertEquals( - self.reporter.get_conditions('test.dummy.spam.eggs').astuple(), - (1, 1, 2, self.stream)) - self.reporter.unset_conditions('test.dummy.spam') - self.assertEquals( - self.reporter.get_conditions('test.dummy.spam.eggs').astuple(), - (0, 5, 5, sys.stderr)) - - def test_debug(self): - sw = self.reporter.debug('debug output', category='lemon.curry') - self.assertEquals(self.stream.getvalue(), '') - sw = self.reporter.debug('debug output') - self.assertEquals(self.stream.getvalue(), - 'test data:: (DEBUG/0) debug output\n') - - def test_info(self): - sw = self.reporter.info('some info') - self.assertEquals(self.stream.getvalue(), '') - sw = self.reporter.info('some info', category='lemon.curry') - self.assertEquals( - self.stream.getvalue(), - 'test data:: (INFO/1) some info [lemon.curry]\n') - - def test_warning(self): - sw = self.reporter.warning('a warning') - self.assertEquals(self.stream.getvalue(), - 'test data:: (WARNING/2) a warning\n') - sw = self.reporter.warning('a warning', category='lemon.curry') - self.assertEquals(self.stream.getvalue(), """\ -test data:: (WARNING/2) a warning -test data:: (WARNING/2) a warning [lemon.curry] -""") - - def test_error(self): - sw = self.reporter.error('an error') - self.assertEquals(self.stream.getvalue(), - 'test data:: (ERROR/3) an error\n') - self.assertRaises(utils.SystemMessage, self.reporter.error, - 'an error', category='lemon.curry') - self.assertEquals(self.stream.getvalue(), """\ -test data:: (ERROR/3) an error -test data:: (ERROR/3) an error [lemon.curry] -""") - - def test_severe(self): - self.assertRaises(utils.SystemMessage, self.reporter.severe, - 'a severe error') - self.assertEquals(self.stream.getvalue(), - 'test data:: (SEVERE/4) a severe error\n') - self.assertRaises(utils.SystemMessage, self.reporter.severe, - 'a severe error', category='lemon.curry') - self.assertEquals(self.stream.getvalue(), """\ -test data:: (SEVERE/4) a severe error -test data:: (SEVERE/4) a severe error [lemon.curry] -""") - - class NameValueTests(unittest.TestCase): def test_extract_name_value(self): -- cgit v1.2.1 From e4d2d4afbc58816274503dcff87405d809db1013 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 18:51:18 +0000 Subject: assigned classes to <th> elements to indicate role: table head and/or stub git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3172 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 13 ++++++-- .../expected/standalone_rst_html4css1.html | 36 +++++++++++----------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0ed0f1544..6ec9ca547 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -456,6 +456,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_colspec(self, node): self.colspecs.append(node) + # "stubs" list is an attribute of the tgroup element: node.parent.stubs.append(node.attributes.get('stub')) def depart_colspec(self, node): @@ -604,13 +605,19 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</em>') def visit_entry(self, node): - if ( isinstance(node.parent.parent, nodes.thead) - or node.parent.parent.parent.stubs[node.parent.column]): + atts = {'class': []} + if isinstance(node.parent.parent, nodes.thead): + atts['class'].append('head') + if node.parent.parent.parent.stubs[node.parent.column]: + # "stubs" list is an attribute of the tgroup element + atts['class'].append('stub') + if atts['class']: tagname = 'th' + atts['class'] = ' '.join(atts['class']) else: tagname = 'td' + del atts['class'] node.parent.column += 1 - atts = {} if node.has_key('morerows'): atts['rowspan'] = node['morerows'] + 1 if node.has_key('morecols'): diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index f3b49e496..be1c9816e 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -745,12 +745,12 @@ Fifth test in HTML.<br />Line two.</div> <col width="38%" /> </colgroup> <thead valign="bottom"> -<tr><th colspan="2">Inputs</th> -<th>Output</th> +<tr><th class="head" colspan="2">Inputs</th> +<th class="head">Output</th> </tr> -<tr><th>A</th> -<th>B</th> -<th>A or B</th> +<tr><th class="head">A</th> +<th class="head">B</th> +<th class="head">A or B</th> </tr> </thead> <tbody valign="top"> @@ -783,10 +783,10 @@ Fifth test in HTML.<br />Line two.</div> <col width="33%" /> </colgroup> <thead valign="bottom"> -<tr><th>Header row, column 1 +<tr><th class="head">Header row, column 1 (header rows optional)</th> -<th>Header 2</th> -<th>Header 3</th> +<th class="head">Header 2</th> +<th class="head">Header 3</th> </tr> </thead> <tbody valign="top"> @@ -820,11 +820,11 @@ span rows.</td> <col width="18%" /> </colgroup> <thead valign="bottom"> -<tr><th>Header row, column 1 +<tr><th class="head">Header row, column 1 (header rows optional)</th> -<th>Header 2</th> -<th>Header 3</th> -<th>Header 4</th> +<th class="head">Header 2</th> +<th class="head">Header 3</th> +<th class="head">Header 4</th> </tr> </thead> <tbody valign="top"> @@ -869,22 +869,22 @@ empty: <tt class="docutils literal"><span class="pre">--></span></tt></td> <col width="50%" /> </colgroup> <thead valign="bottom"> -<tr><th>Treat</th> -<th>Quantity</th> -<th>Description</th> +<tr><th class="head stub">Treat</th> +<th class="head">Quantity</th> +<th class="head">Description</th> </tr> </thead> <tbody valign="top"> -<tr><th>Albatross</th> +<tr><th class="stub">Albatross</th> <td>2.99</td> <td>On a stick!</td> </tr> -<tr><th>Crunchy Frog</th> +<tr><th class="stub">Crunchy Frog</th> <td>1.49</td> <td>If we took the bones out, it wouldn't be crunchy, now would it?</td> </tr> -<tr><th>Gannet Ripple</th> +<tr><th class="stub">Gannet Ripple</th> <td>1.99</td> <td>On a stick!</td> </tr> -- cgit v1.2.1 From 260212205f6acb893a305d3575d76f493a68b724 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 21:04:04 +0000 Subject: removed unnecessary backslash git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3173 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 3de9832db..d0f6cd453 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -815,7 +815,7 @@ Example:: - On a stick! * - Crunchy Frog - 1.49 - - If we took the bones out, it wouldn\'t be + - If we took the bones out, it wouldn't be crunchy, now would it? * - Gannet Ripple - 1.99 -- cgit v1.2.1 From 5b2787e17e9dc54537136f376fc2a499a7b90b66 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 21:52:48 +0000 Subject: added links for image and meta directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3174 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 4ed975144..c32e48db6 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -807,7 +807,7 @@ processing. They may also be used for two-column table-like structures resembling database records (label & data pairs). Applications of reStructuredText may recognize field names and transform fields or field bodies in certain contexts. For examples, -see `Bibliographic Fields`_ below, or the "image" and "meta" +see `Bibliographic Fields`_ below, or the "image_" and "meta_" directives in `reStructuredText Directives`_. Field lists are mappings from field names to field bodies, modeled on @@ -2814,6 +2814,8 @@ Markup errors are handled according to the specification in `PEP .. _World Wide Web Consortium: http://www.w3.org/ .. _HTML Techniques for Web Content Accessibility Guidelines: http://www.w3.org/TR/WCAG10-HTML-TECHS/#link-text +.. _image: directives.html#image +.. _meta: directives.html#meta .. _reStructuredText Directives: directives.html .. _reStructuredText Interpreted Text Roles: roles.html .. _RFC2396: http://www.rfc-editor.org/rfc/rfc2396.txt -- cgit v1.2.1 From 0e2d41b9ac2cd4c2fd17ece211048d9727685af6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Apr 2005 21:59:20 +0000 Subject: added some more links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3175 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index c32e48db6..57362c5db 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1927,17 +1927,17 @@ Directives`_ document, and are always available. Any other directives are domain-specific, and may require special action to make them available when processing the document. -For example, here's how an image may be placed:: +For example, here's how an image_ may be placed:: .. image:: mylogo.jpeg -A figure (a graphic with a caption) may placed like this:: +A figure_ (a graphic with a caption) may placed like this:: .. figure:: larch.png The larch. -An admonition (note, caution, etc.) contains other body elements:: +An admonition_ (note, caution, etc.) contains other body elements:: .. note:: This is a paragraph @@ -2028,7 +2028,7 @@ Substitution definitions are indicated by an explicit markup start vertical bar, whitespace, and the definition block. Substitution text may not begin or end with whitespace. A substitution definition block contains an embedded inline-compatible directive (without the leading -".. "), such as an image. For example:: +".. "), such as an image_. For example:: The |biohazard| symbol must be used on containers used to dispose of medical waste. @@ -2133,7 +2133,7 @@ Images .. |-><-| image:: discord.png .. _POEE: http://www.poee.org/ - The "image" directive has been implemented. + The "image_" directive has been implemented. Styles [#]_ Substitution references may be used to associate inline text with @@ -2816,6 +2816,8 @@ Markup errors are handled according to the specification in `PEP http://www.w3.org/TR/WCAG10-HTML-TECHS/#link-text .. _image: directives.html#image .. _meta: directives.html#meta +.. _figure: directives.html#figure +.. _admonition: directives.html#admonitions .. _reStructuredText Directives: directives.html .. _reStructuredText Interpreted Text Roles: roles.html .. _RFC2396: http://www.rfc-editor.org/rfc/rfc2396.txt -- cgit v1.2.1 From 929f0718c0eb410e888df9d56ab2d0c68d2db44d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Apr 2005 15:43:49 +0000 Subject: use universal newlines when opening expected output files to guard against cross-platform line ending problems git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3176 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_functional.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_functional.py b/test/test_functional.py index a6eafd9bf..e52d41422 100755 --- a/test/test_functional.py +++ b/test/test_functional.py @@ -112,7 +112,9 @@ class FunctionalTestCase(DocutilsTestSupport.CustomTestCase): # Get the expected output *after* writing the actual output. self.assert_(os.access(expected_path, os.R_OK),\ 'Cannot find expected output at\n' + expected_path) - expected = open(expected_path).read() + f = open(expected_path, 'rU') + expected = f.read() + f.close() diff = ('The expected and actual output differs.\n' 'Please compare the expected and actual output files:\n' ' diff %s %s\n' -- cgit v1.2.1 From d9aa90d0084ff873108c7ede8854fed0803eab95 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Apr 2005 16:11:47 +0000 Subject: added some directive ideas git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3177 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 0f0f07e2c..3d6c910ac 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1095,6 +1095,12 @@ when used in a document. - All directives that produce titled elements should grow implicit reference names based on the titles. + - Allow the _`:trim:` option for all directives when they occur in a + substitution definition, not only the unicode_ directive. + + .. _unicode: + http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes + - _`images.image`: "border"? _`Units of measure`? (See `docutils-users, 2003-03-02 @@ -1155,6 +1161,10 @@ when used in a document. Add an option to include topics in the TOC? Another for sidebars? See docutils-develop 2003-01-29. + - _`parts.header` & _`parts.footer`: Add "header" and "footer" + directives to specify document-specific contents for header and + footer? + - _`misc.include`: - "encoding" option? Take default from runtime settings. Use @@ -1200,11 +1210,15 @@ when used in a document. .. include:: :url: http://www.example.org/inclusion.txt - - Allow the _`:trim:` option for all directives when they occur in a - substitution definition, not only the unicode_ directive. + - _`misc.raw`: add a "destination" option to the "raw" directive? :: - .. _unicode: - http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes + .. raw:: html + :destination: head + + <link ...> + + It needs thought & discussion though, to come up with a consistent + set of destination labels and consistent behavior. * Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The -- cgit v1.2.1 From 57b9447562a8e3717e751ebc0512eaa525667747 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Apr 2005 18:55:30 +0000 Subject: added some more auto-props git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3178 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 5311f9a1b..842e5b694 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -87,6 +87,9 @@ correct properties set:: [auto-props] *.py = svn:eol-style=native;svn:keywords=Author Date Id Revision *.txt = svn:eol-style=native;svn:keywords=Author Date Id Revision + *.html = svn:eol-style=native;svn:keywords=Author Date Id Revision + *.xml = svn:eol-style=native;svn:keywords=Author Date Id Revision + *.tex = svn:eol-style=native;svn:keywords=Author Date Id Revision *.sh = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id Revision *.png = svn:mime-type=image/png -- cgit v1.2.1 From dc47ace1b81b477ae3383ac48e13faab201e66dd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Apr 2005 19:38:32 +0000 Subject: reworked instructions as enumerated list git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3179 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 842e5b694..ade960c12 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -102,32 +102,32 @@ Subversion servers without having to enter your password. There are two places to add your SSH public key on BerliOS: your web account and your shell account. -1. Adding your SSH key to your BerliOS web account: +* Adding your SSH key to your BerliOS web account: - * Log in on the web at https://developer.berlios.de/. Create your + 1. Log in on the web at https://developer.berlios.de/. Create your account first if necessary. You should be taken to your "My Personal Page" (https://developer.berlios.de/my/). - * Choose "Account Options" from the menu below the top banner. + 2. Choose "Account Options" from the menu below the top banner. - * At the bottom of the "Account Maintenance" page + 3. At the bottom of the "Account Maintenance" page (https://developer.berlios.de/account/) you'll find a "Shell Account Information" section; click on "[Edit Keys]". - * Copy and paste your SSH public key into the edit box on this page + 4. Copy and paste your SSH public key into the edit box on this page (https://developer.berlios.de/account/editsshkeys.php). Further instructions are available on this page. -2. Adding your SSH key to your BerliOS shell account: +* Adding your SSH key to your BerliOS shell account: - * Log in to the BerliOS shell server:: + 1. Log in to the BerliOS shell server:: ssh username@shell.berlios.de You'll be asked for your password, which you set when you created your account. - * Create a .ssh directory in your home directory, and remove + 2. Create a .ssh directory in your home directory, and remove permissions for group & other:: mkdir .ssh @@ -135,12 +135,12 @@ your shell account. Exit the SSH session. - * Copy your public key to the .ssh directory on BerliOS:: + 3. Copy your public key to the .ssh directory on BerliOS:: scp .ssh/id_dsa.pub username@shell.berlios.de:.ssh/authorized_keys - Now you should be able to start an SSH session without needing your - password. + Now you should be able to start an SSH session without needing your + password. Web Access -- cgit v1.2.1 From 7aacd6e6d0db8e988b1718dd6fd52703223fda52 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 03:07:14 +0000 Subject: moved descriptions to the correct sections git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3180 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index fdc05842a..26f4a24f8 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -228,25 +228,6 @@ _`expose_internals` Default: don't (None). Options: ``--expose-internal-attribute`` (hidden, for development use only). -_`field_name_limit` - - The maximum width (in characters) for one-column field names. - Longer field names will span the entire row. 0 indicates "no - limit". - - Default: 14 characters. Option: ``--field-name-limit``. - -_`file_insertion_enabled` - Enable or disable directives that insert the contents of external - files, such as the "include_" & "raw_". A "warning" system - message (including the directive text) is inserted instead. - - Default: enabled (1). Options: ``--file-insertion-enabled, - --no-file-insertion``. - - .. _include: ../ref/rst/directives.html#include - .. _raw: ../ref/rst/directives.html#raw - _`footnote_backlinks` Enable or disable backlinks from footnotes and citations to their references. @@ -328,12 +309,6 @@ _`output_encoding_error_handler` Default: "strict". Options: ``--output-encoding-error-handler, --output-encoding, -o``. -_`raw_enabled` - Enable or disable the "raw_" directive. A "warning" system - message (including the directive text) is inserted instead. - - Default: enabled (1). Options: ``--raw-enabled, --no-raw``. - _`report_level` Verbosity threshold at or above which system messages are reported. @@ -412,6 +387,17 @@ Docutils currently supports only one parser, for reStructuredText. [restructuredtext parser] ````````````````````````` +_`file_insertion_enabled` + Enable or disable directives that insert the contents of external + files, such as the "include_" & "raw_". A "warning" system + message (including the directive text) is inserted instead. + + Default: enabled (1). Options: ``--file-insertion-enabled, + --no-file-insertion``. + + .. _include: ../ref/rst/directives.html#include + .. _raw: ../ref/rst/directives.html#raw + _`pep_references` Recognize and link to standalone PEP references (like "PEP 258"). @@ -424,6 +410,12 @@ _`pep_base_url` Default: "http://www.python.org/peps/". Option: ``--pep-base-url``. +_`raw_enabled` + Enable or disable the "raw_" directive. A "warning" system + message (including the directive text) is inserted instead. + + Default: enabled (1). Options: ``--raw-enabled, --no-raw``. + _`rfc_references` Recognize and link to standalone RFC references (like "RFC 822"). @@ -550,6 +542,14 @@ _`embed_stylesheet` Default: link, don't embed (None). Options: ``--embed-stylesheet, --link-stylesheet``. +_`field_name_limit` + + The maximum width (in characters) for one-column field names. + Longer field names will span the entire row. 0 indicates "no + limit". + + Default: 14 characters. Option: ``--field-name-limit``. + .. _footnote_references [html4css1 writer]: footnote_references -- cgit v1.2.1 From 4cd2bcbe53510b93a2ab547c9b315a55eeda301b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 03:13:31 +0000 Subject: added the "option_limit" setting & docs; clarified "field_name_limit" docs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3181 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 ++- docs/user/config.txt | 12 +++++++++--- docutils/writers/html4css1.py | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index e8200d037..756cb4973 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -109,7 +109,8 @@ Changes Since 0.3.7 tags). - Added support for multiple IDs per node by creating empty ``span`` tags. - - Added the ``field_name_limit`` setting & support. + - Added the ``field_name_limit`` & ``option_limit`` settings & + support. - Added support for table stub columns. * docutils/writers/latex2e.py: diff --git a/docs/user/config.txt b/docs/user/config.txt index 26f4a24f8..7e93626a1 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -543,10 +543,9 @@ _`embed_stylesheet` --link-stylesheet``. _`field_name_limit` - The maximum width (in characters) for one-column field names. - Longer field names will span the entire row. 0 indicates "no - limit". + Longer field names will span an entire row of the table used to + render the field list. 0 indicates "no limit". Default: 14 characters. Option: ``--field-name-limit``. @@ -571,6 +570,13 @@ _`initial_header_level` .. _stylesheet [html4css1 writer]: +_`option_limit` + The maximum width (in characters) for options in option lists. + Longer options will span an entire row of the table used to render + the option list. 0 indicates "no limit". + + Default: 14 characters. Option: ``--option-limit``. + stylesheet CSS stylesheet URL, used verbatim. Overrides stylesheet_path [#override]_. diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 6ec9ca547..f23238307 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -64,11 +64,19 @@ class Writer(writers.Writer): {'choices': '1 2 3 4 5 6'.split(), 'default': '1', 'metavar': '<level>'}), ('Specify the maximum width (in characters) for one-column field ' - 'names. Longer field names will span the entire row. Default is ' - '14 characters. Use 0 for "no limit".', + 'names. Longer field names will span an entire row of the table ' + 'used to render the field list. Default is 14 characters. ' + 'Use 0 for "no limit".', ['--field-name-limit'], {'default': 14, 'metavar': '<level>', 'validator': frontend.validate_nonnegative_int}), + ('Specify the maximum width (in characters) for options in option ' + 'lists. Longer options will span an entire row of the table used ' + 'to render the option list. Default is 14 characters. ' + 'Use 0 for "no limit".', + ['--option-limit'], + {'default': 14, 'metavar': '<level>', + 'validator': frontend.validate_nonnegative_int}), ('Format for footnote references: one of "superscript" or ' '"brackets". Default is "brackets".', ['--footnote-references'], @@ -973,7 +981,8 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_option_group(self, node): atts = {} - if len(node.astext()) > 14: + if ( self.settings.option_limit + and len(node.astext()) > self.settings.option_limit): atts['colspan'] = 2 self.context.append('</tr>\n<tr><td> </td>') else: -- cgit v1.2.1 From 46507a14aebfe22b79a1564e28c73aa063e508a0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 16:02:49 +0000 Subject: moved directive idea (they're *new*) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3182 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 3d6c910ac..f4a77b94b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1161,10 +1161,6 @@ when used in a document. Add an option to include topics in the TOC? Another for sidebars? See docutils-develop 2003-01-29. - - _`parts.header` & _`parts.footer`: Add "header" and "footer" - directives to specify document-specific contents for header and - footer? - - _`misc.include`: - "encoding" option? Take default from runtime settings. Use @@ -1472,6 +1468,10 @@ when used in a document. either by running it at the command line with a ``--help`` option or through an exposed API. [Suggestion for Optik.] + - _`parts.header` & _`parts.footer`: Add "header" and "footer" + directives to specify document-specific contents for header and + footer? + Interpreted Text ---------------- -- cgit v1.2.1 From 71532b70cb8661bee0e5cb6cdf823c6902eb80bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 16:22:05 +0000 Subject: updated & added some ideas git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3183 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 5757c8013..99eade2e7 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -10,9 +10,10 @@ .. contents:: -A few quotes sum up the policies of the Docutils project. The IETF's -classic credo (by MIT professor Dave Clark) is an ideal we can aspire -to: +Docutils is a meritocracy based on code contribution and lots of +discussion [#bcs]_. A few quotes sum up the policies of the Docutils +project. The IETF's classic credo (by MIT professor Dave Clark) is an +ideal we can aspire to: We reject: kings, presidents, and voting. We believe in: rough consensus and running code. @@ -35,7 +36,7 @@ Therefore, we will endeavour to keep the barrier to entry as low as possible. The policies below should not be thought of as barriers, but merely as a codification of experience to date. These are "best practices", not absolutes; exceptions are expected, tolerated, and -used as a source of improvement. +used as a source of improvement. Feedback and criticism is welcome. As for control issues, Emmett Plant (CEO of the Xiph.org Foundation, originators of Ogg Vorbis) put it well when he said: @@ -43,6 +44,9 @@ originators of Ogg Vorbis) put it well when he said: Open source dictates that you lose a certain amount of control over your codebase, and that's okay with us. +.. [#bcs] Phrase borrowed from `Ben Collins-Sussman of the Subversion + project <http://www.red-bean.com/sussman/svn-anti-fud.html>`__. + Python Coding Conventions ========================= @@ -153,16 +157,16 @@ applicable), with particular emphasis as follows: cd docutils/test ./alltests.py - Docutils currently supports Python 2.1 [1]_ or later, with some - things only working (and being tested) on 2.3. Therefore, you - should actually have Pythons 2.1 [1]_, 2.2 and 2.3 installed and - always run the tests on all of them. (A good way to do that is to - always run the test suite through a short script that runs + Docutils currently supports Python 2.1 [#py21]_ or later, with some + things only working (and being tested) on Python 2.3+. Therefore, + you should actually have Pythons 2.1 [#py21]_, 2.2 and 2.3 installed + and always run the tests on all of them. (A good way to do that is + to always run the test suite through a short script that runs ``alltests.py`` under each version of Python.) If you can't afford intalling 3 Python versions, the edge cases (2.1 and 2.3) should cover most of it. - .. [1] Python 2.1 may be used providing the compiler package is + .. [#py21] Python 2.1 may be used providing the compiler package is installed. The compiler package can be found in the Tools/ directory of Python 2.1's source distribution. @@ -174,18 +178,10 @@ applicable), with particular emphasis as follows: * `PEP 290 - Code Migration and Modernization`__ __ http://www.python.org/doc/2.2.3/whatsnew/whatsnew22.html - __ http://www.python.org/doc/2.3.4/whatsnew/whatsnew23.html - __ http://www.python.org/dev/doc/devel/whatsnew/whatsnew24.html + __ http://www.python.org/doc/2.3.5/whatsnew/whatsnew23.html + __ http://www.python.org/doc/2.4.1/whatsnew/whatsnew24.html __ http://www.python.org/peps/pep-0290.html - Note that there are currently some known issues with development - versions of Python 2.4-to-be (see the thread about `Python 2.4 - compatibility`_ for details). There is no need to pass the test - suite under it, unless you wish to tackle these issues... - - .. _Python 2.4 compatibility: - http://thread.gmane.org/gmane.text.docutils.devel/2071 - * When adding new functionality (or fixing bugs), be sure to add test cases to the test suite. Practise test-first programming; it's fun, it's addictive, and it works! -- cgit v1.2.1 From dcc80f043243f34d0373a3150bacfff20b3212ae Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 19:36:11 +0000 Subject: added "header" & "footer" directives, tests, docs, support, and some tweaks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3184 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 ++ docs/ref/doctree.txt | 71 +++++++++++------ docs/ref/docutils.dtd | 7 +- docs/ref/rst/directives.txt | 41 +++++++++- docs/user/rst/cheatsheet.txt | 3 +- docutils/nodes.py | 40 +++++++--- docutils/parsers/rst/directives/__init__.py | 2 + docutils/parsers/rst/directives/parts.py | 33 ++++++++ docutils/parsers/rst/languages/af.py | 2 + docutils/parsers/rst/languages/cs.py | 2 + docutils/parsers/rst/languages/de.py | 2 + docutils/parsers/rst/languages/en.py | 2 + docutils/parsers/rst/languages/eo.py | 2 + docutils/parsers/rst/languages/es.py | 2 + docutils/parsers/rst/languages/fi.py | 2 + docutils/parsers/rst/languages/fr.py | 2 + docutils/parsers/rst/languages/it.py | 2 + docutils/parsers/rst/languages/nl.py | 2 + docutils/parsers/rst/languages/pt_br.py | 2 + docutils/parsers/rst/languages/ru.py | 4 +- docutils/parsers/rst/languages/sk.py | 2 + docutils/parsers/rst/languages/sv.py | 2 + docutils/parsers/rst/languages/zh_tw.py | 2 + docutils/transforms/frontmatter.py | 3 +- docutils/transforms/universal.py | 27 +++---- docutils/writers/html4css1.py | 4 +- .../expected/standalone_rst_html4css1.html | 8 ++ test/functional/input/data/header_footer.txt | 2 + test/functional/input/standalone_rst_html4css1.txt | 1 + .../test_rst/test_directives/test_decorations.py | 93 ++++++++++++++++++++++ 30 files changed, 310 insertions(+), 64 deletions(-) create mode 100644 test/functional/input/data/header_footer.txt create mode 100755 test/test_parsers/test_rst/test_directives/test_decorations.py diff --git a/HISTORY.txt b/HISTORY.txt index 756cb4973..645738786 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -42,6 +42,9 @@ Changes Since 0.3.7 - Added empty list as default value for the following attributes: ``ids``, ``names``, ``dupnames``, ``classes``, and ``backrefs``. - Removed ``Element.set_class()`` method. + - Added ``document.decoration`` attribute, + ``document.get_decoration`` method, and ``decoration.get_header`` + & ``.get_footer`` methods. * docutils/languages/nl.py: Added to project; Dutch mappings by Martijn Pieters. @@ -80,6 +83,10 @@ Changes Since 0.3.7 - Added support for ``file_insertion_enabled`` & ``raw_enabled`` settings in "include" & "raw" directives. +* docutils/parsers/rst/directives/parts.py: + + - Added "header" & "footer" directives. + * docutils/parsers/rst/directives/tables.py: - Added "list-table" directive. diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index dc19bdff3..912789239 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -62,7 +62,7 @@ one-to-many relationships; sections may contain (sub)sections, tables contain further body elements, etc. :: +--------------------------------------------------------------------+ - | document [may begin with a title, subtitle, docinfo, decoration] | + | document [may begin with a title, subtitle, decoration, docinfo] | | +--------------------------------------+ | | sections [each begins with a title] | +-----------------------------+-------------------------+------------+ @@ -112,7 +112,7 @@ Structural subelements are child elements of structural elements. Simple structuctural subelements (title_, subtitle_) contain text data; the others are compound and do not directly contain text data. -Category members: title_, subtitle_, docinfo_, decoration_, +Category members: title_, subtitle_, decoration_, docinfo_, transition_ @@ -146,7 +146,7 @@ body elements. There are two subcategories of body elements: simple and compound. Category members: admonition_, attention_, block_quote_, bullet_list_, -caution_, citation_, comment_, danger_, definition_list_, +caution_, citation_, comment_, compound_, danger_, definition_list_, doctest_block_, enumerated_list_, error_, field_list_, figure_, footnote_, hint_, image_, important_, line_block_, literal_block_, note_, option_list_, paragraph_, pending_, raw_, rubric_, @@ -173,9 +173,10 @@ Compound body elements contain local substructure (body subelements) and further body elements. They do not directly contain text data. Category members: admonition_, attention_, block_quote_, bullet_list_, -caution_, citation_, danger_, definition_list_, enumerated_list_, -error_, field_list_, figure_, footnote_, hint_, important_, note_, -option_list_, system_message_, table_, tip_, warning_ +caution_, citation_, compound_, danger_, definition_list_, +enumerated_list_, error_, field_list_, figure_, footnote_, hint_, +important_, note_, option_list_, system_message_, table_, tip_, +warning_ Body Subelements @@ -959,6 +960,12 @@ Pseudo-XML_ fragment from simple parsing:: `To be completed`_. +``compound`` +============ + +`To be completed`_. + + ``contact`` =========== @@ -1251,6 +1258,7 @@ Details :Processing: See the individual `decorative elements`_. + Content Model ------------- @@ -1758,20 +1766,21 @@ Content Model .. parsed-literal:: - ((title_, - subtitle_?)?, - docinfo_?, - decoration_?, - `%structure.model;`_) + ( (title_, subtitle_?)?, + decoration_?, + (docinfo_, transition_?)?, + `%structure.model;`_ ) Depending on the source of the data and the stage of processing, the "document" may not initially contain a "title". A document title is not directly representable in reStructuredText_. Instead, a lone top-level section may have its title promoted to become the document title_, and similarly for a lone second-level (sub)section's title to -become the document subtitle_. The "docinfo_" may be transformed from -an initial field_list_, and "decoration_" is usually constructed -programmatically. +become the document subtitle_. + +The contents of "decoration_" may be specified in a document, +constructed programmatically, or both. The "docinfo_" may be +transformed from an initial field_list_. See the `%structure.model;`_ parameter entity for details of the body of a ``document``. @@ -2314,7 +2323,7 @@ section numbers inserted by the "sectnum" directive. The ``header`` element is a container element whose contents are meant to appear at the top of a web page, or at the top of every printed -page. Docutils does not yet make use of the ``header`` element. +page. Details @@ -2350,7 +2359,17 @@ Content Model Examples -------- -None. +reStructuredText source fragment:: + + .. header:: This space for rent. + +Pseudo-XML_ fragment from simple parsing:: + + <document> + <decoration> + <header> + <paragraph> + This space for rent. ``hint`` @@ -4611,14 +4630,14 @@ Entity definition: .. parsed-literal:: - paragraph_ | literal_block_ | doctest_block_ | line_block_ - | block_quote_ | table_ | figure_ | image_ | footnote_ | citation_ - | rubric_ + paragraph_ | compound_ | literal_block_ | doctest_block_ + | line_block_ | block_quote_ + | table_ | figure_ | image_ | footnote_ | citation_ | rubric_ | bullet_list_ | enumerated_list_ | definition_list_ | field_list_ | option_list_ - | attention_ | caution_ | danger_ | error_ | hint_ | important_ - | note_ | tip_ | warning_ | admonition_ - | target_ | substitution_definition_ | comment_ | pending_ + | attention_ | caution_ | danger_ | error_ | hint_ | important_ | note_ + | tip_ | warning_ | admonition_ + | reference_ | target_ | substitution_definition_ | comment_ | pending_ | system_message_ | raw_ %additional.body.elements; @@ -4627,10 +4646,10 @@ wrapper DTDs to extend ``%body.elements;``. The ``%body.elements;`` parameter entity is directly employed in the content models of the following elements: admonition_, attention_, -block_quote_, caution_, citation_, danger_, definition_, description_, -entry_, error_, field_body_, footer_, footnote_, header_, hint_, -important_, legend_, list_item_, note_, sidebar_, system_message_, -tip_, topic_, warning_ +block_quote_, caution_, citation_, compound_, danger_, definition_, +description_, entry_, error_, field_body_, footer_, footnote_, +header_, hint_, important_, legend_, list_item_, note_, sidebar_, +system_message_, tip_, topic_, warning_ Via `%structure.model;`_, the ``%body.elements;`` parameter entity is indirectly employed in the content models of the document_ and diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index d9a76ce2e..0c0a55003 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -183,9 +183,10 @@ http://www.oasis-open.org/html/tm9901.htm). <!-- Optional elements may be generated by internal processing. --> <!ELEMENT document - ((title, subtitle?)?, - ((docinfo, decoration?, transition?) | decoration?), - %structure.model;)> + ( (title, subtitle?)?, + decoration?, + (docinfo, transition?)?, + %structure.model; )> <!ATTLIST document %basic.atts;> <!-- diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index d0f6cd453..5af9987e7 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -464,11 +464,10 @@ For example, all the element names in this content model are links:: .. parsed-literal:: - ((title_, - subtitle_?)?, - docinfo_?, + ( (title_, subtitle_?)?, decoration_?, - `%structure.model;`_) + (docinfo_, transition_?)?, + `%structure.model;`_ ) The following option is recognized: @@ -958,6 +957,40 @@ The following options are recognized: default is 1. +.. _header: +.. _footer: + +Document Header & Footer +======================== + +:Directive Types: "header" and "footer" +:Doctree Elements: decoration, header, footer +:Directive Arguments: None. +:Directive Options: None. +:Directive Content: Interpreted as body elements. + +(New in Docutils 0.3.8) + +The "header" and "footer" directives create document decorations, +useful for page navigation, notes, time/datestamp, etc. For example:: + + .. header:: This space for rent. + +This will add a paragraph to the document header, which will appear at +the top of the generated web page or at the top of every printed page. + +These directives may be used multiple times, cumulatively. There is +currently support for only one header and footer. + +In addition to the use of these directives to populate header and +footer content, content may also be added automatically by the +processing system. For example, if certain runtime settings are +enabled, the document footer is populated with processing information +such as a datestamp, a link to `the Docutils website`_, etc. + +.. _the Docutils website: http://docutils.sourceforge.net + + ------------ References ------------ diff --git a/docs/user/rst/cheatsheet.txt b/docs/user/rst/cheatsheet.txt index 73f7d27e3..03eddf814 100644 --- a/docs/user/rst/cheatsheet.txt +++ b/docs/user/rst/cheatsheet.txt @@ -87,10 +87,11 @@ highlights Block quote with class="highlights" pull-quote Block quote with class="pull-quote" compound Compound paragraphs [0.3.6] table Create a titled table [0.3.1] -list-table Create a table from a uniform two-level bullet list [0.3.8] +list-table Create a table from a uniform two-level bullet list [0.3.8] csv-table Create a table from CSV data (requires Python 2.3+) [0.3.4] contents Generate a table of contents sectnum Automatically number sections, subsections, etc. +header, footer Create document decorations [0.3.8] target-notes Create an explicit footnote for each external target meta HTML-specific metadata include Read an external reST file as if it were inline diff --git a/docutils/nodes.py b/docutils/nodes.py index e6bb52fac..270840dd3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -103,7 +103,7 @@ class Node: or replaced occurs after the current node, the old node will still be traversed, and any new nodes will not. - Within ``visit`` methods (and ``depart`` methods for + Within ``visit`` methods (and ``depart`` methods for `walkabout()`), `TreePruningException` subclasses may be raised (`SkipChildren`, `SkipSiblings`, `SkipNode`, `SkipDeparture`). @@ -168,7 +168,7 @@ class Node: # condition as first parameter). """ Return an iterable containing - + * self (if include_self is true) * all descendants in tree traversal order (if descend is true) * all siblings (if siblings is true) and their descendants (if @@ -672,15 +672,12 @@ class Root: pass class Titular: pass -class PreDecorative: - """Category of Node which may occur before Decorative Nodes.""" - -class PreBibliographic(PreDecorative): +class PreBibliographic: """Category of Node which may occur before Bibliographic Nodes.""" -class Bibliographic(PreDecorative): pass +class Bibliographic: pass -class Decorative: pass +class Decorative(PreBibliographic): pass class Structural: pass @@ -819,6 +816,9 @@ class document(Root, Structural, Element): self.transformer = docutils.transforms.Transformer(self) """Storage for transforms to be applied to this document.""" + self.decoration = None + """Document's `decoration` node.""" + self.document = self def asdom(self, dom=xml.dom.minidom): @@ -1036,6 +1036,16 @@ class document(Root, Structural, Element): return self.__class__(self.settings, self.reporter, **self.attributes) + def get_decoration(self): + if not self.decoration: + self.decoration = decoration() + index = self.first_child_not_matching_class(Titular) + if index is None: + self.children.append(self.decoration) + else: + self.children.insert(index, self.decoration) + return self.decoration + # ================ # Title Elements @@ -1067,7 +1077,19 @@ class copyright(Bibliographic, TextElement): pass # Decorative Elements # ===================== -class decoration(Decorative, Element): pass +class decoration(Decorative, Element): + + def get_header(self): + if not len(self.children) or not isinstance(self.children[0], header): + self.children.insert(0, header()) + return self.children[0] + + def get_footer(self): + if not len(self.children) or not isinstance(self.children[-1], footer): + self.children.append(footer()) + return self.children[-1] + + class header(Decorative, Element): pass class footer(Decorative, Element): pass diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 05f552edd..8e9f42284 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -118,6 +118,8 @@ _directive_registry = { 'figure': ('images', 'figure'), 'contents': ('parts', 'contents'), 'sectnum': ('parts', 'sectnum'), + 'header': ('parts', 'header'), + 'footer': ('parts', 'footer'), #'footnotes': ('parts', 'footnotes'), #'citations': ('parts', 'citations'), 'target-notes': ('references', 'target_notes'), diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index c87c239ec..623e2cd5e 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -80,3 +80,36 @@ sectnum.options = {'depth': int, 'start': int, 'prefix': directives.unchanged_required, 'suffix': directives.unchanged_required} + +def header_footer(node, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Contents of document header or footer.""" + if not content: + warning = state_machine.reporter.warning( + 'Content block expected for the "%s" directive; none found.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + node.children.append(nodes.paragraph( + '', 'Problem with the "%s" directive: no content supplied.' % name)) + return [warning] + text = '\n'.join(content) + state.nested_parse(content, content_offset, node) + return [] + +def header(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + decoration = state_machine.document.get_decoration() + node = decoration.get_header() + return header_footer(node, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine) + +header.content = 1 + +def footer(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + decoration = state_machine.document.get_decoration() + node = decoration.get_footer() + return header_footer(node, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine) + +footer.content = 1 diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index e3664f717..9dddae716 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -56,6 +56,8 @@ directives = { 'inhoud': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'voetnote': 'footnotes', #'aanhalings': 'citations', 'teikennotas': 'target-notes', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index af32e69d6..7163cbf8f 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -57,6 +57,8 @@ directives = { u'obsah': 'contents', u'sectnum (translation required)': 'sectnum', u'section-numbering (translation required)': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', u'target-notes (translation required)': 'target-notes', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 8ea77485b..9431f0e9d 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -60,6 +60,8 @@ directives = { 'kapitel-nummerierung': 'sectnum', 'abschnitts-nummerierung': 'sectnum', u'linkziel-fu\xdfnoten': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #u'fu\xdfnoten': 'footnotes', #'zitate': 'citations', } diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index dcd5b9584..63ddcb1b9 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -57,6 +57,8 @@ directives = { 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', + 'header': 'header', + 'footer': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', 'target-notes': 'target-notes', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 4065f88d4..8f7e33807 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -63,6 +63,8 @@ directives = { u'enhavo': 'contents', u'seknum': 'sectnum', u'sekcia-numerado': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', u'celaj-notoj': 'target-notes', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index efd7ece08..59b3a2228 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -68,6 +68,8 @@ directives = { u'numeracion-seccion': 'sectnum', u'numeraci\u00f3n-secci\u00f3n': 'sectnum', u'notas-destino': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', u'restructuredtext-test-directive': 'restructuredtext-test-directive'} diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index a718e7773..c60444e3f 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -54,6 +54,8 @@ directives = { u'rooli': u'role', u'sis\u00e4llys': u'contents', u'kappale': u'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #u'alaviitteet': u'footnotes', #u'viitaukset': u'citations', u'target-notes (translation required)': u'target-notes'} diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 26668ef09..8b9cb04de 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -61,6 +61,8 @@ directives = { u'sectnum': 'sectnum', u'section-num\u00E9rot\u00E9e': 'sectnum', u'liens': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #u'footnotes (translation required)': 'footnotes', #u'citations (translation required)': 'citations', } diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index a04f98fa4..ee31b42ae 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -58,6 +58,8 @@ directives = { 'seznum': 'sectnum', 'sezioni-autonumerate': 'sectnum', 'annota-riferimenti-esterni': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} diff --git a/docutils/parsers/rst/languages/nl.py b/docutils/parsers/rst/languages/nl.py index fa6a1324a..35942ca05 100644 --- a/docutils/parsers/rst/languages/nl.py +++ b/docutils/parsers/rst/languages/nl.py @@ -59,6 +59,8 @@ directives = { 'sectnum': 'sectnum', 'sectie-nummering': 'sectnum', 'hoofdstuk-nummering': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'voetnoten': 'footnotes', #'citaten': 'citations', 'verwijzing-voetnoten': 'target-notes', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 92801268b..6f5d4cc6b 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -57,6 +57,8 @@ directives = { u'\u00EDndice': 'contents', 'numsec': 'sectnum', u'numera\u00E7\u00E3o-de-se\u00E7\u00F5es': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #u'notas-de-rorap\u00E9': 'footnotes', #u'cita\u00E7\u00F5es': 'citations', u'links-no-rodap\u00E9': 'target-notes', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 44363f5f1..4ccca658c 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -61,7 +61,9 @@ directives = { u'\u0441\u043e\u0432\u0435\u0442': u'hint', u'\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435': u'contents', u'\u0442\u0435\u043c\u0430': u'topic', - u'\u044d\u043f\u0438\u0433\u0440\u0430\u0444': u'epigraph'} + u'\u044d\u043f\u0438\u0433\u0440\u0430\u0444': u'epigraph', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer',} """Russian name to registered (in directives/__init__.py) directive name mapping.""" diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index fc1c54752..2ba849700 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -57,6 +57,8 @@ directives = { u'\xe8as\x9d': 'sectnum', u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', u'cie\xbeov\xe9-pozn\xe1mky': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #u'footnotes': 'footnotes', #u'citations': 'citations', } diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index b64b7a57f..d6f6fba46 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -56,6 +56,8 @@ directives = { u'inneh\u00e5ll': 'contents', u'sektionsnumrering': 'sectnum', u'target-notes (translation required)': 'target-notes', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', } diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 57c04eaaa..15f253114 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -57,6 +57,8 @@ directives = { 'contents (translation required)': 'contents', 'sectnum (translation required)': 'sectnum', 'section-numbering (translation required)': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', #'footnotes (translation required)': 'footnotes', #'citations (translation required)': 'citations', 'target-notes (translation required)': 'target-notes', diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 8a5581313..22ecbbf25 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -258,11 +258,10 @@ class DocInfo(Transform): candidate = document[index] if isinstance(candidate, nodes.field_list): biblioindex = document.first_child_not_matching_class( - nodes.Titular) + (nodes.Titular, nodes.Decorative)) nodelist = self.extract_bibliographic(candidate) del document[index] # untransformed field list (candidate) document[biblioindex:biblioindex] = nodelist - return def extract_bibliographic(self, field_list): docinfo = nodes.docinfo() diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index c77d72df8..4ed7b6896 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -32,19 +32,16 @@ class Decorations(Transform): default_priority = 820 def apply(self): - header = self.generate_header() - footer = self.generate_footer() - if header or footer: - decoration = nodes.decoration() - decoration += header - decoration += footer - document = self.document - index = document.first_child_not_matching_class( - nodes.PreDecorative) - if index is None: - document += decoration - else: - document[index:index] = [decoration] + header_nodes = self.generate_header() + if header_nodes: + decoration = self.document.get_decoration() + header = decoration.get_header() + header.children.extend(header_nodes) + footer_nodes = self.generate_footer() + if footer_nodes: + decoration = self.document.get_decoration() + footer = decoration.get_footer() + footer.children.extend(footer_nodes) def generate_header(self): return None @@ -79,9 +76,7 @@ class Decorations(Transform): nodes.reference('', 'reStructuredText', refuri='http://' 'docutils.sourceforge.net/rst.html'), nodes.Text(' source.\n')]) - footer = nodes.footer() - footer += nodes.paragraph('', '', *text) - return footer + return [nodes.paragraph('', '', *text)] else: return None diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f23238307..07e03b4b1 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -732,7 +732,7 @@ class HTMLTranslator(nodes.NodeVisitor): start = self.context.pop() footer = (['<hr class="docutils footer" />\n', self.starttag(node, 'div', CLASS='footer')] - + self.body[start:] + ['</div>\n']) + + self.body[start:] + ['\n</div>\n']) self.footer.extend(footer) self.body_suffix[:0] = footer del self.body[start:] @@ -814,7 +814,7 @@ class HTMLTranslator(nodes.NodeVisitor): start = self.context.pop() header = [self.starttag(node, 'div', CLASS='header')] header.extend(self.body[start:]) - header.append('<hr class="docutils header"/>\n</div>\n') + header.append('\n</div>\n<hr class="docutils header"/>\n') self.body_prefix.extend(header) self.header = header del self.body[start:] diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index be1c9816e..78605137a 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -17,6 +17,10 @@ <link rel="stylesheet" href="../../../tools/stylesheets/default.css" type="text/css" /> </head> <body> +<div class="header"> +Document header +</div> +<hr class="docutils header"/> <span id="doctitle"></span><div class="document" id="restructuredtext-test-document"> <h1 class="title">reStructuredText Test Document</h1> <span id="subtitle"></span><h2 class="subtitle" id="examples-of-syntax-constructs">Examples of Syntax Constructs</h2> @@ -918,5 +922,9 @@ Unknown target name: "hyperlink reference without a target".</div> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> +<hr class="docutils footer" /> +<div class="footer"> +Document footer +</div> </body> </html> diff --git a/test/functional/input/data/header_footer.txt b/test/functional/input/data/header_footer.txt new file mode 100644 index 000000000..875c9fac0 --- /dev/null +++ b/test/functional/input/data/header_footer.txt @@ -0,0 +1,2 @@ +.. header:: Document header +.. footer:: Document footer diff --git a/test/functional/input/standalone_rst_html4css1.txt b/test/functional/input/standalone_rst_html4css1.txt index 3847a089e..05f0287d0 100644 --- a/test/functional/input/standalone_rst_html4css1.txt +++ b/test/functional/input/standalone_rst_html4css1.txt @@ -1,4 +1,5 @@ .. include:: data/standard.txt +.. include:: data/header_footer.txt .. include:: data/table_colspan.txt .. include:: data/table_rowspan.txt .. include:: data/table_complex.txt diff --git a/test/test_parsers/test_rst/test_directives/test_decorations.py b/test/test_parsers/test_rst/test_directives/test_decorations.py new file mode 100755 index 000000000..c770c6a49 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_decorations.py @@ -0,0 +1,93 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for the "header" & "footer" directives. +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['headers'] = [ +["""\ +.. header:: a paragraph for the header +""", +"""\ +<document source="test data"> + <decoration> + <header> + <paragraph> + a paragraph for the header +"""], +["""\ +.. header:: +""", +"""\ +<document source="test data"> + <decoration> + <header> + <paragraph> + Problem with the "header" directive: no content supplied. + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Content block expected for the "header" directive; none found. + <literal_block xml:space="preserve"> + .. header:: +"""], +["""\ +.. header:: first part of the header +.. header:: second part of the header +""", +"""\ +<document source="test data"> + <decoration> + <header> + <paragraph> + first part of the header + <paragraph> + second part of the header +"""], +] + +totest['footers'] = [ +["""\ +.. footer:: a paragraph for the footer +""", +"""\ +<document source="test data"> + <decoration> + <footer> + <paragraph> + a paragraph for the footer +"""], +["""\ +.. footer:: even if a footer is declared first +.. header:: the header appears first +""", +"""\ +<document source="test data"> + <decoration> + <header> + <paragraph> + the header appears first + <footer> + <paragraph> + even if a footer is declared first +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 9999f5ba8278fd069bdd966d506d27def9f03bc3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 19:37:12 +0000 Subject: new functional test for pseudo-XML output git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3185 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../expected/standalone_rst_pseudoxml.txt | 1700 ++++++++++++++++++++ test/functional/tests/standalone_rst_pseudoxml.py | 8 + 2 files changed, 1708 insertions(+) create mode 100644 test/functional/expected/standalone_rst_pseudoxml.txt create mode 100644 test/functional/tests/standalone_rst_pseudoxml.py diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt new file mode 100644 index 000000000..b4d510854 --- /dev/null +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -0,0 +1,1700 @@ +<document ids="restructuredtext-test-document doctitle" names="restructuredtext test document doctitle" source="functional/input/standalone_rst_html4css1.txt"> + <title> + reStructuredText Test Document + <subtitle ids="examples-of-syntax-constructs subtitle" names="examples of syntax constructs subtitle"> + Examples of Syntax Constructs + <decoration> + <header> + <paragraph> + Document header + <footer> + <paragraph> + Document footer + <docinfo> + <author> + David Goodger + <address xml:space="preserve"> + 123 Example Street + Example, EX Canada + A1B 2C3 + <contact> + <reference refuri="mailto:goodger@users.sourceforge.net"> + goodger@users.sourceforge.net + <authors> + <author> + Me + <author> + Myself + <author> + I + <organization> + humankind + <date> + Now, or yesterday. Or maybe even + <emphasis> + before + yesterday. + <status> + This is a "work in progress" + <revision> + is managed by a version control system. + <version> + 1 + <copyright> + This document has been placed in the public domain. You + may do with it as you wish. You may copy, modify, + redistribute, reattribute, sell, buy, rent, lease, + destroy, or improve it, quote it at length, excerpt, + incorporate, collate, fold, staple, or mutilate it, or do + anything else to it that your or anyone else's heart + desires. + <field> + <field_name> + field name + <field_body> + <paragraph> + This is a "generic bibliographic field". + <field> + <field_name> + field name "2" + <field_body> + <paragraph> + Generic bibliographic fields may contain multiple body elements. + <paragraph> + Like this. + <topic classes="dedication"> + <title> + Dedication + <paragraph> + For Docutils users & co-developers. + <topic classes="abstract"> + <title> + Abstract + <paragraph> + This is a test document, containing at least one example of each + reStructuredText construct. + <comment xml:space="preserve"> + This is a comment. Note how any initial comments are moved by + transforms to after the document title, subtitle, and docinfo. + <target refid="doctitle"> + <comment xml:space="preserve"> + Above is the document title, and below is the subtitle. + They are transformed from section titles after parsing. + <target refid="subtitle"> + <comment xml:space="preserve"> + bibliographic fields (which also require a transform): + <meta content="reStructuredText, test, parser" name="keywords"> + <meta content="A test document, containing at least one example of each reStructuredText construct." lang="en" name="description"> + <topic classes="contents" ids="table-of-contents" names="table of contents"> + <title> + Table of Contents + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id25" refid="structural-elements"> + <generated classes="sectnum"> + 1    + Structural Elements + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id26" refid="section-title"> + <generated classes="sectnum"> + 1.1    + Section Title + <list_item> + <paragraph> + <reference ids="id27" refid="empty-section"> + <generated classes="sectnum"> + 1.2    + Empty Section + <list_item> + <paragraph> + <reference ids="id28" refid="transitions"> + <generated classes="sectnum"> + 1.3    + Transitions + <list_item> + <paragraph> + <reference ids="id29" refid="body-elements"> + <generated classes="sectnum"> + 2    + Body Elements + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id30" refid="paragraphs"> + <generated classes="sectnum"> + 2.1    + Paragraphs + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id31" refid="inline-markup"> + <generated classes="sectnum"> + 2.1.1    + Inline Markup + <list_item> + <paragraph> + <reference ids="id32" refid="bullet-lists"> + <generated classes="sectnum"> + 2.2    + Bullet Lists + <list_item> + <paragraph> + <reference ids="id33" refid="enumerated-lists"> + <generated classes="sectnum"> + 2.3    + Enumerated Lists + <list_item> + <paragraph> + <reference ids="id34" refid="definition-lists"> + <generated classes="sectnum"> + 2.4    + Definition Lists + <list_item> + <paragraph> + <reference ids="id35" refid="field-lists"> + <generated classes="sectnum"> + 2.5    + Field Lists + <list_item> + <paragraph> + <reference ids="id36" refid="option-lists"> + <generated classes="sectnum"> + 2.6    + Option Lists + <list_item> + <paragraph> + <reference ids="id37" refid="literal-blocks"> + <generated classes="sectnum"> + 2.7    + Literal Blocks + <list_item> + <paragraph> + <reference ids="id38" refid="line-blocks"> + <generated classes="sectnum"> + 2.8    + Line Blocks + <list_item> + <paragraph> + <reference ids="id39" refid="block-quotes"> + <generated classes="sectnum"> + 2.9    + Block Quotes + <list_item> + <paragraph> + <reference ids="id40" refid="doctest-blocks"> + <generated classes="sectnum"> + 2.10    + Doctest Blocks + <list_item> + <paragraph> + <reference ids="id41" refid="footnotes"> + <generated classes="sectnum"> + 2.11    + Footnotes + <list_item> + <paragraph> + <reference ids="id42" refid="citations"> + <generated classes="sectnum"> + 2.12    + Citations + <list_item> + <paragraph> + <reference ids="id43" refid="targets"> + <generated classes="sectnum"> + 2.13    + Targets + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id44" refid="duplicate-target-names"> + <generated classes="sectnum"> + 2.13.1    + Duplicate Target Names + <list_item> + <paragraph> + <reference ids="id45" refid="id18"> + <generated classes="sectnum"> + 2.13.2    + Duplicate Target Names + <list_item> + <paragraph> + <reference ids="id46" refid="directives"> + <generated classes="sectnum"> + 2.14    + Directives + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id47" refid="document-parts"> + <generated classes="sectnum"> + 2.14.1    + Document Parts + <list_item> + <paragraph> + <reference ids="id48" refid="images"> + <generated classes="sectnum"> + 2.14.2    + Images + <list_item> + <paragraph> + <reference ids="id49" refid="admonitions"> + <generated classes="sectnum"> + 2.14.3    + Admonitions + <list_item> + <paragraph> + <reference ids="id50" refid="topics-sidebars-and-rubrics"> + <generated classes="sectnum"> + 2.14.4    + Topics, Sidebars, and Rubrics + <list_item> + <paragraph> + <reference ids="id51" refid="target-footnotes"> + <generated classes="sectnum"> + 2.14.5    + Target Footnotes + <list_item> + <paragraph> + <reference ids="id52" refid="replacement-text"> + <generated classes="sectnum"> + 2.14.6    + Replacement Text + <list_item> + <paragraph> + <reference ids="id53" refid="compound-paragraph"> + <generated classes="sectnum"> + 2.14.7    + Compound Paragraph + <list_item> + <paragraph> + <reference ids="id54" refid="substitution-definitions"> + <generated classes="sectnum"> + 2.15    + Substitution Definitions + <list_item> + <paragraph> + <reference ids="id55" refid="comments"> + <generated classes="sectnum"> + 2.16    + Comments + <list_item> + <paragraph> + <reference ids="id56" refid="raw-text"> + <generated classes="sectnum"> + 2.17    + Raw text + <list_item> + <paragraph> + <reference ids="id57" refid="colspanning-tables"> + <generated classes="sectnum"> + 2.18    + Colspanning tables + <list_item> + <paragraph> + <reference ids="id58" refid="rowspanning-tables"> + <generated classes="sectnum"> + 2.19    + Rowspanning tables + <list_item> + <paragraph> + <reference ids="id59" refid="complex-tables"> + <generated classes="sectnum"> + 2.20    + Complex tables + <list_item> + <paragraph> + <reference ids="id60" refid="list-tables"> + <generated classes="sectnum"> + 2.21    + List Tables + <list_item> + <paragraph> + <reference ids="id61" refid="error-handling"> + <generated classes="sectnum"> + 3    + Error Handling + <section ids="structural-elements" names="structural elements"> + <title auto="1" refid="id25"> + <generated classes="sectnum"> + 1    + Structural Elements + <section ids="section-title" names="section title"> + <title auto="1" refid="id26"> + <generated classes="sectnum"> + 1.1    + Section Title + <paragraph> + That's it, the text just above this line. + <section ids="empty-section" names="empty section"> + <title auto="1" refid="id27"> + <generated classes="sectnum"> + 1.2    + Empty Section + <section ids="transitions" names="transitions"> + <title auto="1" refid="id28"> + <generated classes="sectnum"> + 1.3    + Transitions + <paragraph> + Here's a transition: + <transition> + <paragraph> + It divides the section. Transitions may also occur between sections: + <transition> + <section ids="body-elements" names="body elements"> + <title auto="1" refid="id29"> + <generated classes="sectnum"> + 2    + Body Elements + <section ids="paragraphs" names="paragraphs"> + <title auto="1" refid="id30"> + <generated classes="sectnum"> + 2.1    + Paragraphs + <paragraph> + A paragraph. + <section ids="inline-markup" names="inline markup"> + <title auto="1" refid="id31"> + <generated classes="sectnum"> + 2.1.1    + Inline Markup + <paragraph> + Paragraphs contain text and may contain inline markup: + <emphasis> + emphasis + , + <strong> + strong emphasis + , + <literal> + inline literals + , standalone hyperlinks + ( + <reference refuri="http://www.python.org"> + http://www.python.org + ), external hyperlinks ( + <reference name="Python" refuri="http://www.python.org/"> + Python + + <footnote_reference auto="1" ids="id22" refid="id21"> + 5 + ), internal + cross-references ( + <reference name="example" refid="example"> + example + ), external hyperlinks with embedded URIs + ( + <reference name="Python web site" refuri="http://www.python.org"> + Python web site + ), footnote references + (manually numbered + <footnote_reference ids="id1" refid="id6"> + 1 + , anonymous auto-numbered + <footnote_reference auto="1" ids="id2" refid="id9"> + 3 + , labeled + auto-numbered + <footnote_reference auto="1" ids="id3" refid="label"> + 2 + , or symbolic + <footnote_reference auto="*" ids="id4" refid="id10"> + * + ), citation references + ( + <citation_reference ids="id5" refid="cit2002"> + CIT2002 + ), substitution references ( + <image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"> + ), and + <target ids="inline-hyperlink-targets" names="inline hyperlink targets"> + inline + hyperlink targets + (see + <reference name="Targets" refid="targets"> + Targets + below for a reference back to here). + Character-level inline markup is also possible (although exceedingly + ugly!) in + <emphasis> + re + <literal> + Structured + <emphasis> + Text + . Problems are indicated by + <problematic ids="id20" refid="id19"> + |problematic| + text (generated by processing errors; this one is + intentional). Here is a reference to the + <reference name="doctitle" refid="doctitle"> + doctitle + and the + <reference name="subtitle" refid="subtitle"> + subtitle + . + <paragraph> + The default role for interpreted text is + <title_reference> + Title Reference + . Here are + some explicit interpreted text roles: a PEP reference ( + <reference refuri="http://www.python.org/peps/pep-0287.html"> + PEP 287 + ); an + RFC reference ( + <reference refuri="http://www.faqs.org/rfcs/rfc2822.html"> + RFC 2822 + ); a + <subscript> + subscript + ; a + <superscript> + superscript + ; + and explicit roles for + <emphasis> + standard + + <strong> + inline + + <literal> + markup + . + <comment xml:space="preserve"> + DO NOT RE-WRAP THE FOLLOWING PARAGRAPH! + <paragraph> + Let's test wrapping and whitespace significance in inline literals: + <literal> + This is an example of --inline-literal --text, --including some-- + strangely--hyphenated-words. Adjust-the-width-of-your-browser-window + to see how the text is wrapped. -- ---- -------- Now note the + spacing between the words of this sentence (words + should be grouped in pairs). + <paragraph> + If the + <literal> + --pep-references + option was supplied, there should be a + live link to PEP 258 here. + <section ids="bullet-lists" names="bullet lists"> + <title auto="1" refid="id32"> + <generated classes="sectnum"> + 2.2    + Bullet Lists + <bullet_list bullet="-"> + <list_item> + <paragraph> + A bullet list + <bullet_list bullet="+"> + <list_item> + <paragraph> + Nested bullet list. + <list_item> + <paragraph> + Nested item 2. + <list_item> + <paragraph> + Item 2. + <paragraph> + Paragraph 2 of item 2. + <bullet_list bullet="*"> + <list_item> + <paragraph> + Nested bullet list. + <list_item> + <paragraph> + Nested item 2. + <bullet_list bullet="-"> + <list_item> + <paragraph> + Third level. + <list_item> + <paragraph> + Item 2. + <list_item> + <paragraph> + Nested item 3. + <list_item> + <paragraph> + This nested list should be compacted by the HTML writer. + <target ids="target" names="target"> + <comment xml:space="preserve"> + Even if this item contains a target and a comment. + <section ids="enumerated-lists" names="enumerated lists"> + <title auto="1" refid="id33"> + <generated classes="sectnum"> + 2.3    + Enumerated Lists + <enumerated_list enumtype="arabic" prefix="" suffix="."> + <list_item> + <paragraph> + Arabic numerals. + <enumerated_list enumtype="loweralpha" prefix="" suffix=")"> + <list_item> + <paragraph> + lower alpha) + <enumerated_list enumtype="lowerroman" prefix="(" suffix=")"> + <list_item> + <paragraph> + (lower roman) + <enumerated_list enumtype="upperalpha" prefix="" suffix="."> + <list_item> + <paragraph> + upper alpha. + <enumerated_list enumtype="upperroman" prefix="" suffix=")"> + <list_item> + <paragraph> + upper roman) + <list_item> + <paragraph> + Lists that don't start at 1: + <enumerated_list enumtype="arabic" prefix="" start="3" suffix="."> + <list_item> + <paragraph> + Three + <list_item> + <paragraph> + Four + <enumerated_list enumtype="upperalpha" prefix="" start="3" suffix="."> + <list_item> + <paragraph> + C + <list_item> + <paragraph> + D + <enumerated_list enumtype="lowerroman" prefix="" start="3" suffix="."> + <list_item> + <paragraph> + iii + <list_item> + <paragraph> + iv + <section ids="definition-lists" names="definition lists"> + <title auto="1" refid="id34"> + <generated classes="sectnum"> + 2.4    + Definition Lists + <definition_list> + <definition_list_item> + <term> + Term + <definition> + <paragraph> + Definition + <definition_list_item> + <term> + Term + <classifier> + classifier + <definition> + <paragraph> + Definition paragraph 1. + <paragraph> + Definition paragraph 2. + <definition_list_item> + <term> + Term + <definition> + <paragraph> + Definition + <definition_list_item> + <term> + Term + <classifier> + classifier one + <classifier> + classifier two + <definition> + <paragraph> + Definition + <section ids="field-lists" names="field lists"> + <title auto="1" refid="id35"> + <generated classes="sectnum"> + 2.5    + Field Lists + <field_list> + <field> + <field_name> + what + <field_body> + <paragraph> + Field lists map field names to field bodies, like database + records. They are often part of an extension syntax. They are + an unambiguous variant of RFC 2822 fields. + <field> + <field_name> + how arg1 arg2 + <field_body> + <paragraph> + The field marker is a colon, the field name, and a colon. + <paragraph> + The field body may contain one or more body elements, indented + relative to the field marker. + <field> + <field_name> + credits + <field_body> + <paragraph classes="credits"> + This paragraph has the + <title_reference> + credits + class set. (This is actually not + about credits but just for ensuring that the class attribute + doesn't get stripped away.) + <section ids="option-lists" names="option lists"> + <title auto="1" refid="id36"> + <generated classes="sectnum"> + 2.6    + Option Lists + <paragraph> + For listing command-line options: + <option_list> + <option_list_item> + <option_group> + <option> + <option_string> + -a + <description> + <paragraph> + command-line option "a" + <option_list_item> + <option_group> + <option> + <option_string> + -b + <option_argument delimiter=" "> + file + <description> + <paragraph> + options can have arguments + and long descriptions + <option_list_item> + <option_group> + <option> + <option_string> + --long + <description> + <paragraph> + options can be long also + <option_list_item> + <option_group> + <option> + <option_string> + --input + <option_argument delimiter="="> + file + <description> + <paragraph> + long options can also have + arguments + <option_list_item> + <option_group> + <option> + <option_string> + --very-long-option + <description> + <paragraph> + The description can also start on the next line. + <paragraph> + The description may contain multiple body elements, + regardless of where it starts. + <option_list_item> + <option_group> + <option> + <option_string> + -x + <option> + <option_string> + -y + <option> + <option_string> + -z + <description> + <paragraph> + Multiple options are an "option group". + <option_list_item> + <option_group> + <option> + <option_string> + -v + <option> + <option_string> + --verbose + <description> + <paragraph> + Commonly-seen: short & long options. + <option_list_item> + <option_group> + <option> + <option_string> + -1 + <option_argument delimiter=" "> + file + <option> + <option_string> + --one + <option_argument delimiter="="> + file + <option> + <option_string> + --two + <option_argument delimiter=" "> + file + <description> + <paragraph> + Multiple options with arguments. + <option_list_item> + <option_group> + <option> + <option_string> + /V + <description> + <paragraph> + DOS/VMS-style options too + <paragraph> + There must be at least two spaces between the option and the + description. + <section ids="literal-blocks" names="literal blocks"> + <title auto="1" refid="id37"> + <generated classes="sectnum"> + 2.7    + Literal Blocks + <paragraph> + Literal blocks are indicated with a double-colon ("::") at the end of + the preceding paragraph (over there + <literal> + --> + ). They can be indented: + <literal_block xml:space="preserve"> + if literal_block: + text = 'is left as-is' + spaces_and_linebreaks = 'are preserved' + markup_processing = None + <paragraph> + Or they can be quoted without indentation: + <literal_block xml:space="preserve"> + >> Great idea! + > + > Why didn't I think of that? + <section ids="line-blocks" names="line blocks"> + <title auto="1" refid="id38"> + <generated classes="sectnum"> + 2.8    + Line Blocks + <paragraph> + This section tests line blocks. Line blocks are body elements which + consist of lines and other line blocks. Nested line blocks cause + indentation. + <line_block> + <line> + This is a line block. It ends with a blank line. + <line_block> + <line> + New lines begin with a vertical bar ("|"). + <line> + Line breaks and initial indent are significant, and preserved. + <line_block> + <line> + Continuation lines are also possible. A long line that is intended + to wrap should begin with a space in place of the vertical bar. + <line> + The left edge of a continuation line need not be aligned with + the left edge of the text above it. + <line_block> + <line> + This is a second line block. + <line> + <line> + Blank lines are permitted internally, but they must begin with a "|". + <paragraph> + Another line block, surrounded by paragraphs: + <line_block> + <line> + And it's no good waiting by the window + <line> + It's no good waiting for the sun + <line> + Please believe me, the things you dream of + <line> + They don't fall in the lap of no-one + <paragraph> + Take it away, Eric the Orchestra Leader! + <block_quote> + <line_block> + <line> + A one, two, a one two three four + <line> + <line> + Half a bee, philosophically, + <line_block> + <line> + must, + <emphasis> + ipso facto + , half not be. + <line> + But half the bee has got to be, + <line_block> + <line> + <emphasis> + vis a vis + its entity. D'you see? + <line> + <line> + But can a bee be said to be + <line_block> + <line> + or not to be an entire bee, + <line_block> + <line> + when half the bee is not a bee, + <line_block> + <line> + due to some ancient injury? + <line> + <line> + Singing... + <section ids="block-quotes" names="block quotes"> + <title auto="1" refid="id39"> + <generated classes="sectnum"> + 2.9    + Block Quotes + <paragraph> + Block quotes consist of indented body elements: + <block_quote> + <paragraph> + My theory by A. Elk. Brackets Miss, brackets. This theory goes + as follows and begins now. All brontosauruses are thin at one + end, much much thicker in the middle and then thin again at the + far end. That is my theory, it is mine, and belongs to me and I + own it, and what it is too. + <attribution> + Anne Elk (Miss) + <section ids="doctest-blocks" names="doctest blocks"> + <title auto="1" refid="id40"> + <generated classes="sectnum"> + 2.10    + Doctest Blocks + <doctest_block xml:space="preserve"> + >>> print 'Python-specific usage examples; begun with ">>>"' + Python-specific usage examples; begun with ">>>" + >>> print '(cut and pasted from interactive Python sessions)' + (cut and pasted from interactive Python sessions) + <section ids="footnotes" names="footnotes"> + <title auto="1" refid="id41"> + <generated classes="sectnum"> + 2.11    + Footnotes + <footnote backrefs="id1 id7" ids="id6" names="1"> + <label> + 1 + <paragraph> + A footnote contains body elements, consistently indented by at + least 3 spaces. + <paragraph> + This is the footnote's second paragraph. + <footnote auto="1" backrefs="id3 id8" ids="label" names="label"> + <label> + 2 + <paragraph> + Footnotes may be numbered, either manually (as in + <footnote_reference ids="id7" refid="id6"> + 1 + ) or + automatically using a "#"-prefixed label. This footnote has a + label so it can be referred to from multiple places, both as a + footnote reference ( + <footnote_reference auto="1" ids="id8" refid="label"> + 2 + ) and as a hyperlink reference + ( + <reference name="label" refid="label"> + label + ). + <footnote auto="1" backrefs="id2" ids="id9" names="3"> + <label> + 3 + <paragraph> + This footnote is numbered automatically and anonymously using a + label of "#" only. + <paragraph> + This is the second paragraph. + <paragraph> + And this is the third paragraph. + <footnote auto="*" backrefs="id4" ids="id10"> + <label> + * + <paragraph> + Footnotes may also use symbols, specified with a "*" label. + Here's a reference to the next footnote: + <footnote_reference auto="*" ids="id11" refid="id12"> + † + . + <footnote auto="*" backrefs="id11" ids="id12"> + <label> + † + <paragraph> + This footnote shows the next symbol in the sequence. + <footnote ids="id13" names="4"> + <label> + 4 + <paragraph> + Here's an unreferenced footnote, with a reference to a + nonexistent footnote: + <problematic ids="id70" refid="id69"> + [5]_ + . + <section ids="citations" names="citations"> + <title auto="1" refid="id42"> + <generated classes="sectnum"> + 2.12    + Citations + <citation backrefs="id5 id15" ids="cit2002" names="cit2002"> + <label> + CIT2002 + <paragraph> + Citations are text-labeled footnotes. They may be + rendered separately and differently from footnotes. + <paragraph> + Here's a reference to the above, + <citation_reference ids="id15" refid="cit2002"> + CIT2002 + , and a + <problematic ids="id72" refid="id71"> + [nonexistent]_ + + citation. + <section ids="targets" names="targets"> + <title auto="1" refid="id43"> + <generated classes="sectnum"> + 2.13    + Targets + <target refid="example"> + <paragraph ids="example" names="example"> + This paragraph is pointed to by the explicit "example" target. A + reference can be found under + <reference name="Inline Markup" refid="inline-markup"> + Inline Markup + , above. + <reference name="Inline hyperlink targets" refid="inline-hyperlink-targets"> + Inline + hyperlink targets + are also possible. + <paragraph> + Section headers are implicit targets, referred to by name. See + <reference name="Targets" refid="targets"> + Targets + , which is a subsection of + <reference name="Body Elements" refid="body-elements"> + Body Elements + . + <paragraph> + Explicit external targets are interpolated into references such as + " + <reference name="Python" refuri="http://www.python.org/"> + Python + + <footnote_reference auto="1" ids="id23" refid="id21"> + 5 + ". + <target ids="python" names="python" refuri="http://www.python.org/"> + <paragraph> + Targets may be indirect and anonymous. Thus + <reference anonymous="1" name="this phrase" refid="targets"> + this phrase + may also + refer to the + <reference name="Targets" refid="targets"> + Targets + section. + <target anonymous="1" ids="id17" refid="targets"> + <paragraph> + Here's a + <problematic ids="id74" refid="id73"> + `hyperlink reference without a target`_ + , which generates an + error. + <section dupnames="duplicate target names" ids="duplicate-target-names"> + <title auto="1" refid="id44"> + <generated classes="sectnum"> + 2.13.1    + Duplicate Target Names + <paragraph> + Duplicate names in section headers or other implicit targets will + generate "info" (level-1) system messages. Duplicate names in + explicit targets will generate "warning" (level-2) system messages. + <section dupnames="duplicate target names" ids="id18"> + <title auto="1" refid="id45"> + <generated classes="sectnum"> + 2.13.2    + Duplicate Target Names + <paragraph> + Since there are two "Duplicate Target Names" section headers, we + cannot uniquely refer to either of them by name. If we try to (like + this: + <problematic ids="id76" refid="id75"> + `Duplicate Target Names`_ + ), an error is generated. + <section ids="directives" names="directives"> + <title auto="1" refid="id46"> + <generated classes="sectnum"> + 2.14    + Directives + <topic classes="contents" ids="contents" names="contents"> + <bullet_list classes="auto-toc"> + <list_item> + <paragraph> + <reference ids="id62" refid="document-parts"> + <generated classes="sectnum"> + 2.14.1    + Document Parts + <list_item> + <paragraph> + <reference ids="id63" refid="images"> + <generated classes="sectnum"> + 2.14.2    + Images + <list_item> + <paragraph> + <reference ids="id64" refid="admonitions"> + <generated classes="sectnum"> + 2.14.3    + Admonitions + <list_item> + <paragraph> + <reference ids="id65" refid="topics-sidebars-and-rubrics"> + <generated classes="sectnum"> + 2.14.4    + Topics, Sidebars, and Rubrics + <list_item> + <paragraph> + <reference ids="id66" refid="target-footnotes"> + <generated classes="sectnum"> + 2.14.5    + Target Footnotes + <list_item> + <paragraph> + <reference ids="id67" refid="replacement-text"> + <generated classes="sectnum"> + 2.14.6    + Replacement Text + <list_item> + <paragraph> + <reference ids="id68" refid="compound-paragraph"> + <generated classes="sectnum"> + 2.14.7    + Compound Paragraph + <paragraph> + These are just a sample of the many reStructuredText Directives. For + others, please see + <reference refuri="http://docutils.sourceforge.net/docs/ref/rst/directives.html"> + http://docutils.sourceforge.net/docs/ref/rst/directives.html + . + <section ids="document-parts" names="document parts"> + <title auto="1" refid="id62"> + <generated classes="sectnum"> + 2.14.1    + Document Parts + <paragraph> + An example of the "contents" directive can be seen above this section + (a local, untitled table of + <reference name="contents" refid="contents"> + contents + ) and at the beginning of the + document (a document-wide + <reference name="table of contents" refid="table-of-contents"> + table of contents + ). + <section ids="images" names="images"> + <title auto="1" refid="id63"> + <generated classes="sectnum"> + 2.14.2    + Images + <paragraph> + An image directive (also clickable -- a hyperlink reference): + <reference name="directives_" refid="directives"> + <image classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> + <paragraph> + A figure directive: + <figure classes="figclass1 figclass2"> + <image alt="reStructuredText, the markup syntax" classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> + <caption> + A figure is an image with a caption and/or a legend: + <legend> + <table> + <tgroup cols="2"> + <colspec colwidth="12"> + <colspec colwidth="47"> + <tbody> + <row> + <entry> + <paragraph> + re + <entry> + <paragraph> + Revised, revisited, based on 're' module. + <row> + <entry> + <paragraph> + Structured + <entry> + <paragraph> + Structure-enhanced text, structuredtext. + <row> + <entry> + <paragraph> + Text + <entry> + <paragraph> + Well it is, isn't it? + <paragraph> + This paragraph is also part of the legend. + <section ids="admonitions" names="admonitions"> + <title auto="1" refid="id64"> + <generated classes="sectnum"> + 2.14.3    + Admonitions + <attention> + <paragraph> + Directives at large. + <caution> + <paragraph> + Don't take any wooden nickels. + <danger> + <paragraph> + Mad scientist at work! + <error> + <paragraph> + Does not compute. + <hint> + <paragraph> + It's bigger than a bread box. + <important> + <bullet_list bullet="-"> + <list_item> + <paragraph> + Wash behind your ears. + <list_item> + <paragraph> + Clean up your room. + <list_item> + <paragraph> + Call your mother. + <list_item> + <paragraph> + Back up your data. + <note> + <paragraph> + This is a note. + <tip> + <paragraph> + 15% if the service is good. + <warning> + <paragraph> + Strong prose may provoke extreme mental exertion. + Reader discretion is strongly advised. + <admonition classes="admonition-and-by-the-way"> + <title> + And, by the way... + <paragraph> + You can make up your own admonition too. + <section ids="topics-sidebars-and-rubrics" names="topics, sidebars, and rubrics"> + <title auto="1" refid="id65"> + <generated classes="sectnum"> + 2.14.4    + Topics, Sidebars, and Rubrics + <sidebar> + <title> + Sidebar Title + <subtitle> + Optional Subtitle + <paragraph> + This is a sidebar. It is for text outside the flow of the main + text. + <rubric> + This is a rubric inside a sidebar + <paragraph> + Sidebars often appears beside the main text with a border and + background color. + <topic> + <title> + Topic Title + <paragraph> + This is a topic. + <rubric> + This is a rubric + <section ids="target-footnotes" names="target footnotes"> + <title auto="1" refid="id66"> + <generated classes="sectnum"> + 2.14.5    + Target Footnotes + <footnote auto="1" backrefs="id22 id23 id24" ids="id21" names="TARGET_NOTE: id21"> + <label> + 5 + <paragraph> + <reference refuri="http://www.python.org/"> + http://www.python.org/ + <section ids="replacement-text" names="replacement text"> + <title auto="1" refid="id67"> + <generated classes="sectnum"> + 2.14.6    + Replacement Text + <paragraph> + I recommend you try + <reference refuri="http://www.python.org/"> + Python, + <emphasis> + the + best language around + + <footnote_reference auto="1" ids="id24" refid="id21"> + 5 + . + <substitution_definition names="Python"> + Python, + <emphasis> + the + best language around + <section ids="compound-paragraph" names="compound paragraph"> + <title auto="1" refid="id68"> + <generated classes="sectnum"> + 2.14.7    + Compound Paragraph + <compound classes="some-class"> + <paragraph> + Compound 1, paragraph 1. + <paragraph> + Compound 1, paragraph 2. + <bullet_list bullet="*"> + <list_item> + <paragraph> + Compound 1, list item one. + <list_item> + <paragraph> + Compound 1, list item two. + <paragraph> + Another compound statement: + <compound> + <paragraph> + Compound 2, a literal block: + <literal_block xml:space="preserve"> + Compound 2, literal. + <paragraph> + Compound 2, this is a test. + <compound> + <paragraph> + Compound 3, only consisting of one paragraph. + <compound> + <literal_block xml:space="preserve"> + Compound 4. + This one starts with a literal block. + <paragraph> + Compound 4, a paragraph. + <paragraph> + Now something + <emphasis> + really + perverted -- a nested compound block. In + LaTeX, the following paragraphs should all be first-line indented: + <compound> + <paragraph> + Compound 5, block 1 (a paragraph). + <compound> + <paragraph> + Compound 6, block 2 in compound 5. + <paragraph> + Compound 6, another paragraph. + <paragraph> + Compound 5, block 3 (a paragraph). + <compound> + <paragraph> + Compound 7, with a table inside: + <table> + <tgroup cols="3"> + <colspec colwidth="20"> + <colspec colwidth="20"> + <colspec colwidth="20"> + <tbody> + <row> + <entry> + <paragraph> + Left cell, first + paragraph. + <paragraph> + Left cell, second + paragraph. + <entry> + <paragraph> + Middle cell, + consisting of + exactly one + paragraph. + <entry> + <paragraph> + Right cell. + <paragraph> + Paragraph 2. + <paragraph> + Paragraph 3. + <paragraph> + Compound 7, a paragraph after the table. + <paragraph> + Compound 7, another paragraph. + <section ids="substitution-definitions" names="substitution definitions"> + <title auto="1" refid="id54"> + <generated classes="sectnum"> + 2.15    + Substitution Definitions + <paragraph> + An inline image ( + <image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"> + ) example: + <substitution_definition names="EXAMPLE"> + <image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"> + <paragraph> + (Substitution definitions are not visible in the HTML source.) + <section ids="comments" names="comments"> + <title auto="1" refid="id55"> + <generated classes="sectnum"> + 2.16    + Comments + <paragraph> + Here's one: + <comment xml:space="preserve"> + Comments begin with two dots and a space. Anything may + follow, except for the syntax of footnotes, hyperlink + targets, directives, or substitution definitions. + + Double-dashes -- "--" -- must be escaped somehow in HTML output. + <paragraph> + (View the HTML source to see the comment.) + <section ids="raw-text" names="raw text"> + <title auto="1" refid="id56"> + <generated classes="sectnum"> + 2.17    + Raw text + <paragraph> + This does not necessarily look nice, because there may be missing white space. + <paragraph> + It's just there to freeze the behavior. + <raw format="html latex" xml:space="preserve"> + A test. + <raw format="html latex" xml:space="preserve"> + Second test. + <raw classes="myclass" format="html latex" xml:space="preserve"> + Another test with myclass set. + <paragraph> + This is the + <raw classes="myrawroleclass" format="html latex" xml:space="preserve"> + fourth test + with myrawroleclass set. + <raw format="html" xml:space="preserve"> + Fifth test in HTML.<br />Line two. + <raw format="latex" xml:space="preserve"> + Fifth test in LaTeX.\\Line two. + <section ids="colspanning-tables" names="colspanning tables"> + <title auto="1" refid="id57"> + <generated classes="sectnum"> + 2.18    + Colspanning tables + <paragraph> + This table has a cell spanning two columns: + <table> + <tgroup cols="3"> + <colspec colwidth="5"> + <colspec colwidth="5"> + <colspec colwidth="6"> + <thead> + <row> + <entry morecols="1"> + <paragraph> + Inputs + <entry> + <paragraph> + Output + <row> + <entry> + <paragraph> + A + <entry> + <paragraph> + B + <entry> + <paragraph> + A or B + <tbody> + <row> + <entry> + <paragraph> + False + <entry> + <paragraph> + False + <entry> + <paragraph> + False + <row> + <entry> + <paragraph> + True + <entry> + <paragraph> + False + <entry> + <paragraph> + True + <row> + <entry> + <paragraph> + False + <entry> + <paragraph> + True + <entry> + <paragraph> + True + <row> + <entry> + <paragraph> + True + <entry> + <paragraph> + True + <entry> + <paragraph> + True + <section ids="rowspanning-tables" names="rowspanning tables"> + <title auto="1" refid="id58"> + <generated classes="sectnum"> + 2.19    + Rowspanning tables + <paragraph> + Here's a table with cells spanning several rows: + <table> + <tgroup cols="3"> + <colspec colwidth="24"> + <colspec colwidth="12"> + <colspec colwidth="18"> + <thead> + <row> + <entry> + <paragraph> + Header row, column 1 + (header rows optional) + <entry> + <paragraph> + Header 2 + <entry> + <paragraph> + Header 3 + <tbody> + <row> + <entry> + <paragraph> + body row 1, column 1 + <entry> + <paragraph> + column 2 + <entry> + <paragraph> + column 3 + <row> + <entry> + <paragraph> + body row 2 + <entry morerows="1"> + <paragraph> + Cells may + span rows. + <entry morerows="1"> + <bullet_list bullet="-"> + <list_item> + <paragraph> + Table cells + <list_item> + <paragraph> + contain + <list_item> + <paragraph> + body elements. + <row> + <entry> + <paragraph> + body row 3 + <section ids="complex-tables" names="complex tables"> + <title auto="1" refid="id59"> + <generated classes="sectnum"> + 2.20    + Complex tables + <paragraph> + Here's a complex table, which should test all features. + <table> + <tgroup cols="4"> + <colspec colwidth="24"> + <colspec colwidth="12"> + <colspec colwidth="10"> + <colspec colwidth="10"> + <thead> + <row> + <entry> + <paragraph> + Header row, column 1 + (header rows optional) + <entry> + <paragraph> + Header 2 + <entry> + <paragraph> + Header 3 + <entry> + <paragraph> + Header 4 + <tbody> + <row> + <entry> + <paragraph> + body row 1, column 1 + <entry> + <paragraph> + column 2 + <entry> + <paragraph> + column 3 + <entry> + <paragraph> + column 4 + <row> + <entry> + <paragraph> + body row 2 + <entry morecols="2"> + <paragraph> + Cells may span columns. + <row> + <entry> + <paragraph> + body row 3 + <entry morerows="1"> + <paragraph> + Cells may + span rows. + <paragraph> + Paragraph. + <entry morecols="1" morerows="1"> + <bullet_list bullet="-"> + <list_item> + <paragraph> + Table cells + <list_item> + <paragraph> + contain + <list_item> + <paragraph> + body elements. + <row> + <entry> + <paragraph> + body row 4 + <row> + <entry> + <paragraph> + body row 5 + <entry morecols="1"> + <paragraph> + Cells may also be + empty: + <literal> + --> + <entry> + <section ids="list-tables" names="list tables"> + <title auto="1" refid="id60"> + <generated classes="sectnum"> + 2.21    + List Tables + <paragraph> + Here's a list table exercising all features: + <table classes="test"> + <title> + list table with integral header + <tgroup cols="3"> + <colspec colwidth="10" stub="1"> + <colspec colwidth="20"> + <colspec colwidth="30"> + <thead> + <row> + <entry> + <paragraph> + Treat + <entry> + <paragraph> + Quantity + <entry> + <paragraph> + Description + <tbody> + <row> + <entry> + <paragraph> + Albatross + <entry> + <paragraph> + 2.99 + <entry> + <paragraph> + On a stick! + <row> + <entry> + <paragraph> + Crunchy Frog + <entry> + <paragraph> + 1.49 + <entry> + <paragraph> + If we took the bones out, it wouldn't be + crunchy, now would it? + <row> + <entry> + <paragraph> + Gannet Ripple + <entry> + <paragraph> + 1.99 + <entry> + <paragraph> + On a stick! + <section ids="error-handling" names="error handling"> + <title auto="1" refid="id61"> + <generated classes="sectnum"> + 3    + Error Handling + <paragraph> + Any errors caught during processing will generate system messages. + <paragraph> + There should be five messages in the following, auto-generated + section, "Docutils System Messages": + <comment xml:space="preserve"> + section should be added by Docutils automatically + <section classes="system-messages"> + <title> + Docutils System Messages + <system_message backrefs="id20" ids="id19" level="3" line="98" source="functional/input/data/standard.txt" type="ERROR"> + <paragraph> + Undefined substitution referenced: "problematic". + <system_message backrefs="id70" ids="id69" level="3" line="352" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <paragraph> + Unknown target name: "5". + <system_message backrefs="id72" ids="id71" level="3" line="361" source="functional/input/data/standard.txt" type="ERROR"> + <paragraph> + Unknown target name: "nonexistent". + <system_message backrefs="id74" ids="id73" level="3" line="386" source="functional/input/data/standard.txt" type="ERROR"> + <paragraph> + Unknown target name: "hyperlink reference without a target". + <system_message backrefs="id76" ids="id75" level="3" line="399" source="functional/input/data/standard.txt" type="ERROR"> + <paragraph> + Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/tests/standalone_rst_pseudoxml.py b/test/functional/tests/standalone_rst_pseudoxml.py new file mode 100644 index 000000000..4df832f64 --- /dev/null +++ b/test/functional/tests/standalone_rst_pseudoxml.py @@ -0,0 +1,8 @@ +# Source and destination file names. +test_source = "standalone_rst_html4css1.txt" +test_destination = "standalone_rst_pseudoxml.txt" + +# Keyword parameters passed to publish_file. +reader_name = "standalone" +parser_name = "rst" +writer_name = "pseudoxml" -- cgit v1.2.1 From e743c7a5d3e7908af5702ddacfbcb4b7556914d9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 19:51:45 +0000 Subject: fixed bugs: don't access a node's children attribute directly\! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3186 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 8 ++++---- docutils/parsers/rst/directives/parts.py | 2 +- docutils/transforms/universal.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 270840dd3..0cebdb5b0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1041,9 +1041,9 @@ class document(Root, Structural, Element): self.decoration = decoration() index = self.first_child_not_matching_class(Titular) if index is None: - self.children.append(self.decoration) + self.append(self.decoration) else: - self.children.insert(index, self.decoration) + self.insert(index, self.decoration) return self.decoration @@ -1081,12 +1081,12 @@ class decoration(Decorative, Element): def get_header(self): if not len(self.children) or not isinstance(self.children[0], header): - self.children.insert(0, header()) + self.insert(0, header()) return self.children[0] def get_footer(self): if not len(self.children) or not isinstance(self.children[-1], footer): - self.children.append(footer()) + self.append(footer()) return self.children[-1] diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 623e2cd5e..2c0171696 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -89,7 +89,7 @@ def header_footer(node, name, arguments, options, content, lineno, 'Content block expected for the "%s" directive; none found.' % name, nodes.literal_block(block_text, block_text), line=lineno) - node.children.append(nodes.paragraph( + node.append(nodes.paragraph( '', 'Problem with the "%s" directive: no content supplied.' % name)) return [warning] text = '\n'.join(content) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 4ed7b6896..aac05a2e4 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -36,12 +36,12 @@ class Decorations(Transform): if header_nodes: decoration = self.document.get_decoration() header = decoration.get_header() - header.children.extend(header_nodes) + header.extend(header_nodes) footer_nodes = self.generate_footer() if footer_nodes: decoration = self.document.get_decoration() footer = decoration.get_footer() - footer.children.extend(footer_nodes) + footer.extend(footer_nodes) def generate_header(self): return None -- cgit v1.2.1 From 4c3442a63e090ec8a2414df48f2beadd80339b69 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 19:54:30 +0000 Subject: one done git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3187 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f4a77b94b..bbbeab92a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1468,10 +1468,6 @@ when used in a document. either by running it at the command line with a ``--help`` option or through an exposed API. [Suggestion for Optik.] - - _`parts.header` & _`parts.footer`: Add "header" and "footer" - directives to specify document-specific contents for header and - footer? - Interpreted Text ---------------- -- cgit v1.2.1 From 9588a08dd3e57f2ffba9ee15441e32bd8c357f0b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Apr 2005 20:38:42 +0000 Subject: added some ideas git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3188 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index bbbeab92a..0cb24fdbe 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -476,6 +476,10 @@ General * Add support for _`plugins`. +* Add support for document decorations other than headers & footers? + For example, top/bottom/side navigation bars for web pages. Generic + decorations? + Documentation ============= @@ -1161,6 +1165,10 @@ when used in a document. Add an option to include topics in the TOC? Another for sidebars? See docutils-develop 2003-01-29. + - _`parts.header` & _`parts.footer`: Support multiple, named headers + & footers? For example, separate headers & footers for odd, even, + and the first page of a document. + - _`misc.include`: - "encoding" option? Take default from runtime settings. Use -- cgit v1.2.1 From ff539aca41253daa55523d0d4bbbb465f450adfe Mon Sep 17 00:00:00 2001 From: richieadler <richieadler@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 03:05:45 +0000 Subject: translation of "list-table", "header" and "footer" directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3189 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 8f7e33807..069fea45e 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -48,7 +48,7 @@ directives = { u'tabelo': 'table', u'tabelo-vdk': 'csv-table', # "valoroj disigitaj per komoj" u'tabelo-csv': 'csv-table', - u'list-table (translation required)': 'list-table', + u'tabelo-lista': 'list-table', u'meta': 'meta', #'imagemap': 'imagemap', u'bildo': 'image', @@ -63,8 +63,8 @@ directives = { u'enhavo': 'contents', u'seknum': 'sectnum', u'sekcia-numerado': 'sectnum', - u'header (translation required)': 'header', - u'footer (translation required)': 'footer', + u'kapsekcio': 'header', + u'piedsekcio': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', u'celaj-notoj': 'target-notes', -- cgit v1.2.1 From 962a4420aa386783d5c475e84a84e2efea8b3ab2 Mon Sep 17 00:00:00 2001 From: richieadler <richieadler@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 03:06:12 +0000 Subject: translation of "list-table", "header" and "footer" directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3190 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/es.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 59b3a2228..5f0a094da 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -50,7 +50,7 @@ directives = { u'tabla': 'table', u'tabla-vsc': 'csv-table', u'tabla-csv': 'csv-table', - u'list-table (translation required)': 'list-table', + u'tabla-lista': 'list-table', u'meta': 'meta', #'imagemap': 'imagemap', u'imagen': 'image', @@ -68,8 +68,8 @@ directives = { u'numeracion-seccion': 'sectnum', u'numeraci\u00f3n-secci\u00f3n': 'sectnum', u'notas-destino': 'target-notes', - u'header (translation required)': 'header', - u'footer (translation required)': 'footer', + u'cabecera': 'header', + u'pie': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', u'restructuredtext-test-directive': 'restructuredtext-test-directive'} -- cgit v1.2.1 -- cgit v1.2.1 From 70252527abecd4374c194876c1c337db1976fb6b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 15:19:09 +0000 Subject: moved the <hr> tags inside the header and footer <div>s; changed the classes of these <hr> to just "header" and "footer" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3192 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 11 ++++++----- test/functional/expected/standalone_rst_html4css1.html | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 07e03b4b1..1374b82a6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -730,9 +730,10 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_footer(self, node): start = self.context.pop() - footer = (['<hr class="docutils footer" />\n', - self.starttag(node, 'div', CLASS='footer')] - + self.body[start:] + ['\n</div>\n']) + footer = [self.starttag(node, 'div', CLASS='footer'), + '<hr class="footer" />\n'] + footer.extend(self.body[start:]) + footer.append('\n</div>\n') self.footer.extend(footer) self.body_suffix[:0] = footer del self.body[start:] @@ -814,9 +815,9 @@ class HTMLTranslator(nodes.NodeVisitor): start = self.context.pop() header = [self.starttag(node, 'div', CLASS='header')] header.extend(self.body[start:]) - header.append('\n</div>\n<hr class="docutils header"/>\n') + header.append('\n<hr class="header"/>\n</div>\n') self.body_prefix.extend(header) - self.header = header + self.header.extend(header) del self.body[start:] def visit_hint(self, node): diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 78605137a..66879b19f 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -19,8 +19,8 @@ <body> <div class="header"> Document header +<hr class="header"/> </div> -<hr class="docutils header"/> <span id="doctitle"></span><div class="document" id="restructuredtext-test-document"> <h1 class="title">reStructuredText Test Document</h1> <span id="subtitle"></span><h2 class="subtitle" id="examples-of-syntax-constructs">Examples of Syntax Constructs</h2> @@ -922,8 +922,8 @@ Unknown target name: "hyperlink reference without a target".</div> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> -<hr class="docutils footer" /> <div class="footer"> +<hr class="footer" /> Document footer </div> </body> -- cgit v1.2.1 From 7e297f36f3c1d3ebf5f26a60dcec7613efa63ba5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 18:42:33 +0000 Subject: moved implementation description out of the docs into the code; whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3193 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 12 +++--------- docutils/parsers/rst/directives/parts.py | 16 +++++++++------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 5af9987e7..5e07ba449 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -854,21 +854,15 @@ Table of Contents :Directive Options: Possible. :Directive Content: None. -The "contents" directive inserts a table of contents (TOC) in two -passes: initial parse and transform. During the initial parse, a -"pending" element is generated which acts as a placeholder, storing -the TOC title and any options internally. At a later stage in the -processing, the "pending" element is replaced by a "topic" element, a -title and the table of contents proper. - -The directive in its simplest form:: +The "contents" directive generates a table of contents (TOC). Here's +the directive in its simplest form:: .. contents:: Language-dependent boilerplate text will be used for the title. The English default title text is "Contents". -An explicit title, may be specified:: +An explicit title may be specified:: .. contents:: Table of Contents diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 2c0171696..a224101f6 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -26,10 +26,17 @@ def backlinks(arg): def contents(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - """Table of contents.""" + """ + Table of contents. + + The table of contents is generated in two passes: initial parse and + transform. During the initial parse, a 'pending' element is generated + which acts as a placeholder, storing the TOC title and any options + internally. At a later stage in the processing, the 'pending' element is + replaced by a 'topic' element, a title and the table of contents proper. + """ document = state_machine.document language = languages.get_language(document.settings.language_code) - if arguments: title_text = arguments[0] text_nodes, messages = state.inline_text(title_text, lineno) @@ -40,22 +47,17 @@ def contents(name, arguments, options, content, lineno, title = None else: title = nodes.title('', language.labels['contents']) - topic = nodes.topic(classes=['contents']) - topic['classes'] += options.get('class', []) - if title: name = title.astext() topic += title else: name = language.labels['contents'] - name = nodes.fully_normalize_name(name) if not document.has_name(name): topic['names'].append(name) document.note_implicit_target(topic) - pending = nodes.pending(parts.Contents, rawsource=block_text) pending.details.update(options) document.note_pending(pending) -- cgit v1.2.1 From be2f10a55253e7feb5047f15f505141bfe1d82e8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 18:43:33 +0000 Subject: moved idea for existing sidebar directive into the correct position; updated idea with "?" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3194 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 0cb24fdbe..977c33270 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1091,7 +1091,7 @@ when used in a document. * Change directive functions to directive classes? Superclass' ``__init__()`` could handle all the bookkeeping. -* Implement options on existing directives: +* Implement options or features on existing directives: - Add a "name" option to directives, to set an author-supplied identifier? @@ -1211,7 +1211,7 @@ when used in a document. - Add support for inclusion by URL:: - .. include:: + .. include:: :url: http://www.example.org/inclusion.txt - _`misc.raw`: add a "destination" option to the "raw" directive? :: @@ -1223,7 +1223,10 @@ when used in a document. It needs thought & discussion though, to come up with a consistent set of destination labels and consistent behavior. - + + - _`body.sidebar`: Allow internal section structure? Adornment + styles would be independent of the main document. + * Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The directive name itself could be the same as the @@ -1394,10 +1397,6 @@ when used in a document. See docutils-users 2003-03-03. - - _`body.sidebar`: Add to the already implemented directive. Allow - internal section structure, with adornment styles independent of - the main document. - - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need some kind of "alternate" mechanism? Perhaps use a "pending" -- cgit v1.2.1 From 850a8250fc1aeaf129da6a15458b45938f34ed37 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 19:44:13 +0000 Subject: fixed part of the "contents" directive context problem git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3195 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/parts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 20dbec880..6fc616a03 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -86,7 +86,8 @@ class Contents(Transform): startnode = self.startnode.parent.parent # @@@ generate an error if the startnode (directive) not at # section/document top-level? Drag it up until it is? - while not isinstance(startnode, nodes.Structural): + while not (isinstance(startnode, nodes.section) + or isinstance(startnode, nodes.document)): startnode = startnode.parent else: startnode = self.document -- cgit v1.2.1 From 8876767b0b70633c00649879ce4404e2cdd3a431 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 19:44:19 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3196 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 977c33270..cdfb1a2af 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1163,7 +1163,9 @@ when used in a document. down. Or a new directive, like "prune-contents"? Add an option to include topics in the TOC? Another for sidebars? - See docutils-develop 2003-01-29. + The "topic" directive could have a "contents" option, or the + "contents" directive" could have an "include-topics" option. See + docutils-develop 2003-01-29. - _`parts.header` & _`parts.footer`: Support multiple, named headers & footers? For example, separate headers & footers for odd, even, -- cgit v1.2.1 From 51a18532eab6031187426e26bb8f409b0fc25599 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 23:26:35 +0000 Subject: added "HTML SlideShow Writer" section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3197 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index cdfb1a2af..5a4f23abe 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1751,6 +1751,186 @@ LaTeX writer * Add an ``--embed-stylesheet`` (and ``--link-stylesheet``) option. +HTML SlideShow Writer +===================== + +Add a Writer for presentations, derivative of the HTML Writer. Given +an input document containing one section per slide, the output would +consist of a master document for the speaker, and a slide file (or set +of filess, one (or more) for each slide). Each slide would contain +the slide text (large, stylesheet-controlled) and images, plus "next" +and "previous" links in consistent places. The speaker's master +document would contain a small version of the slide text with +speaker's notes interspersed. The master document could use +``target="whatever"`` to direct links to a separate window on a second +monitor (e.g., a projector). + +Ideas: + +* Base the output on `S5 <http://www.meyerweb.com/eric/tools/s5/>`_. + +Below, "[S5?]" indicates that S5 already implements (or may implement) +part of the feature. + +Features & issues: + +* [S5?] Incremental slides, where each slide adds to the one before + (ticking off items in a list, delaying display of later items). The + speaker's master document would list each transition in the TOC and + provide links in the content. + + Have special support for this, or just copy slide text? Could use + transitions to separate stages, or a special directive. Problem + with transitions is that they can't be used everywhere -- not, for + example, within a list (see the example below). A directive + (possible names: pause, delay, break, cut, continue, suspend, hold, + stay, stop) seems like a better solution. Should the directive be + available in all contexts (and ineffectual in all but SlideShow + context), or added at runtime by the SlideShow Writer? + + The directive could accept text content, which would be rendered + while paused but would disappear when the slide is continued (the + text could also be a link to the next slide). In the speaker's + master document, the text "paused:" could appear, prefixed to the + directive text. + +* Speaker's notes -- how to intersperse? Could use reST comments + (".."), but make them visible in the speaker's master document. If + structure is necessary, we could use a "comment" directive (to avoid + nonsensical DTD changes, the "comment" directive could produce an + untitled topic element). + + The speaker's notes would be separate from S5's handout content. + +* Speaker's master document could use frames for easy navigation: TOC + on the left, content on the right. + + - It would be nice if clicking in the TOC frame simultaneously + linked to both the speaker's notes frame and to the slide window, + synchronizing both. Needs JavaScript? + + - TOC would have to be tightly formatted -- minimal indentation. + + - TOC auto-generated, as in the PEP Reader. (What if there already + is a "contents" directive in the document?) + + - There could be another frame on the left (top-left or bottom-left) + containing a single "Next" link, always pointing to the next slide + (synchronized, of course). Also "Previous" link? FF/Rew go to + the beginning of the next/current parent section? First/Last + also? Tape-player-style buttons like ``|<< << < > >> >>|``? + +* [S5?] Need to support templating of some kind, for uniform slide + layout. Or build in support for limited features? E.g., top/bottom + or left/right banners, images on each page, background color and/or + image, etc. + +* [S5?] One layout for all slides, or allow some variation? + +* For nested sections, do we show the section's ancestry on each + slide? Optional? No -- leave the implementation to someone who + wants it. + +* [S5?] Stylesheets for slides: + + - Tweaked for different resolutions, 1024x768 etc. + - Some layout elements have fixed positions. + - Text must be quite large. + - Allow 10 lines of text per slide? 15? + - Title styles vary by level, but not so much? + +* [S5?] Need a transform to number slides for output filenames?, and + for hyperlinks? + +* Directive to begin a new, untitled (blank) slide? + +* Directive to begin a new slide, continuation, using the same title + as the previous slide? + +Here's an example that I was hoping to show at PyCon DC 2005:: + + ======================== + The Docutils SlideShow + ======================== + + Welcome To The Docutils SlideShow! + ================================== + + .. pause:: + + David Goodger + + goodger@python.org + + http://python.net/~goodger + + .. (introduce yourself) + + Hi, I'm David Goodger from Montreal, Canada. + + I've been working on Docutils since 2000. + Time flies! + + .. pause:: + + Docutils + + http://docutils.sourceforge.net + + .. I also volunteer as a Python Enhancement Proposal (or PEP) + editor. + + .. SlideShow is a new feature of Docutils. This presentation was + written using the Docutils SlideShow system. The slides you + are seeing are HTML, rendered by a standard Mozilla Firefox + browser. + + + The Docutils SlideShow System + ============================= + + .. The Docutils SlideShow System provides + + Easy and open presentations. + + + Features + ======== + + * reStructuredText-based input files. + + .. reStructuredText is a what-you-see-is-what-you-get + plaintext format. Easy to read & write, non-proprietary, + editable in your favourite text editor. + + .. Parsers for other markup languages can be added to Docutils. + In the future, I hope some are. + + .. pause:: ... + + * Stylesheet-driven HTML output. + + .. The format of all elements of the output slides are + controlled by CSS (cascading stylesheets). + + .. pause:: ... + + * Works with any modern browser. + + .. that supports CSS, frames, and JavaScript. + Tested with Mozilla Firefox. + + .. pause:: ... + + * Works on any OS. + + + Etc. + ==== + + That's as far as I got, but you get the idea... + + Front-End Tools =============== -- cgit v1.2.1 From 914a483a4eb5e5ad9bc36a56b284f2c2336f9063 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Apr 2005 23:28:53 +0000 Subject: added link to Chris Liechti's work git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3198 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5a4f23abe..b7e43a710 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1769,6 +1769,9 @@ Ideas: * Base the output on `S5 <http://www.meyerweb.com/eric/tools/s5/>`_. + Chris Liechti has `integrated S5 with the HTML writer + <http://homepage.hispeed.ch/py430/python/index.html#rst2s5>`__. + Below, "[S5?]" indicates that S5 already implements (or may implement) part of the feature. -- cgit v1.2.1 From a65d49465f32f45cc8152ccfdd0ee4d26c398353 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 9 Apr 2005 01:32:29 +0000 Subject: allow topics within sidebars; no topics within body elements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3199 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 9 ++-- docs/ref/docutils.dtd | 2 +- docs/ref/rst/directives.txt | 10 +++-- docutils/parsers/rst/directives/body.py | 5 ++- docutils/parsers/rst/directives/parts.py | 7 +++ docutils/transforms/parts.py | 4 +- .../test_rst/test_directives/test_contents.py | 31 +++++++++++++ .../test_rst/test_directives/test_topics.py | 16 +++---- test/test_transforms/test_contents.py | 51 ++++++++++++++++++++++ 9 files changed, 113 insertions(+), 22 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 912789239..b5458017b 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -3550,7 +3550,7 @@ Details :Children: ``sidebar`` elements begin with a title_ and an optional subtitle_ - and contain `body elements`_. + and contain `body elements`_ and topic_ elements. :Analogues: ``sidebar`` is analogous to the DocBook "sidebar" element. @@ -3568,7 +3568,7 @@ Content Model .. parsed-literal:: (title_, subtitle_?, - (`%body.elements;`_)+) + (`%body.elements;`_ | topic_)+) :Attributes: The ``sidebar`` element contains only the `common attributes`_: @@ -3985,7 +3985,7 @@ The ``topic`` element is a nonrecursive section_-like construct which may occur at the top level of a section_ wherever a body element (list, table, etc.) is allowed. In other words, ``topic`` elements cannot nest inside body elements, so you can't have a ``topic`` inside -a ``table`` or a ``list``, or inside another ``topic`` (or sidebar_). +a ``table`` or a ``list``, or inside another ``topic``. Details @@ -3995,7 +3995,8 @@ Details `Structural Elements`_ :Parents: - The following elements may contain ``topic``: document_, section_ + The following elements may contain ``topic``: document_, section_, + sidebar_ :Children: ``topic`` elements begin with a title_ and may contain `body diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 0c0a55003..357703f04 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -279,7 +279,7 @@ Eventual replacement for docinfo? --> <!ELEMENT topic (title?, (%body.elements;)+)> <!ATTLIST topic %basic.atts;> -<!ELEMENT sidebar (title, subtitle?, (%body.elements;)+)> +<!ELEMENT sidebar (title, subtitle?, (%body.elements; | topic)+)> <!ATTLIST sidebar %basic.atts;> <!ELEMENT transition EMPTY> diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 5e07ba449..859d32487 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -331,7 +331,7 @@ A topic is like a block quote with a title, or a self-contained section with no subsections. Use the "topic" directive to indicate a self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. Body -elements (including topics) may not contain nested topics. +elements and topics may not contain nested topics. The directive's sole argument is interpreted as the topic title; the next line must be blank. All subsequent lines make up the topic body, @@ -854,8 +854,12 @@ Table of Contents :Directive Options: Possible. :Directive Content: None. -The "contents" directive generates a table of contents (TOC). Here's -the directive in its simplest form:: +The "contents" directive generates a table of contents (TOC) in a +topic_. Topics, and therefore tables of contents, may occur anywhere +a section or transition may occur. Body elements and topics may not +contain tables of contents. + +Here's the directive in its simplest form:: .. contents:: diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 117311720..61c58daad 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -22,9 +22,10 @@ from docutils.parsers.rst.roles import set_classes def topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.topic): - if not state_machine.match_titles: + if not (state_machine.match_titles + or isinstance(state_machine.node, nodes.sidebar)): error = state_machine.reporter.error( - 'The "%s" directive may not be used within topics, sidebars, ' + 'The "%s" directive may not be used within topics ' 'or body elements.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index a224101f6..37a32a963 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -35,6 +35,13 @@ def contents(name, arguments, options, content, lineno, internally. At a later stage in the processing, the 'pending' element is replaced by a 'topic' element, a title and the table of contents proper. """ + if not (state_machine.match_titles + or isinstance(state_machine.node, nodes.sidebar)): + error = state_machine.reporter.error( + 'The "%s" directive may not be used within topics ' + 'or body elements.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [error] document = state_machine.document language = languages.get_language(document.settings.language_code) if arguments: diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 6fc616a03..0feb74409 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -84,14 +84,12 @@ class Contents(Transform): details = self.startnode.details if details.has_key('local'): startnode = self.startnode.parent.parent - # @@@ generate an error if the startnode (directive) not at - # section/document top-level? Drag it up until it is? while not (isinstance(startnode, nodes.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 details.has_key('backlinks'): self.backlinks = details['backlinks'] diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 7577152cc..e2b5f29a2 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -202,6 +202,37 @@ totest['contents'] = [ .. contents:: :backlinks: """], +["""\ +* .. contents:: +""", +"""\ +<document source="test data"> + <bullet_list bullet="*"> + <list_item> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + The "contents" directive may not be used within topics or body elements. + <literal_block xml:space="preserve"> + .. contents:: +"""], +["""\ +.. sidebar:: containing contents + + .. contents:: +""", +"""\ +<document source="test data"> + <sidebar> + <title> + containing contents + <topic classes="contents" ids="contents" names="contents"> + <title> + Contents + <pending> + .. internal attributes: + .transform: docutils.transforms.parts.Contents + .details: +"""], ] diff --git a/test/test_parsers/test_rst/test_directives/test_topics.py b/test/test_parsers/test_rst/test_directives/test_topics.py index fa3d91100..4d0fae27b 100755 --- a/test/test_parsers/test_rst/test_directives/test_topics.py +++ b/test/test_parsers/test_rst/test_directives/test_topics.py @@ -121,7 +121,7 @@ totest['topics'] = [ Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - The "topic" directive may not be used within topics, sidebars, or body elements. + The "topic" directive may not be used within topics or body elements. <literal_block xml:space="preserve"> .. topic:: Nested \n\ @@ -142,7 +142,7 @@ totest['topics'] = [ Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - The "topic" directive may not be used within topics, sidebars, or body elements. + The "topic" directive may not be used within topics or body elements. <literal_block xml:space="preserve"> .. topic:: Nested \n\ @@ -171,7 +171,7 @@ More. Title <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - The "topic" directive may not be used within topics, sidebars, or body elements. + The "topic" directive may not be used within topics or body elements. <literal_block xml:space="preserve"> .. topic:: Nested \n\ @@ -222,13 +222,11 @@ More. Title <subtitle> Outer - <system_message level="3" line="4" source="test data" type="ERROR"> + <topic> + <title> + Nested <paragraph> - The "topic" directive may not be used within topics, sidebars, or body elements. - <literal_block xml:space="preserve"> - .. topic:: Nested - \n\ - Body. + Body. <paragraph> More. <paragraph> diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 95cc098a6..0871aa8f0 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -375,6 +375,57 @@ Degenerate case, no table of contents generated. <paragraph> Degenerate case, no table of contents generated. """], +["""\ +Title 1 +======= + +Paragraph 1. + +.. sidebar:: Contents + + .. contents:: + :local: + +Title 2 +------- +Paragraph 2. + +Title 3 +``````` +Paragraph 3. +""", +"""\ +<document source="test data"> + <section ids="title-1" names="title 1"> + <title> + Title 1 + <paragraph> + Paragraph 1. + <sidebar> + <title> + Contents + <topic classes="contents" ids="contents" names="contents"> + <bullet_list> + <list_item> + <paragraph> + <reference ids="id1" refid="title-2"> + Title 2 + <bullet_list> + <list_item> + <paragraph> + <reference ids="id2" refid="title-3"> + Title 3 + <section ids="title-2" names="title 2"> + <title refid="id1"> + Title 2 + <paragraph> + Paragraph 2. + <section ids="title-3" names="title 3"> + <title refid="id2"> + Title 3 + <paragraph> + Paragraph 3. +"""], ]) -- cgit v1.2.1 From 0d09d08b1b3bb856aaff320d99fc93faa3d50fa4 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 9 Apr 2005 21:13:28 +0000 Subject: added note about misuse of header and footer directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3200 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 859d32487..737cbe97a 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -980,6 +980,20 @@ the top of the generated web page or at the top of every printed page. These directives may be used multiple times, cumulatively. There is currently support for only one header and footer. +.. note:: + + While it is possible to use the "header" and "footer" directives to + create navigational elements for web pages, you should be aware + that Docutils is meant to be used for *document* processing, and + that a navigation bar is not typically part of a document. + + Thus, you may soon find Docutils' abilities to be insufficient for + these purposes. At that time, you should consider using a + templating system (like ht2html_) rather than the "header" and + "footer" directives. + + .. _ht2html: http://ht2html.sourceforge.net/ + In addition to the use of these directives to populate header and footer content, content may also be added automatically by the processing system. For example, if certain runtime settings are -- cgit v1.2.1 From 6db67cd640718472dfafef9b56aac635b3f48a88 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 9 Apr 2005 21:56:34 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3201 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 645738786..ca0871493 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -69,6 +69,11 @@ Changes Since 0.3.7 - 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. @@ -86,6 +91,8 @@ Changes Since 0.3.7 * 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: @@ -134,6 +141,7 @@ Changes Since 0.3.7 - Added ``stub`` attribute to ``colspec`` element via the ``tbl.colspec.att`` parameter entity. + - Allowed topic elements within sidebars Release 0.3.7 (2004-12-24) -- cgit v1.2.1 From 2dfdc12dbaa20c84a7365bfe37686b4e33ebf4df Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 10 Apr 2005 00:08:40 +0000 Subject: leet typographical tweak git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3202 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b7e43a710..c61f2b14d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1767,11 +1767,14 @@ monitor (e.g., a projector). Ideas: -* Base the output on `S5 <http://www.meyerweb.com/eric/tools/s5/>`_. +* Base the output on |S5|_. Chris Liechti has `integrated S5 with the HTML writer <http://homepage.hispeed.ch/py430/python/index.html#rst2s5>`__. + .. |S5| replace:: S\ :sup:`5` + .. _S5: http://www.meyerweb.com/eric/tools/s5/ + Below, "[S5?]" indicates that S5 already implements (or may implement) part of the feature. -- cgit v1.2.1 From 900f0119a0c17fef3d368e56c971834982e85e0a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 10 Apr 2005 00:09:24 +0000 Subject: another tweak git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3203 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c61f2b14d..ea28b506d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1775,8 +1775,8 @@ Ideas: .. |S5| replace:: S\ :sup:`5` .. _S5: http://www.meyerweb.com/eric/tools/s5/ -Below, "[S5?]" indicates that S5 already implements (or may implement) -part of the feature. +Below, "[S5?]" indicates that |S5| already implements (or may +implement) part of the feature. Features & issues: -- cgit v1.2.1 From aaa2e23c448f54a7cf9d50d600481c06bde8829c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 11 Apr 2005 23:15:21 +0000 Subject: updated slideshow ideas git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3205 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 85 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index ea28b506d..b08b82477 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1767,7 +1767,9 @@ monitor (e.g., a projector). Ideas: -* Base the output on |S5|_. +* Base the output on |S5|_. I discovered |S5| a few weeks before it + appeared on Slashdot, after writing most of this section. It turns + out that |S5| does most of what I wanted. Chris Liechti has `integrated S5 with the HTML writer <http://homepage.hispeed.ch/py430/python/index.html#rst2s5>`__. @@ -1775,30 +1777,47 @@ Ideas: .. |S5| replace:: S\ :sup:`5` .. _S5: http://www.meyerweb.com/eric/tools/s5/ -Below, "[S5?]" indicates that |S5| already implements (or may -implement) part of the feature. +Below, "[S5]" indicates that |S5| already implements the feature or +may implement all or part of the feature. "[S5 1.1]" indicates that +|S5| version 1.1 implements the feature (a preview of the 1.1 beta is +available in the `S5 testbed`_). + +.. _S5 testbed: http://meyerweb.com/eric/tools/s5/testbed/ Features & issues: -* [S5?] Incremental slides, where each slide adds to the one before +* [S5 1.1] Incremental slides, where each slide adds to the one before (ticking off items in a list, delaying display of later items). The speaker's master document would list each transition in the TOC and provide links in the content. - Have special support for this, or just copy slide text? Could use - transitions to separate stages, or a special directive. Problem - with transitions is that they can't be used everywhere -- not, for - example, within a list (see the example below). A directive - (possible names: pause, delay, break, cut, continue, suspend, hold, - stay, stop) seems like a better solution. Should the directive be - available in all contexts (and ineffectual in all but SlideShow - context), or added at runtime by the SlideShow Writer? - - The directive could accept text content, which would be rendered - while paused but would disappear when the slide is continued (the - text could also be a link to the next slide). In the speaker's - master document, the text "paused:" could appear, prefixed to the - directive text. + * Use transitions to separate stages. Problem with transitions is + that they can't be used everywhere -- not, for example, within a + list (see the example below). + + * Use a special directive to separate stages. Possible names: + pause, delay, break, cut, continue, suspend, hold, stay, stop. + Should the directive be available in all contexts (and ineffectual + in all but SlideShow context), or added at runtime by the + SlideShow Writer? + + The directive could accept text content, which would be rendered + while paused but would disappear when the slide is continued (the + text could also be a link to the next slide). In the speaker's + master document, the text "paused:" could appear, prefixed to the + directive text. + + * Use a special directive or class to declare incremental content. + This works best with the S5 ideas. For example:: + + Slide Title + =========== + + .. incremental:: + + * item one + * item two + * item three * Speaker's notes -- how to intersperse? Could use reST comments (".."), but make them visible in the speaker's master document. If @@ -1806,10 +1825,11 @@ Features & issues: nonsensical DTD changes, the "comment" directive could produce an untitled topic element). - The speaker's notes would be separate from S5's handout content. + The speaker's notes could (should?) be separate from S5's handout + content. -* Speaker's master document could use frames for easy navigation: TOC - on the left, content on the right. +* The speaker's master document could use frames for easy navigation: + TOC on the left, content on the right. - It would be nice if clicking in the TOC frame simultaneously linked to both the speaker's notes frame and to the slide window, @@ -1826,18 +1846,27 @@ Features & issues: the beginning of the next/current parent section? First/Last also? Tape-player-style buttons like ``|<< << < > >> >>|``? -* [S5?] Need to support templating of some kind, for uniform slide - layout. Or build in support for limited features? E.g., top/bottom - or left/right banners, images on each page, background color and/or +* [S5] Need to support templating of some kind, for uniform slide + layout. S5 handles this via CSS. + + Build in support for limited features? E.g., top/bottom or + left/right banners, images on each page, background color and/or image, etc. * [S5?] One layout for all slides, or allow some variation? + While S5 seems to support only one style per HTML file, it's + pretty easy to split a presentation in different files and + insert a hyperlink to the last slide of the first part and load + the second part by a click on it. + + -- Chris Liechti + * For nested sections, do we show the section's ancestry on each slide? Optional? No -- leave the implementation to someone who wants it. -* [S5?] Stylesheets for slides: +* [S5] Stylesheets for slides: - Tweaked for different resolutions, 1024x768 etc. - Some layout elements have fixed positions. @@ -1845,13 +1874,13 @@ Features & issues: - Allow 10 lines of text per slide? 15? - Title styles vary by level, but not so much? -* [S5?] Need a transform to number slides for output filenames?, and - for hyperlinks? +* [not required with S5.] Need a transform to number slides for + output filenames?, and for hyperlinks? * Directive to begin a new, untitled (blank) slide? * Directive to begin a new slide, continuation, using the same title - as the previous slide? + as the previous slide? (Unnecessary?) Here's an example that I was hoping to show at PyCon DC 2005:: -- cgit v1.2.1 From f74332157ab86e93794a4e9566f6737aefa7328d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 11 Apr 2005 23:16:11 +0000 Subject: added checks for recursive sidebars git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3206 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/body.py | 5 ++ .../test_rst/test_directives/test_sidebars.py | 73 ++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100755 test/test_parsers/test_rst/test_directives/test_sidebars.py diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 61c58daad..28682328a 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -57,6 +57,11 @@ topic.content = 1 def sidebar(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): + if isinstance(state_machine.node, nodes.sidebar): + error = state_machine.reporter.error( + 'The "%s" directive may not be used within a sidebar element.' + % name, nodes.literal_block(block_text, block_text), line=lineno) + return [error] return topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.sidebar) diff --git a/test/test_parsers/test_rst/test_directives/test_sidebars.py b/test/test_parsers/test_rst/test_directives/test_sidebars.py new file mode 100755 index 000000000..a84fc248d --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_sidebars.py @@ -0,0 +1,73 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for the "sidebar" directive. +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['sidebars'] = [ +["""\ +.. sidebar:: Outer + + .. sidebar:: Nested + + Body. +""", +"""\ +<document source="test data"> + <sidebar> + <title> + Outer + <system_message level="3" line="3" source="test data" type="ERROR"> + <paragraph> + The "sidebar" directive may not be used within a sidebar element. + <literal_block xml:space="preserve"> + .. sidebar:: Nested + \n\ + Body. +"""], +["""\ +.. sidebar:: Outer + + .. topic:: Topic + + .. sidebar:: Inner + + text +""", +"""\ +<document source="test data"> + <sidebar> + <title> + Outer + <topic> + <title> + Topic + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + The "sidebar" directive may not be used within topics or body elements. + <literal_block xml:space="preserve"> + .. sidebar:: Inner + \n\ + text +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 2969f919b08ef2becf68428aeca78c695225c695 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 12 Apr 2005 10:35:12 +0000 Subject: added my objections to more document decorations git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3208 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b08b82477..f8cb68d5e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -480,6 +480,9 @@ General For example, top/bottom/side navigation bars for web pages. Generic decorations? + Seems like a bad idea as long as it isn't independent from the ouput + format (for example, navigation bars are only useful for web pages). + Documentation ============= -- cgit v1.2.1 From e99a08422249d679f7f4ba9d943214290c7fba32 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 12 Apr 2005 10:35:43 +0000 Subject: removed already implemented to-do list entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3209 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f8cb68d5e..5b14fb77c 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -470,10 +470,6 @@ General directories (e.g. --prune=docs/user/rst/cheatsheet.txt, which should *not* be converted to HTML). -* stylesheet & stylesheet_path settings: either one should set the - other one to ``None`` as a side effect. See discussion on - docutils-develop from 2004-07-03. - * Add support for _`plugins`. * Add support for document decorations other than headers & footers? -- cgit v1.2.1 From ad9b5e34aa316c7883797ec4a4f0efec2c6b5c90 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 12 Apr 2005 10:43:33 +0000 Subject: added my ideas about slide shows git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3210 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5b14fb77c..5554d5132 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1798,7 +1798,10 @@ Features & issues: pause, delay, break, cut, continue, suspend, hold, stay, stop. Should the directive be available in all contexts (and ineffectual in all but SlideShow context), or added at runtime by the - SlideShow Writer? + SlideShow Writer? Probably such a "pause" directive should only + be available for slide shows; slide shows are too much of a + special case to justify adding a directive (and node?) to the + core. The directive could accept text content, which would be rendered while paused but would disappear when the slide is continued (the @@ -1818,6 +1821,8 @@ Features & issues: * item two * item three + Add an option to make all bullet lists implicitly incremental? + * Speaker's notes -- how to intersperse? Could use reST comments (".."), but make them visible in the speaker's master document. If structure is necessary, we could use a "comment" directive (to avoid -- cgit v1.2.1 From 80f50583a15744360806e435c9dabd965f6cac8c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 12 Apr 2005 17:12:46 +0000 Subject: updated "Web Site" document to BerliOS and Subversion; cron job is set up again git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3212 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/website.txt | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/dev/website.txt b/docs/dev/website.txt index 0fe2aaf58..e54acb802 100644 --- a/docs/dev/website.txt +++ b/docs/dev/website.txt @@ -9,30 +9,29 @@ :Copyright: This document has been placed in the public domain. The Docutils web site, <http://docutils.sourceforge.net/>, is -maintained by the ``docutils-update`` script. The script used to run -as a cron job, but since mid-2004, cron isn't working on -SourceForge.net, so you will have to run it manually. It will process -any .txt file which is newer than the corresponding .html file in the -project's web directory on SourceForge -(``/home/groups/d/do/docutils/htdocs/``). For a new .txt file, just -SSH to ``<username>@shell.sourceforge.net`` and :: - +maintained automatically by the ``docutils-update`` script, run as an +hourly cron job on shell.berlios.de (by user "felixwiemann"). The +script will process any .txt file which is newer than the +corresponding .html file in the project's web directory on +shell.berlios.de (``/home/groups/docutils/htdocs/aux/htdocs/``) and +upload the changes to the web site at SourceForge. For a new .txt +file, just SSH to ``<username>@shell.berlios.de`` and :: + + cd /home/groups/docutils/htdocs/aux/htdocs/ touch filename.html chmod g+w filename.html sleep 1 touch filename.txt - /home/groups/d/do/docutils/snapshots/sandbox/davidg/infrastructure/docutils-update -p -The ``docutils-update`` script will retrieve the most current version -of the .txt file from CVS and generate the .html file. Thereafter -whenever the .txt file is modified (checked in to CVS), the .html will -be regenerated when ``docutils-update`` is run. +The script will take care of the rest within an hour. Thereafter +whenever the .txt file is modified (checked in to SVN), the .html will +be regenerated automatically. -After adding directories to CVS, allow the script to run once to +After adding directories to SVN, allow the script to run once to create the directories in the filesystem before preparing for HTML processing as described above. -The docutils-update__ script is in CVS as +The docutils-update__ script is located as ``sandbox/davidg/infrastructure/docutils-update``. __ http://docutils.sf.net/sandbox/davidg/infrastructure/docutils-update -- cgit v1.2.1 From 8524aa921c1e97daf41b2d263f15fe38039bc763 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Apr 2005 20:00:30 +0000 Subject: added a syntax idea for parameterized interpreted text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3214 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 50b13392b..51930be3a 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -2764,6 +2764,18 @@ text, analogous to function calls. Ideas: Do angle brackets connote URLs too much for this to be acceptable? How about the "tag" connotation -- does it save them or doom them? +3. `Nested inline markup`_ could prove useful here:: + + `CSS :def:`Cascading Style Sheets``:acronym: is used for HTML, + and `CSS :def:`Content Scrambling System``:acronym: is used for + DVDs. + + Inline markup roles could even define the default roles of nested + inline markup, allowing this cleaner syntax:: + + `CSS `Cascading Style Sheets``:acronym: is used for HTML, and + `CSS `Content Scrambling System``:acronym: is used for DVDs. + Does this push inline markup too far? Readability becomes a serious issue. Substitutions may provide a better alternative (at the expense of verbosity and duplication) by pulling the details out of the text -- cgit v1.2.1 From ff6a81eb833aa1f58fa481a6fe3992575a7736e9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Apr 2005 20:01:12 +0000 Subject: updated adaptable file extensions idea git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3215 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5554d5132..4c064e1aa 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -704,21 +704,35 @@ __ rst/alternatives.html#or-not-to-do In target URLs, it would be useful to not explicitly specify the file extension. If we're generating HTML, then ".html" is appropriate; if PDF, then ".pdf"; etc. How about using ".*" to - indicate "choose the most appropriate filename extension? For + indicate "choose the most appropriate filename extension"? For example:: .. _Another Document: another.* - Should the choice be from among existing files only? Documents - only, or objects (images, etc.) also? (How to differentiate? - Element context [within "image"]?) + What is to be done for output formats that don't *have* hyperlinks? + For example, LaTeX targeted at print. Hyperlinks may be "called + out", as footnotes with explicit URLs. - This may not be just a parser issue though; it may need framework - support. + But then there's also LaTeX targeted at PDFs, which *can* have + links. Perhaps a runtime setting for "*" could explicitly provide + the extension, defaulting to the output file's extension. - Mailing list thread: `Images in both HTML and LaTeX`__ + Should the system check for existing files? No, not practical. + + Handle documents only, or objects (images, etc.) also? + + If this handles images also, how to differentiate between document + and image links? Element context (within "image")? Which image + extension to use for which document format? Again, a runtime + setting would suffice. + + This may not be just a parser issue; it may need framework support. + + Mailing list threads: `Images in both HTML and LaTeX`__, + `more-universal links?`__ __ http://thread.gmane.org/gmane.text.docutils.user/1239 + __ http://thread.gmane.org/gmane.text.docutils.user/1915 * Implement the header row separator modification to table.el. (Wrote to Takaaki Ota & the table.el mailing list on 2001-08-12, suggesting -- cgit v1.2.1 From 1ba990451695b1544ab0535c84fdcd92323174ad Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Apr 2005 20:04:26 +0000 Subject: removed completed item; removed outdated "@" markers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3216 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4c064e1aa..40510eddc 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -142,9 +142,9 @@ General top-level modules if the module name is not in docutils/readers. Potential nastiness.) -* @@@ Perhaps store a _`name-to-id mapping file`? This could be - stored permanently, read by subsequent processing runs, and updated - with new entries. ("Persistent ID mapping"?) +* Perhaps store a _`name-to-id mapping file`? This could be stored + permanently, read by subsequent processing runs, and updated with + new entries. ("Persistent ID mapping"?) * Perhaps the ``Component.supports`` method should deal with individual features ("meta" etc.) instead of formats ("html" etc.)? @@ -496,8 +496,8 @@ Developer Docs * Complete `Docutils Runtime Settings <../api/runtime-settings.html>`_. -* @@@ Improve the internal module documentation (docstrings in the - code). Specific deficiencies listed below. +* Improve the internal module documentation (docstrings in the code). + Specific deficiencies listed below. - docutils.parsers.rst.states.State.build_table: data structure required (including StringList). @@ -743,11 +743,11 @@ __ rst/alternatives.html#or-not-to-do exposition in the spec, to make clear what is going on for people with head colds. -* @@ Fix the parser's indentation handling to conform with the - stricter definition in the spec. (Explicit markup blocks should be - strict or forgiving?) +* Fix the parser's indentation handling to conform with the stricter + definition in the spec. (Explicit markup blocks should be strict or + forgiving?) -* @@ Tighten up the spec for indentation of "constructs using complex +* Tighten up the spec for indentation of "constructs using complex markers": field lists and option lists? Bodies may begin on the same line as the marker or on a subsequent line (with blank lines optional). Require that for bodies beginning on the same line as @@ -2031,9 +2031,6 @@ Front-End Tools * Implement the "sectnum" directive as a command-line option also? -* @@@ Come up with better names for the most-used tools, and install - them as scripts. - * Create a single dynamic_ or unqualified_ front end that can be installed? -- cgit v1.2.1 From 82d5edddc7405351697ad1f1aca772fe8a60f74e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 15 Apr 2005 12:40:31 +0000 Subject: removed unnecessary support for "refname" attribute git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3218 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1374b82a6..3e465d3d3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -443,14 +443,9 @@ class HTMLTranslator(nodes.NodeVisitor): '</tbody>\n</table>\n') def visit_citation_reference(self, node): - href = '' - if node.has_key('refid'): - href = '#' + node['refid'] - elif node.has_key('refname'): - href = '#' + self.document.nameids[node['refname']] - self.body.append(self.starttag(node, 'a', '[', - CLASS='citation-reference', - **(href and {'href': href} or {}))) + href = '#' + node['refid'] + self.body.append(self.starttag( + node, 'a', '[', CLASS='citation-reference', href=href)) def depart_citation_reference(self, node): self.body.append(']</a>') @@ -780,11 +775,7 @@ class HTMLTranslator(nodes.NodeVisitor): '</tbody>\n</table>\n') def visit_footnote_reference(self, node): - href = '' - if node.has_key('refid'): - href = '#' + node['refid'] - elif node.has_key('refname'): - href = '#' + self.document.nameids[node['refname']] + href = '#' + node['refid'] format = self.settings.footnote_references if format == 'brackets': suffix = '[' @@ -1091,15 +1082,14 @@ class HTMLTranslator(nodes.NodeVisitor): div_atts['class'] += ' image-reference' self.body.append(self.starttag({}, 'div', '', **div_atts)) self.context.append('</div>\n') - href = '' if node.has_key('refuri'): href = node['refuri'] - elif node.has_key('refid'): + else: + assert node.has_key('refid'), \ + 'References must have "refuri" or "refid" attribute.' href = '#' + node['refid'] - elif node.has_key('refname'): - href = '#' + self.document.nameids[node['refname']] self.body.append(self.starttag(node, 'a', '', CLASS='reference', - **(href and {'href': href} or {}))) + href=href)) def depart_reference(self, node): self.body.append('</a>') -- cgit v1.2.1 From 42d2207ba264301b24a72c8c564398e8f4a330da Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 16 Apr 2005 19:54:58 +0000 Subject: restored Element.set_class method for compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3220 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 - docutils/nodes.py | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ca0871493..c4dedbd16 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -41,7 +41,6 @@ Changes Since 0.3.7 - Added ``attr_defaults`` dictionary for default attribute values. - Added empty list as default value for the following attributes: ``ids``, ``names``, ``dupnames``, ``classes``, and ``backrefs``. - - Removed ``Element.set_class()`` method. - Added ``document.decoration`` attribute, ``document.get_decoration`` method, and ``decoration.get_header`` & ``.get_footer`` methods. diff --git a/docutils/nodes.py b/docutils/nodes.py index 0cebdb5b0..1113a3c7c 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -346,8 +346,7 @@ class Element(Node): self.extend(children) # maintain parent info - self.attributes = {'ids': [], 'classes': [], 'names': [], - 'dupnames': [], 'backrefs': []} + self.attributes = self.attr_defaults.copy() """Dictionary of attribute {name: value}.""" for att, value in attributes.items(): @@ -595,6 +594,10 @@ class Element(Node): def copy(self): return self.__class__(**self.attributes) + def set_class(self, name): + """Add a new class to the "classes" attribute.""" + self['classes'].append(name.lower()) + def note_referenced_by(self, name=None, id=None): """Note that this Element has been referenced by its name `name` or id `id`.""" -- cgit v1.2.1 From 405c017f38f29c1276893db2114ab66e051b72bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 16 Apr 2005 20:02:03 +0000 Subject: Element.attr_defaults needs to be deepcopied git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3222 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 1113a3c7c..4f13791f6 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -26,6 +26,7 @@ __docformat__ = 'reStructuredText' import sys import os import re +import copy import xml.dom.minidom from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType @@ -346,7 +347,7 @@ class Element(Node): self.extend(children) # maintain parent info - self.attributes = self.attr_defaults.copy() + self.attributes = copy.deepcopy(self.attr_defaults) """Dictionary of attribute {name: value}.""" for att, value in attributes.items(): -- cgit v1.2.1 From 615d45718520914eb81f6436f9f2e418574b7e19 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 16 Apr 2005 20:29:01 +0000 Subject: restored utils.Reporter.set_conditions (with deprecation warning) for compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3223 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docutils/utils.py b/docutils/utils.py index c61aedd4e..674769815 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -13,6 +13,7 @@ __docformat__ = 'reStructuredText' import sys import os import os.path +import warnings from types import StringType, UnicodeType from docutils import ApplicationError, DataError from docutils import frontend, nodes @@ -119,6 +120,17 @@ class Reporter: self.max_level = -1 """The highest level system message generated so far.""" + def set_conditions(self, category, report_level, halt_level, + stream=None, debug=0): + warnings.warn('set attributes via configuration settings or directly', + DeprecationWarning, stacklevel=2) + self.report_level = report_level + self.halt_level = halt_level + if stream is None: + stream = sys.stderr + self.stream = stream + self.debug = debug + def attach_observer(self, observer): """ The `observer` parameter is a function or bound method which takes one -- cgit v1.2.1 From 113803aad456f90a5192d9159ed4edc1be3f1651 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 16 Apr 2005 20:30:32 +0000 Subject: updated with forgotten entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3224 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index c4dedbd16..412539776 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -45,6 +45,12 @@ Changes Since 0.3.7 ``document.get_decoration`` method, and ``decoration.get_header`` & ``.get_footer`` 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. -- cgit v1.2.1 From aac47cffe857ae51f61949a950ff11df2308b1a8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 16 Apr 2005 20:49:11 +0000 Subject: added assert to make sure we aren't accidentally adding two classes in one string (because that wouldn't be noticed in HTML) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3225 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 4f13791f6..fab2fe9c4 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -597,6 +597,7 @@ class Element(Node): def set_class(self, name): """Add a new class to the "classes" attribute.""" + assert ' ' not in name self['classes'].append(name.lower()) def note_referenced_by(self, name=None, id=None): -- cgit v1.2.1 From 147ab4806e250e3a97d8e8e9376c30b71445cbc0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Apr 2005 03:09:56 +0000 Subject: added deprecation warning for obsolete Element.set_class method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3226 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index fab2fe9c4..300d687c3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -27,6 +27,7 @@ import sys import os import re import copy +import warnings import xml.dom.minidom from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType @@ -597,6 +598,9 @@ class Element(Node): def set_class(self, name): """Add a new class to the "classes" attribute.""" + warnings.warn('docutils.nodes.Element.set_class deprecated; ' + "append to Element.attributes['classes'] list " + 'attribute directly', DeprecationWarning, stacklevel=2) assert ' ' not in name self['classes'].append(name.lower()) -- cgit v1.2.1 From 23aec339aa4a72e246cfa3488b5bdd5a0def5969 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Apr 2005 03:10:05 +0000 Subject: clarified warning git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3227 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index 674769815..b763c7c02 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -122,7 +122,8 @@ class Reporter: def set_conditions(self, category, report_level, halt_level, stream=None, debug=0): - warnings.warn('set attributes via configuration settings or directly', + warnings.warn('docutils.utils.Reporter.set_condition deprecated; ' + 'set attributes via configuration settings or directly', DeprecationWarning, stacklevel=2) self.report_level = report_level self.halt_level = halt_level -- cgit v1.2.1 From 3f71f8ea5d87643dda490266ec3723ce95a93eb3 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Apr 2005 22:18:30 +0000 Subject: Two things to the underlining function for emacs: 1. when the underlining is invoked with a negative argument on a line that has no decoration, we should not interpret that as a style switch (box vs simple). This is reserved for a positive prefix-arg only. This is more consistent with the behaviour when there already is some decoration present on the current title. 2. changed the default sectioning char to a list, and the underlining function to suggest a new underlining char (i.e. one that is not already present in the file), choosing it from the list formed by the difference between the preferred sectioning chars and the chars already in the file, when rotating the section underlines. This is really useful, because in practice, you often start a new file, and need to underline a new section which doesn't have other existing underlining. By using the list in the rest-preferred-characters variables you can specify your usual preferred order for sectioning chars and the new suggested character is automatically the one you're expecting. I set the default preferred list to something reasonable, =, then -, then ~, then other stuff. Feel free to customize for your own needs. Note that the order that is already present in the file is used above the preferred chars list. The preferred list is only used to suggest new characters. This is getting pretty cool. I feel like this is probably the end of feature enhancements for this function. Very happy with it. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3228 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 56 +++++++++++++++++------ tools/editors/emacs/tests/tests-adjust-section.el | 32 ++++++++++--- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index c7c431f05..6ab001cec 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -88,6 +88,13 @@ This is useful for filling list item paragraphs." ;; If the function is invoked on a section that is complete, the character ;; is rotated among the existing ones. ;; +;; Note that when rotating the underlining characters, if we come to the end +;; of the hierarchy of characters, the variable rest-preferred-characters +;; is consulted to propose a new underline char, and if continued, we cycle +;; the underline characters all over again. Set this variable to nil if +;; you want to limit the underlining character propositions to the existing +;; underlines in the file. +;; ;; - prefix argument is used to alternate the sectioning style. ;; ;; Examples: @@ -211,6 +218,16 @@ This is useful for filling list item paragraphs." )) chars)) +(defun rest-suggest-new-char (allchars) + "Given the last char that has been seen, suggest a new, + different character, different from all that have been seen." + (let ((potentials (copy-sequence rest-preferred-characters))) + (dolist (x allchars) + (setq potentials (delq x potentials)) + ) + (car potentials) + )) + (defun rest-update-section (underlinechar style &optional indent) "Unconditionally updates the overline/underline of a section title using the given character CHAR, with STYLE 'simple or @@ -275,10 +292,10 @@ This is useful for filling list item paragraphs." (goto-char marker) )) - -(defvar rest-default-section-char ?= - "Default section underlining character to use when there aren't - any others to be used in the file.") +(defvar rest-preferred-characters '(?= ?- ?~ ?+ ?` ?# ?@) + "Preferred ordering of underline characters. This sequence is + consulted to offer a new underline character when we rotate the + underlines at the end of the existing hierarchy of characters.") (defvar rest-default-under-and-over-indent 1 "Number of characters to indent the section title when toggling @@ -312,10 +329,10 @@ This is useful for filling list item paragraphs." and underline the current line as a section title (also see prefix argument below). - If no pre-existing underlining character is found in the - file, we use the last seen underline char or - rest-default-section-char if this is the first title in the - entire file. + If no pre-existing underlining character is found in the on + the line, we use the last seen underline char or consult the + first element of rest-preferred-characters if this is the + first title in the entire file. - If the current line does have an underline or overline, and if @@ -393,18 +410,20 @@ This is useful for filling list item paragraphs." (if (or (and current-prefix-arg (not (< (prefix-numeric-value current-prefix-arg) 0))) (eq curchar nil)) - + ;; we're switching characters or there is currently no sectioning (progn (setq curchar (or curchar (rest-find-last-section-char) (car (rest-all-section-chars)) - rest-default-section-char)) - + (car rest-preferred-characters) + ?=)) + (rest-update-section - (or curchar rest-default-section-char) - (if current-prefix-arg + curchar + (if (and current-prefix-arg + (not (< (prefix-numeric-value current-prefix-arg) 0))) (if (eq init-style 'over-and-under) 'simple 'over-and-under) init-style) rest-default-under-and-over-indent) @@ -434,7 +453,15 @@ This is useful for filling list item paragraphs." (if (bolp) 1 0))) (allchars (rest-all-section-chars (list (- curline 1) curline (+ curline 1)))) - (rotchars (append allchars (list (car allchars)))) + + (rotchars + (append allchars + (filter 'identity + (list + ;; suggest a new char + (rest-suggest-new-char allchars) + ;; rotate to first char + (car allchars))))) (nextchar (or (cadr (memq curchar (if (< (prefix-numeric-value @@ -442,6 +469,7 @@ This is useful for filling list item paragraphs." (reverse rotchars) rotchars))) (car allchars)) ) ) + (if nextchar (rest-update-section nextchar init-style curindent)) ))) diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index df01b2bd5..a1fa9ec3d 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -111,6 +111,30 @@ Subtitle ") + (with-suggested-new-text +" +Some Title +========== + +Subtitle +-------- + +Subtitle2@ + +" +" +Some Title +========== + +Subtitle +-------- + +Subtitle2 +~~~~~~~~~ + +" +2) + (with-previous-text-rotating " Some Title @@ -133,7 +157,7 @@ Subtitle2 ========= " -2) +3) ) @@ -173,9 +197,3 @@ Subtitle2 rest-adjust-section-tests (lambda () (call-interactively 'rest-adjust-section-title))) - - - - - - -- cgit v1.2.1 From 352f98b31a39a3ccf81dbf5746e088cea3df2abd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 20 Apr 2005 19:01:41 +0000 Subject: added to the instructions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3229 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/README.txt | 30 ++++++++++++++++++++++++++++++ tools/editors/emacs/restructuredtext.el | 8 ++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index 560a59c75..d4359213b 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -6,6 +6,36 @@ :Date: $Date$ + +Directory Contents +================== + +This directory contains the following Emacs lisp package files: + +* restructuredtext.el by Martin Blais and David Goodger + + Support code for editing reStructuredText with Emacs indented-text + mode. + +* rst-mode.el by Stefan Merten + + Provides support for documents marked up using the reStructuredText + format, including font locking as well as some convenience functions + for editing. + +* rst-html.el by Martin Blais + + Provides a few functions and variables that can help in automating + the conversion of reST documents to HTML from within Emacs. + +Each file includes specific usage instructions. To install a package, +put a copy of the package file in a directory on your ``load-path`` +(use ``C-h v load-path`` to check). + + +Character Processing Notes +========================== + Since reStructuredText punts on the issue of character processing, here are some useful resources for Emacs users in the Unicode world: diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 6ab001cec..9fa83d057 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -9,6 +9,10 @@ ;; Installation instructions ;; ------------------------- ;; +;; Add this line to your .emacs file:: +;; +;; (require 'restructuredtext) +;; ;; You should bind the versatile sectioning command to some key in the text-mode ;; hook. Something like this:: ;; @@ -18,8 +22,8 @@ ;; (add-hook 'text-mode-hook 'user-rst-mode-hook) ;; ;; Other specialized and more generic functions are also available. -;; Note that C-= is a good binding, since it allows you to specif a negative arg -;; easily with C-- C-= (easy to type), as well as ordinary prefix arg with +;; Note that C-= is a good binding, since it allows you to specify a negative +;; arg easily with C-- C-= (easy to type), as well as ordinary prefix arg with ;; C-u C-=. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- cgit v1.2.1 From 035df151ab0b098ff504576f19f3306dee21c72e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 14:42:52 +0000 Subject: updated list of known-good browsers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3230 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index aa99d13ab..43ca284a4 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -720,10 +720,10 @@ What browsers are supported? No specific browser is targeted; all modern graphical browsers should work. Some older browsers, text-only browsers, and browsers without -full CSS support are known to produce inferior results. Mozilla -(version 1.0 and up) and MS Internet Explorer (version 5.0 and up) are -known to give good results. Reports of experiences with other -browsers are welcome. +full CSS support are known to produce inferior results. Firefox, +Safari, Mozilla (version 1.0 and up), and MS Internet Explorer +(version 5.0 and up) are known to give good results. Reports of +experiences with other browsers are welcome. Unexpected results from tools/rst2html.py: H1, H1 instead of H1, H2. Why? -- cgit v1.2.1 From bd559044426b3f80dd1e7cc9b2d3a25c61bb952f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 14:52:41 +0000 Subject: "image" directive: added checks for valid values of "align" option, depending on context. "figure" directive: added specialized "align" option and attribute on "figure" element. Added HTML support for ``align`` attribute on ``figure`` elements. Updated docs & tests. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3231 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 ++++ docs/ref/docutils.dtd | 8 ++++++ docs/ref/rst/directives.txt | 5 ++++ docutils/parsers/rst/directives/images.py | 30 +++++++++++++++++++++- docutils/writers/html4css1.py | 2 ++ .../expected/standalone_rst_html4css1.html | 2 +- .../expected/standalone_rst_pseudoxml.txt | 2 +- test/functional/input/data/standard.txt | 1 + .../test_rst/test_directives/test_figures.py | 13 ++++++++++ 9 files changed, 65 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 412539776..95af46972 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -84,6 +84,9 @@ Changes Since 0.3.7 - 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. * docutils/parsers/rst/directives/misc.py: @@ -131,6 +134,7 @@ Changes Since 0.3.7 - Added the ``field_name_limit`` & ``option_limit`` settings & support. - Added support for table stub columns. + - Added support for ``align`` attribute on ``figure`` elements. * docutils/writers/latex2e.py: @@ -147,6 +151,7 @@ Changes Since 0.3.7 - Added ``stub`` attribute to ``colspec`` element via the ``tbl.colspec.att`` parameter entity. - Allowed topic elements within sidebars + - Added ``align`` attribute to ``figure`` element. Release 0.3.7 (2004-12-24) diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 357703f04..f3a7d37ca 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -97,6 +97,12 @@ resolve to either an internal or external reference. <!ENTITY % fixedspace.att " xml:space (default | preserve) #FIXED 'preserve' "> +<!ENTITY % align-h.att + " align (left | center | right) #IMPLIED "> + +<!ENTITY % align-hv.att + " align (top | middle | bottom | left | center | right) #IMPLIED "> + <!-- Element OR-Lists ============================================================= --> @@ -465,12 +471,14 @@ or " ") or the text between option arguments (typically either "," or <!ELEMENT figure (image, ((caption, legend?) | legend)) > <!ATTLIST figure %basic.atts; + %align-h.att; width %number; #IMPLIED> <!-- Also an inline element. --> <!ELEMENT image EMPTY> <!ATTLIST image %basic.atts; + %align-hv.att; uri CDATA #REQUIRED alt CDATA #IMPLIED height %number; #IMPLIED diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 737cbe97a..f888ef556 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -309,6 +309,11 @@ options are recognized: Set a "class" attribute value on the figure element. See the class_ directive below. +``align`` : "left", "center", or "right" + The horizontal alignment of the figure, allowing the image to + float and have the text flow around it. The specific behavior + depends upon the browser or rendering software used. + .. [#PIL] `Python Imaging Library`_. .. _Python Imaging Library: http://www.pythonware.com/products/pil/ diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index d4cd20a7f..7efb2588d 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -22,13 +22,33 @@ try: except ImportError: Image = None -align_values = ('top', 'middle', 'bottom', 'left', 'center', 'right') +align_h_values = ('left', 'center', 'right') +align_v_values = ('top', 'middle', 'bottom') +align_values = align_v_values + align_h_values def align(argument): return directives.choice(argument, align_values) def image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): + if options.has_key('align'): + # check for align_v values only + if isinstance(state, states.SubstitutionDef): + if options['align'] not in align_v_values: + error = state_machine.reporter.error( + 'Error in "%s" directive: "%s" is not a valid value for ' + 'the "align" option within a substitution definition. ' + 'Valid values for "align" are: "%s".' + % (name, options['align'], '", "'.join(align_v_values)), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + elif options['align'] not in align_h_values: + error = state_machine.reporter.error( + 'Error in "%s" directive: "%s" is not a valid value for ' + 'the "align" option. Valid values for "align" are: "%s".' + % (name, options['align'], '", "'.join(align_h_values)), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] messages = [] reference = directives.uri(arguments[0]) options['uri'] = reference @@ -63,12 +83,17 @@ image.options = {'alt': directives.unchanged, 'target': directives.unchanged_required, 'class': directives.class_option} +def figure_align(argument): + return directives.choice(argument, align_h_values) + def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): figwidth = options.setdefault('figwidth') figclasses = options.setdefault('figclass') + align = options.setdefault('align') del options['figwidth'] del options['figclass'] + del options['align'] (image_node,) = image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine) if isinstance(image_node, nodes.system_message): @@ -88,6 +113,8 @@ def figure(name, arguments, options, content, lineno, figure_node['width'] = figwidth if figclasses: figure_node['classes'] += figclasses + if align: + figure_node['align'] = align if content: node = nodes.Element() # anonymous container for parsing state.nested_parse(content, content_offset, node) @@ -116,4 +143,5 @@ figure.arguments = (1, 0, 1) figure.options = {'figwidth': figwidth_value, 'figclass': directives.class_option} figure.options.update(image.options) +figure.options['align'] = figure_align figure.content = 1 diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 3e465d3d3..cdc8bf583 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -715,6 +715,8 @@ class HTMLTranslator(nodes.NodeVisitor): atts = {'class': 'figure'} if node.get('width'): atts['style'] = 'width: %spx' % node['width'] + if node.get('align'): + atts['align'] = node['align'] self.body.append(self.starttag(node, 'div', **atts)) def depart_figure(self, node): diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 66879b19f..8ea472629 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -546,7 +546,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>An image directive (also clickable -- a hyperlink reference):</p> <div class="image class1 class2 image-reference"><a class="reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a></div> <p>A figure directive:</p> -<div class="figclass1 figclass2 figure"> +<div align="left" class="figclass1 figclass2 figure"> <div class="image class1 class2"><img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></div> <p class="caption">A figure is an image with a caption and/or a legend:</p> <div class="legend"> diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index b4d510854..6fd48b818 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1121,7 +1121,7 @@ <image classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> <paragraph> A figure directive: - <figure classes="figclass1 figclass2"> + <figure align="left" classes="figclass1 figclass2"> <image alt="reStructuredText, the markup syntax" classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> <caption> A figure is an image with a caption and/or a legend: diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 092a0ae44..507838b88 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -429,6 +429,7 @@ A figure directive: :figclass: figclass1 figclass2 :class: class1 class2 :alt: reStructuredText, the markup syntax + :align: left A figure is an image with a caption and/or a legend: diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index 821841e07..38c6e821f 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -106,6 +106,19 @@ totest['figures'] = [ A picture with image options on individual lines, and this caption. """], ["""\ +.. figure:: picture.png + :align: center + + A figure with explicit alignment. +""", +"""\ +<document source="test data"> + <figure align="center"> + <image uri="picture.png"> + <caption> + A figure with explicit alignment. +"""], +["""\ This figure lacks a caption. It may still have a "Figure 1."-style caption appended in the output. -- cgit v1.2.1 From 4d46596ac406d5a0f1fe2696e8d7a264b59a38da Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 15:09:30 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3232 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/THANKS.txt b/THANKS.txt index 22431536b..2ca6741d1 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -1,3 +1,5 @@ +-*- coding: utf-8 -*- + Acknowledgements ================ @@ -67,6 +69,7 @@ donations, tasty treats, and related projects: * Richard Jones * Andreas Jung * Garth Kidd +* Philipp Knüsel * Axel Kollmorgen * Jeff Kowalczyk * Dave Kuhlman -- cgit v1.2.1 From 9de1584b478ea720d2e684a28dd8c51ee07262d0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 15:16:10 +0000 Subject: another update (been neglecting this list) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3233 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/THANKS.txt b/THANKS.txt index 2ca6741d1..91b90f259 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -1,4 +1,4 @@ --*- coding: utf-8 -*- +.. -*- coding: utf-8 -*- Acknowledgements ================ @@ -92,6 +92,7 @@ donations, tasty treats, and related projects: * Nigel W. Moriarty * Mark Nodine * Patrick K. O'Brien +* Omidyar Network (Pierre Omidyar & Doug Solomon) * Michel Pelletier * Sam Penrose * Tim Peters -- cgit v1.2.1 From eb73794f2e210475c3cafc3f740a3157d834cd4a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 16:17:00 +0000 Subject: removed reference to Element.attributes; let's access attributes consistently (and shorter) via Element.__getitem__ (David, if you disagree, please feel free to revert the change without prior discussion) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3234 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 300d687c3..b79c0e688 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -599,8 +599,8 @@ class Element(Node): def set_class(self, name): """Add a new class to the "classes" attribute.""" warnings.warn('docutils.nodes.Element.set_class deprecated; ' - "append to Element.attributes['classes'] list " - 'attribute directly', DeprecationWarning, stacklevel=2) + "append to Element['classes'] list attribute directly", + DeprecationWarning, stacklevel=2) assert ' ' not in name self['classes'].append(name.lower()) -- cgit v1.2.1 From 40ccd0d9f29e9fb5a6eef4bc0b437ef1a4f8273a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 16:18:45 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3235 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index b763c7c02..aeb882485 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -122,7 +122,7 @@ class Reporter: def set_conditions(self, category, report_level, halt_level, stream=None, debug=0): - warnings.warn('docutils.utils.Reporter.set_condition deprecated; ' + warnings.warn('docutils.utils.Reporter.set_conditions deprecated; ' 'set attributes via configuration settings or directly', DeprecationWarning, stacklevel=2) self.report_level = report_level -- cgit v1.2.1 From 45afa3ca4d5aa4932685a91ec8ae15c876335de5 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 16:20:11 +0000 Subject: added test for targets in front of sections git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3236 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_html4css1.html | 6 +++--- test/functional/expected/standalone_rst_latex.tex | 2 ++ test/functional/expected/standalone_rst_pseudoxml.txt | 7 ++++--- test/functional/input/data/standard.txt | 2 ++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 8ea472629..13f8c02c6 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -493,7 +493,7 @@ rendered separately and differently from footnotes.</td></tr> <p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id71" name="id72"><span class="problematic" id="id72">[nonexistent]_</span></a> citation.</p> </div> -<div class="section" id="targets"> +<span id="another-target"></span><div class="section" id="targets"> <h2><a class="toc-backref" href="#id43" name="targets">2.13   Targets</a></h2> <p id="example">This paragraph is pointed to by the explicit "example" target. A reference can be found under <a class="reference" href="#inline-markup">Inline Markup</a>, above. <a class="reference" href="#inline-hyperlink-targets">Inline @@ -915,10 +915,10 @@ Unknown target name: "5".</div> <p class="system-message-title">System Message: <a name="id71">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 361); <em><a href="#id72">backlink</a></em></p> Unknown target name: "nonexistent".</div> <div class="system-message" id="id73"> -<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 386); <em><a href="#id74">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 388); <em><a href="#id74">backlink</a></em></p> Unknown target name: "hyperlink reference without a target".</div> <div class="system-message" id="id75"> -<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 399); <em><a href="#id76">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 401); <em><a href="#id76">backlink</a></em></p> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 32add09e3..5e937878c 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -770,7 +770,9 @@ citation. %___________________________________________________________________________ \hypertarget{targets}{} +\hypertarget{another-target}{} \pdfbookmark[1]{2.13~~~Targets}{targets} +\pdfbookmark[1]{2.13~~~Targets}{another-target} \subsection*{2.13~~~Targets} This paragraph is pointed to by the explicit ``example'' target. A diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 6fd48b818..d647b11a8 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -969,7 +969,8 @@ [nonexistent]_ citation. - <section ids="targets" names="targets"> + <target refid="another-target"> + <section ids="targets another-target" names="targets another target"> <title auto="1" refid="id43"> <generated classes="sectnum"> 2.13    @@ -1692,9 +1693,9 @@ <system_message backrefs="id72" ids="id71" level="3" line="361" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id74" ids="id73" level="3" line="386" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id74" ids="id73" level="3" line="388" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id76" ids="id75" level="3" line="399" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id76" ids="id75" level="3" line="401" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 507838b88..7019df74a 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -359,6 +359,8 @@ Citations Here's a reference to the above, [CIT2002]_, and a [nonexistent]_ citation. +.. _Another Target: + Targets ------- -- cgit v1.2.1 From 09d3cf06d997a37f1b173e050daa2577009f3c5d Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 17:46:08 +0000 Subject: added (more) tests for :align: option of image and figure directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3237 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/test_figures.py | 19 +++++++++ .../test_rst/test_directives/test_images.py | 49 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index 38c6e821f..cdc95a2e3 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -119,6 +119,25 @@ totest['figures'] = [ A figure with explicit alignment. """], ["""\ +.. figure:: picture.png + :align: top + + A figure with wrong alignment. +""", +"""\ +<document source="<stdin>"> + <system_message level="3" line="1" source="<stdin>" type="ERROR"> + <paragraph> + Error in "figure" directive: + invalid option value: (option: "align"; value: u'top') + "top" unknown; choose from "left", "center", or "right". + <literal_block xml:space="preserve"> + .. figure:: picture.png + :align: top + + A figure with wrong alignment. +"""], +["""\ This figure lacks a caption. It may still have a "Figure 1."-style caption appended in the output. diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index 256f2e00f..6d016a82d 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -293,6 +293,55 @@ totest['images'] = [ .. image:: picture.png :target: """], +["""\ +.. image:: picture.png + :align: left +""", +"""\ +<document source="test data"> + <image align="left" uri="picture.png"> +"""], +["""\ +.. image:: picture.png + :align: top +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "image" directive: "top" is not a valid value for the "align" option. Valid values for "align" are: "left", "center", "right". + <literal_block xml:space="preserve"> + .. image:: picture.png + :align: top +"""], +["""\ +.. |img| image:: picture.png + :align: top +""", +"""\ +<document source="test data"> + <substitution_definition names="img"> + <image align="top" alt="img" uri="picture.png"> +"""], +["""\ +.. |img| image:: picture.png + :align: left +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "image" directive: "left" is not a valid value for the "align" option within a substitution definition. Valid values for "align" are: "top", "middle", "bottom". + <literal_block xml:space="preserve"> + image:: picture.png + :align: left + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + Substitution definition "img" empty or invalid. + <literal_block xml:space="preserve"> + .. |img| image:: picture.png + :align: left +"""], ] -- cgit v1.2.1 From df9f154b022a494b353fb6df0bbc04dc374d9ae5 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 19:02:28 +0000 Subject: added note about using "compound" as a block-level container git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3238 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index f888ef556..130f0d154 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -605,6 +605,16 @@ example:: In the example above, a literal block is "embedded" within a sentence that begins in one physical paragraph and ends in another. +.. note:: + + The "compound" directive is *not* a generic block-level container + like HTML's ``<div>`` element. Do not use it only to group a + sequence of elements, or you may get unexpected results. + + If you happen to need a generic block-level container, please + describe your use-case in an email to + docutils-users@lists.sourceforge.net. + Compound paragraphs are typically rendered as multiple distinct text blocks, with the possibility of variations to emphasize their logical unity: -- cgit v1.2.1 From 7fb1f1f2c393439adac542626fb64b13955e269d Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 19:23:36 +0000 Subject: fixed bug in LaTeX writer with --use-latex-toc git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3239 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index f756f1e39..9f883bb13 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1974,7 +1974,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_topic(self, node): self.topic_classes = node['classes'] - if self.use_latex_toc: + if 'contents' in node['classes'] and self.use_latex_toc: self.body.append('\\tableofcontents\n\n\\bigskip\n') self.topic_classes = [] raise nodes.SkipNode -- cgit v1.2.1 From 306200306bd41a9104d23d9a95f1512d6c9c0685 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 20:43:53 +0000 Subject: fixed error in test code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3240 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_directives/test_figures.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index cdc95a2e3..91fd91596 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -125,11 +125,11 @@ totest['figures'] = [ A figure with wrong alignment. """, """\ -<document source="<stdin>"> - <system_message level="3" line="1" source="<stdin>" type="ERROR"> +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Error in "figure" directive: - invalid option value: (option: "align"; value: u'top') + invalid option value: (option: "align"; value: 'top') "top" unknown; choose from "left", "center", or "right". <literal_block xml:space="preserve"> .. figure:: picture.png -- cgit v1.2.1 From 5582f0c0893cae4661d8e16449e69e75a49bbe04 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 21 Apr 2005 21:59:05 +0000 Subject: added link to Felix's objections of adaptable file extension syntax git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3241 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 40510eddc..79d124a21 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -728,10 +728,11 @@ __ rst/alternatives.html#or-not-to-do This may not be just a parser issue; it may need framework support. - Mailing list threads: `Images in both HTML and LaTeX`__, - `more-universal links?`__ + Mailing list threads: `Images in both HTML and LaTeX`__ (especially + `this summary of Felix's objections`__), `more-universal links?`__ __ http://thread.gmane.org/gmane.text.docutils.user/1239 + __ http://article.gmane.org/gmane.text.docutils.user/1278 __ http://thread.gmane.org/gmane.text.docutils.user/1915 * Implement the header row separator modification to table.el. (Wrote -- cgit v1.2.1 From 18bd99c8f3343501694e159080192f47eb16c34c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 22 Apr 2005 23:57:18 +0000 Subject: Added "cloak_email_addresses" setting & support; updated test & docs. Thanks to Barry Warsaw & Ned Batchelder for the idea and initial patch. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3243 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + THANKS.txt | 1 + docs/user/config.txt | 13 +++++++++++++ docutils/writers/html4css1.py | 32 ++++++++++++++++++++++++++++++-- test/functional/expected/pep_html.html | 29 +++++++++++++++++++++++------ test/functional/input/pep_html.txt | 11 ++++++++++- test/functional/tests/pep_html.py | 1 + 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 95af46972..7218ac5bc 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -135,6 +135,7 @@ Changes Since 0.3.7 support. - Added support for table stub columns. - Added support for ``align`` attribute on ``figure`` elements. + - Added the ``cloak_email_addresses`` setting & support. * docutils/writers/latex2e.py: diff --git a/THANKS.txt b/THANKS.txt index 91b90f259..26b6e9114 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -17,6 +17,7 @@ donations, tasty treats, and related projects: * Aahz * David Abrahams * David Ascher +* Ned Batchelder * Heiko Baumann * Eric Bellot * Ian Bicking diff --git a/docs/user/config.txt b/docs/user/config.txt index 7e93626a1..ebff78289 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -527,6 +527,19 @@ attribution __ `attribution [latex2e writer]`_ +_`cloak_email_addresses` + Scramble email addresses to confuse harvesters. In the visible + text of an email address, the "@" will be replaced by "at", and + all periods (".") will be replaced by "dot", with spaces added. + In the reference URI, the address will be replaced by %-escapes. + For example, "abc@example.org" will be output as:: + + <a class="reference" + href="mailto:%61%62%63%40%65%78%61%6D%70%6C%65%2E%6F%72%67"> + abc at example dot org</a> + + Default: don't cloak (None). Option: ``--cloak-email``. + _`compact_lists` Remove extra vertical whitespace between items of bullet lists and enumerated lists, when list items are "simple" (i.e., all items diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cdc8bf583..cdb3f7f88 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -101,7 +101,12 @@ class Writer(writers.Writer): ('Omit the XML declaration. Use with caution.', ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', - 'validator': frontend.validate_boolean}),)) + 'validator': frontend.validate_boolean}), + ('Scramble email addresses to confuse harvesters. ' + 'For example, "abc@example.org" will become ' + '``<a href="mailto:%61%62%63%40...">abc at example dot org</a>``.', + ['--cloak-email-addresses'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) relative_path_settings = ('stylesheet_path',) @@ -240,6 +245,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.header = [] self.footer = [] self.in_document_title = 0 + self.in_mailto = 0 def astext(self): return ''.join(self.head_prefix + self.head @@ -259,6 +265,20 @@ class HTMLTranslator(nodes.NodeVisitor): text = text.replace(u'\u00a0', " ") return text + def cloak_mailto(self, uri): + """Try to hide a mailto: URL from harvesters.""" + addr = uri.split(':', 1)[1] + if '?' in addr: + addr, query = addr.split('?', 1) + query = '?' + query + else: + query = '' + escaped = ['%%%02X' % ord(c) for c in addr] + return 'mailto:%s%s' % (''.join(escaped), query) + + def cloak_email(self, addr): + return addr.replace('@', ' at ').replace('.', ' dot ') + def attval(self, text, whitespace=re.compile('[\n\r\t\v\f]')): """Cleanse, HTML encode, and return attribute value text.""" @@ -315,7 +335,10 @@ class HTMLTranslator(nodes.NodeVisitor): node[-1]['classes'].append('last') def visit_Text(self, node): - self.body.append(self.encode(node.astext())) + text = node.astext() + if self.in_mailto and self.settings.cloak_email_addresses: + text = self.cloak_email(text) + self.body.append(self.encode(text)) def depart_Text(self, node): pass @@ -1086,6 +1109,10 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('</div>\n') if node.has_key('refuri'): href = node['refuri'] + if ( self.settings.cloak_email_addresses + and href.startswith('mailto:')): + href = self.cloak_mailto(href) + self.in_mailto = 1 else: assert node.has_key('refid'), \ 'References must have "refuri" or "refid" attribute.' @@ -1096,6 +1123,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_reference(self, node): self.body.append('</a>') self.body.append(self.context.pop()) + self.in_mailto = 0 def visit_revision(self, node): self.visit_docinfo_item(node, 'revision', meta=None) diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index 6e990e61a..00d7d1d2b 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -38,7 +38,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! </tr> <tr class="field"><th class="field-name">Author:</th><td class="field-body">John Doe <john at example.org></td> </tr> -<tr class="field"><th class="field-name">Discussions-To:</th><td class="field-body"><<a class="reference" href="mailto:devnull@example.org?subject=PEP%20100">devnull at example.org</a>></td> +<tr class="field"><th class="field-name">Discussions-To:</th><td class="field-body"><<a class="reference" href="mailto:%64%65%76%6E%75%6C%6C%40%65%78%61%6D%70%6C%65%2E%6F%72%67?subject=PEP%20100">devnull at example.org</a>></td> </tr> <tr class="field"><th class="field-name">Status:</th><td class="field-body">Draft</td> </tr> @@ -56,18 +56,35 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! <div class="contents topic" id="contents"> <p class="topic-title first"><a name="contents">Contents</a></p> <ul class="simple"> -<li><a class="reference" href="#abstract" id="id2" name="id2">Abstract</a></li> -<li><a class="reference" href="#copyright" id="id3" name="id3">Copyright</a></li> +<li><a class="reference" href="#abstract" id="id5" name="id5">Abstract</a></li> +<li><a class="reference" href="#copyright" id="id6" name="id6">Copyright</a></li> +<li><a class="reference" href="#references-and-footnotes" id="id7" name="id7">References and Footnotes</a></li> </ul> </div> <div class="section" id="abstract"> -<h1><a class="toc-backref" href="#id2" name="abstract">Abstract</a></h1> -<p>Just a test.</p> +<h1><a class="toc-backref" href="#id5" name="abstract">Abstract</a></h1> +<p>This is just a test <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a>. See the <a class="reference" href="http://www.python.org/peps/">PEP repository</a> <a class="footnote-reference" href="#id3" id="id4" name="id4">[2]</a> for the real +thing.</p> </div> <div class="section" id="copyright"> -<h1><a class="toc-backref" href="#id3" name="copyright">Copyright</a></h1> +<h1><a class="toc-backref" href="#id6" name="copyright">Copyright</a></h1> <p>This document has been placed in the public domain.</p> </div> +<div class="section" id="references-and-footnotes"> +<h1><a class="toc-backref" href="#id7" name="references-and-footnotes">References and Footnotes</a></h1> +<table class="docutils footnote" frame="void" id="id2" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>PEP editors: <a class="reference" href="mailto:%70%65%70%73%40%70%79%74%68%6F%6E%2E%6F%72%67">peps at python dot org</a></td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="id3" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#id4" name="id3">[2]</a></td><td><a class="reference" href="http://www.python.org/peps/">http://www.python.org/peps/</a></td></tr> +</tbody> +</table> +</div> </div> </body> diff --git a/test/functional/input/pep_html.txt b/test/functional/input/pep_html.txt index 5cca3726e..483077131 100644 --- a/test/functional/input/pep_html.txt +++ b/test/functional/input/pep_html.txt @@ -14,10 +14,19 @@ Post-History: 13-Jun-2001 Abstract ======== -Just a test. +This is just a test [#]_. See the `PEP repository`_ for the real +thing. + +.. _PEP repository: http://www.python.org/peps/ Copyright ========= This document has been placed in the public domain. + + +References and Footnotes +======================== + +.. [#] PEP editors: peps@python.org diff --git a/test/functional/tests/pep_html.py b/test/functional/tests/pep_html.py index 47e8b52d3..efb067ac4 100644 --- a/test/functional/tests/pep_html.py +++ b/test/functional/tests/pep_html.py @@ -14,3 +14,4 @@ settings_overrides['template'] = "../tools/pep-html-template" settings_overrides['python_home'] = "http://www.python.org" settings_overrides['pep_home'] = "http://www.python.org/peps" settings_overrides['no_random'] = 1 +settings_overrides['cloak_email_addresses'] = 1 -- cgit v1.2.1 From 5cc9857610e2efed8396e58ded7509fc3288edf0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 23 Apr 2005 19:23:00 +0000 Subject: added link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3245 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 79d124a21..4e24efe4e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -76,7 +76,8 @@ for inclusion in the Python standard library. of the resulting documents is more easily customizable. (Similar to what you wrote about a new HTML Writer.) -* Suitability for Python module documentation. +* Suitability for `Python module documentation + <http://docutils.sf.net/sandbox/README.html#documenting-python>`_. General -- cgit v1.2.1 From 3936ba5b90dc0277460d89d0e336405bae3dcb07 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 23 Apr 2005 19:23:21 +0000 Subject: added to project; a do-nothing Writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3246 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/null.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docutils/writers/null.py diff --git a/docutils/writers/null.py b/docutils/writers/null.py new file mode 100644 index 000000000..cf3566480 --- /dev/null +++ b/docutils/writers/null.py @@ -0,0 +1,23 @@ +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +A do-nothing Writer. +""" + +from docutils import writers + + +class Writer(writers.Writer): + + supported = ('null',) + """Formats this writer supports.""" + + config_section = 'null writer' + config_section_dependencies = ('writers',) + + def translate(self): + pass -- cgit v1.2.1 From 82cc76e7a4930cfaea13703311d87e6d2e40bbba Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 23 Apr 2005 19:23:57 +0000 Subject: added examples.internals function for exploring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3247 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 ++++++ docutils/examples.py | 29 +++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 7218ac5bc..39f90a568 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -26,6 +26,10 @@ Changes Since 0.3.7 - Enabled ``--dump-*`` options when ``--traceback`` specified, allowing for easier debugging. +* docutils/examples.py: + + - Added ``internals`` function for exploration. + * docutils/io.py: - Fixed ``Input.decode`` method to apply heuristics only if no @@ -147,6 +151,8 @@ Changes Since 0.3.7 - Made sure that latex doesn't fill in today's date if no date field was given. +* docutils/writers/null.py: Added to project; a do-nothing Writer. + * docs/ref/docutils.dtd: - Added ``stub`` attribute to ``colspec`` element via the diff --git a/docutils/examples.py b/docutils/examples.py index 6936acd25..3b099b482 100644 --- a/docutils/examples.py +++ b/docutils/examples.py @@ -7,12 +7,13 @@ """ This module contains practical examples of Docutils client code. -Importing this module is not recommended; its contents are subject to change -in future Docutils releases. Instead, it is recommended that you copy and -paste the parts you need into your own code, modifying as necessary. +Importing this module from client code is not recommended; its contents are +subject to change in future Docutils releases. Instead, it is recommended +that you copy and paste the parts you need into your own code, modifying as +necessary. """ -from docutils import core +from docutils import core, io def html_parts(input_string, source_path=None, destination_path=None, @@ -72,3 +73,23 @@ def html_fragment(input_string, source_path=None, destination_path=None, if output_encoding != 'unicode': fragment = fragment.encode(output_encoding) return fragment + +def internals(input_string, source_path=None, destination_path=None, + input_encoding='unicode'): + """ + Return the document tree and publisher, for exploring Docutils internals. + + Parameters: see `html_parts()`. + """ + overrides = {'input_encoding': input_encoding} + output, pub = core.publish_programmatically( + source_class=io.StringInput, source=input_string, + source_path=source_path, + destination_class=io.NullOutput, destination=None, + destination_path=destination_path, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + writer=None, writer_name='null', + settings=None, settings_spec=None, settings_overrides=overrides, + config_section=None, enable_exit_status=None) + return pub.writer.document, pub -- cgit v1.2.1 From 873ff59a77fea8390df56adc5aec025a3d766584 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 24 Apr 2005 03:01:33 +0000 Subject: updated footer descriptions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3248 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index b5458017b..2ae37b9f5 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -1233,9 +1233,7 @@ context. The ``decoration`` element is a container for header_ and footer_ elements and potential future extensions. These elements are used for -page navigation, notes, time/datestamp, etc. Currently only the -footer_ element is implemented, populated with processing information -(datestamp, a link to Docutils_, etc.). +notes, time/datestamp, processing information, etc. Details @@ -2242,8 +2240,9 @@ See the examples for the field_list_ and docinfo_ elements. The ``footer`` element is a container element whose contents are meant to appear at the bottom of a web page, or repeated at the bottom of -every printed page. Currently the ``footer`` element may contain -processing information (datestamp, a link to Docutils_, etc.). +every printed page. The ``footer`` element may contain processing +information (datestamp, a link to Docutils_, etc.) as well as custom +content. Details -- cgit v1.2.1 From edc53d064c0242cf29ca1c683f52794132a48ded Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 24 Apr 2005 03:02:10 +0000 Subject: fixed typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3249 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index e3764adfb..9c09792ae 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -807,7 +807,7 @@ def _format_str(*args): r = r[1:] # quote_char = "'" or '"' quote_char = r[0] - assert quote_char in ("'", "'") + assert quote_char in ("'", '"') assert r[0] == r[-1] r = r[1:-1] r = (stripped + 3 * quote_char + '\\\n' + -- cgit v1.2.1 From 09c84f6a848fd546d06e4b8f80094c02c06a0122 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 24 Apr 2005 15:30:03 +0000 Subject: corrected option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3250 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index ebff78289..e3e052aaf 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -538,7 +538,7 @@ _`cloak_email_addresses` href="mailto:%61%62%63%40%65%78%61%6D%70%6C%65%2E%6F%72%67"> abc at example dot org</a> - Default: don't cloak (None). Option: ``--cloak-email``. + Default: don't cloak (None). Option: ``--cloak-email-addresses``. _`compact_lists` Remove extra vertical whitespace between items of bullet lists and -- cgit v1.2.1 From 03da26f3c9d0d99ea4afd99cf5330fe307ce3bb3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 24 Apr 2005 23:21:48 +0000 Subject: Added ``html_body``, ``html_title``, & ``html_subtitle`` to HTML writer parts dictionary exposed by ``docutils.core.publish_parts``; updated tests. Added "``publish_parts`` Details" section to docs/api/publish.txt. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3251 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 ++ docs/api/publisher.txt | 83 +++++++++++++++++++++-- docutils/writers/html4css1.py | 11 ++- test/DocutilsTestSupport.py | 1 + test/test_writers/test_html4css1.py | 129 +++++++++++++++++++++++++++++------- 5 files changed, 201 insertions(+), 29 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 39f90a568..9fa7e30d6 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -140,6 +140,8 @@ Changes Since 0.3.7 - Added support for table stub columns. - Added support for ``align`` attribute on ``figure`` elements. - Added the ``cloak_email_addresses`` setting & support. + - Added ``html_body``, ``html_title``, & ``html_subtitle`` to parts + dictionary exposed by ``docutils.core.publish_parts``. * docutils/writers/latex2e.py: @@ -153,6 +155,10 @@ Changes Since 0.3.7 * docutils/writers/null.py: Added to project; a do-nothing Writer. +* docs/api/publisher.txt: + + - Added "``publish_parts`` Details" section. + * docs/ref/docutils.dtd: - Added ``stub`` attribute to ``colspec`` element via the diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index b018bbe90..5d793f003 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -35,9 +35,9 @@ handles everything else. There are five convenience functions in the dictionary of document parts. Dictionary keys are the names of parts, and values are Unicode strings; encoding is up to the client. Useful when only portions of the processed document are desired. - Currently only implemented for the HTML Writer. + See `publish_parts Details`_ below. - There are examples in the `docutils/examples.py`_ module. + There are usage examples in the `docutils/examples.py`_ module. * ``publish_programmatically``: for custom programmatic use. This function implements common code and is used by ``publish_file``, @@ -74,7 +74,82 @@ Encodings The default output encoding of Docutils is UTF-8. If you have any non-ASCII in your input text, you may have to do a bit more setup. Docutils may introduce some non-ASCII text if you use -symbol-footnotes_. +`auto-symbol footnotes`_ or the `"contents" directive`_. -.. _symbol-footnotes: +.. _auto-symbol footnotes: ../ref/rst/restructuredtext.html#auto-symbol-footnotes +.. _"contents" directive: + ../ref/rst/directives.html#table-of-contents + + +``publish_parts`` Details +========================= + +The ``docutils.core.publish_parts`` convenience function returns a +dictionary of document parts. Dictionary keys are the names of parts, +and values are Unicode strings. + +Each Writer component may publish a different set of document parts, +described below. Currently only the HTML Writer implements more than +the "whole" part. + + +Parts Provided By All Writers +----------------------------- + +whole + ``parts['whole']`` contains the entire formatted document. + + +Parts Provided By the HTML Writer +--------------------------------- + +body + ``parts['body']`` is equivalent to ``parts['fragment']``. + +docinfo + ``parts['docinfo']`` contains the document bibliographic data. + +footer + ``parts['footer']`` contains the document footer content, meant to + appear at the bottom of a web page, or repeated at the bottom of + every printed page. + +fragment + ``parts['fragment']`` contains the document body (*not* the HTML + ``<body>``). In other words, it contains the entire document, + less the document title, subtitle, docinfo, header, and footer. + +header + ``parts['header']`` contains the document header content, meant to + appear at the top of a web page, or repeated at the top of every + printed page. + +html_body + ``parts['html_body']`` contains the HTML ``<body>`` content, less + the ``<body>`` and ``</body>`` tags themselves. + +html_subtitle + ``parts['html_subtitle']`` contains the document subtitle, + including the enclosing ``<h2 class="subtitle">`` & ``</h2>`` + tags. + +html_title + ``parts['html_title']`` contains the document title, including the + enclosing ``<h1 class="title">`` & ``</h1>`` tags. + +meta + ``parts['meta']`` contains all ``<meta ... />`` tags. + +stylesheet + ``parts['stylesheet']`` contains the document stylesheet link. + +subtitle + ``parts['subtitle']`` contains the document subtitle text and any + inline markup. It does not include the enclosing ``<h2>`` & + ``</h2>`` tags. + +title + ``parts['title']`` contains the document title text and any inline + markup. It does not include the enclosing ``<h1>`` & ``</h1>`` + tags. diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cdb3f7f88..691ebb4ec 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -130,7 +130,8 @@ class Writer(writers.Writer): def assemble_parts(self): writers.Writer.assemble_parts(self) for part in ('title', 'subtitle', 'docinfo', 'body', 'header', - 'footer', 'meta', 'stylesheet', 'fragment'): + 'footer', 'meta', 'stylesheet', 'fragment', + 'html_title', 'html_subtitle', 'html_body'): self.parts[part] = ''.join(getattr(self.visitor, part)) @@ -244,6 +245,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.subtitle = [] self.header = [] self.footer = [] + self.html_title = [] + self.html_subtitle = [] + self.html_body = [] self.in_document_title = 0 self.in_mailto = 0 @@ -623,6 +627,9 @@ class HTMLTranslator(nodes.NodeVisitor): self.fragment.extend(self.body) self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) self.body_suffix.insert(0, '</div>\n') + self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + + self.docinfo + self.body + + self.body_suffix[:-1]) def visit_emphasis(self, node): self.body.append('<em>') @@ -1202,6 +1209,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.subtitle = self.body[self.in_document_title:-1] self.in_document_title = 0 self.body_pre_docinfo.extend(self.body) + self.html_subtitle.extend(self.body) del self.body[:] def visit_superscript(self, node): @@ -1366,6 +1374,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.title = self.body[self.in_document_title:-1] self.in_document_title = 0 self.body_pre_docinfo.extend(self.body) + self.html_title.extend(self.body) del self.body[:] def visit_title_reference(self, node): diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 9c09792ae..40ac89c4f 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -742,6 +742,7 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): """Minimize & standardize the output.""" # remove redundant bits: del parts['whole'] + assert parts['body'] == parts['fragment'] del parts['body'] # remove standard bits: parts['meta'] = parts['meta'].replace(self.standard_meta_value, '') diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 142465994..d93997a2d 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -29,30 +29,39 @@ totest['Title promotion'] = ({}, [ Simple String """, """\ -{'fragment': '''<p>Simple String</p>\\n'''} -""" -], +{'fragment': '''<p>Simple String</p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String</p> +</div>\\n'''} +"""], ["""\ Simple String with *markup* """, """\ -{'fragment': '''<p>Simple String with <em>markup</em></p>\\n'''} -""" -], +{'fragment': '''<p>Simple String with <em>markup</em></p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String with <em>markup</em></p> +</div>\\n'''} +"""], ["""\ Simple String with an even simpler ``inline literal`` """, """\ -{'fragment': '''<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p>\\n'''} -""" -], +{'fragment': '''<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p> +</div>\\n'''} +"""], ["""\ A simple `anonymous reference`__ __ http://www.test.com/test_url """, """\ -{'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p>\\n'''} +{'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p>\\n''', + 'html_body': '''<div class="document"> +<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p> +</div>\\n'''} """], ["""\ One paragraph. @@ -61,7 +70,11 @@ Two paragraphs. """, """\ {'fragment': '''<p>One paragraph.</p> -<p>Two paragraphs.</p>\\n'''} +<p>Two paragraphs.</p>\\n''', + 'html_body': '''<div class="document"> +<p>One paragraph.</p> +<p>Two paragraphs.</p> +</div>\\n'''} """], ["""\ A simple `named reference`_ with stuff in between the @@ -71,7 +84,11 @@ reference and the target. """, """\ {'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">named reference</a> with stuff in between the -reference and the target.</p>\\n'''} +reference and the target.</p>\\n''', + 'html_body': '''<div class="document"> +<p>A simple <a class="reference" href="http://www.test.com/test_url">named reference</a> with stuff in between the +reference and the target.</p> +</div>\\n'''} """], ["""\ +++++ @@ -103,6 +120,21 @@ And even more stuff <p>And even more stuff</p> </div> </div>\\n''', + 'html_body': '''<div class="document" id="title"> +<h1 class="title">Title</h1> +<h2 class="subtitle" id="subtitle">Subtitle</h2> +<p>Some stuff</p> +<div class="section" id="section"> +<h1><a name="section">Section</a></h1> +<p>Some more stuff</p> +<div class="section" id="another-section"> +<h2><a name="another-section">Another Section</a></h2> +<p>And even more stuff</p> +</div> +</div> +</div>\\n''', + 'html_subtitle': '''<h2 class="subtitle" id="subtitle">Subtitle</h2>\\n''', + 'html_title': '''<h1 class="title">Title</h1>\\n''', 'subtitle': '''Subtitle''', 'title': '''Title'''} """], @@ -125,6 +157,19 @@ Some stuff </tbody> </table>\\n''', 'fragment': '''<p>Some stuff</p>\\n''', + 'html_body': '''<div class="document" id="title"> +<h1 class="title">Title</h1> +<table class="docinfo" frame="void" rules="none"> +<col class="docinfo-name" /> +<col class="docinfo-content" /> +<tbody valign="top"> +<tr><th class="docinfo-name">Author:</th> +<td>me</td></tr> +</tbody> +</table> +<p>Some stuff</p> +</div>\\n''', + 'html_title': '''<h1 class="title">Title</h1>\\n''', 'meta': '''<meta name="author" content="me" />\\n''', 'title': '''Title'''} """] @@ -135,30 +180,39 @@ totest['No title promotion'] = ({'doctitle_xform' : 0}, [ Simple String """, """\ -{'fragment': '''<p>Simple String</p>\\n'''} -""" -], +{'fragment': '''<p>Simple String</p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String</p> +</div>\\n'''} +"""], ["""\ Simple String with *markup* """, """\ -{'fragment': '''<p>Simple String with <em>markup</em></p>\\n'''} -""" -], +{'fragment': '''<p>Simple String with <em>markup</em></p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String with <em>markup</em></p> +</div>\\n'''} +"""], ["""\ Simple String with an even simpler ``inline literal`` """, """\ -{'fragment': '''<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p>\\n'''} -""" -], +{'fragment': '''<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p>\\n''', + 'html_body': '''<div class="document"> +<p>Simple String with an even simpler <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literal</span></tt></p> +</div>\\n'''} +"""], ["""\ A simple `anonymous reference`__ __ http://www.test.com/test_url """, """\ -{'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p>\\n'''} +{'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p>\\n''', + 'html_body': '''<div class="document"> +<p>A simple <a class="reference" href="http://www.test.com/test_url">anonymous reference</a></p> +</div>\\n'''} """], ["""\ A simple `named reference`_ with stuff in between the @@ -168,7 +222,11 @@ reference and the target. """, """\ {'fragment': '''<p>A simple <a class="reference" href="http://www.test.com/test_url">named reference</a> with stuff in between the -reference and the target.</p>\\n'''} +reference and the target.</p>\\n''', + 'html_body': '''<div class="document"> +<p>A simple <a class="reference" href="http://www.test.com/test_url">named reference</a> with stuff in between the +reference and the target.</p> +</div>\\n'''} """], ["""\ +++++ @@ -205,6 +263,23 @@ And even more stuff </div> </div> </div> +</div>\\n''', + 'html_body': '''<div class="document"> +<div class="section" id="title"> +<h1><a name="title">Title</a></h1> +<div class="section" id="not-a-subtitle"> +<h2><a name="not-a-subtitle">Not A Subtitle</a></h2> +<p>Some stuff</p> +<div class="section" id="section"> +<h3><a name="section">Section</a></h3> +<p>Some more stuff</p> +<div class="section" id="another-section"> +<h4><a name="another-section">Another Section</a></h4> +<p>And even more stuff</p> +</div> +</div> +</div> +</div> </div>\\n'''} """], ["""\ @@ -215,7 +290,13 @@ And even more stuff {'fragment': '''<ul class="simple"> <li>bullet</li> <li>list</li> -</ul>\\n'''} +</ul>\\n''', + 'html_body': '''<div class="document"> +<ul class="simple"> +<li>bullet</li> +<li>list</li> +</ul> +</div>\\n'''} """], ]) -- cgit v1.2.1 From 81cb7c2f9cdf5038595399f3afecae526f72f4d0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 25 Apr 2005 01:12:00 +0000 Subject: added bug: HTML fragment identifiers & duplicate target names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3252 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index 2f036d24b..4e97af5a1 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -222,6 +222,39 @@ Also see the `SourceForge Bug Tracker`_. <paragraph> four +* IDs are based on names. Explicit hyperlink targets have priority + over implicit targets. But if an explicit target comes after an + implicit target with the same name, the ID of the first (implicit) + target remains based on the implicit name. Since HTML fragment + identifiers based on the IDs, the first target keeps the name. For + example:: + + .. contents:: + + Section + ======= + + .. _contents: + + Subsection + ---------- + + text with a reference to contents_ and section_ + + .. _section: + + This paragraph is explicitly targeted with the name "section". + + When processed to HTML, the 2 internal hyperlinks (to "contents" & + "section") will work fine, but hyperlinks from outside the document + using ``href="...#contents"`` and ``href="...#section"`` won't work. + Such external links will connect to the implicit targets (table of + contents and "Section" title) instead of the explicit targets + ("Subsection" title and last paragraph). + + Hyperlink targets with duplicate names should be assigned new IDs + unrelated to the target names (i.e., "id"-prefix serial IDs). + .. Local Variables: -- cgit v1.2.1 From 3da860aec26788ffd148bdbbedeee98b53a1436a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 25 Apr 2005 15:08:01 +0000 Subject: str(Exception) doesn't work for anything but ASCII Exception texts, so '%s' % exception_instance is unsafe unless exception_instance.args contains only byte strings. The change in alltests.py is a first attempt to catch such cases where a str(Exception) is done with an Exception text which is not necessarily ASCII-only (i.e. with a unicode string in Exception.args), but since most input data (in the totest dicts) is passed in as byte strings, it doesn't catch much. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3253 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 10 ++++++---- docutils/utils.py | 2 +- test/alltests.py | 11 +++++++++++ test/test_parsers/test_rst/test_directives/test_images.py | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index f779df8b2..1ee9dc6f2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1565,7 +1565,8 @@ class Body(RSTState): table = self.build_table(tabledata, tableline) nodelist = [table] + messages except tableparser.TableMarkupError, detail: - nodelist = self.malformed_table(block, str(detail)) + messages + nodelist = self.malformed_table( + block, ' '.join(detail.args)) + messages else: nodelist = messages return nodelist, blank_finish @@ -1982,7 +1983,8 @@ class Body(RSTState): directive_fn, option_presets)) except MarkupError, detail: error = self.reporter.error( - 'Error in "%s" directive:\n%s.' % (type_name, detail), + 'Error in "%s" directive:\n%s.' % (type_name, + ' '.join(detail.args)), nodes.literal_block(block_text, block_text), line=lineno) return [error], blank_finish result = directive_fn(type_name, arguments, options, content, lineno, @@ -2093,9 +2095,9 @@ class Body(RSTState): except KeyError, detail: return 0, ('unknown option: "%s"' % detail.args[0]) except (ValueError, TypeError), detail: - return 0, ('invalid option value: %s' % detail) + return 0, ('invalid option value: %s' % ' '.join(detail.args)) except utils.ExtensionOptionError, detail: - return 0, ('invalid option data: %s' % detail) + return 0, ('invalid option data: %s' % ' '.join(detail.args)) if blank_finish: return 1, options else: diff --git a/docutils/utils.py b/docutils/utils.py index aeb882485..a28b5326d 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -306,7 +306,7 @@ def assemble_option_dict(option_list, options_spec): options[name] = convertor(value) except (ValueError, TypeError), detail: raise detail.__class__('(option: "%s"; value: %r)\n%s' - % (name, value, detail)) + % (name, value, ' '.join(detail.args))) return options diff --git a/test/alltests.py b/test/alltests.py index ee73f0376..4092d38a6 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -21,9 +21,20 @@ start = time.time() import sys import os +from types import UnicodeType import docutils +def new_exception_str(self): + for i in self.args: + if isinstance(i, UnicodeType): + raise RuntimeError('Error (unicode): %r' % (self.args,)) + return old_exception_str(self) + +old_exception_str = Exception.__str__ +Exception.__str__ = new_exception_str + + class Tee: """Write to a file and a stream (default: stdout) simultaneously.""" diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index 6d016a82d..b35cab355 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -342,6 +342,21 @@ totest['images'] = [ .. |img| image:: picture.png :align: left """], +[u"""\ +.. image:: picture.png + :align: \xe4 +""", +u"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "image" directive: + invalid option value: (option: "align"; value: u\'\\xe4\') + "\xe4" unknown; choose from "top", "middle", "bottom", "left", "center", or "right". + <literal_block xml:space="preserve"> + .. image:: picture.png + :align: \xe4 +"""], ] -- cgit v1.2.1 From 93102bb86e422b933a96346a97e8adeed8d7e83f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 25 Apr 2005 19:24:28 +0000 Subject: expanded ``node[x]`` entry with link to thread git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3254 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4e24efe4e..cba560dca 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -445,10 +445,11 @@ General .. _discussion: http://thread.gmane.org/gmane.text.docutils.user/1319 -* The docutils.nodes.Element APIs could use some simplification. For - example, ``node[x]`` is ambiguous (different results if x is a - string or an integer). Replace with ``node[int]`` and - ``node.attributes[string]``? +* Simplify the docutils.nodes.Element implementation? ``node[x]`` is + convenient but can be considered ambiguous (different results if + ``x`` is a string or an integer). Replace with ``node[int]`` and + ``node.attributes[string]``? See + <http://thread.gmane.org/gmane.text.docutils.devel/2844>. * Add file-specific settings support to config files, like:: -- cgit v1.2.1 From c4914648bbb9a351bbac1962525bbfccf88b3d71 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 25 Apr 2005 20:00:12 +0000 Subject: removed angle brackets because otherwise the validator complains about unknown tags when embedding the stylesheet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3255 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index f9bd7dbdf..ec9f9cd5b 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -10,7 +10,7 @@ Default cascading style sheet for the HTML output of Docutils. /* "! important" is used here to override other ``margin-top`` and ``margin-bottom`` styles that are later in the stylesheet or - more specific. See <http://www.w3.org/TR/CSS1#the-cascade>. */ + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ .first { margin-top: 0 ! important } -- cgit v1.2.1 From 0f8bc9eb02c14f9668be6ab14295ee018fbd1ca9 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 25 Apr 2005 20:24:49 +0000 Subject: made field-lists left-aligned by removing the left padding from field names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3256 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index ec9f9cd5b..2cfc4c892 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -238,10 +238,11 @@ table.docinfo td, table.docinfo th { padding-right: 0.5em ; vertical-align: top } -th.docinfo-name, th.field-name { +table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; - white-space: nowrap } + white-space: nowrap ; + padding-left: 0 } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { -- cgit v1.2.1 From df86c29341bb830c87ee468323c1e3afa9d32a03 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 26 Apr 2005 03:57:00 +0000 Subject: Added ``html_prolog`` & ``html_head`` to HTML writer parts dictionary exposed by ``docutils.core.publish_parts``; updated tests & docs. At the request of Marcelo Huerta. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3257 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++-- docs/api/publisher.txt | 9 ++++++++ docutils/writers/html4css1.py | 25 +++++++++++++--------- test/DocutilsTestSupport.py | 13 ++++++++++-- test/test_writers/test_html4css1.py | 42 +++++++++++++++++++++++++------------ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 9fa7e30d6..66a611350 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -140,8 +140,9 @@ Changes Since 0.3.7 - Added support for table stub columns. - Added support for ``align`` attribute on ``figure`` elements. - Added the ``cloak_email_addresses`` setting & support. - - Added ``html_body``, ``html_title``, & ``html_subtitle`` to parts - dictionary exposed by ``docutils.core.publish_parts``. + - Added ``html_prolog``, ``html_head``, ``html_body``, + ``html_title``, & ``html_subtitle`` to parts dictionary exposed by + ``docutils.core.publish_parts``. * docutils/writers/latex2e.py: diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index 5d793f003..55883f1ae 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -129,6 +129,15 @@ html_body ``parts['html_body']`` contains the HTML ``<body>`` content, less the ``<body>`` and ``</body>`` tags themselves. +html_head + ``parts['html_head']`` contains the HTML ``<head>`` content, less + the stylesheet link and the ``<head>`` and ``</head>`` tags + themselves. + +html_prolog + ``parts['html_prolog]`` contains the XML declaration and the + doctype declaration. + html_subtitle ``parts['html_subtitle']`` contains the document subtitle, including the enclosing ``<h2 class="subtitle">`` & ``</h2>`` diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 691ebb4ec..76499dea6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -131,7 +131,8 @@ class Writer(writers.Writer): writers.Writer.assemble_parts(self) for part in ('title', 'subtitle', 'docinfo', 'body', 'header', 'footer', 'meta', 'stylesheet', 'fragment', - 'html_title', 'html_subtitle', 'html_body'): + 'html_prolog', 'html_head', 'html_title', 'html_subtitle', + 'html_body'): self.parts[part] = ''.join(getattr(self.visitor, part)) @@ -183,8 +184,8 @@ class HTMLTranslator(nodes.NodeVisitor): ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' ' "http://www.w3.org/TR/xhtml1/DTD/' 'xhtml1-transitional.dtd">\n') - html_head = ('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="%s" ' - 'lang="%s">\n<head>\n') + head_prefix_template = ('<html xmlns="http://www.w3.org/1999/xhtml"' + ' xml:lang="%s" lang="%s">\n<head>\n') content_type = ('<meta http-equiv="Content-Type" content="text/html; ' 'charset=%s" />\n') generator = ('<meta name="generator" content="Docutils %s: ' @@ -201,14 +202,16 @@ class HTMLTranslator(nodes.NodeVisitor): self.language = languages.get_language(lcode) self.meta = [self.content_type % settings.output_encoding, self.generator % docutils.__version__] - self.head_prefix = [ - self.doctype, - self.html_head % (lcode, lcode)] - self.head_prefix.extend(self.meta) + self.head_prefix = [] + self.html_prolog = [] if settings.xml_declaration: - self.head_prefix.insert(0, self.xml_declaration + self.head_prefix.append(self.xml_declaration % settings.output_encoding) - self.head = [] + self.html_prolog.append(self.xml_declaration) # not interpolated + self.head_prefix.extend([self.doctype, + self.head_prefix_template % (lcode, lcode)]) + self.html_prolog.append(self.doctype) + self.head = self.meta[:] if settings.embed_stylesheet: stylesheet = utils.get_stylesheet_reference(settings, os.path.join(os.getcwd(), 'dummy')) @@ -245,6 +248,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.subtitle = [] self.header = [] self.footer = [] + self.html_head = [] self.html_title = [] self.html_subtitle = [] self.html_body = [] @@ -621,12 +625,13 @@ class HTMLTranslator(nodes.NodeVisitor): # empty or untitled document? if not len(node) or not isinstance(node[0], nodes.title): # for XHTML conformance, modulo IE6 appeasement: - self.head.insert(0, '<title>\n') + self.head.append('\n') def depart_document(self, node): self.fragment.extend(self.body) self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) self.body_suffix.insert(0, '
    \n') + self.html_head.extend(self.head) self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + self.docinfo + self.body + self.body_suffix[:-1]) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 40ac89c4f..87a200598 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -731,12 +731,17 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): expected = self.expected % {'version': docutils.__version__} self.compare_output(self.input, output, expected) - standard_meta_value = """\ + standard_meta_value_template = """\ -""" % docutils.__version__ +""" + standard_meta_value = standard_meta_value_template % docutils.__version__ standard_stylesheet_value = ('\n') + standard_html_prolog = """\ + + +""" def format_output(self, parts): """Minimize & standardize the output.""" @@ -748,6 +753,10 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): parts['meta'] = parts['meta'].replace(self.standard_meta_value, '') if parts['stylesheet'] == self.standard_stylesheet_value: del parts['stylesheet'] + parts['html_head'] = parts['html_head'].replace( + self.standard_meta_value, '...') + parts['html_prolog'] = parts['html_prolog'].replace( + self.standard_html_prolog, '') # remove empty values: for key in parts.keys(): if not parts[key]: diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index d93997a2d..70d3be772 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -32,7 +32,8 @@ Simple String {'fragment': '''

    Simple String

    \\n''', 'html_body': '''

    Simple String

    -
    \\n'''} +
    \\n''', + 'html_head': '''...\\n'''} """], ["""\ Simple String with *markup* @@ -41,7 +42,8 @@ Simple String with *markup* {'fragment': '''

    Simple String with markup

    \\n''', 'html_body': '''

    Simple String with markup

    -
    \\n'''} +
    \\n''', + 'html_head': '''...\\n'''} """], ["""\ Simple String with an even simpler ``inline literal`` @@ -50,7 +52,8 @@ Simple String with an even simpler ``inline literal`` {'fragment': '''

    Simple String with an even simpler inline literal

    \\n''', 'html_body': '''

    Simple String with an even simpler inline literal

    -
    \\n'''} +
    \\n''', + 'html_head': '''...\\n'''} """], ["""\ A simple `anonymous reference`__ @@ -61,7 +64,8 @@ __ http://www.test.com/test_url {'fragment': '''

    A simple anonymous reference

    \\n''', 'html_body': '''\\n'''} +
    \\n''', + 'html_head': '''...\\n'''} """], ["""\ One paragraph. @@ -74,7 +78,8 @@ Two paragraphs. 'html_body': '''

    One paragraph.

    Two paragraphs.

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ A simple `named reference`_ with stuff in between the @@ -88,7 +93,8 @@ reference and the target.

    \\n''', 'html_body': '''

    A simple named reference with stuff in between the reference and the target.

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ +++++ @@ -133,6 +139,7 @@ And even more stuff \\n''', + 'html_head': '''...Title\\n''', 'html_subtitle': '''

    Subtitle

    \\n''', 'html_title': '''

    Title

    \\n''', 'subtitle': '''Subtitle''', @@ -169,6 +176,8 @@ Some stuff

    Some stuff

    \\n''', + 'html_head': '''...Title +\\n''', 'html_title': '''

    Title

    \\n''', 'meta': '''\\n''', 'title': '''Title'''} @@ -183,7 +192,8 @@ Simple String {'fragment': '''

    Simple String

    \\n''', 'html_body': '''

    Simple String

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ Simple String with *markup* @@ -192,7 +202,8 @@ Simple String with *markup* {'fragment': '''

    Simple String with markup

    \\n''', 'html_body': '''

    Simple String with markup

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ Simple String with an even simpler ``inline literal`` @@ -201,7 +212,8 @@ Simple String with an even simpler ``inline literal`` {'fragment': '''

    Simple String with an even simpler inline literal

    \\n''', 'html_body': '''

    Simple String with an even simpler inline literal

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ A simple `anonymous reference`__ @@ -212,7 +224,8 @@ __ http://www.test.com/test_url {'fragment': '''

    A simple anonymous reference

    \\n''', 'html_body': '''\\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ A simple `named reference`_ with stuff in between the @@ -226,7 +239,8 @@ reference and the target.

    \\n''', 'html_body': '''

    A simple named reference with stuff in between the reference and the target.

    -
    \\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ +++++ @@ -280,7 +294,8 @@ And even more stuff -\\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ["""\ * bullet @@ -296,7 +311,8 @@ And even more stuff
  • bullet
  • list
  • -\\n'''} +\\n''', + 'html_head': '''...\\n'''} """], ]) -- cgit v1.2.1 From 8850d672d0c5e6e5890c4a4b412ef0c8eeec9658 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 26 Apr 2005 22:45:28 +0000 Subject: removed unnecessary comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3259 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 - docutils/writers/newlatex2e.py | 673 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 673 insertions(+), 3 deletions(-) create mode 100644 docutils/writers/newlatex2e.py diff --git a/docutils/nodes.py b/docutils/nodes.py index b79c0e688..33c93e42a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -165,9 +165,6 @@ class Node: def traverse(self, condition=None, include_self=1, descend=1, siblings=0, ascend=0): - # condition is the first parameter to allow the same parameter - # list for next_node (for which it's convenient to have - # condition as first parameter). """ Return an iterable containing diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py new file mode 100644 index 000000000..09a723baa --- /dev/null +++ b/docutils/writers/newlatex2e.py @@ -0,0 +1,673 @@ +""" +:Author: Felix Wiemann +:Contact: Felix_Wiemann@ososo.de +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +LaTeX2e document tree Writer. +""" + +# Thanks to Engelbert Gruber and various contributors for the original +# LaTeX writer, some code and many ideas of which have been used for +# this writer. + +__docformat__ = 'reStructuredText' + + +import re +import os.path +from types import ListType +import roman + +import docutils +from docutils import nodes, writers, utils + + +class Writer(writers.Writer): + + supported = ('newlatex', 'newlatex2e') + """Formats this writer supports.""" + + settings_spec = ( + 'LaTeX-Specific Options', + 'The LaTeX "--output-encoding" default is "latin-1:strict". ' + 'Note that this LaTeX writer is still EXPERIMENTAL.', + (('Specify a stylesheet file. The file will be "input" by latex in ' + 'the document header. Overrides --stylesheet-path.', + ['--stylesheet'], + {'default': '', 'metavar': '', + 'overrides': 'stylesheet_path'}), + ('Specify a stylesheet file, relative to the current working ' + 'directory. Overrides --stylesheet.', + ['--stylesheet-path'], + {'metavar': '', 'overrides': 'stylesheet'}), + ),) + + settings_defaults = {'output_encoding': 'latin-1', + 'trim_footnote_reference_space': 1, + # Currently unsupported: + 'docinfo_xform': 0, + # During development: + 'traceback': 1} + + relative_path_settings = ('stylesheet_path',) + + config_section = 'latex2e writer' + config_section_dependencies = ('writers',) + + output = None + """Final translated form of `document`.""" + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = LaTeXTranslator + + def translate(self): + visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + self.head = visitor.header + self.body = visitor.body + + +class Babel: + """Language specifics for LaTeX.""" + # country code by a.schlock. + # partly manually converted from iso and babel stuff, dialects and some + _ISO639_TO_BABEL = { + 'no': 'norsk', # added by hand ( forget about nynorsk?) + 'gd': 'scottish', # added by hand + 'hu': 'magyar', # added by hand + 'pt': 'portuguese',# added by hand + 'sl': 'slovenian', + 'af': 'afrikaans', + 'bg': 'bulgarian', + 'br': 'breton', + 'ca': 'catalan', + 'cs': 'czech', + 'cy': 'welsh', + 'da': 'danish', + 'fr': 'french', + # french, francais, canadien, acadian + 'de': 'ngerman', # rather than german + # ngerman, naustrian, german, germanb, austrian + 'el': 'greek', + 'en': 'english', + # english, USenglish, american, UKenglish, british, canadian + 'eo': 'esperanto', + 'es': 'spanish', + 'et': 'estonian', + 'eu': 'basque', + 'fi': 'finnish', + 'ga': 'irish', + 'gl': 'galician', + 'he': 'hebrew', + 'hr': 'croatian', + 'hu': 'hungarian', + 'is': 'icelandic', + 'it': 'italian', + 'la': 'latin', + 'nl': 'dutch', + 'pl': 'polish', + 'pt': 'portuguese', + 'ro': 'romanian', + 'ru': 'russian', + 'sk': 'slovak', + 'sr': 'serbian', + 'sv': 'swedish', + 'tr': 'turkish', + 'uk': 'ukrainian' + } + + def __init__(self, lang): + self.language = lang + + def get_language(self): + if self._ISO639_TO_BABEL.has_key(self.language): + return self._ISO639_TO_BABEL[self.language] + else: + # Support dialects. + l = self.language.split("_")[0] + if self._ISO639_TO_BABEL.has_key(l): + return self._ISO639_TO_BABEL[l] + return None + + +class LaTeXException(Exception): + """ + Exception base class to for exceptions which influence the + automatic generation of LaTeX code. + """ + + +class SkipAttrParentLaTeX(LaTeXException): + """ + Do not generate \Dattr and \renewcommand{\Dparent}{...} for this + node. + + To be raised from before_... methods. + """ + + +class SkipParentLaTeX(LaTeXException): + """ + Do not generate \renewcommand{\DNparent}{...} for this node. + + To be raised from before_... methods. + """ + + +class LaTeXTranslator(nodes.SparseNodeVisitor): + + # Start with left double quote. + left_quote = 1 + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = document.settings + self.header = [] + self.body = [] + self.context = [] + self.stylesheet_path = utils.get_stylesheet_reference( + self.settings, os.path.join(os.getcwd(), 'dummy')) + if self.stylesheet_path: + self.settings.record_dependencies.add(self.stylesheet_path) + #self.stylesheet = open(stylesheet_path).read() + #else: + #self.stylesheet = '' + self.write_header() + for key, value in self.character_map.items(): + self.character_map[key] = '{%s}' % value + + def write_header(self): + a = self.header.append + a('%% Generated by Docutils %s .\n' + % docutils.__version__) + #a('% User stylesheet:\n') + a(r'\input{%s}' % self.stylesheet_path) + #a('\n% End of user stylesheet.') + a('% Definitions for Docutils Nodes:') + for node_name in nodes.node_class_names: + a(r'\providecommand{\DN%s}[1]{#1}' % node_name.replace('_', '')) + a('') + a('% Auxiliary definitions:') + a(r'\providecommand{\Dsetattr}[2]{}') + a(r'\providecommand{\Dparent}{} % variable') + a(r'\providecommand{\Dattr}[5]{#5}') + a(r'\providecommand{\Dattrlen}{} % variable') + a(r'\providecommand{\Dtitleastext}{x}') + a(r'\providecommand{\Dsinglebackref}{} % variable') + a(r'\providecommand{\Dmultiplebackrefs}{} % variable') + a('\n\n') + + def to_latex_encoding(self,docutils_encoding): + """ + Translate docutils encoding name into latex's. + + Default fallback method is remove "-" and "_" chars from + docutils_encoding. + """ + tr = { "iso-8859-1": "latin1", # west european + "iso-8859-2": "latin2", # east european + "iso-8859-3": "latin3", # esperanto, maltese + "iso-8859-4": "latin4", # north european,scandinavian, baltic + "iso-8859-5": "iso88595", # cyrillic (ISO) + "iso-8859-9": "latin5", # turkish + "iso-8859-15": "latin9", # latin9, update to latin1. + "mac_cyrillic": "maccyr", # cyrillic (on Mac) + "windows-1251": "cp1251", # cyrillic (on Windows) + "koi8-r": "koi8-r", # cyrillic (Russian) + "koi8-u": "koi8-u", # cyrillic (Ukrainian) + "windows-1250": "cp1250", # + "windows-1252": "cp1252", # + "us-ascii": "ascii", # ASCII (US) + # unmatched encodings + #"": "applemac", + #"": "ansinew", # windows 3.1 ansi + #"": "ascii", # ASCII encoding for the range 32--127. + #"": "cp437", # dos latine us + #"": "cp850", # dos latin 1 + #"": "cp852", # dos latin 2 + #"": "decmulti", + #"": "latin10", + #"iso-8859-6": "" # arabic + #"iso-8859-7": "" # greek + #"iso-8859-8": "" # hebrew + #"iso-8859-10": "" # latin6, more complete iso-8859-4 + } + if tr.has_key(docutils_encoding.lower()): + return tr[docutils_encoding.lower()] + return docutils_encoding.translate(string.maketrans("",""),"_-").lower() + + def language_label(self, docutil_label): + return self.language.labels[docutil_label] + + # To do: Use unimap.py from TeXML instead. Have to deal with + # legal cruft before, because it's LPGL. + character_map_string = r""" + \ \textbackslash + { \{ + } \} + $ \$ + & \& + % \% + # \# + [ [ + ] ] + - - + ` ` + ' ' + , , + " " + | \textbar + < \textless + > \textgreater + ^ \textasciicircum + ~ \textasciitilde + _ \Dtextunderscore + """ + + #special_map = {'\n': ' ', '\r': ' ', '\t': ' ', '\v': ' ', '\f': ' '} + + unicode_map = { + u'\u00A0': '~', + u'\u2013': '{--}', + u'\u2014': '{---}', + u'\u2018': '`', + u'\u2019': '\'', + u'\u201A': ',', + u'\u201C': '``', + u'\u201D': "''", + u'\u201E': ',,', + u'\u2020': '{\\dag}', + u'\u2021': '{\\ddag}', + u'\u2026': '{\\dots}', + u'\u2122': '{\\texttrademark}', + u'\u21d4': '{$\\Leftrightarrow$}', + } + + character_map = {} + for pair in character_map_string.strip().split('\n'): + char, replacement = pair.split() + character_map[char] = replacement + character_map.update(unicode_map) + #character_map.update(special_map) + + def encode(self, text, preserve=0): + """ + Encode special characters in ``text`` and return it. + + If preserve is true, preserve as much as possible (used in + attribute value encoding). + """ + get = self.character_map.get + text = ''.join([get(c, c) for c in text]) + if (self.literal_block or self.inline_literal) and not preserve: + # NB: We can have inline literals within literal blocks. + # Shrink '\r\n'. + text = text.replace('\r\n', '\n') + # Convert space. If "{ }~~~~~" is wrapped (at the + # brace-enclosed space "{ }"), the following non-breaking + # spaces ("~~~~") do *not* wind up at the beginning of the + # next line. Also note that, for some not-so-obvious + # reason, no hyphenation is done if the breaking space ("{ + # }") comes *after* the non-breaking spaces. + if self.literal_block: + # Replace newlines with real newlines. + text = text.replace('\n', '\mbox{}\\\\') + firstspace = '~' + else: + firstspace = '{ }' + text = re.sub(r'\s+', lambda m: firstspace + + '~' * (len(m.group()) - 1), text) + # Protect hyphens; if we don't, line breaks will be + # possible at the hyphens and even the \textnhtt macro + # from the hyphenat package won't change that. + text = text.replace('-', r'\mbox{-}') + text = text.replace("'", r'{\Dtextliteralsinglequote}') + return text + else: + if not preserve: + # Replace space with single protected space. + text = re.sub(r'\s+', '{ }', text) + # Replace double quotes with macro calls. + L = [] + for part in text.split('"'): + if L: + # Insert quote. + L.append(self.left_quote and r'\Dtextleftdblquote' or + r'\Dtextrightdblquote') + self.left_quote = not self.left_quote + L.append(part) + return ''.join(L) + else: + return text + + def astext(self): + return '\n'.join(self.header) + (''.join(self.body)) + + def append(self, text, newline='%\n'): + """ + Append text, stripping newlines, producing nice LaTeX code. + """ + lines = [' ' * self.indentation_level + line + newline + for line in text.splitlines(0)] + self.body.append(''.join(lines)) + + def visit_Text(self, node): + self.append(self.encode(node.astext())) + + def depart_Text(self, node): + pass + + def before_title(self, node): + self.append(r'\renewcommand{\Dtitleastext}{%s}' + % self.encode(node.astext())) + self.append(r'\renewcommand{\Dhassubtitle}{%s}' + % ((len(node.parent) > 2 and + isinstance(node.parent[1], nodes.subtitle)) + and 'true' or 'false')) + + literal_block = 0 + + def visit_literal_block(self, node): + self.literal_block = 1 + + def depart_literal_block(self, node): + self.literal_block = 0 + + visit_doctest_block = visit_literal_block + depart_doctest_block = depart_literal_block + + inline_literal = 0 + + def visit_literal(self, node): + self.inline_literal += 1 + + def depart_literal(self, node): + self.inline_literal -= 1 + + def visit_comment(self, node): + self.append('\n'.join(['% ' + line for line + in node.astext().splitlines(0)]), newline='\n') + raise nodes.SkipChildren + + bullet_list_level = 0 + + def visit_bullet_list(self, node): + self.append(r'\Dsetbullet{\labelitem%s}' % + ['i', 'ii', 'iii', 'iv'][min(self.bullet_list_level, 3)]) + self.bullet_list_level += 1 + + def depart_bullet_list(self, node): + self.bullet_list_level -= 1 + + enum_styles = {'arabic': 'arabic', 'loweralpha': 'alph', 'upperalpha': + 'Alph', 'lowerroman': 'roman', 'upperroman': 'Roman'} + + enum_counter = 0 + + def visit_enumerated_list(self, node): + # We create our own enumeration list environment. This allows + # to set the style and starting value and unlimited nesting. + self.enum_counter += 1 + enum_prefix = self.encode(node['prefix']) + enum_suffix = self.encode(node['suffix']) + enum_type = '\\' + self.enum_styles.get(node['enumtype'], r'arabic') + start = node.get('start', 1) - 1 + counter = 'Denumcounter%d' % self.enum_counter + self.append(r'\Dmakeenumeratedlist{%s}{%s}{%s}{%s}{%s}{' + % (enum_prefix, enum_type, enum_suffix, counter, start)) + # for Emacs: } + + def depart_enumerated_list(self, node): + self.append('}') # for Emacs: { + + def visit_raw(self, node): + if 'latex' in node.get('format', '').split(): + self.append(node.astext()) + raise nodes.SkipChildren + + def process_backlinks(self, node, type): + self.append(r'\renewcommand{\Dsinglebackref}{}') + self.append(r'\renewcommand{\Dmultiplebackrefs}{}') + if len(node['backrefs']) > 1: + refs = [] + for i in range(len(node['backrefs'])): + refs.append(r'\Dmulti%sbacklink{%s}{%s}' + % (type, node['backrefs'][i], i + 1)) + self.append(r'\renewcommand{\Dmultiplebackrefs}{(%s){ }}' + % ', '.join(refs)) + elif len(node['backrefs']) == 1: + self.append(r'\renewcommand{\Dsinglebackref}{%s}' + % node['backrefs'][0]) + + def visit_footnote(self, node): + self.process_backlinks(node, 'footnote') + + def visit_citation(self, node): + self.process_backlinks(node, 'citation') + + def visit_table(self, node): + # Everything's handled in tgroup. + pass + + def before_table(self, node): + # A tables contains exactly one tgroup. See before_tgroup. + pass + + def before_tgroup(self, node): + widths = [] + total_width = 0 + for i in range(int(node['cols'])): + assert isinstance(node[i], nodes.colspec) + widths.append(int(node[i]['colwidth']) + 1) + total_width += widths[-1] + del node[:len(widths)] + tablespec = '|' + for w in widths: + tablespec += r'p{%s\linewidth}|' % (0.93 * w / + max(total_width, 60)) + self.append(r'\Dmaketable{%s}{' % tablespec) + self.context.append('}') + raise SkipAttrParentLaTeX + + def depart_tgroup(self, node): + self.append(self.context.pop()) + + def before_row(self, node): + raise SkipAttrParentLaTeX + + def before_thead(self, node): + raise SkipAttrParentLaTeX + + def before_tbody(self, node): + raise SkipAttrParentLaTeX + + def is_simply_entry(self, node): + return (len(node) == 1 and isinstance(node[0], nodes.paragraph) or + len(node) == 0) + + def before_entry(self, node): + is_leftmost = 0 + if node.hasattr('morerows'): + self.document.reporter.severe('Rowspans are not supported.') + # Todo: Add empty cells below rowspanning cell and issue + # warning instead of severe. + if node.hasattr('morecols'): + # The author got a headache trying to implement + # multicolumn support. + if not self.is_simply_entry(node): + self.document.reporter.severe( + 'Colspanning table cells may only contain one paragraph.') + # Todo: Same as above. + # The number of columns this entry spans (as a string). + colspan = int(node['morecols']) + 1 + del node['morecols'] + else: + colspan = 1 + # Macro to call. + macro_name = r'\Dcolspan' + if node.parent.index(node) == 0: + # Leftmost column. + macro_name += 'left' + is_leftmost = 1 + if colspan > 1: + self.append('%s{%s}{' % (macro_name, colspan)) + self.context.append('}') + else: + # Do not add a multicolumn with colspan 1 beacuse we need + # at least one non-multicolumn cell per column to get the + # desired column widths, and we can only do colspans with + # cells consisting of only one paragraph. + if not is_leftmost: + self.append(r'\Dsubsequententry{') + self.context.append('}') + else: + self.context.append('') + if isinstance(node.parent.parent, nodes.thead): + node['tableheaderentry'] = 'true' + + # Don't add \renewcommand{\Dparent}{...} because there may not + # be any non-expandable commands in front of \multicolumn. + raise SkipParentLaTeX + + def depart_entry(self, node): + self.append(self.context.pop()) + + def before_substitution_definition(self, node): + raise nodes.SkipNode + + indentation_level = 0 + + def node_name(self, node): + return node.__class__.__name__.replace('_', '') + + def propagate_attributes(self, node): + # Propagate attributes using \Dattr macros. + node_name = self.node_name(node) + attlist = [] + if isinstance(node, nodes.Element): + attlist = node.attlist() + numatts = 0 + for key, value in attlist: + if isinstance(value, ListType): + self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) + for i in range(len(value)): + self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % + (i+1, key, self.encode(value[i], preserve=1), + node_name)) # for Emacs: } + numatts += len(value) + else: + self.append(r'\Dattr{}{%s}{%s}{%s}{' % + (key, self.encode(unicode(value), preserve=1), + node_name)) + # for Emacs: } + numatts += 1 + self.context.append('}' * numatts) # for Emacs: { + + def visit_docinfo(self, node): + raise NotImplementedError('Docinfo not yet implemented.') + + def visit_document(self, node): + document = node + # Move IDs into TextElements. This won't work for images. + # Need to review this. + for node in document.traverse(lambda n: isinstance(n, nodes.Element)): + if node.has_key('ids') and not isinstance(node, + nodes.TextElement): + next_text_element = node.next_node( + lambda n: isinstance(n, nodes.TextElement)) + if next_text_element: + next_text_element['ids'].extend(node['ids']) + node['ids'] = [] + + def dispatch_visit(self, node): + skip_attr = skip_parent = 0 + # TreePruningException to be propagated. + tree_pruning_exception = None + if hasattr(self, 'before_' + node.__class__.__name__): + try: + getattr(self, 'before_' + node.__class__.__name__)(node) + except SkipParentLaTeX: + skip_parent = 1 + except SkipAttrParentLaTeX: + skip_attr = 1 + skip_parent = 1 + except nodes.SkipNode: + raise + except (nodes.SkipChildren, nodes.SkipSiblings), instance: + tree_pruning_exception = instance + except nodes.SkipDeparture: + raise NotImplementedError( + 'SkipDeparture not usable in LaTeX writer') + + if not isinstance(node, nodes.Text): + node_name = self.node_name(node) + if not skip_parent: + self.append(r'\renewcommand{\Dparent}{%s}' + % self.node_name(node.parent)) + self.append(r'\DN%s{' % node_name) + self.context.append('}') + self.indentation_level += 1 + if not skip_attr: + self.propagate_attributes(node) + else: + self.context.append('') + + if (isinstance(node, nodes.TextElement) and + not isinstance(node.parent, nodes.TextElement)): + # Reset current quote to left. + self.left_quote = 1 + + # Call visit_... method. + try: + nodes.SparseNodeVisitor.dispatch_visit(self, node) + except LaTeXException: + raise NotImplementedError( + 'visit_... methods must not raise LaTeXExceptions') + + if tree_pruning_exception: + # Propagate TreePruningException raised in before_... method. + raise tree_pruning_exception + + def is_invisible(self, node): + # Return true if node is invisible or moved away in the LaTeX + # rendering. + return (isinstance(node, nodes.Invisible) or + isinstance(node, nodes.footnote) or + isinstance(node, nodes.citation)) + + def needs_auxiliary_space(self, node): + # Return true if node is a visible Body element or topic or + # transition and it occurs in block-level context. + return ((isinstance(node, nodes.Body) or + isinstance(node, nodes.topic) or + #isinstance(node, nodes.rubric) or + isinstance(node, nodes.transition)) and + not (self.is_invisible(node) or + isinstance(node.parent, nodes.TextElement))) + + def dispatch_departure(self, node): + # Call departure method. + nodes.SparseNodeVisitor.dispatch_departure(self, node) + + if not isinstance(node, nodes.Text): + # Close attribute and node handler call (\DN...{...}). + self.indentation_level -= 1 + self.append(self.context.pop() + self.context.pop()) + + # Insert auxiliary space. + if self.needs_auxiliary_space(node): + # Next sibling. + next_node = node.next_node( + ascend=0, siblings=1, descend=0, + condition=lambda n: not self.is_invisible(n)) + if self.needs_auxiliary_space(next_node): + if not (isinstance(node, nodes.paragraph) and + isinstance(next_node, nodes.paragraph)): + # Insert space. + self.append(r'\Dauxiliaryspace') + else: + self.append(r'\Dparagraphspace') -- cgit v1.2.1 From 608f4cf68d51bd72da4a582b6746772d75286ab6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 26 Apr 2005 23:03:00 +0000 Subject: Added the rest of the new LaTeX writer (I accidentally committed newlatex.py together with nodes.py). To test the new LaTeX writer you must (currently) specify tools/latex.tex as a stylesheet. You can use test/functional/input/standalone_rst_latex.txt as input document. Note that the writer is not yet complete; I'm checking it in to the trunk anyway because I don't want to have to merge changes from the trunk to a branch. Things to do: * Implement support for missing elements. * Restructure. * Add tests for a lot of special cases. * Write documentation, esp. how to customize the behavior. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3260 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/rst2newlatex.py | 27 ++ tools/stylesheets/latex-notes.txt | 14 + tools/stylesheets/latex.tex | 731 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 772 insertions(+) create mode 100755 tools/rst2newlatex.py create mode 100644 tools/stylesheets/latex-notes.txt create mode 100644 tools/stylesheets/latex.tex diff --git a/tools/rst2newlatex.py b/tools/rst2newlatex.py new file mode 100755 index 000000000..46524753f --- /dev/null +++ b/tools/rst2newlatex.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing LaTeX using +the new LaTeX writer. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates LaTeX documents from standalone reStructuredText ' + 'sources. This writer is EXPERIMENTAL and should not be used ' + 'in a production environment. ' + default_description) + +publish_cmdline(writer_name='newlatex2e', description=description) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt new file mode 100644 index 000000000..829ba9aa4 --- /dev/null +++ b/tools/stylesheets/latex-notes.txt @@ -0,0 +1,14 @@ +Try the commands mentioned in +. + +Regarding UTF-8: + +* Read . + +* From :: + + > The amssymb package and the postscript option were simply so that + > LaTeX could find the fonts and symbol definitions for the particular + > Unicode characters I used. + > However the DeclareUnicodeCharacter directive was to work around a + > missing or misnamed character in the UCS database. diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex new file mode 100644 index 000000000..c7c25994a --- /dev/null +++ b/tools/stylesheets/latex.tex @@ -0,0 +1,731 @@ +\providecommand{\Ddocumentclass}{scrartcl} +\providecommand{\Ddocumentoptions}{a4paper} + +\documentclass[\Ddocumentoptions]{\Ddocumentclass} + + +\providecommand{\DSpackages}{% + % All kinds of useful packages. + \usepackage{ifthen} +} + + +\providecommand{\DSfontencoding}{ + % T1-emulation. Provides most characters and features we're used + % from T1-encoded fonts but doesn't use bitmap fonts. + \usepackage{ae} + % Provide the characters not contained in AE from EC bitmap fonts. + \usepackage{aecompl} + % Guillemets ("<<", ">>") in AE. + \usepackage{aeguill} +} + + +% Taken from +% +% and modified. Used with permission. +\makeatletter +\providecommand{\Dprovidelength}[2]{% + \begingroup% + \escapechar\m@ne% + \xdef\@gtempa{{\string#1}}% + \endgroup% + \expandafter\@ifundefined\@gtempa% + {\newlength{#1}\setlength{#1}{#2}}% + {}% +} +\makeatother + +\makeatletter +\providecommand{\Dprovidecounter}[1]{% + % Like \newcounter except that it doesn't crash if the counter + % already exists. + \@ifundefined{c@#1}{\newcounter{#1}}{} +} +\makeatother + +\providecommand{\DSboxcommands}{ + \Dprovidelength{\Dboxparindent}{\parindent} + \providecommand{\Dmakeboxminipage}[1]{% + % Make minipage for use in a box created by \Dmakefbox. + \begin{minipage}[t]{0.9\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + ##1% + \end{minipage}% + } + \providecommand{\Dmakefbox}[1]{% + % Make a centered, framed box. Useful e.g. for admonitions. + \vspace{0.4\baselineskip}% + \begin{center}% + \fbox{\Dmakeboxminipage{##1}}% + \end{center}% + \vspace{0.4\baselineskip}% + } + \providecommand{\Dmakebox}[1]{% + % Make a centered, frameless box. Useful e.g. for block quotes. + % Do not use minipages here, but create pseudo-lists to allow + % page-breaking. (Don't uses KOMA-script's addmargin environment + % because it messes up bullet lists.) + \Dmakelistenvironment{}{}{% + \setlength{\parskip}{0pt}% + \setlength{\parindent}{\Dboxparindent}% + \item{##1}% + }% + } +} + + +\providecommand{\DSfrenchspacing}{ + \frenchspacing +} + + +\providecommand{\DSauxiliaryspace}{ + \providecommand{\Dblocklevelvspace}{% + % Space between block-level elements other than paragraphs. + 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% + } + \providecommand{\Dauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{yes}}{\vspace{\Dblocklevelvspace}}{}% + \Dpar% + } + \providecommand{\Dparagraphspace}{\Dpar} + \providecommand{\Dneedvspace}{yes} +} + + +\providecommand{\DSparagraphs}{ + \providecommand{\Dnextparindent}{} + \providecommand{\Dnextpar}{\par} + %\newcommand{\Dnextpar}{\par\Dnextparindent} + \providecommand{\Dpar}{% + \Dnextpar% + \Dnextparindent% + \protect\renewcommand{\Dnextpar}{\par}% + \protect\renewcommand{\Dnextparindent}{}% + } + \providecommand{\Dnopar}{% + \protect\renewcommand{\Dnextpar}{\par}% + \protect\renewcommand{\Dnextparindent}{}% + } +} + +\makeatletter +\providecommand{\DSlinks}{ + % Targets and references. + \usepackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} + + \providecommand{\Draisedlink}[1]{\Hy@raisedlink{##1}} + + % References. + % We're assuming here that the "refid" and "refuri" attributes occur + % only in inline context (in TextElements). + \providecommand{\DArefid}[5]{% + \ifthenelse{\equal{##4}{reference}}{% + \Dexplicitreference{\###3}{##5}% + }{% + % If this is not a target node (targets with refids are + % uninteresting and should be silently dropped). + \ifthenelse{\not\equal{##4}{target}}{% + % If this is a footnote reference, call special macro. + \ifthenelse{\equal{##4}{footnotereference}}{% + \Dimplicitfootnotereference{\###3}{##5}% + }{% + \ifthenelse{\equal{##4}{citationreference}}{% + \Dimplicitcitationreference{\###3}{##5}% + }{% + \Dimplicitreference{\###3}{##5}% + }% + }% + }{}% + }% + } + \providecommand{\DArefuri}[5]{% + % We only have explicit URI references, so one macro suffices. + \Durireference{##3}{##5}% + } + % Targets. + \Dprovidelength{\Dorgbaselineskip}{0pt} + \providecommand{\DAids}[5]{% + \ifthenelse{\equal{##4}{footnotereference}}{% + {% + \renewcommand{\HyperRaiseLinkDefault}{% + % Dirty hack to make backrefs to footnote references work. + % For some reason, \baselineskip is 0pt in fn references. + 0.5\Dorgbaselineskip% + }% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + }{% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + } + % Color in references. + \usepackage{color} + \providecommand{\Dimplicitreference}[2]{% + % Create implicit reference to ID. Implicit references occur + % e.g. in TOC-backlinks of section titles. Parameters: + % 1. Target. + % 2. Link text. + {% + \protect\href{##1}{##2}% + }% + } + \providecommand{\Dimplicitfootnotereference}[2]{% + % Ditto, but for the special case of footnotes. + % We want them to be rendered like explicit references. + \Dexplicitreference{##1}{##2}% + } + \providecommand{\Dimplicitcitationreference}[2]{% + % Ditto for citation references. + \Dimplicitfootnotereference{##1}{##2}% + } + \providecommand{\Dexplicitreference}[2]{% + % Create explicit reference to ID, e.g. created with "foo_". + % Parameters: + % 1. Target. + % 2. Link text. + {% + \color{blue}\protect% + \href{##1}{##2}% + }% + } + \providecommand{\Durireference}[2]{% + % Create reference to URI. Parameters: + % 1. Target. + % 2. Link text. + {% + \color{blue} + \protect\href{##1}{##2}% + }% + } +} +\makeatother + + +\providecommand{\DAclasses}[5]{% + #5% +} + +\makeatletter +\providecommand{\Dattr}[5]{% + % Global attribute dispatcher. + % Parameters: + % 1. Attribute number. + % 2. Attribute name. + % 3. Attribute value. + % 4. Node name. + % 5. Node contents. + \@ifundefined{DA#2}{#5}{\csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}}% +} +\makeatother + +\providecommand{\DNparagraph}[1]{#1} +\providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} +\providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} +\providecommand{\Dtopictitle}[1]{% + \noindent\Dformatboxtitle{#1}% + \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% + \Dpar\noindent% +} +\providecommand{\Dtopicsubtitle}[1]{% + \noindent\Dformatboxsubtitle{#1}% + \vspace{1em}% + \Dpar\noindent% +} +\providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}} +\providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}} +\providecommand{\Ddocumenttitle}[1]{% + \begin{center}{\Huge#1}\end{center}% + \ifthenelse{\equal{\Dhassubtitle}{true}}{\vspace{0.1cm}}{\vspace{1cm}}% +} +\providecommand{\Ddocumentsubtitle}[1]{% + \begin{center}{\huge#1}\end{center}% + \vspace{1cm}% +} +\providecommand{\Dsectiontitle}[1]{\section*{#1}} +\providecommand{\Dsubsectiontitle}[1]{\subsection*{#1}} +\providecommand{\Dsubsubsectiontitle}[1]{\subsubsection*{#1}} +\providecommand{\Dsubsubsubsectiontitle}[1]{% + \par\textbf{\vspace{1.5em}#1\vspace{1em}}} +\providecommand{\Dmakesectiontitletext}[1]{% + % Return text suitable for use in \section*, \subsection*, etc. + % Parameter: The title (as node tree). + \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% + #1% +} +\providecommand{\Ddispatchsectiontitle}[1]{% + \ifthenelse{\value{Dsectionlevel}=1}{\Dsectiontitle{#1}}{}% + \ifthenelse{\value{Dsectionlevel}=2}{\Dsubsectiontitle{#1}}{}% + \ifthenelse{\value{Dsectionlevel}=3}{\Dsubsubsectiontitle{#1}}{}% + \ifthenelse{\value{Dsectionlevel}>3}{\Dsubsubsubsectiontitle{#1}}{}% +} +% Boolean variable. +\providecommand{\Dhassubtitle}{} +\makeatother +\providecommand{\DNtitle}[1]{% + \ifthenelse{\equal{\Dparent}{topic}}{\Dtopictitle{#1}}{% + \ifthenelse{\equal{\Dparent}{document}}{\Ddocumenttitle{#1}}{% + \ifthenelse{\equal{\Dparent}{section}}{% + \Ddispatchsectiontitle{\Dmakesectiontitletext{#1}}% + }{% + \ifthenelse{\equal{\Dparent}{sidebar}}{\Dsidebartitle{#1}}{}% + }% + }% + }% +} +\providecommand{\DNsubtitle}[1]{% + \ifthenelse{\equal{\Dparent}{topic}}{\Dtopicsubtitle{#1}}{% + \ifthenelse{\equal{\Dparent}{document}}{\Ddocumentsubtitle{#1}}{% + \ifthenelse{\equal{\Dparent}{sidebar}}{\Dsidebarsubtitle{#1}}{}% + }% + }% +} +\newcounter{Dpdfbookmarkid} +\setcounter{Dpdfbookmarkid}{0} +\providecommand{\Dpdfbookmark}[1]{% + % Temporarily decrement Desctionlevel counter. + \addtocounter{Dsectionlevel}{-1}% + %\typeout{\arabic{Dsectionlevel}}% + %\typeout{#1}% + %\typeout{docutils\roman{Dpdfbookmarkid}}% + %\typeout{}% + \pdfbookmark[\arabic{Dsectionlevel}]{#1}{docutils\arabic{Dpdfbookmarkid}}% + \addtocounter{Dsectionlevel}{1}% + \addtocounter{Dpdfbookmarkid}{1}% +} + +%\providecommand{\DNliteralblock}[1]{\begin{quote}\ttfamily\raggedright#1\end{quote}} +\providecommand{\DNliteralblock}[1]{% + \Dmakelistenvironment{}{}{% + \raggedright\item\noindent\nohyphens{\textnhtt{#1}}% + }% +} +\providecommand{\DNdoctestblock}[1]{% + % Treat doctest blocks the same as literal blocks. + \DNliteralblock{#1}% +} +\usepackage{hyphenat} +\providecommand{\DNliteral}[1]{\textnhtt{#1}} +\providecommand{\DNemphasis}[1]{\emph{#1}} +\providecommand{\DNstrong}[1]{\textbf{#1}} +\providecommand{\DNdocument}[1]{\begin{document}\protect\renewcommand{\Dnextparindent}{\noindent}#1\end{document}} +\providecommand{\DNtopic}[1]{% + \par% + \Dmakebox{% + %% % Close with \par because otherwise LaTeX wouldn't notice the + %% % changed \baselineskip (due to the font size change). + %% {\small#1\par}% + #1% + }% +} +\providecommand{\Dformatrubric}[1]{{\large\textbf{#1}}} +\providecommand{\DNrubric}[1]{\begin{center}\Dformatrubric{#1}\end{center}} + +\providecommand{\Dbullet}{} +\providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} +\providecommand{\DNbulletlist}[1]{\Dmakelistenvironment{\Dbullet}{}{#1}} + +\providecommand{\DNlistitem}[1]{\item{#1}} +\providecommand{\DNenumeratedlist}[1]{#1} +\newcounter{Dsectionlevel} +\providecommand{\DNsection}[1]{\addtocounter{Dsectionlevel}{1}#1\addtocounter{Dsectionlevel}{-1}} + +% Using \_ will cause hyphenation after _ even in \textnhtt-typewriter +% because the hyphenat package redefines \_. So we use +% \textunderscore here. +\providecommand{\Dtextunderscore}{\textunderscore} + +\providecommand{\Dtextinlineliteralfirstspace}{{ }} +\providecommand{\Dtextinlineliteralsecondspace}{{~}} + +\Dprovidelength{\Dlistspacing}{0.8\baselineskip} + +% Current hardcoded. +\usepackage[latin1]{inputenc} + +\providecommand{\Dresetlistdepth}{false} +\makeatletter +\providecommand{\Dmakelistenvironment}[3]{% + % Make list environment with support for unlimited nesting and with + % reasonable default lengths. Parameters: + % 1. Label (same as in list environment). + % 2. Spacing (same as in list environment). + % 3. List contents (contents of list environment). + {% + \renewcommand{\Dneedvspace}{no}% + % \parsep0.5\baselineskip + \renewcommand{\Dresetlistdepth}{false}% + \ifnum \@listdepth>5% + \protect\renewcommand{\Dresetlistdepth}{true}% + \@listdepth=5% + \fi% + \begin{list}{% + #1% + }{% + \setlength{\itemsep}{0pt}% + \setlength{\partopsep}{0pt}% + \setlength{\topsep}{0pt}% + % List should take 90% of total width. + \setlength{\leftmargin}{0.05\linewidth}% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + #2% + }{% + #3% + }% + \end{list}% + \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% + }% +} +\makeatother + +\providecommand{\Dmakeenumeratedlist}[6]{% + % Make enumerated list. + % Parameters: + % - prefix + % - type (\arabic, \roman, ...) + % - suffix + % - suggested counter name + % - start number - 1 + % - list contents + \newcounter{#4}% + \Dmakelistenvironment{#1#2{#4}#3}{% + % Use as much space as needed for the label. + \setlength{\labelwidth}{10em}% + % Reserve enough space so that the label doesn't go beyond the + % left margin of preceding paragraphs. Like that: + % + % A paragraph. + % + % 1. First item. + \setlength{\leftmargin}{2.5em}% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + % Use counter recommended by Python module. + \usecounter{#4}% + % Set start value. + \addtocounter{#4}{#5}% + }{% + % The list contents. + #6}% +} + + +\providecommand{\Dlanguage}{english} +\usepackage[\Dlanguage]{babel} + +% Single quote in literal mode. \textquotesingle from package +% textcomp has wrong width when using package ae, so we use a normal +% single curly quote here. +\providecommand{\Dtextliteralsinglequote}{'} + + +\providecommand{\Dtwocolumntable}[1]{% + % Create a simple borderless two-column table, the right column of + % which has a variable width. + \begin{tabularx}{\linewidth}{@{}lX@{}}#1\end{tabularx}% +} + + +\usepackage{tabularx} +\providecommand{\Dformatfieldname}[1]{\bfseries{#1:}} +\providecommand{\DNfieldlist}[1]{% + \noindent\Dtwocolumntable{#1}% +} +\providecommand{\DNfieldname}[1]{\Dformatfieldname{#1}{}&{}} +\providecommand{\DNfieldbody}[1]{{#1}{}\tabularnewline} + + +\providecommand{\DNdefinitionlist}[1]{% + \noindent\begin{description}#1\end{description}% +} +\providecommand{\DNdefinitionlistitem}[1]{% + % LaTeX expects the label in square brackets; we provide an empty + % label. + \item[]#1% +} +\providecommand{\DNterm}[1]{#1} +% I'm still not sure what's the best rendering for classifiers. The +% colon syntax is used by reStructuredText, so it's at least WYSIWYG. +% Use slanted text because italic would cause too much emphasis. +\providecommand{\DNclassifier}[1]{~:~\textsl{#1}} +\providecommand{\DNdefinition}[1]{\Dpar#1} + + +\providecommand{\Dformatoptiongroup}[1]{% + % Format option group, e.g. "-f file, --input file". + \texttt{#1}% +} +\providecommand{\Dformatoption}[1]{% + % Format option, e.g. "-f file". + % Put into mbox to avoid line-breaking at spaces. + \mbox{#1}% +} +\providecommand{\Dformatoptionstring}[1]{% + % Format option string, e.g. "-f". + #1% +} +\providecommand{\Dformatoptionargument}[1]{% + % Format option argument, e.g. "file". + \textsl{#1}% +} +\providecommand{\Dformatoptiondescription}[1]{% + % Format option description, e.g. + % "\DNparagraph{Read input data from file.}" + #1% +} +\providecommand{\DNoptionlist}[1]{% + \noindent\Dtwocolumntable{#1}% +} +\providecommand{\Doptiongroupjoiner}{,{ }} +\providecommand{\Disfirstoption}{% + % Auxiliary macro indicating if a given option is the first child + % of its option group (if it's not, it has to preceded by + % \Doptiongroupjoiner). + false% +} +\providecommand{\DNoptiongroup}[1]{% + \renewcommand{\Disfirstoption}{true}% + \Dformatoptiongroup{#1}{}&{}% +} +\providecommand{\DNoption}[1]{% + % If this is not the first option in this option group, add a + % joiner. + \ifthenelse{\equal{\Disfirstoption}{true}}{% + \renewcommand{\Disfirstoption}{false}% + }{% + \Doptiongroupjoiner% + }% + \Dformatoption{#1}% +} +\providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}} +\providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}} +\providecommand{\DNdescription}[1]{% + \Dformatoptiondescription{#1}% + \tabularnewline% +} + +\providecommand{\Dlineblockindentation}{2.5em} +\providecommand{\DNlineblock}[1]{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dparent}{lineblock}}{% + % Parent is a line block, so indent. + \setlength{\leftmargin}{\Dlineblockindentation}% + }{% + % At top level; don't indent. + \setlength{\leftmargin}{0pt}% + }% + \setlength{\parsep}{0pt} + }% + {% + #1% + }% +} +\providecommand{\DNline}[1]{\item#1} + + +\providecommand{\DNtransition}{% + \Dpar\noindent{}\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}% +} + + +\providecommand{\Dformatblockquote}[1]{% + % Format contents of block quote. + % This occurs in block-level context, so we cannot use \textsl. + {\slshape#1}% +} +\providecommand{\Dformatattribution}[1]{---\textup{#1}} +\providecommand{\DNblockquote}[1]{% + \renewcommand{\Dnextparindent}{\noindent}% + \renewcommand{\Dnextpar}{}% + \Dmakebox{% + \Dformatblockquote{#1} + }% +} +\providecommand{\DNattribution}[1]{% + \Dpar% + \begin{flushright}\Dformatattribution{#1}\end{flushright}% +} + + +% Sidebars: +\usepackage{picins} +% Vertical and horizontal margins. +\Dprovidelength{\Dsidebarvmargin}{0.5em} +\Dprovidelength{\Dsidebarhmargin}{1em} +% Padding (space between contents and frame). +\Dprovidelength{\Dsidebarpadding}{1em} +% Frame width. +\Dprovidelength{\Dsidebarframewidth}{2\fboxrule} +% Position ("l" or "r"). +\providecommand{\Dsidebarposition}{r} +% Width. +\Dprovidelength{\Dsidebarwidth}{0.45\linewidth} +\providecommand{\DNsidebar}[1]{\parpic[\Dsidebarposition]{% + \Dpar% + \begin{minipage}[t]{\Dsidebarwidth} + % Doing this with nested minipages is ugly, but I haven't found + % another way to place vertical space before and after the fbox. + \vspace{\Dsidebarvmargin} + {% + \setlength{\fboxrule}{\Dsidebarframewidth}% + \setlength{\fboxsep}{\Dsidebarpadding}% + \fbox{% + \begin{minipage}[t]{\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% + }% + }% + \vspace{\Dsidebarvmargin} + \end{minipage}% + }% +} + + +% Citations and footnotes. +\providecommand{\Dformatfootnote}[1]{% + % Format footnote. + {% + \footnotesize#1% + % \par is necessary for LaTeX to adjust baselineskip to the + % changed font size. + \par% + }% +} +\providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}} +\providecommand{\DNfootnotereference}[1]{% + {% + % \baselineskip is 0pt in \textsuperscript, so we save it here. + \setlength{\Dorgbaselineskip}{\baselineskip}% + \textsuperscript{#1}% + }% +} +\providecommand{\DNcitationreference}[1]{{[}#1{]}} +\Dprovidelength{\Dfootnotesep}{5pt} +\providecommand{\Dfootnotespacing}{% + % Spacing commands executed at the beginning of footnotes. + \setlength{\parindent}{0pt}% + \hspace{1em}% +} +\providecommand{\DNfootnote}[1]{% + % See ltfloat.dtx for details. + {% + \insert\footins{% + \Dnopar\vspace{\Dfootnotesep}\Dfootnotespacing% + \Dformatfootnote{#1}% + }% + }% +} +\providecommand{\DNcitation}[1]{\DNfootnote{#1}} +\providecommand{\Dformatfootnotelabel}[1]{% + % Keep \footnotesize in footnote labels (\textsuperscript would + % reduce the font size even more). + \textsuperscript{\footnotesize#1{ }}% +} +\providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }} +\providecommand{\Dformatmultiplebackrefs}[1]{\textsl{#1}} +\providecommand{\Dthislabel}{} +\providecommand{\DNlabel}[1]{% + \renewcommand{\Dthislabel}{#1} + \ifthenelse{\not\equal{\Dsinglebackref}{}}{% + \let\Doriginallabel=\Dthislabel% + \def\Dthislabel{% + \Dsinglefootnotebacklink{\Dsinglebackref}{\Doriginallabel}% + }% + }{}% + \ifthenelse{\equal{\Dparent}{footnote}}{% + % Footnote label. + \Dformatfootnotelabel{\Dthislabel}% + }{% + \ifthenelse{\equal{\Dparent}{citation}}{% + % Citation label. + \Dformatcitationlabel{\Dthislabel}% + }{}% + }% + % If there are multiple backrefs, add them now. + \Dformatmultiplebackrefs{\Dmultiplebackrefs}% + % Supress next paragraph change. + \renewcommand{\Dnextpar}{}% +} +\providecommand{\Dsinglefootnotebacklink}[2]{% + % Create normal backlink of a footnote label. Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dmultifootnotebacklink}[2]{% + % Create generated backlink, as in (1, 2). Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dsinglecitationbacklink}[2]{\Dsinglefootnotebacklink{#1}{#2}} +\providecommand{\Dmulticitationbacklink}[2]{\Dmultifootnotebacklink{#1}{#2}} + + +\usepackage{longtable} +\providecommand{\Dmaketable}[2]{% + % Make table. Parameters: + % 1. Table spec (like "|p|p|"). + % 2. Table contents. + \begin{longtable}{#1}% + \hline% + #2% + \end{longtable} +} +\providecommand{\DNthead}[1]{% + #1% + \endhead% +} +\providecommand{\DNrow}[1]{% + #1\tabularnewline% + \hline% +} +\providecommand{\Dcolspan}[2]{% + % Take care of the morecols attribute (but incremented by 1). + &\multicolumn{#1}{l|}{#2}% +} +\providecommand{\Dcolspanleft}[2]{% + % Like \Dmorecols, but called for the leftmost entries in a table + % row. + \multicolumn{#1}{|l|}{#2}% +} +\providecommand{\Dsubsequententry}[1]{% + % +} +% \DNentry is not used because we set the ampersand ("&") in the +% \DAcolspan... macros. +\providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} +\providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} + + +\providecommand{\DNsystemmessage}[1]{% + {% + \noindent% + \color{red}% + \bfseries% + #1% + }% +} + + +% Need to replace by language-specific stuff. +\providecommand{\Dtextleftdblquote}{``} +\providecommand{\Dtextrightdblquote}{''} + + +%\usepackage{fixmath} +%\usepackage{amsmath} + + +\DSpackages +\DSfontencoding +\DSboxcommands +\DSfrenchspacing +\DSauxiliaryspace +\DSparagraphs +\DSlinks -- cgit v1.2.1 From 2ed86e77045d1f2ae058c69e23c50a245330c1ec Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 27 Apr 2005 11:44:59 +0000 Subject: added target at end of admonition git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3261 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_html4css1.html | 2 +- test/functional/expected/standalone_rst_pseudoxml.txt | 1 + test/functional/input/data/standard.txt | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 13f8c02c6..e4067e2eb 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -617,7 +617,7 @@ Reader discretion is strongly advised.

    And, by the way...

    -

    You can make up your own admonition too.

    +

    You can make up your own admonition too.

    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index d647b11a8..597408d23 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1204,6 +1204,7 @@ And, by the way... You can make up your own admonition too. +
    <generated classes="sectnum"> diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 7019df74a..b06a158d4 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -477,6 +477,8 @@ Admonitions You can make up your own admonition too. + .. _Docutils: http://docutils.sourceforge.net/ + Topics, Sidebars, and Rubrics ````````````````````````````` -- cgit v1.2.1 From ae9d340239b7bc97b08f3e0397a6c31ce0bc3919 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 27 Apr 2005 11:50:29 +0000 Subject: do not add first/last class to invisible elements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3262 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 7 ++++--- test/functional/expected/standalone_rst_html4css1.html | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 76499dea6..9323565d7 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -338,9 +338,10 @@ class HTMLTranslator(nodes.NodeVisitor): return self.starttag(node, tagname, suffix, infix=' /', **attributes) def set_first_last(self, node): - if len(node): - node[0]['classes'].append('first') - node[-1]['classes'].append('last') + children = [n for n in node if not isinstance(n, nodes.Invisible)] + if children: + children[0]['classes'].append('first') + children[-1]['classes'].append('last') def visit_Text(self, node): text = node.astext() diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index e4067e2eb..13f8c02c6 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -617,7 +617,7 @@ Reader discretion is strongly advised.</p> </div> <div class="admonition-and-by-the-way admonition"> <p class="first admonition-title">And, by the way...</p> -<p>You can make up your own admonition too.</p> +<p class="last">You can make up your own admonition too.</p> </div> </div> <div class="section" id="topics-sidebars-and-rubrics"> -- cgit v1.2.1 From fa387fdb69c9d4aa34cbcbabae2db046b329cd25 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 27 Apr 2005 15:24:22 +0000 Subject: more sophisticated spacing; image support; node-specific attribute handlers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3265 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 58 +++++++++++++++++++++++++++--------------- tools/stylesheets/latex.tex | 28 ++++++++++++++++++-- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 09a723baa..abdaed60c 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -18,7 +18,6 @@ __docformat__ = 'reStructuredText' import re import os.path from types import ListType -import roman import docutils from docutils import nodes, writers, utils @@ -294,16 +293,29 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): character_map.update(unicode_map) #character_map.update(special_map) - def encode(self, text, preserve=0): + def encode(self, text, attval=0): """ Encode special characters in ``text`` and return it. - If preserve is true, preserve as much as possible (used in + If attval is true, preserve as much as possible verbatim (used in attribute value encoding). """ - get = self.character_map.get + if not attval: + get = self.character_map.get + else: + # According to + # <http://www-h.eng.cam.ac.uk/help/tpl/textprocessing/teTeX/latex/latex2e-html/ltx-164.html>, + # the following characters are special: # $ % & ~ _ ^ \ { } + # These work without special treatment in macro parameters: + # $, &, ~, _, ^ + get = {'#': '\\#', + '%': '\\%', + # We cannot do anything about backslashes. + '\\': '', + '{': '\\{', + '}': '\\}'}.get text = ''.join([get(c, c) for c in text]) - if (self.literal_block or self.inline_literal) and not preserve: + if (self.literal_block or self.inline_literal) and not attval: # NB: We can have inline literals within literal blocks. # Shrink '\r\n'. text = text.replace('\r\n', '\n') @@ -328,7 +340,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): text = text.replace("'", r'{\Dtextliteralsinglequote}') return text else: - if not preserve: + if not attval: # Replace space with single protected space. text = re.sub(r'\s+', '{ }', text) # Replace double quotes with macro calls. @@ -556,12 +568,12 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) for i in range(len(value)): self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % - (i+1, key, self.encode(value[i], preserve=1), + (i+1, key, self.encode(value[i], attval=1), node_name)) # for Emacs: } numatts += len(value) else: self.append(r'\Dattr{}{%s}{%s}{%s}{' % - (key, self.encode(unicode(value), preserve=1), + (key, self.encode(unicode(value), attval=1), node_name)) # for Emacs: } numatts += 1 @@ -639,13 +651,14 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): isinstance(node, nodes.footnote) or isinstance(node, nodes.citation)) - def needs_auxiliary_space(self, node): - # Return true if node is a visible Body element or topic or - # transition and it occurs in block-level context. + def needs_space(self, node): + # Return true if node is a visible block-level element. return ((isinstance(node, nodes.Body) or isinstance(node, nodes.topic) or #isinstance(node, nodes.rubric) or - isinstance(node, nodes.transition)) and + isinstance(node, nodes.transition) or + isinstance(node, nodes.caption) or + isinstance(node, nodes.legend)) and not (self.is_invisible(node) or isinstance(node.parent, nodes.TextElement))) @@ -658,16 +671,21 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.indentation_level -= 1 self.append(self.context.pop() + self.context.pop()) - # Insert auxiliary space. - if self.needs_auxiliary_space(node): + # Insert space. + if self.needs_space(node): # Next sibling. next_node = node.next_node( ascend=0, siblings=1, descend=0, condition=lambda n: not self.is_invisible(n)) - if self.needs_auxiliary_space(next_node): - if not (isinstance(node, nodes.paragraph) and - isinstance(next_node, nodes.paragraph)): - # Insert space. - self.append(r'\Dauxiliaryspace') + if self.needs_space(next_node): + # Insert space. + if isinstance(next_node, nodes.paragraph): + if isinstance(node, nodes.paragraph): + # Space between paragraphs. + self.append(r'\Dparagraphspace') + else: + # Space in front of a paragraph. + self.append(r'\Dauxiliaryparspace') else: - self.append(r'\Dparagraphspace') + # Space in front of something else than a paragraph. + self.append(r'\Dauxiliaryspace') diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c7c25994a..9b250d9b9 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -86,6 +86,10 @@ 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% } \providecommand{\Dauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{yes}}{\vspace{\Dblocklevelvspace}}{}% + \Dpar\noindent% + } + \providecommand{\Dauxiliaryparspace}{% \ifthenelse{\equal{\Dneedvspace}{yes}}{\vspace{\Dblocklevelvspace}}{}% \Dpar% } @@ -216,7 +220,11 @@ % 3. Attribute value. % 4. Node name. % 5. Node contents. - \@ifundefined{DA#2}{#5}{\csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}}% + \@ifundefined{DN#4A#2}{% + \@ifundefined{DA#2}{#5}{\csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}}% + }{% + \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }% } \makeatother @@ -713,7 +721,23 @@ } -% Need to replace by language-specific stuff. +\usepackage{graphicx} +\Dprovidelength{\Dimagewidth}{0pt} +\newsavebox{\Dimagesavebox} +\providecommand{\DNimageAuri}[5]{% + % Insert image. We treat the URI like a path here. +% \ + \settowidth{\Dimagewidth}{\includegraphics{#3}}% + \ifthenelse{\Dimagewidth>\linewidth}{% + \includegraphics[width=\linewidth]{#3}% + }{% + \includegraphics{#3}% + }% +} + + +% Need to replace with language-specific stuff. Maybe look at +% csquotes.sty and ask the author for permission to use parts of it. \providecommand{\Dtextleftdblquote}{``} \providecommand{\Dtextrightdblquote}{''} -- cgit v1.2.1 From 8b0a779861f10ccfe3214975d38df595a5aa0dd0 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 27 Apr 2005 17:43:05 +0000 Subject: testing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3266 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/svn | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/svn diff --git a/test/svn b/test/svn new file mode 100644 index 000000000..e5ed7a988 --- /dev/null +++ b/test/svn @@ -0,0 +1 @@ +Testing whether check-in mails work when sent directly to SourceForge. -- cgit v1.2.1 From b5cedba871fd97228585a6d6484fc8363a45e07c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 27 Apr 2005 17:51:01 +0000 Subject: Yes, it works. So now check-in mails are no longer sent via a forwarder at GMX but they are sent directly from BerliOS to SF.net; thanks to the SF.net people; the original support request was at <https://sourceforge.net/tracker/?func=detail&atid=200001&aid=1168447&group_id=1>. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3267 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/svn | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test/svn diff --git a/test/svn b/test/svn deleted file mode 100644 index e5ed7a988..000000000 --- a/test/svn +++ /dev/null @@ -1 +0,0 @@ -Testing whether check-in mails work when sent directly to SourceForge. -- cgit v1.2.1 From ce727c88d8d89f9f86275c0d3fca3ae2be392cec Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 27 Apr 2005 21:04:03 +0000 Subject: fixed encoding/charset values in "html_prolog" & "html_head" parts, which should not have been interpolated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3268 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/api/publisher.txt | 14 ++++++++++++-- docutils/writers/html4css1.py | 12 +++++++----- test/DocutilsTestSupport.py | 21 +++++++++++++-------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index 55883f1ae..66aaa06fb 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -132,11 +132,21 @@ html_body html_head ``parts['html_head']`` contains the HTML ``<head>`` content, less the stylesheet link and the ``<head>`` and ``</head>`` tags - themselves. + themselves. The "Content-Type" meta tag's "charset" value is left + unresolved, as "%s":: + + <meta http-equiv="Content-Type" content="text/html; charset=%s" /> + + The interpolation should be done by client code. html_prolog ``parts['html_prolog]`` contains the XML declaration and the - doctype declaration. + doctype declaration. The XML declaration's "encoding" attribute's + value is left unresolved, as "%s":: + + <?xml version="1.0" encoding="%s" ?> + + The interpolation should be done by client code. html_subtitle ``parts['html_subtitle']`` contains the document subtitle, diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9323565d7..fc602cdbd 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -186,8 +186,8 @@ class HTMLTranslator(nodes.NodeVisitor): 'xhtml1-transitional.dtd">\n') head_prefix_template = ('<html xmlns="http://www.w3.org/1999/xhtml"' ' xml:lang="%s" lang="%s">\n<head>\n') - content_type = ('<meta http-equiv="Content-Type" content="text/html; ' - 'charset=%s" />\n') + content_type = ('<meta http-equiv="Content-Type"' + ' content="text/html; charset=%s" />\n') generator = ('<meta name="generator" content="Docutils %s: ' 'http://docutils.sourceforge.net/" />\n') stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n' @@ -207,7 +207,8 @@ class HTMLTranslator(nodes.NodeVisitor): if settings.xml_declaration: self.head_prefix.append(self.xml_declaration % settings.output_encoding) - self.html_prolog.append(self.xml_declaration) # not interpolated + # encoding not interpolated: + self.html_prolog.append(self.xml_declaration) self.head_prefix.extend([self.doctype, self.head_prefix_template % (lcode, lcode)]) self.html_prolog.append(self.doctype) @@ -248,7 +249,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.subtitle = [] self.header = [] self.footer = [] - self.html_head = [] + self.html_head = [self.content_type] # charset not interpolated self.html_title = [] self.html_subtitle = [] self.html_body = [] @@ -632,7 +633,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.fragment.extend(self.body) self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) self.body_suffix.insert(0, '</div>\n') - self.html_head.extend(self.head) + # skip content-type meta tag with interpolated charset value: + self.html_head.extend(self.head[1:]) self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + self.docinfo + self.body + self.body_suffix[:-1]) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 87a200598..d9f78f774 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -731,11 +731,16 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): expected = self.expected % {'version': docutils.__version__} self.compare_output(self.input, output, expected) - standard_meta_value_template = """\ -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils %s: http://docutils.sourceforge.net/" /> -""" - standard_meta_value = standard_meta_value_template % docutils.__version__ + + standard_content_type_template = ('<meta http-equiv="Content-Type"' + ' content="text/html; charset=%s" />\n') + standard_generator_template = ( + '<meta name="generator"' + ' content="Docutils %s: http://docutils.sourceforge.net/" />\n') + standard_html_meta_value = ( + standard_content_type_template + + standard_generator_template % docutils.__version__) + standard_meta_value = standard_html_meta_value % 'utf-8' standard_stylesheet_value = ('<link rel="stylesheet" href="default.css" ' 'type="text/css" />\n') standard_html_prolog = """\ @@ -745,16 +750,16 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): def format_output(self, parts): """Minimize & standardize the output.""" - # remove redundant bits: + # remove redundant parts: del parts['whole'] assert parts['body'] == parts['fragment'] del parts['body'] - # remove standard bits: + # remove standard portions: parts['meta'] = parts['meta'].replace(self.standard_meta_value, '') if parts['stylesheet'] == self.standard_stylesheet_value: del parts['stylesheet'] parts['html_head'] = parts['html_head'].replace( - self.standard_meta_value, '...') + self.standard_html_meta_value, '...') parts['html_prolog'] = parts['html_prolog'].replace( self.standard_html_prolog, '') # remove empty values: -- cgit v1.2.1 From 154ecc473fd947a0d9155873c3c7d736790eb3ee Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Apr 2005 19:39:02 +0000 Subject: fixed spacing problem with hyperlinks; removed some unused commands git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3269 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 9b250d9b9..e3d50b60a 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -171,9 +171,7 @@ % e.g. in TOC-backlinks of section titles. Parameters: % 1. Target. % 2. Link text. - {% - \protect\href{##1}{##2}% - }% + \href{##1}{##2}% } \providecommand{\Dimplicitfootnotereference}[2]{% % Ditto, but for the special case of footnotes. @@ -189,19 +187,13 @@ % Parameters: % 1. Target. % 2. Link text. - {% - \color{blue}\protect% - \href{##1}{##2}% - }% + \href{##1}{{\color{blue}##2}}% } \providecommand{\Durireference}[2]{% % Create reference to URI. Parameters: % 1. Target. % 2. Link text. - {% - \color{blue} - \protect\href{##1}{##2}% - }% + \href{##1}{{\color{blue}##2}}% } } \makeatother @@ -713,7 +705,6 @@ \providecommand{\DNsystemmessage}[1]{% {% - \noindent% \color{red}% \bfseries% #1% @@ -723,10 +714,8 @@ \usepackage{graphicx} \Dprovidelength{\Dimagewidth}{0pt} -\newsavebox{\Dimagesavebox} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. -% \ \settowidth{\Dimagewidth}{\includegraphics{#3}}% \ifthenelse{\Dimagewidth>\linewidth}{% \includegraphics[width=\linewidth]{#3}% -- cgit v1.2.1 From dd2eb8aa50f8fcb4b865b90d0edc3b4de38a5cd3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Apr 2005 22:06:20 +0000 Subject: ignore hyperlink targets; fixed line-blocks in tabular environments (e.g. field lists) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3270 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 102 ++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index e3d50b60a..f0a7e7f1f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -86,15 +86,15 @@ 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% } \providecommand{\Dauxiliaryspace}{% - \ifthenelse{\equal{\Dneedvspace}{yes}}{\vspace{\Dblocklevelvspace}}{}% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% \Dpar\noindent% } \providecommand{\Dauxiliaryparspace}{% - \ifthenelse{\equal{\Dneedvspace}{yes}}{\vspace{\Dblocklevelvspace}}{}% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% \Dpar% } \providecommand{\Dparagraphspace}{\Dpar} - \providecommand{\Dneedvspace}{yes} + \providecommand{\Dneedvspace}{true} } @@ -145,8 +145,13 @@ }% } \providecommand{\DArefuri}[5]{% - % We only have explicit URI references, so one macro suffices. - \Durireference{##3}{##5}% + \ifthenelse{\equal{##4}{target}}{% + % Hyperlink targets can (and should be) ignored because they are + % invisible. + }{% + % We only have explicit URI references, so one macro suffices. + \Durireference{##3}{##5}% + }% } % Targets. \Dprovidelength{\Dorgbaselineskip}{0pt} @@ -229,7 +234,7 @@ \Dpar\noindent% } \providecommand{\Dtopicsubtitle}[1]{% - \noindent\Dformatboxsubtitle{#1}% + \Dformatboxsubtitle{#1}% \vspace{1em}% \Dpar\noindent% } @@ -309,7 +314,12 @@ \providecommand{\DNliteral}[1]{\textnhtt{#1}} \providecommand{\DNemphasis}[1]{\emph{#1}} \providecommand{\DNstrong}[1]{\textbf{#1}} -\providecommand{\DNdocument}[1]{\begin{document}\protect\renewcommand{\Dnextparindent}{\noindent}#1\end{document}} +\providecommand{\DNdocument}[1]{% + \begin{document}% + \noindent% + #1% + \end{document}% +} \providecommand{\DNtopic}[1]{% \par% \Dmakebox{% @@ -352,31 +362,37 @@ % 1. Label (same as in list environment). % 2. Spacing (same as in list environment). % 3. List contents (contents of list environment). - {% - \renewcommand{\Dneedvspace}{no}% - % \parsep0.5\baselineskip - \renewcommand{\Dresetlistdepth}{false}% - \ifnum \@listdepth>5% - \protect\renewcommand{\Dresetlistdepth}{true}% - \@listdepth=5% - \fi% - \begin{list}{% - #1% - }{% - \setlength{\itemsep}{0pt}% - \setlength{\partopsep}{0pt}% - \setlength{\topsep}{0pt}% - % List should take 90% of total width. - \setlength{\leftmargin}{0.05\linewidth}% - % Equal margins. - \setlength{\rightmargin}{\leftmargin}% - #2% - }{% - #3% - }% - \end{list}% - \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% - }% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Unfortunately, vertical spacing doesn't work correctly when + % using lists inside tabular environments, so we use a minipage. + \begin{minipage}[t]{\linewidth}% + }{}% + {% + \renewcommand{\Dneedvspace}{false}% + % \parsep0.5\baselineskip + \renewcommand{\Dresetlistdepth}{false}% + \ifnum \@listdepth>5% + \protect\renewcommand{\Dresetlistdepth}{true}% + \@listdepth=5% + \fi% + \begin{list}{% + #1% + }{% + \setlength{\itemsep}{0pt}% + \setlength{\partopsep}{0pt}% + \setlength{\topsep}{0pt}% + % List should take 90% of total width. + \setlength{\leftmargin}{0.05\linewidth}% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + #2% + }{% + #3% + }% + \end{list}% + \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% + }% + \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% } \makeatother @@ -421,20 +437,25 @@ \providecommand{\Dtextliteralsinglequote}{'} +\providecommand{\Dinsidetabular}{false} \providecommand{\Dtwocolumntable}[1]{% % Create a simple borderless two-column table, the right column of % which has a variable width. - \begin{tabularx}{\linewidth}{@{}lX@{}}#1\end{tabularx}% + {% + \protect\renewcommand{\Dinsidetabular}{true}% + \begin{tabularx}{\linewidth}{@{}lX@{}}% + #1% + \end{tabularx}% + }% } - \usepackage{tabularx} \providecommand{\Dformatfieldname}[1]{\bfseries{#1:}} \providecommand{\DNfieldlist}[1]{% - \noindent\Dtwocolumntable{#1}% + \Dtwocolumntable{#1}% } -\providecommand{\DNfieldname}[1]{\Dformatfieldname{#1}{}&{}} -\providecommand{\DNfieldbody}[1]{{#1}{}\tabularnewline} +\providecommand{\DNfieldname}[1]{\Dformatfieldname{#1}&} +\providecommand{\DNfieldbody}[1]{#1\tabularnewline} \providecommand{\DNdefinitionlist}[1]{% @@ -476,7 +497,7 @@ #1% } \providecommand{\DNoptionlist}[1]{% - \noindent\Dtwocolumntable{#1}% + \Dtwocolumntable{#1}% } \providecommand{\Doptiongroupjoiner}{,{ }} \providecommand{\Disfirstoption}{% @@ -516,9 +537,8 @@ % At top level; don't indent. \setlength{\leftmargin}{0pt}% }% - \setlength{\parsep}{0pt} - }% - {% + \setlength{\parsep}{0pt}% + }{% #1% }% } -- cgit v1.2.1 From 8bdafc4194c3b1afa95ca4172878fa15247cb8e4 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Apr 2005 23:51:01 +0000 Subject: added some tests for the new latex writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3271 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/latex.txt | 104 +++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 test/functional/input/data/latex.txt diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt new file mode 100644 index 000000000..31e57c85d --- /dev/null +++ b/test/functional/input/data/latex.txt @@ -0,0 +1,104 @@ +Some Tests for the LaTeX Writer +=============================== + +These tests have been written to exercise some unusual combinations of +syntax elements which may cause trouble for the LaTeX writer but do +not need to be tested with other writers (e.g. the HTML writer). + +This file is not yet used by any automated test. It is currently only +used to control the visual appearance of the output. + + +Block Quotes +------------ + + This block quote comes directly after the section heading and is + followed by a paragraph. + + This is the second paragraph of the block quote and it contains + some more text filling up some space which would otherwise be + empty. + + -- Attribution + +This is a paragraph. + + This block quote does not have an attribution. + +This is another paragraph. + + Another block quote at the end of the section. + + +More Block Quotes +----------------- + + Block quote followed by a transition. + +---------- + + Another block quote. + + +Sidebars +-------- + +This paragraph precedes the sidebar. This is some text. This is some +text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. + +.. sidebar:: Sidebar Title + + These are the sidebar contents. These are the sidebar contents. + + These are the sidebar contents. These are the sidebar contents. + + These are the sidebar contents. These are the sidebar contents. + These are the sidebar contents. These are the sidebar contents. + +This paragraph follows the sidebar. This is some text. This is some +text. This is some text. + +This is some text. This is some text. This is some text. This is +some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. + + +Next Section +------------ + +This section comes after the sidebar, and this text should float +around the sidebar as well. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. + + +Nested Elements +--------------- + +:Field list: | Line + | Block +:Another field: * Bullet + * list + +* * * * * * * * Deeply nested list. + +1. 2. 3. 4. 5. 6. 7. 8. Deeply nested list. + ++---------------+ +| | Line block | +| | +| * Bullet list | +| | +| :: | +| | +| Literal | +| block | ++---------------+ -- cgit v1.2.1 From 0614aa5b89346e821552f758d3eb6ef586b572ab Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Apr 2005 23:54:25 +0000 Subject: added test file for new LaTeX writer including everything than can be tested git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3272 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/standalone_rst_newlatex.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/functional/input/standalone_rst_newlatex.txt diff --git a/test/functional/input/standalone_rst_newlatex.txt b/test/functional/input/standalone_rst_newlatex.txt new file mode 100644 index 000000000..81b4e5ea6 --- /dev/null +++ b/test/functional/input/standalone_rst_newlatex.txt @@ -0,0 +1,12 @@ +.. include:: data/standard.txt +.. include:: data/table_colspan.txt +.. include:: data/latex.txt + + +Tests for the LaTeX writer +========================== + +.. include:: data/nonalphanumeric.txt +.. include:: data/unicode.txt + +.. include:: data/errors.txt -- cgit v1.2.1 From 0d367a20ddf73937c88f48eefe81a9de83649aa9 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Apr 2005 23:54:36 +0000 Subject: checking in my intermediate results, trying to fix spacing problems in field lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3273 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 13 +++++++++++-- tools/stylesheets/latex-notes.txt | 2 ++ tools/stylesheets/latex.tex | 16 +++++----------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index abdaed60c..5a6065b5a 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -32,8 +32,8 @@ class Writer(writers.Writer): 'LaTeX-Specific Options', 'The LaTeX "--output-encoding" default is "latin-1:strict". ' 'Note that this LaTeX writer is still EXPERIMENTAL.', - (('Specify a stylesheet file. The file will be "input" by latex in ' - 'the document header. Overrides --stylesheet-path.', + (('Specify a stylesheet file. The path is used verbatim to include ' + 'the file. Overrides --stylesheet-path.', ['--stylesheet'], {'default': '', 'metavar': '<file>', 'overrides': 'stylesheet_path'}), @@ -436,6 +436,15 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def depart_enumerated_list(self, node): self.append('}') # for Emacs: { + def before_list_item(self, node): + # XXX needs cleanup. + if (len(node) and (isinstance(node[-1], nodes.TextElement) or + isinstance(node[-1], nodes.Text)) and + node.parent.index(node) == len(node.parent) - 1): + node['lastitem'] = 'true' + + before_line = before_list_item + def visit_raw(self, node): if 'latex' in node.get('format', '').split(): self.append(node.astext()) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt index 829ba9aa4..a3bd3720c 100644 --- a/tools/stylesheets/latex-notes.txt +++ b/tools/stylesheets/latex-notes.txt @@ -12,3 +12,5 @@ Regarding UTF-8: > Unicode characters I used. > However the DeclareUnicodeCharacter directive was to work around a > missing or misnamed character in the UCS database. + +Long field lists with ltxtable? diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index f0a7e7f1f..80b89e471 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -1,3 +1,5 @@ +\makeatletter + \providecommand{\Ddocumentclass}{scrartcl} \providecommand{\Ddocumentoptions}{a4paper} @@ -24,7 +26,6 @@ % Taken from % <http://groups.google.de/groups?selm=1i0n5tgtplti420e1omp4pctlv19jpuhbb%404ax.com> % and modified. Used with permission. -\makeatletter \providecommand{\Dprovidelength}[2]{% \begingroup% \escapechar\m@ne% @@ -34,15 +35,12 @@ {\newlength{#1}\setlength{#1}{#2}}% {}% } -\makeatother -\makeatletter \providecommand{\Dprovidecounter}[1]{% % Like \newcounter except that it doesn't crash if the counter % already exists. \@ifundefined{c@#1}{\newcounter{#1}}{} } -\makeatother \providecommand{\DSboxcommands}{ \Dprovidelength{\Dboxparindent}{\parindent} @@ -114,7 +112,6 @@ } } -\makeatletter \providecommand{\DSlinks}{ % Targets and references. \usepackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} @@ -201,14 +198,12 @@ \href{##1}{{\color{blue}##2}}% } } -\makeatother \providecommand{\DAclasses}[5]{% #5% } -\makeatletter \providecommand{\Dattr}[5]{% % Global attribute dispatcher. % Parameters: @@ -223,7 +218,6 @@ \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% }% } -\makeatother \providecommand{\DNparagraph}[1]{#1} \providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} @@ -267,7 +261,6 @@ } % Boolean variable. \providecommand{\Dhassubtitle}{} -\makeatother \providecommand{\DNtitle}[1]{% \ifthenelse{\equal{\Dparent}{topic}}{\Dtopictitle{#1}}{% \ifthenelse{\equal{\Dparent}{document}}{\Ddocumenttitle{#1}}{% @@ -355,7 +348,6 @@ \usepackage[latin1]{inputenc} \providecommand{\Dresetlistdepth}{false} -\makeatletter \providecommand{\Dmakelistenvironment}[3]{% % Make list environment with support for unlimited nesting and with % reasonable default lengths. Parameters: @@ -394,7 +386,7 @@ }% \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% } -\makeatother +\providecommand{\DAlastitem}[5]{#5\@finalstrut\@arstrutbox} \providecommand{\Dmakeenumeratedlist}[6]{% % Make enumerated list. @@ -762,3 +754,5 @@ \DSauxiliaryspace \DSparagraphs \DSlinks + +%\makeatother -- cgit v1.2.1 From a80c28dc5a92a783ab1bfec1be70da89fe158aa3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 00:11:35 +0000 Subject: added some indirection with \Dformat... git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3274 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 80b89e471..4e2a070b5 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -458,12 +458,15 @@ % label. \item[]#1% } -\providecommand{\DNterm}[1]{#1} +\providecommand{\Dformatterm}[1]{#1} +\providecommand{\DNterm}[1]{\Dformatterm{#1}} % I'm still not sure what's the best rendering for classifiers. The % colon syntax is used by reStructuredText, so it's at least WYSIWYG. % Use slanted text because italic would cause too much emphasis. -\providecommand{\DNclassifier}[1]{~:~\textsl{#1}} -\providecommand{\DNdefinition}[1]{\Dpar#1} +\providecommand{\Dformatclassifier}[1]{\textsl{#1}} +\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} +\providecommand{\Dformatdefinition}[1]{#1} +\providecommand{\DNdefinition}[1]{\Dpar\Dformatdefinition{#1}} \providecommand{\Dformatoptiongroup}[1]{% -- cgit v1.2.1 From 29686d0ea64c4790b23a689f7e1c67a93af6485b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 00:12:09 +0000 Subject: added --user-stylesheet; this will have to cleaned up, really; but for now, it's OK git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3275 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 5a6065b5a..4035ac610 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -41,7 +41,14 @@ class Writer(writers.Writer): 'directory. Overrides --stylesheet.', ['--stylesheet-path'], {'metavar': '<file>', 'overrides': 'stylesheet'}), - ),) + ('Specify a uesr stylesheet file. See --stylesheet.', + ['--user-stylesheet'], + {'default': '', 'metavar': '<file>', + 'overrides': 'user_stylesheet_path'}), + ('Specify a user stylesheet file. See --stylesheet-path.', + ['--user-stylesheet-path'], + {'metavar': '<file>', 'overrides': 'user_stylesheet'}) + ),) settings_defaults = {'output_encoding': 'latin-1', 'trim_footnote_reference_space': 1, @@ -172,9 +179,14 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.settings, os.path.join(os.getcwd(), 'dummy')) if self.stylesheet_path: self.settings.record_dependencies.add(self.stylesheet_path) - #self.stylesheet = open(stylesheet_path).read() - #else: - #self.stylesheet = '' + # This ugly hack will be cleaned up when refactoring the + # stylesheet mess. + self.settings.stylesheet = self.settings.user_stylesheet + self.settings.stylesheet_path = self.settings.user_stylesheet_path + self.user_stylesheet_path = utils.get_stylesheet_reference( + self.settings, os.path.join(os.getcwd(), 'dummy')) + if self.user_stylesheet_path: + self.settings.record_dependencies.add(self.user_stylesheet_path) self.write_header() for key, value in self.character_map.items(): self.character_map[key] = '{%s}' % value @@ -183,9 +195,12 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a = self.header.append a('%% Generated by Docutils %s <http://docutils.sourceforge.net>.\n' % docutils.__version__) - #a('% User stylesheet:\n') + if self.user_stylesheet_path: + a('% User stylesheet:') + a(r'\input{%s}' % self.user_stylesheet_path) + a('% Docutils stylesheet:') a(r'\input{%s}' % self.stylesheet_path) - #a('\n% End of user stylesheet.') + a('') a('% Definitions for Docutils Nodes:') for node_name in nodes.node_class_names: a(r'\providecommand{\DN%s}[1]{#1}' % node_name.replace('_', '')) -- cgit v1.2.1 From 4fcf4836929b04bcd10083a7200c0930ac858893 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 11:34:52 +0000 Subject: added Catalan language mappings; thanks to Ivan Vilata i Balaguer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3276 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/ca.py | 62 ++++++++++++++++++ docutils/parsers/rst/languages/ca.py | 119 +++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 docutils/languages/ca.py create mode 100644 docutils/parsers/rst/languages/ca.py diff --git a/docutils/languages/ca.py b/docutils/languages/ca.py new file mode 100644 index 000000000..069a853b3 --- /dev/null +++ b/docutils/languages/ca.py @@ -0,0 +1,62 @@ +# Author: Ivan Vilata i Balaguer +# Contact: ivan@selidor.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Catalan-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'Autor', + 'authors': u'Autors', + 'organization': u'Organitzaci\u00F3', + 'address': u'Adre\u00E7a', + 'contact': u'Contacte', + 'version': u'Versi\u00F3', + 'revision': u'Revisi\u00F3', + 'status': u'Estat', + 'date': u'Data', + 'copyright': u'Copyright', + 'dedication': u'Dedicat\u00F2ria', + 'abstract': u'Resum', + 'attention': u'Atenci\u00F3!', + 'caution': u'Compte!', + 'danger': u'PERILL!', + 'error': u'Error', + 'hint': u'Suggeriment', + 'important': u'Important', + 'note': u'Nota', + 'tip': u'Consell', + 'warning': u'Av\u00EDs', + 'contents': u'Contingut'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + u'autor': 'author', + u'autors': 'authors', + u'organitzaci\u00F3': 'organization', + u'adre\u00E7a': 'address', + u'contacte': 'contact', + u'versi\u00F3': 'version', + u'revisi\u00F3': 'revision', + u'estat': 'status', + u'data': 'date', + u'copyright': 'copyright', + u'dedicat\u00F2ria': 'dedication', + u'resum': 'abstract'} +"""Catalan (lowcased) to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/ca.py b/docutils/parsers/rst/languages/ca.py new file mode 100644 index 000000000..9fdce400d --- /dev/null +++ b/docutils/parsers/rst/languages/ca.py @@ -0,0 +1,119 @@ +# Author: Ivan Vilata i Balaguer +# Contact: ivan@selidor.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Catalan-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + u'atenci\u00F3': 'attention', + u'compte': 'caution', + u'perill': 'danger', + u'error': 'error', + u'suggeriment': 'hint', + u'important': 'important', + u'nota': 'note', + u'consell': 'tip', + u'av\u00EDs': 'warning', + u'advertiment': 'admonition', + u'nota-al-marge': 'sidebar', + u'nota-marge': 'sidebar', + u'tema': 'topic', + u'bloc-de-l\u00EDnies': 'line-block', + u'bloc-l\u00EDnies': 'line-block', + u'literal-analitzat': 'parsed-literal', + u'r\u00FAbrica': 'rubric', + u'ep\u00EDgraf': 'epigraph', + u'sumari': 'highlights', + u'cita-destacada': 'pull-quote', + u'compost': 'compound', + #'questions': 'questions', + u'taula': 'table', + u'taula-csv': 'csv-table', + u'taula-llista': 'list-table', + #'qa': 'questions', + #'faq': 'questions', + u'meta': 'meta', + #'imagemap': 'imagemap', + u'imatge': 'image', + u'figura': 'figure', + u'inclou': 'include', + u'incloure': 'include', + u'cru': 'raw', + u'reempla\u00E7a': 'replace', + u'reempla\u00E7ar': 'replace', + u'unicode': 'unicode', + u'classe': 'class', + u'rol': 'role', + u'contingut': 'contents', + u'numsec': 'sectnum', + u'numeraci\u00F3-de-seccions': 'sectnum', + u'numeraci\u00F3-seccions': 'sectnum', + u'cap\u00E7alera': 'header', + u'peu-de-p\u00E0gina': 'footer', + u'peu-p\u00E0gina': 'footer', + #'footnotes': 'footnotes', + #'citations': 'citations', + u'notes-amb-destinacions': 'target-notes', + u'notes-destinacions': 'target-notes', + u'directiva-de-prova-de-restructuredtext': 'restructuredtext-test-directive'} +"""Catalan name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + u'abreviatura': 'abbreviation', + u'abreviaci\u00F3': 'abbreviation', + u'abrev': 'abbreviation', + u'ab': 'abbreviation', + u'acr\u00F2nim': 'acronym', + u'ac': 'acronym', + u'\u00EDndex': 'index', + u'i': 'index', + u'sub\u00EDndex': 'subscript', + u'sub': 'subscript', + u'super\u00EDndex': 'superscript', + u'sup': 'superscript', + u'refer\u00E8ncia-a-t\u00EDtol': 'title-reference', + u'refer\u00E8ncia-t\u00EDtol': 'title-reference', + u't\u00EDtol': 'title-reference', + u't': 'title-reference', + u'refer\u00E8ncia-a-pep': 'pep-reference', + u'refer\u00E8ncia-pep': 'pep-reference', + u'pep': 'pep-reference', + u'refer\u00E8ncia-a-rfc': 'rfc-reference', + u'refer\u00E8ncia-rfc': 'rfc-reference', + u'rfc': 'rfc-reference', + u'\u00E8mfasi': 'emphasis', + u'destacat': 'strong', + u'literal': 'literal', + u'refer\u00E8ncia-amb-nom': 'named-reference', + u'refer\u00E8ncia-nom': 'named-reference', + u'refer\u00E8ncia-an\u00F2nima': 'anonymous-reference', + u'refer\u00E8ncia-a-nota-al-peu': 'footnote-reference', + u'refer\u00E8ncia-nota-al-peu': 'footnote-reference', + u'refer\u00E8ncia-a-cita': 'citation-reference', + u'refer\u00E8ncia-cita': 'citation-reference', + u'refer\u00E8ncia-a-substituci\u00F3': 'substitution-reference', + u'refer\u00E8ncia-substituci\u00F3': 'substitution-reference', + u'destinaci\u00F3': 'target', + u'refer\u00E8ncia-a-uri': 'uri-reference', + u'refer\u00E8ncia-uri': 'uri-reference', + u'uri': 'uri-reference', + u'url': 'uri-reference', + u'cru': 'raw',} +"""Mapping of Catalan role names to canonical role names for interpreted text. +""" -- cgit v1.2.1 From db457ece7560202b31912dbb7b06058dc2adb597 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 16:03:14 +0000 Subject: added assertion; simplified code (there is always a href) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3277 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index fc602cdbd..cfb088fcb 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -820,15 +820,12 @@ class HTMLTranslator(nodes.NodeVisitor): if format == 'brackets': suffix = '[' self.context.append(']') - elif format == 'superscript': + else: + assert format == 'superscript' suffix = '<sup>' self.context.append('</sup>') - else: # shouldn't happen - suffix = '???' - self.content.append('???') self.body.append(self.starttag(node, 'a', suffix, - CLASS='footnote-reference', - **(href and {'href': href} or {}))) + CLASS='footnote-reference', href=href)) def depart_footnote_reference(self, node): self.body.append(self.context.pop() + '</a>') -- cgit v1.2.1 From 0d1b85a3a1746ad160ab7b7853f905e71251a8ad Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 16:47:51 +0000 Subject: changed the LaTeX sidebar-test a bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3278 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/latex.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt index 31e57c85d..26c8319aa 100644 --- a/test/functional/input/data/latex.txt +++ b/test/functional/input/data/latex.txt @@ -61,12 +61,6 @@ text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. -This is some text. This is some text. This is some text. This is -some text. This is some text. This is some text. This is some text. -This is some text. This is some text. This is some text. This is -some text. This is some text. This is some text. This is some text. -This is some text. This is some text. This is some text. This is -some text. This is some text. Next Section @@ -79,6 +73,10 @@ some text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. This is +some text. This is some text. This is some text. This is some text. +This is some text. This is some text. This is some text. + Nested Elements --------------- -- cgit v1.2.1 From e85e00e626eafa6f7271f494ac521cf8fea63d3f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Apr 2005 16:51:33 +0000 Subject: renamed "dangerous" functional test to "restricted" so that it doesn't get in the way when tab-completing to input/data git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3279 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/dangerous.html | 66 -------------------------------- test/functional/expected/restricted.html | 66 ++++++++++++++++++++++++++++++++ test/functional/input/dangerous.txt | 16 -------- test/functional/input/restricted.txt | 16 ++++++++ test/functional/tests/dangerous.py | 12 ------ test/functional/tests/restricted.py | 12 ++++++ 6 files changed, 94 insertions(+), 94 deletions(-) delete mode 100644 test/functional/expected/dangerous.html create mode 100644 test/functional/expected/restricted.html delete mode 100644 test/functional/input/dangerous.txt create mode 100644 test/functional/input/restricted.txt delete mode 100644 test/functional/tests/dangerous.py create mode 100644 test/functional/tests/restricted.py diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html deleted file mode 100644 index 184417b5e..000000000 --- a/test/functional/expected/dangerous.html +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" /> -<title> - - - -
    -

    Potentially dangerous features (security holes):

    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 3)

    -

    "include" directive disabled.

    -
    -.. include:: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 4)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -   :file: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 6)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -   :url: file:///etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 8)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -
    -   <script>
    -       that does something really nasty
    -   </script>
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 13)

    -

    "csv-table" directive disabled.

    -
    -.. csv-table:: :file: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/dangerous.txt, line 14)

    -

    "csv-table" directive disabled.

    -
    -.. csv-table:: :url: file:///etc/passwd
    -
    -
    -
    -
    picture.png
    -
    -
    - - diff --git a/test/functional/expected/restricted.html b/test/functional/expected/restricted.html new file mode 100644 index 000000000..28c6bac7a --- /dev/null +++ b/test/functional/expected/restricted.html @@ -0,0 +1,66 @@ + + + + + + + + + + +
    +

    Potentially dangerous features (security holes):

    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 3)

    +

    "include" directive disabled.

    +
    +.. include:: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 4)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +   :file: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 6)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +   :url: file:///etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 8)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +
    +   <script>
    +       that does something really nasty
    +   </script>
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 13)

    +

    "csv-table" directive disabled.

    +
    +.. csv-table:: :file: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/restricted.txt, line 14)

    +

    "csv-table" directive disabled.

    +
    +.. csv-table:: :url: file:///etc/passwd
    +
    +
    +
    +
    picture.png
    +
    +
    + + diff --git a/test/functional/input/dangerous.txt b/test/functional/input/dangerous.txt deleted file mode 100644 index 8f75386c8..000000000 --- a/test/functional/input/dangerous.txt +++ /dev/null @@ -1,16 +0,0 @@ -Potentially dangerous features (security holes): - -.. include:: /etc/passwd -.. raw:: html - :file: /etc/passwd -.. raw:: html - :url: file:///etc/passwd -.. raw:: html - - -.. csv-table:: :file: /etc/passwd -.. csv-table:: :url: file:///etc/passwd -.. figure:: picture.png - :figwidth: image diff --git a/test/functional/input/restricted.txt b/test/functional/input/restricted.txt new file mode 100644 index 000000000..8f75386c8 --- /dev/null +++ b/test/functional/input/restricted.txt @@ -0,0 +1,16 @@ +Potentially dangerous features (security holes): + +.. include:: /etc/passwd +.. raw:: html + :file: /etc/passwd +.. raw:: html + :url: file:///etc/passwd +.. raw:: html + + +.. csv-table:: :file: /etc/passwd +.. csv-table:: :url: file:///etc/passwd +.. figure:: picture.png + :figwidth: image diff --git a/test/functional/tests/dangerous.py b/test/functional/tests/dangerous.py deleted file mode 100644 index 620a927ba..000000000 --- a/test/functional/tests/dangerous.py +++ /dev/null @@ -1,12 +0,0 @@ -# Source and destination file names. -test_source = "dangerous.txt" -test_destination = "dangerous.html" - -# Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" -writer_name = "html" - -# Settings -settings_overrides['file_insertion_enabled'] = 0 -settings_overrides['raw_enabled'] = 0 diff --git a/test/functional/tests/restricted.py b/test/functional/tests/restricted.py new file mode 100644 index 000000000..375e884e8 --- /dev/null +++ b/test/functional/tests/restricted.py @@ -0,0 +1,12 @@ +# Source and destination file names. +test_source = "restricted.txt" +test_destination = "restricted.html" + +# Keyword parameters passed to publish_file. +reader_name = "standalone" +parser_name = "rst" +writer_name = "html" + +# Settings +settings_overrides['file_insertion_enabled'] = 0 +settings_overrides['raw_enabled'] = 0 -- cgit v1.2.1 From 9d4a0714283832fade9e10836cb68032215ee36c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 30 Apr 2005 16:54:47 +0000 Subject: make lists more deeply nestable by not adding right margin if there is not enough space git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3280 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 4e2a070b5..85c66cdbf 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -409,14 +409,21 @@ % 1. First item. \setlength{\leftmargin}{2.5em}% % Equal margins. - \setlength{\rightmargin}{\leftmargin}% + \ifthenelse{\lengthtest{\linewidth>10em}}{% + \setlength{\rightmargin}{\leftmargin}% + }{% + % If the line is narrower than 10em, we don't remove any further + % space from the right. + \setlength{\rightmargin}{0pt}% + }% % Use counter recommended by Python module. \usecounter{#4}% % Set start value. \addtocounter{#4}{#5}% }{% % The list contents. - #6}% + #6% + }% } @@ -758,4 +765,4 @@ \DSparagraphs \DSlinks -%\makeatother +\makeatother -- cgit v1.2.1 From e85b3c129bcd49f6a911c61f55f7199dd6c79027 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 2 May 2005 03:58:51 +0000 Subject: corrected ``line`` superclass git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3281 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 33c93e42a..5a8cd7c55 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1192,7 +1192,7 @@ class doctest_block(General, FixedTextElement): pass class line_block(General, Element): pass -class line(General, TextElement): +class line(Part, TextElement): indent = None -- cgit v1.2.1 From df05185ff0a8c586230c827b46a1cf43544c65fa Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 2 May 2005 03:59:11 +0000 Subject: added ``line`` element; corrected ``line_block`` details git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3282 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 163 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 114 insertions(+), 49 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 2ae37b9f5..f432ed1f6 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -161,9 +161,8 @@ Simple body elements are empty or directly contain text data. Those that contain text data may also contain inline elements. Such elements therefore have a "mixed content model". -Category members: comment_, doctest_block_, image_, line_block_, -literal_block_, paragraph_, pending_, raw_, rubric_, -substitution_definition_, target_ +Category members: comment_, doctest_block_, image_, literal_block_, +paragraph_, pending_, raw_, rubric_, substitution_definition_, target_ Compound Body Elements @@ -175,8 +174,8 @@ and further body elements. They do not directly contain text data. Category members: admonition_, attention_, block_quote_, bullet_list_, caution_, citation_, compound_, danger_, definition_list_, enumerated_list_, error_, field_list_, figure_, footnote_, hint_, -important_, note_, option_list_, system_message_, table_, tip_, -warning_ +important_, line_block, note_, option_list_, system_message_, table_, +tip_, warning_ Body Subelements @@ -190,7 +189,8 @@ always occur within specific parent elements, never at the body element level (beside paragraphs, etc.). Category members (simple): attribution_, caption_, classifier_, -colspec_, field_name_, label_, option_argument_, option_string_, term_ +colspec_, field_name_, label_, line_, option_argument_, +option_string_, term_ Category members (compound): definition_, definition_list_item_, description_, entry_, field_, field_body_, legend_, list_item_, @@ -305,7 +305,8 @@ its writing. The ``address`` element holds the surface mailing address information for the author (individual or group) of the document, or a third-party contact address. Its structure is identical to that of the -line_block_ element: whitespace is significant, especially newlines. +literal_block_ element: whitespace is significant, especially +newlines. Details @@ -324,9 +325,9 @@ Details ``address`` is analogous to the DocBook "address" element. :Processing: - As with the line_block_ element, newlines and other whitespace is - significant and must be preserved. However, a monospaced typeface - need not be used. + As with the literal_block_ element, newlines and other whitespace + is significant and must be preserved. However, a monospaced + typeface need not be used. See also docinfo_. @@ -2538,21 +2539,67 @@ Pseudo-XML_ fragment from simple parsing:: `To be completed`_. +``line`` +======== + +The ``line`` element contains a single line of text, part of a +`line_block`_. + + +Details +------- + +:Category: + `Body Subelements`_ (simple) + +:Parents: + Only the `line_block`_ element contains ``line``. + +:Children: + ``line`` elements may contain text data plus `inline elements`_. + +:Analogues: + ``line`` has no direct analogues in common DTDs. It can be + emulated with primitives or type effects. + +:Processing: + See `line_block`_. + + +Content Model +------------- + +.. parsed-literal:: + + `%text.model;`_ + +:Attributes: + The ``line`` element contains the `common attributes`_ (id_, + name_, dupname_, source_, and class_), plus `xml:space`_. + + +Examples +-------- + +See `line_block`_. + + ``line_block`` ============== -The ``line_block`` element contains a block of text where line breaks -and whitespace are significant and must be preserved. ``line_block`` -elements are commonly used for verse and addresses. See `line_block`_ -for an alternative useful for program listings and interactive -computer sessions. +The ``line_block`` element contains a sequence of lines and nested +line blocks. Line breaks (implied between elements) and leading +whitespace (indicated by nesting) is significant and must be +preserved. ``line_block`` elements are commonly used for verse and +addresses. See `literal_block`_ for an alternative useful for program +listings and interactive computer sessions. Details ------- :Category: - `Simple Body Elements`_ + `Compound Body Elements`_ :Parents: All elements employing the `%body.elements;`_ or @@ -2560,8 +2607,8 @@ Details may contain ``line_block``. :Children: - ``line_block`` elements may contain text data plus `inline - elements`_. + ``line_block`` elements may contain line_ elements and nested + ``line_block`` elements. :Analogues: ``line_block`` is analogous to the DocBook "literallayout" element @@ -2570,7 +2617,7 @@ Details :Processing: Unline ``literal_block``, ``line_block`` elements are typically - rendered in an ordinary text typeface. It is crucial that all + rendered in an ordinary text typeface. It is crucial that leading whitespace and line breaks are preserved in the rendered form. @@ -2579,7 +2626,7 @@ Content Model .. parsed-literal:: - `%text.model;`_ + (line_ | line_block_)+ :Attributes: The ``line_block`` element contains the `common attributes`_ (id_, @@ -2599,40 +2646,58 @@ Example source:: Take it away, Eric the Orchestra Leader! - .. line-block:: - - A one, two, a one two three four - - Half a bee, philosophically, - must, *ipso facto*, half not be. - But half the bee has got to be, - *vis a vis* its entity. D'you see? - - But can a bee be said to be - or not to be an entire bee, - when half the bee is not a bee, - due to some ancient injury? - - Singing... + | A one, two, a one two three four + | + | Half a bee, philosophically, + | must, *ipso facto*, half not be. + | But half the bee has got to be, + | *vis a vis* its entity. D'you see? + | + | But can a bee be said to be + | or not to be an entire bee, + | when half the bee is not a bee, + | due to some ancient injury? + | + | Singing... Pseudo-XML_ fragment from simple parsing:: Take it away, Eric the Orchestra Leader! - - A one, two, a one two three four - - Half a bee, philosophically, - must, ipso facto, half not be. - But half the bee has got to be, - vis a visits entity. D'you see? - - But can a bee be said to be - or not to be an entire bee, - when half the bee is not a bee, - due to some ancient injury? - - Singing... + + + A one, two, a one two three four + + + Half a bee, philosophically, + + + must, + + ipso facto + , half not be. + + But half the bee has got to be, + + + + vis a vis + its entity. D'you see? + + + But can a bee be said to be + + + or not to be an entire bee, + + + when half the bee is not a bee, + + + due to some ancient injury? + + + Singing... ``list_item`` -- cgit v1.2.1 From abecd9557393b8a49965f04edad866b950feb338 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 2 May 2005 14:59:57 +0000 Subject: added motivation for unresolved charset git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3283 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/api/publisher.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index 66aaa06fb..79bac6202 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -132,8 +132,9 @@ html_body html_head ``parts['html_head']`` contains the HTML ```` content, less the stylesheet link and the ```` and ```` tags - themselves. The "Content-Type" meta tag's "charset" value is left - unresolved, as "%s":: + themselves. Since ``publish_parts`` returns Unicode strings and + does not know about the output encoding, the "Content-Type" meta + tag's "charset" value is left unresolved, as "%s":: -- cgit v1.2.1 From c20e1f296491ce90133eb1dddfe6f504ee9db26c Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 3 May 2005 00:46:17 +0000 Subject: simplification & added test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3284 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index cfb088fcb..5130bf1d4 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -118,10 +118,9 @@ class Writer(writers.Writer): self.translator_class = HTMLTranslator def translate(self): - visitor = self.translator_class(self.document) + self.visitor = visitor = self.translator_class(self.document) self.document.walkabout(visitor) self.output = visitor.astext() - self.visitor = visitor for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix', 'body_pre_docinfo', 'docinfo', 'body', 'fragment', 'body_suffix'): @@ -1347,6 +1346,7 @@ class HTMLTranslator(nodes.NodeVisitor): check_id = 1 close_tag = '\n' elif self.section_level == 0: + assert node.parent is self.document # document title self.head.append('%s\n' % self.encode(node.astext())) -- cgit v1.2.1 From 09e24efaea8da760f29674aa89883d6aa54a94b7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 11:12:11 +0000 Subject: reverted r3279 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3285 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/dangerous.html | 66 ++++++++++++++++++++++++++++++++ test/functional/expected/restricted.html | 66 -------------------------------- test/functional/input/dangerous.txt | 16 ++++++++ test/functional/input/restricted.txt | 16 -------- test/functional/tests/dangerous.py | 12 ++++++ test/functional/tests/restricted.py | 12 ------ 6 files changed, 94 insertions(+), 94 deletions(-) create mode 100644 test/functional/expected/dangerous.html delete mode 100644 test/functional/expected/restricted.html create mode 100644 test/functional/input/dangerous.txt delete mode 100644 test/functional/input/restricted.txt create mode 100644 test/functional/tests/dangerous.py delete mode 100644 test/functional/tests/restricted.py diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html new file mode 100644 index 000000000..184417b5e --- /dev/null +++ b/test/functional/expected/dangerous.html @@ -0,0 +1,66 @@ + + + + + + + + + + +
    +

    Potentially dangerous features (security holes):

    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 3)

    +

    "include" directive disabled.

    +
    +.. include:: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 4)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +   :file: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 6)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +   :url: file:///etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 8)

    +

    "raw" directive disabled.

    +
    +.. raw:: html
    +
    +   <script>
    +       that does something really nasty
    +   </script>
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 13)

    +

    "csv-table" directive disabled.

    +
    +.. csv-table:: :file: /etc/passwd
    +
    +
    +
    +

    System Message: WARNING/2 (functional/input/dangerous.txt, line 14)

    +

    "csv-table" directive disabled.

    +
    +.. csv-table:: :url: file:///etc/passwd
    +
    +
    +
    +
    picture.png
    +
    +
    + + diff --git a/test/functional/expected/restricted.html b/test/functional/expected/restricted.html deleted file mode 100644 index 28c6bac7a..000000000 --- a/test/functional/expected/restricted.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - -
    -

    Potentially dangerous features (security holes):

    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 3)

    -

    "include" directive disabled.

    -
    -.. include:: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 4)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -   :file: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 6)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -   :url: file:///etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 8)

    -

    "raw" directive disabled.

    -
    -.. raw:: html
    -
    -   <script>
    -       that does something really nasty
    -   </script>
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 13)

    -

    "csv-table" directive disabled.

    -
    -.. csv-table:: :file: /etc/passwd
    -
    -
    -
    -

    System Message: WARNING/2 (functional/input/restricted.txt, line 14)

    -

    "csv-table" directive disabled.

    -
    -.. csv-table:: :url: file:///etc/passwd
    -
    -
    -
    -
    picture.png
    -
    -
    - - diff --git a/test/functional/input/dangerous.txt b/test/functional/input/dangerous.txt new file mode 100644 index 000000000..8f75386c8 --- /dev/null +++ b/test/functional/input/dangerous.txt @@ -0,0 +1,16 @@ +Potentially dangerous features (security holes): + +.. include:: /etc/passwd +.. raw:: html + :file: /etc/passwd +.. raw:: html + :url: file:///etc/passwd +.. raw:: html + + +.. csv-table:: :file: /etc/passwd +.. csv-table:: :url: file:///etc/passwd +.. figure:: picture.png + :figwidth: image diff --git a/test/functional/input/restricted.txt b/test/functional/input/restricted.txt deleted file mode 100644 index 8f75386c8..000000000 --- a/test/functional/input/restricted.txt +++ /dev/null @@ -1,16 +0,0 @@ -Potentially dangerous features (security holes): - -.. include:: /etc/passwd -.. raw:: html - :file: /etc/passwd -.. raw:: html - :url: file:///etc/passwd -.. raw:: html - - -.. csv-table:: :file: /etc/passwd -.. csv-table:: :url: file:///etc/passwd -.. figure:: picture.png - :figwidth: image diff --git a/test/functional/tests/dangerous.py b/test/functional/tests/dangerous.py new file mode 100644 index 000000000..620a927ba --- /dev/null +++ b/test/functional/tests/dangerous.py @@ -0,0 +1,12 @@ +# Source and destination file names. +test_source = "dangerous.txt" +test_destination = "dangerous.html" + +# Keyword parameters passed to publish_file. +reader_name = "standalone" +parser_name = "rst" +writer_name = "html" + +# Settings +settings_overrides['file_insertion_enabled'] = 0 +settings_overrides['raw_enabled'] = 0 diff --git a/test/functional/tests/restricted.py b/test/functional/tests/restricted.py deleted file mode 100644 index 375e884e8..000000000 --- a/test/functional/tests/restricted.py +++ /dev/null @@ -1,12 +0,0 @@ -# Source and destination file names. -test_source = "restricted.txt" -test_destination = "restricted.html" - -# Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" -writer_name = "html" - -# Settings -settings_overrides['file_insertion_enabled'] = 0 -settings_overrides['raw_enabled'] = 0 -- cgit v1.2.1 From 833e24efa66cff58dc0b9ca427b44053d1b4228f Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 15:19:41 +0000 Subject: added comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3286 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 4035ac610..2ad9aad6f 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -438,6 +438,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def visit_enumerated_list(self, node): # We create our own enumeration list environment. This allows # to set the style and starting value and unlimited nesting. + # Maybe this can be moved to the stylesheet? self.enum_counter += 1 enum_prefix = self.encode(node['prefix']) enum_suffix = self.encode(node['suffix']) -- cgit v1.2.1 From b44e0f1151201dfa37ccc11753e37ab3fe342ccc Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 19:19:35 +0000 Subject: do not enclose document and sections in macro calls, so that TeX does not run out of memory when processing large documents git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3287 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 30 ++++++++++++++++++++++++------ tools/stylesheets/latex.tex | 11 ++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 2ad9aad6f..559f866ba 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -588,21 +588,28 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if isinstance(node, nodes.Element): attlist = node.attlist() numatts = 0 + pass_contents = self.pass_contents(node) for key, value in attlist: if isinstance(value, ListType): self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) for i in range(len(value)): self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % (i+1, key, self.encode(value[i], attval=1), - node_name)) # for Emacs: } + node_name)) + if not pass_contents: + self.append('}') numatts += len(value) else: self.append(r'\Dattr{}{%s}{%s}{%s}{' % (key, self.encode(unicode(value), attval=1), node_name)) - # for Emacs: } + if not pass_contents: + self.append('}') numatts += 1 - self.context.append('}' * numatts) # for Emacs: { + if pass_contents: + self.context.append('}' * numatts) # for Emacs: { + else: + self.context.append('') def visit_docinfo(self, node): raise NotImplementedError('Docinfo not yet implemented.') @@ -620,6 +627,13 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): next_text_element['ids'].extend(node['ids']) node['ids'] = [] + def pass_contents(self, node): + r""" + Return true if the node contents should be passed in + parameters of \DN... and \Dattr. + """ + return not isinstance(node, (nodes.document, nodes.section)) + def dispatch_visit(self, node): skip_attr = skip_parent = 0 # TreePruningException to be propagated. @@ -642,11 +656,15 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if not isinstance(node, nodes.Text): node_name = self.node_name(node) - if not skip_parent: + if not skip_parent and not isinstance(node, nodes.document): self.append(r'\renewcommand{\Dparent}{%s}' % self.node_name(node.parent)) - self.append(r'\DN%s{' % node_name) - self.context.append('}') + if self.pass_contents(node): + self.append(r'\DN%s{' % node_name) + self.context.append('}') + else: + self.append(r'\Dvisit%s' % node_name) + self.context.append(r'\Ddepart%s' % node_name) self.indentation_level += 1 if not skip_attr: self.propagate_attributes(node) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 85c66cdbf..0cc4d9ac7 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -307,12 +307,8 @@ \providecommand{\DNliteral}[1]{\textnhtt{#1}} \providecommand{\DNemphasis}[1]{\emph{#1}} \providecommand{\DNstrong}[1]{\textbf{#1}} -\providecommand{\DNdocument}[1]{% - \begin{document}% - \noindent% - #1% - \end{document}% -} +\providecommand{\Dvisitdocument}{\begin{document}\noindent} +\providecommand{\Ddepartdocument}{\end{document}} \providecommand{\DNtopic}[1]{% \par% \Dmakebox{% @@ -332,7 +328,8 @@ \providecommand{\DNlistitem}[1]{\item{#1}} \providecommand{\DNenumeratedlist}[1]{#1} \newcounter{Dsectionlevel} -\providecommand{\DNsection}[1]{\addtocounter{Dsectionlevel}{1}#1\addtocounter{Dsectionlevel}{-1}} +\providecommand{\Dvisitsection}{\addtocounter{Dsectionlevel}{1}} +\providecommand{\Ddepartsection}{\addtocounter{Dsectionlevel}{-1}} % Using \_ will cause hyphenation after _ even in \textnhtt-typewriter % because the hyphenat package redefines \_. So we use -- cgit v1.2.1 From 36e258db356cbc21e35145d5e261451b06d87bbf Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 20:42:45 +0000 Subject: improved handling of long field names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3288 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 0cc4d9ac7..c2a5c935d 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -450,7 +450,18 @@ \providecommand{\DNfieldlist}[1]{% \Dtwocolumntable{#1}% } -\providecommand{\DNfieldname}[1]{\Dformatfieldname{#1}&} +\Dprovidelength{\Dmaxfieldnamewidth}{8em}% +\Dprovidelength{\Dplaceholderfieldnamewidth}{2em}% +\Dprovidelength{\Dfieldnamewidth}{0pt}% +\providecommand{\DNfieldname}[1]{% + \settowidth{\Dfieldnamewidth}{\Dformatfieldname{#1}}% + \ifthenelse{\lengthtest{\Dfieldnamewidth>\Dmaxfieldnamewidth}}{% + \makebox[\Dplaceholderfieldnamewidth][l]{\Dformatfieldname{#1}}% + &\tabularnewline~&% + }{% + \Dformatfieldname{#1}&% + }% +} \providecommand{\DNfieldbody}[1]{#1\tabularnewline} -- cgit v1.2.1 From 6d8862ef570ba2c926736ec51da032b0b6b8cddf Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 20:48:15 +0000 Subject: added thin space to unicode translation table git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3289 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 559f866ba..5517da6ec 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -286,6 +286,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): unicode_map = { u'\u00A0': '~', + u'\u2009': '{\\,}', u'\u2013': '{--}', u'\u2014': '{---}', u'\u2018': '`', -- cgit v1.2.1 From a84afc620339bd79b193abb45e580f7c4188c399 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 21:17:18 +0000 Subject: changed config file section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3290 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 5517da6ec..e91dfc61c 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -59,7 +59,7 @@ class Writer(writers.Writer): relative_path_settings = ('stylesheet_path',) - config_section = 'latex2e writer' + config_section = 'newlatex2e writer' config_section_dependencies = ('writers',) output = None -- cgit v1.2.1 From 2a36a20ee7e5d733809a5ef32f12e6b46586e47f Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 21:34:01 +0000 Subject: made auxiliary spacing more flexible git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3291 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c2a5c935d..68daf3fef 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -83,13 +83,20 @@ % Space between block-level elements other than paragraphs. 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% } - \providecommand{\Dauxiliaryspace}{% + \providecommand{\Dnextauxiliaryspace}{% \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \Dpar\noindent% + } + \providecommand{\Dvspace}{% + \Dnextauxiliaryspace% + \renewcommand{\Dnextauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + }% + }% + \providecommand{\Dauxiliaryspace}{% + \Dvspace\Dpar\noindent% } \providecommand{\Dauxiliaryparspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \Dpar% + \Dvspace\Dpar% } \providecommand{\Dparagraphspace}{\Dpar} \providecommand{\Dneedvspace}{true} @@ -457,7 +464,7 @@ \settowidth{\Dfieldnamewidth}{\Dformatfieldname{#1}}% \ifthenelse{\lengthtest{\Dfieldnamewidth>\Dmaxfieldnamewidth}}{% \makebox[\Dplaceholderfieldnamewidth][l]{\Dformatfieldname{#1}}% - &\tabularnewline~&% + &\tabularnewline&% }{% \Dformatfieldname{#1}&% }% -- cgit v1.2.1 From 2dda62ea39b5ad7ad7f063a1843f55ebb996bf07 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 21:42:46 +0000 Subject: removed additional flexibility; probably not needed, on second thought git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3292 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 68daf3fef..44bb91251 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -83,20 +83,13 @@ % Space between block-level elements other than paragraphs. 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% } - \providecommand{\Dnextauxiliaryspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - } - \providecommand{\Dvspace}{% - \Dnextauxiliaryspace% - \renewcommand{\Dnextauxiliaryspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - }% - }% \providecommand{\Dauxiliaryspace}{% - \Dvspace\Dpar\noindent% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \Dpar\noindent% } \providecommand{\Dauxiliaryparspace}{% - \Dvspace\Dpar% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \Dpar% } \providecommand{\Dparagraphspace}{\Dpar} \providecommand{\Dneedvspace}{true} -- cgit v1.2.1 From 2f72811e55a880663a944f366b997a2b6267dbda Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 3 May 2005 22:09:49 +0000 Subject: changed rubric formatting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3293 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 44bb91251..8dbf39ab0 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -318,8 +318,10 @@ #1% }% } -\providecommand{\Dformatrubric}[1]{{\large\textbf{#1}}} -\providecommand{\DNrubric}[1]{\begin{center}\Dformatrubric{#1}\end{center}} +\providecommand{\Dformatrubric}[1]{\textbf{#1}} +\providecommand{\DNrubric}[1]{% + \vspace{0.3em}\Dpar\noindent\Dformatrubric{#1}\Dpar\noindent% +} \providecommand{\Dbullet}{} \providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} -- cgit v1.2.1 From c733dd5af03c81fd76e96a49a0514a87009a0ef6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 11:40:49 +0000 Subject: made curly-bracket-grouping in raw nodes work git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3294 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index e91dfc61c..38dda3d50 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -462,8 +462,11 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): before_line = before_list_item - def visit_raw(self, node): + def before_raw(self, node): if 'latex' in node.get('format', '').split(): + # We're inserting the text in before_raw and thus outside + # of \DN... and \Dattr in order to make grouping with + # curly brackets work. self.append(node.astext()) raise nodes.SkipChildren -- cgit v1.2.1 From b9b8decff0e4249760af913eeb1f7f6f27027fea Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 12:32:29 +0000 Subject: made Dblocklevelvspace a length; need to come up with a shorter name git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3295 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 8dbf39ab0..f382f3f10 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -79,7 +79,7 @@ \providecommand{\DSauxiliaryspace}{ - \providecommand{\Dblocklevelvspace}{% + \Dprovidelength{\Dblocklevelvspace}{% % Space between block-level elements other than paragraphs. 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% } -- cgit v1.2.1 From ed9ab8fe5dd2e4561ea6bee7620a6c471871ef08 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 12:33:35 +0000 Subject: added note about standard-TeX compatibility git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3296 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex-notes.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt index a3bd3720c..ce085024d 100644 --- a/tools/stylesheets/latex-notes.txt +++ b/tools/stylesheets/latex-notes.txt @@ -14,3 +14,24 @@ Regarding UTF-8: > missing or misnamed character in the UCS database. Long field lists with ltxtable? + + +:: + + 3.1.6. How can I make a document portable to both latex and pdflatex + Contributed by: Christian Kumpf + Check for the existence of the variable \pdfoutput: + \newif\ifpdf + \ifx\pdfoutput\undefined + \pdffalse % we are not running PDFLaTeX + \else + \pdfoutput=1 % we are running PDFLaTeX + \pdftrue + \fi + Then use your new variable \ifpdf + \ifpdf + \usepackage[pdftex]{graphicx} + \pdfcompresslevel=9 + \else + \usepackage{graphicx} + \fi -- cgit v1.2.1 From a32ff20498076981eecc28ea34decb06090e2f56 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 12:59:45 +0000 Subject: added early and late initialization macros for usage by user stylesheet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3297 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index f382f3f10..c6ea7be89 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -1,10 +1,14 @@ \makeatletter +\providecommand{\DSearly}{} +\providecommand{\DSlate}{} + \providecommand{\Ddocumentclass}{scrartcl} \providecommand{\Ddocumentoptions}{a4paper} \documentclass[\Ddocumentoptions]{\Ddocumentclass} +\DSearly \providecommand{\DSpackages}{% % All kinds of useful packages. @@ -774,5 +778,6 @@ \DSauxiliaryspace \DSparagraphs \DSlinks +\DSlate \makeatother -- cgit v1.2.1 From 02a8d309eecaffa41c0e6792f5b9490a8278650f Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 16:19:58 +0000 Subject: added raw node to list of invisible nodes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3298 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 38dda3d50..2622c54ad 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -696,7 +696,11 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # rendering. return (isinstance(node, nodes.Invisible) or isinstance(node, nodes.footnote) or - isinstance(node, nodes.citation)) + isinstance(node, nodes.citation) or + # We never know what's inside raw nodes, and often + # they *are* invisible. So let's have the user take + # care of them. + isinstance(node, nodes.raw)) def needs_space(self, node): # Return true if node is a visible block-level element. -- cgit v1.2.1 From 1215ece6bd5e66640245bd0dba2953207ea85845 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 18:39:35 +0000 Subject: made section handling a bit more flexible; added \Dprerubricspace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3299 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c6ea7be89..1596ae291 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -246,10 +246,10 @@ \begin{center}{\huge#1}\end{center}% \vspace{1cm}% } -\providecommand{\Dsectiontitle}[1]{\section*{#1}} -\providecommand{\Dsubsectiontitle}[1]{\subsection*{#1}} -\providecommand{\Dsubsubsectiontitle}[1]{\subsubsection*{#1}} -\providecommand{\Dsubsubsubsectiontitle}[1]{% +\providecommand{\Dsectiontitlei}[1]{\section*{#1}} +\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} +\providecommand{\Dsectiontitleiii}[1]{\subsubsection*{#1}} +\providecommand{\Dsectiontitleiv}[1]{% \par\textbf{\vspace{1.5em}#1\vspace{1em}}} \providecommand{\Dmakesectiontitletext}[1]{% % Return text suitable for use in \section*, \subsection*, etc. @@ -257,11 +257,13 @@ \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% #1% } +% Can be overwritten by user stylesheet. +\providecommand{\Dsectiontitle}[1]{\Ddispatchsectiontitle{#1}} \providecommand{\Ddispatchsectiontitle}[1]{% - \ifthenelse{\value{Dsectionlevel}=1}{\Dsectiontitle{#1}}{}% - \ifthenelse{\value{Dsectionlevel}=2}{\Dsubsectiontitle{#1}}{}% - \ifthenelse{\value{Dsectionlevel}=3}{\Dsubsubsectiontitle{#1}}{}% - \ifthenelse{\value{Dsectionlevel}>3}{\Dsubsubsubsectiontitle{#1}}{}% + \ifthenelse{\value{Dsectionlevel}=1}{\Dsectiontitlei{#1}}{}% + \ifthenelse{\value{Dsectionlevel}=2}{\Dsectiontitleii{#1}}{}% + \ifthenelse{\value{Dsectionlevel}=3}{\Dsectiontitleiii{#1}}{}% + \ifthenelse{\value{Dsectionlevel}>3}{\Dsectiontitleiv{#1}}{}% } % Boolean variable. \providecommand{\Dhassubtitle}{} @@ -269,7 +271,7 @@ \ifthenelse{\equal{\Dparent}{topic}}{\Dtopictitle{#1}}{% \ifthenelse{\equal{\Dparent}{document}}{\Ddocumenttitle{#1}}{% \ifthenelse{\equal{\Dparent}{section}}{% - \Ddispatchsectiontitle{\Dmakesectiontitletext{#1}}% + \Dsectiontitle{\Dmakesectiontitletext{#1}}% }{% \ifthenelse{\equal{\Dparent}{sidebar}}{\Dsidebartitle{#1}}{}% }% @@ -323,8 +325,9 @@ }% } \providecommand{\Dformatrubric}[1]{\textbf{#1}} +\Dprovidelength{\Dprerubricspace}{0.3em} \providecommand{\DNrubric}[1]{% - \vspace{0.3em}\Dpar\noindent\Dformatrubric{#1}\Dpar\noindent% + \vspace{\Dprerubricspace}\Dpar\noindent\Dformatrubric{#1}\Dpar\noindent% } \providecommand{\Dbullet}{} @@ -334,8 +337,16 @@ \providecommand{\DNlistitem}[1]{\item{#1}} \providecommand{\DNenumeratedlist}[1]{#1} \newcounter{Dsectionlevel} -\providecommand{\Dvisitsection}{\addtocounter{Dsectionlevel}{1}} -\providecommand{\Ddepartsection}{\addtocounter{Dsectionlevel}{-1}} +\providecommand{\Dvisitsectionhook}{} +\providecommand{\Ddepartsectionhook}{} +\providecommand{\Dvisitsection}{% + \addtocounter{Dsectionlevel}{1}% + \Dvisitsectionhook% +} +\providecommand{\Ddepartsection}{% + \Ddepartsectionhook% + \addtocounter{Dsectionlevel}{-1}% +} % Using \_ will cause hyphenation after _ even in \textnhtt-typewriter % because the hyphenat package redefines \_. So we use -- cgit v1.2.1 From 235937dbdb0f7aa97e4705a88e03045012e8472c Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 4 May 2005 20:28:28 +0000 Subject: moved \DSearly down; moved definition lists down; rewrote implementation for field lists and option lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3300 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 152 +++++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 58 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 1596ae291..b2422f6d4 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -1,15 +1,5 @@ \makeatletter -\providecommand{\DSearly}{} -\providecommand{\DSlate}{} - -\providecommand{\Ddocumentclass}{scrartcl} -\providecommand{\Ddocumentoptions}{a4paper} - -\documentclass[\Ddocumentoptions]{\Ddocumentclass} - -\DSearly - \providecommand{\DSpackages}{% % All kinds of useful packages. \usepackage{ifthen} @@ -204,6 +194,17 @@ } +\providecommand{\DSearly}{} +\providecommand{\DSlate}{} + +\providecommand{\Ddocumentclass}{scrartcl} +\providecommand{\Ddocumentoptions}{a4paper} + +\documentclass[\Ddocumentoptions]{\Ddocumentclass} + +\DSearly + + \providecommand{\DAclasses}[5]{% #5% } @@ -449,57 +450,74 @@ % single curly quote here. \providecommand{\Dtextliteralsinglequote}{'} - +\usepackage{tabularx} +% "Tabular lists" are field lists and options lists (not definition +% lists because there the term always appears on its own line). We'll +% use the terminology of field lists now ("field", "field name", +% "field body"), but the same is also analogously applicable to option +% lists. +% +% We want these lists to be breakable across pages. We cannot +% automatically get the narrowest possible size for the left column +% (i.e. the field names or option groups) because tabularx does not +% support multi-page tables, ltxtable needs to have the table in an +% external file and we don't want to clutter the user's directories +% with auxiliary files created by the filecontents environment, and +% ltablex is not included in teTeX. +% +% Thus we set a fixed length for the left column and use list +% environments. This also has the nice side effect that breaking is +% now possible anywhere, not just between fields. +% +% Note that we are creating a distinct list environment for each +% field. There is no macro for a whole tabular list! +\Dprovidelength{\Dtabularlistfieldnamewidth}{6em} +\Dprovidelength{\Dtabularlistfieldnamesep}{0.5em} \providecommand{\Dinsidetabular}{false} -\providecommand{\Dtwocolumntable}[1]{% - % Create a simple borderless two-column table, the right column of - % which has a variable width. +\providecommand{\Dsavefieldname}{} +\providecommand{\Dsavefieldbody}{} +\Dprovidelength{\Dusedfieldnamewidth}{0pt} +\Dprovidelength{\Drealfieldnamewidth}{0pt} +\providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}} +\providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}} +\providecommand{\Dtabularlistfield}[1]{% {% - \protect\renewcommand{\Dinsidetabular}{true}% - \begin{tabularx}{\linewidth}{@{}lX@{}}% - #1% - \end{tabularx}% + % This only saves field name and field body in \Dsavefieldname and + % \Dsavefieldbody, resp. It does not insert any text into the + % document. + #1% + % Recalculate the real field name width everytime we encounter a + % tabular list field because it may have been changed using a + % "raw" node. + \setlength{\Drealfieldnamewidth}{\Dtabularlistfieldnamewidth}% + \addtolength{\Drealfieldnamewidth}{\Dtabularlistfieldnamesep}% + \Dmakelistenvironment{% + \makebox[\Drealfieldnamewidth][l]{\Dsavefieldname}% + }{% + \setlength{\labelwidth}{\Drealfieldnamewidth}% + \setlength{\leftmargin}{\Drealfieldnamewidth}% + \setlength{\rightmargin}{0pt}% + \setlength{\labelsep}{0pt}% + }{% + \item% + \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}% + \ifthenelse{% + \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% + }{~\newline}{}% + \Dsavefieldbody% + }% }% } -\usepackage{tabularx} \providecommand{\Dformatfieldname}[1]{\bfseries{#1:}} -\providecommand{\DNfieldlist}[1]{% - \Dtwocolumntable{#1}% -} -\Dprovidelength{\Dmaxfieldnamewidth}{8em}% -\Dprovidelength{\Dplaceholderfieldnamewidth}{2em}% -\Dprovidelength{\Dfieldnamewidth}{0pt}% +\providecommand{\DNfieldlist}[1]{#1} +\providecommand{\DNfield}[1]{\Dtabularlistfield{#1}} \providecommand{\DNfieldname}[1]{% - \settowidth{\Dfieldnamewidth}{\Dformatfieldname{#1}}% - \ifthenelse{\lengthtest{\Dfieldnamewidth>\Dmaxfieldnamewidth}}{% - \makebox[\Dplaceholderfieldnamewidth][l]{\Dformatfieldname{#1}}% - &\tabularnewline&% - }{% - \Dformatfieldname{#1}&% + \Dtabularlistfieldname{% + \Dformatfieldname{#1}% }% } -\providecommand{\DNfieldbody}[1]{#1\tabularnewline} - - -\providecommand{\DNdefinitionlist}[1]{% - \noindent\begin{description}#1\end{description}% -} -\providecommand{\DNdefinitionlistitem}[1]{% - % LaTeX expects the label in square brackets; we provide an empty - % label. - \item[]#1% -} -\providecommand{\Dformatterm}[1]{#1} -\providecommand{\DNterm}[1]{\Dformatterm{#1}} -% I'm still not sure what's the best rendering for classifiers. The -% colon syntax is used by reStructuredText, so it's at least WYSIWYG. -% Use slanted text because italic would cause too much emphasis. -\providecommand{\Dformatclassifier}[1]{\textsl{#1}} -\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} -\providecommand{\Dformatdefinition}[1]{#1} -\providecommand{\DNdefinition}[1]{\Dpar\Dformatdefinition{#1}} - +\providecommand{\DNfieldbody}[1]{\Dtabularlistfieldbody{#1}} \providecommand{\Dformatoptiongroup}[1]{% % Format option group, e.g. "-f file, --input file". @@ -523,9 +541,7 @@ % "\DNparagraph{Read input data from file.}" #1% } -\providecommand{\DNoptionlist}[1]{% - \Dtwocolumntable{#1}% -} +\providecommand{\DNoptionlist}[1]{#1} \providecommand{\Doptiongroupjoiner}{,{ }} \providecommand{\Disfirstoption}{% % Auxiliary macro indicating if a given option is the first child @@ -533,9 +549,12 @@ % \Doptiongroupjoiner). false% } +\providecommand{\DNoptionlistitem}[1]{% + \Dtabularlistfield{#1}% +} \providecommand{\DNoptiongroup}[1]{% \renewcommand{\Disfirstoption}{true}% - \Dformatoptiongroup{#1}{}&{}% + \Dtabularlistfieldname{\Dformatoptiongroup{#1}}% } \providecommand{\DNoption}[1]{% % If this is not the first option in this option group, add a @@ -550,10 +569,27 @@ \providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}} \providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}} \providecommand{\DNdescription}[1]{% - \Dformatoptiondescription{#1}% - \tabularnewline% + \Dtabularlistfieldbody{\Dformatoptiondescription{#1}}% } +\providecommand{\DNdefinitionlist}[1]{% + \noindent\begin{description}#1\end{description}% +} +\providecommand{\DNdefinitionlistitem}[1]{% + % LaTeX expects the label in square brackets; we provide an empty + % label. + \item[]#1% +} +\providecommand{\Dformatterm}[1]{#1} +\providecommand{\DNterm}[1]{\Dformatterm{#1}} +% I'm still not sure what's the best rendering for classifiers. The +% colon syntax is used by reStructuredText, so it's at least WYSIWYG. +% Use slanted text because italic would cause too much emphasis. +\providecommand{\Dformatclassifier}[1]{\textsl{#1}} +\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} +\providecommand{\Dformatdefinition}[1]{#1} +\providecommand{\DNdefinition}[1]{\Dpar\Dformatdefinition{#1}} + \providecommand{\Dlineblockindentation}{2.5em} \providecommand{\DNlineblock}[1]{% \Dmakelistenvironment{}{% -- cgit v1.2.1 From f30c0c75a24de3f5b5e4e91d0127140ccb5a7957 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 15:46:28 +0000 Subject: removed tabularx git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3303 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index b2422f6d4..8d52f00f6 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -450,7 +450,7 @@ % single curly quote here. \providecommand{\Dtextliteralsinglequote}{'} -\usepackage{tabularx} + % "Tabular lists" are field lists and options lists (not definition % lists because there the term always appears on its own line). We'll % use the terminology of field lists now ("field", "field name", -- cgit v1.2.1 From c4b5f8b669d65d53d7cb7c09867c882c84bf8c61 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 16:26:23 +0000 Subject: simplified title and subtitle dispatcher code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3304 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 8d52f00f6..ba64b86ee 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -258,8 +258,9 @@ \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% #1% } -% Can be overwritten by user stylesheet. -\providecommand{\Dsectiontitle}[1]{\Ddispatchsectiontitle{#1}} +\providecommand{\Dsectiontitle}[1]{% + \Ddispatchsectiontitle{\Dmakesectiontitletext{#1}}% +} \providecommand{\Ddispatchsectiontitle}[1]{% \ifthenelse{\value{Dsectionlevel}=1}{\Dsectiontitlei{#1}}{}% \ifthenelse{\value{Dsectionlevel}=2}{\Dsectiontitleii{#1}}{}% @@ -267,24 +268,12 @@ \ifthenelse{\value{Dsectionlevel}>3}{\Dsectiontitleiv{#1}}{}% } % Boolean variable. -\providecommand{\Dhassubtitle}{} +\providecommand{\Dhassubtitle}{false} \providecommand{\DNtitle}[1]{% - \ifthenelse{\equal{\Dparent}{topic}}{\Dtopictitle{#1}}{% - \ifthenelse{\equal{\Dparent}{document}}{\Ddocumenttitle{#1}}{% - \ifthenelse{\equal{\Dparent}{section}}{% - \Dsectiontitle{\Dmakesectiontitletext{#1}}% - }{% - \ifthenelse{\equal{\Dparent}{sidebar}}{\Dsidebartitle{#1}}{}% - }% - }% - }% + \csname D\Dparent title\endcsname{#1}% } \providecommand{\DNsubtitle}[1]{% - \ifthenelse{\equal{\Dparent}{topic}}{\Dtopicsubtitle{#1}}{% - \ifthenelse{\equal{\Dparent}{document}}{\Ddocumentsubtitle{#1}}{% - \ifthenelse{\equal{\Dparent}{sidebar}}{\Dsidebarsubtitle{#1}}{}% - }% - }% + \csname D\Dparent subtitle\endcsname{#1}% } \newcounter{Dpdfbookmarkid} \setcounter{Dpdfbookmarkid}{0} -- cgit v1.2.1 From 423f1e08c383effb9f2be54946e1343de9619c39 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 16:46:11 +0000 Subject: improved section title dispatcher git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3305 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index ba64b86ee..d0b9919d9 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -247,11 +247,6 @@ \begin{center}{\huge#1}\end{center}% \vspace{1cm}% } -\providecommand{\Dsectiontitlei}[1]{\section*{#1}} -\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} -\providecommand{\Dsectiontitleiii}[1]{\subsubsection*{#1}} -\providecommand{\Dsectiontitleiv}[1]{% - \par\textbf{\vspace{1.5em}#1\vspace{1em}}} \providecommand{\Dmakesectiontitletext}[1]{% % Return text suitable for use in \section*, \subsection*, etc. % Parameter: The title (as node tree). @@ -262,10 +257,18 @@ \Ddispatchsectiontitle{\Dmakesectiontitletext{#1}}% } \providecommand{\Ddispatchsectiontitle}[1]{% - \ifthenelse{\value{Dsectionlevel}=1}{\Dsectiontitlei{#1}}{}% - \ifthenelse{\value{Dsectionlevel}=2}{\Dsectiontitleii{#1}}{}% - \ifthenelse{\value{Dsectionlevel}=3}{\Dsectiontitleiii{#1}}{}% - \ifthenelse{\value{Dsectionlevel}>3}{\Dsectiontitleiv{#1}}{}% + \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% + \Ddeepsectionlevel{#1}% + }{% + \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% + }% +} +\providecommand{\Dsectiontitlei}[1]{\section*{#1}} +\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} +\providecommand{\Dsectiontitleiii}[1]{\subsubsection*{#1}} +\providecommand{\Ddeepsectionlevel}[1]{% + % Unsufficiently tested. + \par\textbf{\vspace{1.5em}#1\vspace{1em}}% } % Boolean variable. \providecommand{\Dhassubtitle}{false} -- cgit v1.2.1 From 464f029c73702531fc0d4ab8da98d05bd0f6e1b9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 17:36:21 +0000 Subject: simplified definition of deep section titles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3306 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index d0b9919d9..0f7db08f9 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -258,17 +258,19 @@ } \providecommand{\Ddispatchsectiontitle}[1]{% \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% - \Ddeepsectionlevel{#1}% + \Ddeepsectiontitle{#1}% }{% \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% }% } \providecommand{\Dsectiontitlei}[1]{\section*{#1}} \providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} -\providecommand{\Dsectiontitleiii}[1]{\subsubsection*{#1}} -\providecommand{\Ddeepsectionlevel}[1]{% - % Unsufficiently tested. - \par\textbf{\vspace{1.5em}#1\vspace{1em}}% +\providecommand{\Ddeepsectiontitle}[1]{% + % Anything below \subsubsection (like \paragraph or \subparagraph) + % is useless because it uses the same font. The only way to + % (visually) distinguish such deeply nested sections is to use + % section numbering. + \subsubsection*{#1}% } % Boolean variable. \providecommand{\Dhassubtitle}{false} -- cgit v1.2.1 From dc897efc06b167ed100fd7dcf127ca903dbf071b Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 17:51:59 +0000 Subject: made section title formatting more flexible git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3307 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 0f7db08f9..07792ac7a 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -247,14 +247,16 @@ \begin{center}{\huge#1}\end{center}% \vspace{1cm}% } -\providecommand{\Dmakesectiontitletext}[1]{% - % Return text suitable for use in \section*, \subsection*, etc. - % Parameter: The title (as node tree). +% Can be overwritten by user stylesheet. +\providecommand{\Dformatsectiontitle}[1]{#1} +\providecommand{\Dbookmarksectiontitle}[1]{% + % Return text suitable for use in \section*, \subsection*, etc., + % containing a PDF bookmark. Parameter: The title (as node tree). \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% #1% } \providecommand{\Dsectiontitle}[1]{% - \Ddispatchsectiontitle{\Dmakesectiontitletext{#1}}% + \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% } \providecommand{\Ddispatchsectiontitle}[1]{% \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% -- cgit v1.2.1 From a7f1e611f07982deab4d1e5fa0f34c3c15e9ee99 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 17:53:50 +0000 Subject: added support for section subtitles (sectionsubtitle) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3308 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 07792ac7a..d9ec9a7d8 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -249,6 +249,7 @@ } % Can be overwritten by user stylesheet. \providecommand{\Dformatsectiontitle}[1]{#1} +\providecommand{\Dformatsectionsubtitle}[1]{\Dformatsectiontitle{#1}} \providecommand{\Dbookmarksectiontitle}[1]{% % Return text suitable for use in \section*, \subsection*, etc., % containing a PDF bookmark. Parameter: The title (as node tree). @@ -274,6 +275,10 @@ % section numbering. \subsubsection*{#1}% } +\providecommand{\Dsectionsubtitle}[1]{% + % Don't create a PDF bookmark. + \Ddispatchsectiontitle{\scalebox{.8}{\Dformatsectionsubtitle{#1}}}% +} % Boolean variable. \providecommand{\Dhassubtitle}{false} \providecommand{\DNtitle}[1]{% -- cgit v1.2.1 From 8f539d8a6be8d840143a74b791ad9b6add96ad6d Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 18:00:11 +0000 Subject: reduced space between section title and subtitle (sectionsubtitle) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3309 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index d9ec9a7d8..33ca5d3f7 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -275,7 +275,10 @@ % section numbering. \subsubsection*{#1}% } +\Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} \providecommand{\Dsectionsubtitle}[1]{% + % Move the subtitle nearer to the title. + \vspace{-\Dsectionsubtitleraisedistance}% % Don't create a PDF bookmark. \Ddispatchsectiontitle{\scalebox{.8}{\Dformatsectionsubtitle{#1}}}% } -- cgit v1.2.1 From c5721cdbbb6133a3bda4308ecce8df623ab1d2c0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 5 May 2005 18:27:52 +0000 Subject: added sectiontitlehook and sectionsubtitlehook; added dispatcher for sectionsubtitle git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3310 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex-notes.txt | 3 +-- tools/stylesheets/latex.tex | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt index ce085024d..4b4874a29 100644 --- a/tools/stylesheets/latex-notes.txt +++ b/tools/stylesheets/latex-notes.txt @@ -1,6 +1,7 @@ Try the commands mentioned in . + Regarding UTF-8: * Read . @@ -13,8 +14,6 @@ Regarding UTF-8: > However the DeclareUnicodeCharacter directive was to work around a > missing or misnamed character in the UCS database. -Long field lists with ltxtable? - :: diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 33ca5d3f7..8cb125fee 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -256,8 +256,11 @@ \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% #1% } +\providecommand{\Dsectiontitlehook}[1]{#1} \providecommand{\Dsectiontitle}[1]{% - \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% + \Dsectiontitlehook{% + \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% + }% } \providecommand{\Ddispatchsectiontitle}[1]{% \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% @@ -266,6 +269,9 @@ \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% }% } +\providecommand{\Ddispatchsectionsubtitle}[1]{% + \Ddispatchsectiontitle{#1}% +} \providecommand{\Dsectiontitlei}[1]{\section*{#1}} \providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} \providecommand{\Ddeepsectiontitle}[1]{% @@ -275,12 +281,15 @@ % section numbering. \subsubsection*{#1}% } +\providecommand{\Dsectionsubtitlehook}[1]{#1} \Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} \providecommand{\Dsectionsubtitle}[1]{% - % Move the subtitle nearer to the title. - \vspace{-\Dsectionsubtitleraisedistance}% - % Don't create a PDF bookmark. - \Ddispatchsectiontitle{\scalebox{.8}{\Dformatsectionsubtitle{#1}}}% + \Dsectionsubtitlehook{% + % Move the subtitle nearer to the title. + \vspace{-\Dsectionsubtitleraisedistance}% + % Don't create a PDF bookmark. + \Ddispatchsectionsubtitle{\scalebox{.8}{\Dformatsectionsubtitle{#1}}}% + }% } % Boolean variable. \providecommand{\Dhassubtitle}{false} -- cgit v1.2.1 From 792b40f8338fc4a07aa848baa2a45fef5e52eb0a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 19:02:47 +0000 Subject: made attribute dispatcher more powerful git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3311 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 8cb125fee..a36d84eae 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -209,6 +209,8 @@ #5% } +\providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}} + \providecommand{\Dattr}[5]{% % Global attribute dispatcher. % Parameters: @@ -217,10 +219,16 @@ % 3. Attribute value. % 4. Node name. % 5. Node contents. - \@ifundefined{DN#4A#2}{% - \@ifundefined{DA#2}{#5}{\csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}}% - }{% + \Difdefined{DN#4A#2V#3}{% + \csname DN#4A#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }\Difdefined{DN#4A#2}{% \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }\Difdefined{DA#2V#3}{% + \csname DA#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }\Difdefined{DA#2}{% + \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }{% + #5% }% } @@ -658,7 +666,8 @@ \providecommand{\Dsidebarposition}{r} % Width. \Dprovidelength{\Dsidebarwidth}{0.45\linewidth} -\providecommand{\DNsidebar}[1]{\parpic[\Dsidebarposition]{% +\providecommand{\DNsidebar}[1]{ + \parpic[\Dsidebarposition]{% \Dpar% \begin{minipage}[t]{\Dsidebarwidth} % Doing this with nested minipages is ugly, but I haven't found -- cgit v1.2.1 From 80951770104595473835edfaf9ade8d0c8fb493d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 20:02:10 +0000 Subject: fixed new attribute dispatcher git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3312 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index a36d84eae..41af4156d 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -221,15 +221,14 @@ % 5. Node contents. \Difdefined{DN#4A#2V#3}{% \csname DN#4A#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% - }\Difdefined{DN#4A#2}{% + }{\Difdefined{DN#4A#2}{% \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% - }\Difdefined{DA#2V#3}{% + }{\Difdefined{DA#2V#3}{% \csname DA#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% - }\Difdefined{DA#2}{% + }{\Difdefined{DA#2}{% \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}% - }{% - #5% - }% + }{#5% + }}}}% } \providecommand{\DNparagraph}[1]{#1} -- cgit v1.2.1 From 67b1d363d45dbf81b777d65655b85d74273cb96a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 20:22:31 +0000 Subject: added Dimagemaxwidth command git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3313 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 41af4156d..5c048bbbe 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -817,12 +817,15 @@ \usepackage{graphicx} -\Dprovidelength{\Dimagewidth}{0pt} +% Maximum width of an image. +\providecommand{\Dimagemaxwidth}{\linewidth} +% Auxiliary variable. +\Dprovidelength{\Dcurrentimagewidth}{0pt} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. - \settowidth{\Dimagewidth}{\includegraphics{#3}}% - \ifthenelse{\Dimagewidth>\linewidth}{% - \includegraphics[width=\linewidth]{#3}% + \settowidth{\Dcurrentimagewidth}{\includegraphics{#3}}% + \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dimagemaxwidth}}{% + \includegraphics[width=\Dimagemaxwidth]{#3}% }{% \includegraphics{#3}% }% -- cgit v1.2.1 From f15686d824b8f412c2ca93bad02a0e27640e209a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 20:26:21 +0000 Subject: added protection for quotation mark in attribute values git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3314 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 2622c54ad..07265588c 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -329,7 +329,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # We cannot do anything about backslashes. '\\': '', '{': '\\{', - '}': '\\}'}.get + '}': '\\}', + # The quotation mark may be redefined by babel. + '"': '"{}', + }.get text = ''.join([get(c, c) for c in text]) if (self.literal_block or self.inline_literal) and not attval: # NB: We can have inline literals within literal blocks. -- cgit v1.2.1 From c2ad115cbc8162eca8b510622a33a44eef93b162 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 20:48:27 +0000 Subject: added DcurrentN...A... definitions to allow attribute access in DN... macros git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3315 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 07265588c..bb833baee 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -666,6 +666,12 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if not skip_parent and not isinstance(node, nodes.document): self.append(r'\renewcommand{\Dparent}{%s}' % self.node_name(node.parent)) + for name, value in node.attlist(): + # @@@ Evaluate if this is really needed and refactor. + if not isinstance(value, ListType) and not ':' in name: + self.append(r'\def\DcurrentN%sA%s{%s}' + % (node_name, name, + self.encode(unicode(value), attval=1))) if self.pass_contents(node): self.append(r'\DN%s{' % node_name) self.context.append('}') -- cgit v1.2.1 From 81bbd2d2715c4720a038966f82fdb3053882ad5a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 21:55:21 +0000 Subject: added support for image alignment; this currently breaks figure alignment -- I'll fix that later git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3316 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 4 +++- tools/stylesheets/latex.tex | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index bb833baee..cc5368c1a 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -709,7 +709,9 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # We never know what's inside raw nodes, and often # they *are* invisible. So let's have the user take # care of them. - isinstance(node, nodes.raw)) + isinstance(node, nodes.raw) or + # Horizontally aligned image or figure. + node.get('align', None) in ('left', 'center', 'right')) def needs_space(self, node): # Return true if node is a visible block-level element. diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 5c048bbbe..fd7be48bd 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -816,11 +816,40 @@ } +\providecommand{\Dhalign}[2]{% + % Horizontally align the contents to the left or right so that the + % text flows around it. + % Parameters: + % 1. l or r + % 2. Contents. + \parpic[#1]{#2}% +} + + \usepackage{graphicx} % Maximum width of an image. \providecommand{\Dimagemaxwidth}{\linewidth} % Auxiliary variable. \Dprovidelength{\Dcurrentimagewidth}{0pt} +\providecommand{\DNimageAalign}[5]{% + \ifthenelse{\equal{#3}{left}}{% + \Dhalign{l}{#5}% + }{% + \ifthenelse{\equal{#3}{right}}{% + \Dhalign{r}{#5}% + }{% + \ifthenelse{\equal{#3}{center}}{% + % Text floating around centered figures is brain damage. + % Thus we use a center environment. Note that no extra space + % is added by the writer, so the space added by the center + % environment is fine. + \begin{center}#5\end{center}% + }{% + #5% + }% + }% + }% +} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. \settowidth{\Dcurrentimagewidth}{\includegraphics{#3}}% -- cgit v1.2.1 From 82225b476d879a8dd7a250914fde0bbf915f9e89 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 23:52:52 +0000 Subject: added \Dsimpleimage macro which can be called from user stylesheets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3317 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index fd7be48bd..e2f524f81 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -852,11 +852,15 @@ } \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. - \settowidth{\Dcurrentimagewidth}{\includegraphics{#3}}% + \Dsimpleimage{#3}% +} +\providecommand{\Dsimpleimage}[1]{% + % Insert image, without much parametrization. + \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}% \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dimagemaxwidth}}{% - \includegraphics[width=\Dimagemaxwidth]{#3}% + \includegraphics[width=\Dimagemaxwidth]{#1}% }{% - \includegraphics{#3}% + \includegraphics{#1}% }% } -- cgit v1.2.1 From 301119f58a9aa133cfb1b823a2d20e6762891425 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 7 May 2005 23:59:14 +0000 Subject: added class attribute dispatcher git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3318 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index e2f524f81..0a9c33ac7 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -206,7 +206,16 @@ \providecommand{\DAclasses}[5]{% - #5% + \Difdefined{DN#4C#3}{% + % Pass only contents, nothing else! + \csname DN#4C#3\endcsname{#5}% + }{% + \Difdefined{DC#3}{% + \csname DC#3\endcsname{#5}% + }{% + #5% + }% + }% } \providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}} -- cgit v1.2.1 From 55cd5272b6cec7dc3cc9eae6bd8076dd0df064ab Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 9 May 2005 15:49:37 +0000 Subject: Added "border" option to "image" directive (& attribute to doctree element); updated docs & tests. Closes Feature Request 1193389. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3322 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 +++- THANKS.txt | 1 + docs/dev/todo.txt | 9 ++++----- docs/ref/docutils.dtd | 1 + docs/ref/rst/directives.txt | 6 ++++++ docutils/parsers/rst/directives/images.py | 1 + test/functional/expected/standalone_rst_html4css1.html | 2 +- test/functional/expected/standalone_rst_pseudoxml.txt | 2 +- test/functional/input/data/standard.txt | 1 + 9 files changed, 19 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 66a611350..218095d57 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -91,6 +91,7 @@ Changes Since 0.3.7 - "image" directive: added checks for valid values of "align" option, depending on context. "figure" directive: added specialized "align" option and attribute on "figure" element. + - Added a "border" option to the "image" directive. * docutils/parsers/rst/directives/misc.py: @@ -165,7 +166,8 @@ Changes Since 0.3.7 - Added ``stub`` attribute to ``colspec`` element via the ``tbl.colspec.att`` parameter entity. - Allowed topic elements within sidebars - - Added ``align`` attribute to ``figure`` element. + - Added the ``align`` attribute to ``figure`` element. + - Added the ``border`` option to the ``image`` element. Release 0.3.7 (2004-12-24) diff --git a/THANKS.txt b/THANKS.txt index 26b6e9114..a8133eac3 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -133,6 +133,7 @@ donations, tasty treats, and related projects: * Edward Welbourne * Felix Wiemann * Ka-Ping Yee +* George Yoshida * Moshe Zadka Thank you! diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index cba560dca..fc06bbf85 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1121,12 +1121,11 @@ when used in a document. .. _unicode: http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes - - _`images.image`: "border"? + - _`images.image`:_`Units of measure`? (See `docutils-users, + 2003-03-02`__, and `docutils-develop, 2004-04-29`__.) - _`Units of measure`? (See `docutils-users, 2003-03-02 - `__, and - `docutils-develop, 2004-04-29 - `_.) + __ http://article.gmane.org/gmane.text.docutils.user/154 + __ http://article.gmane.org/gmane.text.docutils.devel/1439 - _`images.figure`: "title" and "number", to indicate a formal figure? diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index f3a7d37ca..455a8ae3a 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -481,6 +481,7 @@ or " ") or the text between option arguments (typically either "," or %align-hv.att; uri CDATA #REQUIRED alt CDATA #IMPLIED + border %number; #IMPLIED height %number; #IMPLIED width %number; #IMPLIED scale %number; #IMPLIED> diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 130f0d154..1ca51f28f 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -226,6 +226,12 @@ The following options are recognized: text flow around it. The specific behavior depends upon the browser or rendering software used. +``border`` : integer + The width of the image border, in pixels. For images that are + also hyperlink references (see the ``target`` option, below), + browsers often draw a border by default. Set ``:border: 0`` to + disable this default. + ``target`` : text (URI or reference name) Makes the image into a hyperlink reference ("clickable"). The option argument may be a URI (relative or absolute), or a diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 7efb2588d..96d01aeab 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -76,6 +76,7 @@ def image(name, arguments, options, content, lineno, image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, + 'border': directives.nonnegative_int, 'height': directives.nonnegative_int, 'width': directives.nonnegative_int, 'scale': directives.nonnegative_int, diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 13f8c02c6..e39f3c4e2 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -544,7 +544,7 @@ document (a document-wide table o

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    -
    ../../../docs/user/rst/images/title.png
    +
    ../../../docs/user/rst/images/title.png

    A figure directive:

    reStructuredText, the markup syntax
    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 597408d23..df683cd6a 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1119,7 +1119,7 @@ An image directive (also clickable -- a hyperlink reference): - + A figure directive:
    diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index b06a158d4..6f3e447bc 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -424,6 +424,7 @@ An image directive (also clickable -- a hyperlink reference): .. image:: ../../../docs/user/rst/images/title.png :class: class1 class2 :target: directives_ + :border: 0 A figure directive: -- cgit v1.2.1 From 32c30721cd7ae4f85d57763630074ae4fe261314 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 16:35:57 +0000 Subject: added support for :width: option of images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3323 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 0a9c33ac7..5fca53d61 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -859,9 +859,14 @@ }% }% } +\providecommand{\DcurrentNimageAwidth}{} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. - \Dsimpleimage{#3}% + \ifthenelse{\equal{\DcurrentNimageAwidth}{}}{% + \Dsimpleimage{#3}% + }{% + \Dpercentwidthimage{\DcurrentNimageAwidth}{#3}% + }% } \providecommand{\Dsimpleimage}[1]{% % Insert image, without much parametrization. @@ -872,6 +877,16 @@ \includegraphics{#1}% }% } +% Auxiliary length. One percent of \linewidth. +\Dprovidelength{\Dlinewidthpercent}{0pt} +\providecommand{\Dpercentwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width in percent of \linewidth (1 to 100). + % 2. Image path. + \setlength{\Dlinewidthpercent}{0.01\linewidth}% + \includegraphics[width=#1\Dlinewidthpercent]{#2}% +} % Need to replace with language-specific stuff. Maybe look at -- cgit v1.2.1 From dc191933df46e54b0c95d5405bdb6b10446241d9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 21:54:23 +0000 Subject: added images for convenience git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3324 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/biohazard.png | Bin 0 -> 179 bytes test/functional/input/data/rst.png | Bin 0 -> 1171 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/functional/input/data/biohazard.png create mode 100644 test/functional/input/data/rst.png diff --git a/test/functional/input/data/biohazard.png b/test/functional/input/data/biohazard.png new file mode 100644 index 000000000..ae4629d8b Binary files /dev/null and b/test/functional/input/data/biohazard.png differ diff --git a/test/functional/input/data/rst.png b/test/functional/input/data/rst.png new file mode 100644 index 000000000..cc6218efe Binary files /dev/null and b/test/functional/input/data/rst.png differ -- cgit v1.2.1 From 8dc84c07c5b8892422dfea066376b9785e53c182 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 21:57:16 +0000 Subject: this was stupid; it doesn't work because of the paths, of course git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3325 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/biohazard.png | Bin 179 -> 0 bytes test/functional/input/data/rst.png | Bin 1171 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/functional/input/data/biohazard.png delete mode 100644 test/functional/input/data/rst.png diff --git a/test/functional/input/data/biohazard.png b/test/functional/input/data/biohazard.png deleted file mode 100644 index ae4629d8b..000000000 Binary files a/test/functional/input/data/biohazard.png and /dev/null differ diff --git a/test/functional/input/data/rst.png b/test/functional/input/data/rst.png deleted file mode 100644 index cc6218efe..000000000 Binary files a/test/functional/input/data/rst.png and /dev/null differ -- cgit v1.2.1 From 3686727ee9114a7d3c30fa4c764c268885ef61c6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 22:38:34 +0000 Subject: added test for images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3326 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/latex.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt index 26c8319aa..39641de3b 100644 --- a/test/functional/input/data/latex.txt +++ b/test/functional/input/data/latex.txt @@ -100,3 +100,16 @@ Nested Elements | Literal | | block | +---------------+ + + +Images +====== + +Image with 20% width: + +.. image:: ../../../docs/user/rst/images/title.png + :width: 20 + +Image with 100% width: + +.. image:: ../../../docs/user/rst/images/title.png -- cgit v1.2.1 From 93290f292f90ffe4f7a9bc2ea11b40b0514dad40 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 22:39:27 +0000 Subject: added deletion of \Dcurrent... macros to avoid left-over attributes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3327 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index cc5368c1a..0aa011f60 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -72,6 +72,7 @@ class Writer(writers.Writer): def translate(self): visitor = self.translator_class(self.document) self.document.walkabout(visitor) + assert not visitor.context, 'context not empty: %s' % visitor.context self.output = visitor.astext() self.head = visitor.header self.body = visitor.body @@ -573,8 +574,8 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if isinstance(node.parent.parent, nodes.thead): node['tableheaderentry'] = 'true' - # Don't add \renewcommand{\Dparent}{...} because there may not - # be any non-expandable commands in front of \multicolumn. + # Don't add \renewcommand{\Dparent}{...} because there must + # not be any non-expandable commands in front of \multicolumn. raise SkipParentLaTeX def depart_entry(self, node): @@ -663,15 +664,19 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if not isinstance(node, nodes.Text): node_name = self.node_name(node) + # attribute_deleters will be appended to self.context. + attribute_deleters = [] if not skip_parent and not isinstance(node, nodes.document): self.append(r'\renewcommand{\Dparent}{%s}' % self.node_name(node.parent)) for name, value in node.attlist(): # @@@ Evaluate if this is really needed and refactor. if not isinstance(value, ListType) and not ':' in name: - self.append(r'\def\DcurrentN%sA%s{%s}' - % (node_name, name, - self.encode(unicode(value), attval=1))) + macro = r'\DcurrentN%sA%s' % (node_name, name) + self.append(r'\def%s{%s}' % ( + macro, self.encode(unicode(value), attval=1))) + attribute_deleters.append(r'\let%s=\relax' % macro) + self.context.append('\n'.join(attribute_deleters)) if self.pass_contents(node): self.append(r'\DN%s{' % node_name) self.context.append('}') @@ -732,7 +737,8 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # Close attribute and node handler call (\DN...{...}). self.indentation_level -= 1 self.append(self.context.pop() + self.context.pop()) - + # Delete \Dcurrent... attribute macros. + self.append(self.context.pop()) # Insert space. if self.needs_space(node): # Next sibling. -- cgit v1.2.1 From 235daed0cb082fc9f18d956c6965ca13db193212 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 22:41:22 +0000 Subject: added support for image base path git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3328 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 5fca53d61..d04dbbe88 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -859,13 +859,17 @@ }% }% } -\providecommand{\DcurrentNimageAwidth}{} +% Base path for images. +\providecommand{\Dimagebase}{} +% Auxiliary command. Current image path. +\providecommand{\Dimagepath}{} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. - \ifthenelse{\equal{\DcurrentNimageAwidth}{}}{% - \Dsimpleimage{#3}% + \renewcommand{\Dimagepath}{\Dimagebase#3} + \Difdefined{DcurrentNimageAwidth}{% + \Dpercentwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% }{% - \Dpercentwidthimage{\DcurrentNimageAwidth}{#3}% + \Dsimpleimage{\Dimagepath}% }% } \providecommand{\Dsimpleimage}[1]{% -- cgit v1.2.1 From 2524210ae50328a7c4383cebe78fc6a985d4148f Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 9 May 2005 23:35:09 +0000 Subject: fixed right margin of line blocks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3329 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index d04dbbe88..fabd57631 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -625,6 +625,7 @@ \ifthenelse{\equal{\Dparent}{lineblock}}{% % Parent is a line block, so indent. \setlength{\leftmargin}{\Dlineblockindentation}% + \setlength{\rightmargin}{0pt}% }{% % At top level; don't indent. \setlength{\leftmargin}{0pt}% -- cgit v1.2.1 From 9f334eed0f7ac19a83b6405200e0d3356c763ca4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 10 May 2005 19:46:05 +0000 Subject: added field list in table cell git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3330 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/input/data/latex.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt index 39641de3b..df1f66d45 100644 --- a/test/functional/input/data/latex.txt +++ b/test/functional/input/data/latex.txt @@ -100,6 +100,11 @@ Nested Elements | Literal | | block | +---------------+ +| :Field 1: | +| Text. | +| :Field 2: | +| More text. | ++---------------+ Images -- cgit v1.2.1 From 95067ca94a445d907461be04811f6c094db3ac79 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 10 May 2005 19:46:57 +0000 Subject: first solution for the broken rendering of field lists in tables git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3331 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index fabd57631..8e9ad93c7 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -534,7 +534,9 @@ \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% }{~\newline}{}% \Dsavefieldbody% + \@finalstrut\@arstrutbox% }% + \par% }% } @@ -786,10 +788,13 @@ % Make table. Parameters: % 1. Table spec (like "|p|p|"). % 2. Table contents. - \begin{longtable}{#1}% - \hline% - #2% - \end{longtable} + {% + \renewcommand{\Dinsidetabular}{true}% + \begin{longtable}{#1}% + \hline% + #2% + \end{longtable}% + }% } \providecommand{\DNthead}[1]{% #1% -- cgit v1.2.1 From d59a8a683fd71e491949d25c08882fb15f1e96d9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 11 May 2005 18:47:11 +0000 Subject: re-fixed right margin of line blocks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3332 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 8e9ad93c7..fcdc6f3fd 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -627,11 +627,11 @@ \ifthenelse{\equal{\Dparent}{lineblock}}{% % Parent is a line block, so indent. \setlength{\leftmargin}{\Dlineblockindentation}% - \setlength{\rightmargin}{0pt}% }{% % At top level; don't indent. \setlength{\leftmargin}{0pt}% }% + \setlength{\rightmargin}{0pt}% \setlength{\parsep}{0pt}% }{% #1% -- cgit v1.2.1 From e5439a73f5e3d4a0b1b0284fca25cecfa133c045 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 11 May 2005 19:06:11 +0000 Subject: some ugly fix for the broken definition list spacing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3333 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index fcdc6f3fd..fc5915ee0 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -604,7 +604,13 @@ } \providecommand{\DNdefinitionlist}[1]{% - \noindent\begin{description}#1\end{description}% + % XXX Replace with a generic list, so we don't have to hack around + % spacing problems with \vspace and \hspace. + \vspace{-2em}% + \begin{description}% + \parskip0pt% + #1% + \end{description}% } \providecommand{\DNdefinitionlistitem}[1]{% % LaTeX expects the label in square brackets; we provide an empty @@ -612,7 +618,7 @@ \item[]#1% } \providecommand{\Dformatterm}[1]{#1} -\providecommand{\DNterm}[1]{\Dformatterm{#1}} +\providecommand{\DNterm}[1]{\hspace{-5pt}\Dformatterm{#1}} % I'm still not sure what's the best rendering for classifiers. The % colon syntax is used by reStructuredText, so it's at least WYSIWYG. % Use slanted text because italic would cause too much emphasis. -- cgit v1.2.1 From 7e44db0a0e450b1e8169792192e9d14a2e3b69e7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 11 May 2005 23:54:06 +0000 Subject: nicer vertical spacing for floating images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3334 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index fc5915ee0..c261960e4 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -837,19 +837,25 @@ } +\providecommand{\Dinsidehalign}{false} \providecommand{\Dhalign}[2]{% % Horizontally align the contents to the left or right so that the % text flows around it. % Parameters: % 1. l or r % 2. Contents. + \renewcommand{\Dinsidehalign}{true}% + % For some obscure reason \parpic consumes some vertical space. + \vspace{-3pt}% \parpic[#1]{#2}% + \renewcommand{\Dinsidehalign}{false}% } \usepackage{graphicx} % Maximum width of an image. \providecommand{\Dimagemaxwidth}{\linewidth} +\providecommand{\Dfloatimagemaxwidth}{0.5\linewidth} % Auxiliary variable. \Dprovidelength{\Dcurrentimagewidth}{0pt} \providecommand{\DNimageAalign}[5]{% @@ -877,18 +883,27 @@ \providecommand{\Dimagepath}{} \providecommand{\DNimageAuri}[5]{% % Insert image. We treat the URI like a path here. - \renewcommand{\Dimagepath}{\Dimagebase#3} + \renewcommand{\Dimagepath}{\Dimagebase#3}% \Difdefined{DcurrentNimageAwidth}{% \Dpercentwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% }{% \Dsimpleimage{\Dimagepath}% }% } +\providecommand{\Dcurrentimagemaxwidth}{} \providecommand{\Dsimpleimage}[1]{% % Insert image, without much parametrization. \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}% - \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dimagemaxwidth}}{% - \includegraphics[width=\Dimagemaxwidth]{#1}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dfloatimagemaxwidth}% + }{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}% + }% + \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{% + \begin{minipage}{\Dcurrentimagemaxwidth}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{\vspace{3.5pt}}{}% + \includegraphics[width=\linewidth]{#1}% + \end{minipage}% }{% \includegraphics{#1}% }% -- cgit v1.2.1 From 4b990d4a1c5ae8b0b04eb0a138071203d2b9dc2c Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 12 May 2005 01:37:11 +0000 Subject: improved vertical spacing of floating images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3335 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c261960e4..c4511e689 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -890,6 +890,26 @@ \Dsimpleimage{\Dimagepath}% }% } +\Dprovidelength{\Dfloatimagevmargin}{0pt} +\providecommand{\Dwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width. + % 2. Image path. + \begin{minipage}{#1}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{ + % Compensate for space previously added in \Dhalign, but not + % entirely. + \vspace*{2.5pt}% + \vspace*{\Dfloatimagevmargin}% + }{}% + \includegraphics[width=\linewidth]{#2}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{% + \vspace*{1.5pt}% + \vspace*{\Dfloatimagevmargin}% + }{}% + \end{minipage}% +} \providecommand{\Dcurrentimagemaxwidth}{} \providecommand{\Dsimpleimage}[1]{% % Insert image, without much parametrization. @@ -900,12 +920,9 @@ \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}% }% \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{% - \begin{minipage}{\Dcurrentimagemaxwidth}% - \ifthenelse{\equal{\Dinsidehalign}{true}}{\vspace{3.5pt}}{}% - \includegraphics[width=\linewidth]{#1}% - \end{minipage}% + \Dwidthimage{\Dcurrentimagemaxwidth}{#1}% }{% - \includegraphics{#1}% + \Dwidthimage{\Dcurrentimagewidth}{#1}% }% } % Auxiliary length. One percent of \linewidth. @@ -916,7 +933,7 @@ % 1. Image width in percent of \linewidth (1 to 100). % 2. Image path. \setlength{\Dlinewidthpercent}{0.01\linewidth}% - \includegraphics[width=#1\Dlinewidthpercent]{#2}% + \Dwidthimage{#1\Dlinewidthpercent}{#2}% } -- cgit v1.2.1 From 8436102c6a159c4c9f4e3c11b9aa60227f99ea88 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 12 May 2005 01:56:01 +0000 Subject: some clean-up git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3336 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 0aa011f60..7f8baaf3f 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -494,10 +494,6 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def visit_citation(self, node): self.process_backlinks(node, 'citation') - def visit_table(self, node): - # Everything's handled in tgroup. - pass - def before_table(self, node): # A tables contains exactly one tgroup. See before_tgroup. pass @@ -512,6 +508,8 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): del node[:len(widths)] tablespec = '|' for w in widths: + # 0.93 is probably wrong in many cases. XXX Find a + # solution which works *always*. tablespec += r'p{%s\linewidth}|' % (0.93 * w / max(total_width, 60)) self.append(r'\Dmaketable{%s}{' % tablespec) -- cgit v1.2.1 From c8d3ad94ae7103823e7ab98db10b270f356a9bdd Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 12 May 2005 21:21:36 +0000 Subject: added \Ditemsep, changed nesting of section subtitle macro calls git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3337 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c4511e689..1e94f9641 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -304,7 +304,7 @@ % Move the subtitle nearer to the title. \vspace{-\Dsectionsubtitleraisedistance}% % Don't create a PDF bookmark. - \Ddispatchsectionsubtitle{\scalebox{.8}{\Dformatsectionsubtitle{#1}}}% + \Ddispatchsectionsubtitle{\Dformatsectionsubtitle{\scalebox{.8}{#1}}}% }% } % Boolean variable. @@ -432,6 +432,7 @@ } \providecommand{\DAlastitem}[5]{#5\@finalstrut\@arstrutbox} +\Dprovidelength{\Ditemsep}{0pt} \providecommand{\Dmakeenumeratedlist}[6]{% % Make enumerated list. % Parameters: @@ -460,6 +461,7 @@ % space from the right. \setlength{\rightmargin}{0pt}% }% + \setlength{\itemsep}{\Ditemsep}% % Use counter recommended by Python module. \usecounter{#4}% % Set start value. -- cgit v1.2.1 From a66a83d891c9cd6f766071e1023ef1657919b2fa Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 14 May 2005 01:13:25 +0000 Subject: changed \Dformatfieldname to use a command rather than a declaration for bold-faced text; added maximum height (= height of the text on the page) for images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3338 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 1e94f9641..25892b94d 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -542,7 +542,7 @@ }% } -\providecommand{\Dformatfieldname}[1]{\bfseries{#1:}} +\providecommand{\Dformatfieldname}[1]{\textbf{#1:}} \providecommand{\DNfieldlist}[1]{#1} \providecommand{\DNfield}[1]{\Dtabularlistfield{#1}} \providecommand{\DNfieldname}[1]{% @@ -905,7 +905,7 @@ \vspace*{2.5pt}% \vspace*{\Dfloatimagevmargin}% }{}% - \includegraphics[width=\linewidth]{#2}% + \includegraphics[width=\linewidth,height=\textheight,keepaspectratio]{#2}% \ifthenelse{\equal{\Dinsidehalign}{true}}{% \vspace*{1.5pt}% \vspace*{\Dfloatimagevmargin}% -- cgit v1.2.1 From 358358c1c586216307713c3be3d8cc20a436dd0c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 14 May 2005 01:32:39 +0000 Subject: added note about image :width: git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3339 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex-notes.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt index 4b4874a29..87e65abd2 100644 --- a/tools/stylesheets/latex-notes.txt +++ b/tools/stylesheets/latex-notes.txt @@ -34,3 +34,7 @@ Regarding UTF-8: \else \usepackage{graphicx} \fi + +Width of images needs cleanup, in the framework. Integers aren't +sufficient (virtually unusable in typeset documents). Need to discuss +on Docutils-develop and come up with a set of standard units. -- cgit v1.2.1 From 9ed38a53f7de2eed5ed8ba98afb3e2ee28f2f75d Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 14 May 2005 16:14:44 +0000 Subject: reverting revision 3322: addition of ":border:" option to "image" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3340 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 +--- THANKS.txt | 1 - docs/dev/todo.txt | 9 +++++---- docs/ref/docutils.dtd | 1 - docs/ref/rst/directives.txt | 6 ------ docutils/parsers/rst/directives/images.py | 1 - test/functional/expected/standalone_rst_html4css1.html | 2 +- test/functional/expected/standalone_rst_pseudoxml.txt | 2 +- test/functional/input/data/standard.txt | 1 - 9 files changed, 8 insertions(+), 19 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 218095d57..66a611350 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -91,7 +91,6 @@ Changes Since 0.3.7 - "image" directive: added checks for valid values of "align" option, depending on context. "figure" directive: added specialized "align" option and attribute on "figure" element. - - Added a "border" option to the "image" directive. * docutils/parsers/rst/directives/misc.py: @@ -166,8 +165,7 @@ Changes Since 0.3.7 - Added ``stub`` attribute to ``colspec`` element via the ``tbl.colspec.att`` parameter entity. - Allowed topic elements within sidebars - - Added the ``align`` attribute to ``figure`` element. - - Added the ``border`` option to the ``image`` element. + - Added ``align`` attribute to ``figure`` element. Release 0.3.7 (2004-12-24) diff --git a/THANKS.txt b/THANKS.txt index a8133eac3..26b6e9114 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -133,7 +133,6 @@ donations, tasty treats, and related projects: * Edward Welbourne * Felix Wiemann * Ka-Ping Yee -* George Yoshida * Moshe Zadka Thank you! diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index fc06bbf85..cba560dca 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1121,11 +1121,12 @@ when used in a document. .. _unicode: http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes - - _`images.image`:_`Units of measure`? (See `docutils-users, - 2003-03-02`__, and `docutils-develop, 2004-04-29`__.) + - _`images.image`: "border"? - __ http://article.gmane.org/gmane.text.docutils.user/154 - __ http://article.gmane.org/gmane.text.docutils.devel/1439 + _`Units of measure`? (See `docutils-users, 2003-03-02 + `__, and + `docutils-develop, 2004-04-29 + `_.) - _`images.figure`: "title" and "number", to indicate a formal figure? diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index 455a8ae3a..f3a7d37ca 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -481,7 +481,6 @@ or " ") or the text between option arguments (typically either "," or %align-hv.att; uri CDATA #REQUIRED alt CDATA #IMPLIED - border %number; #IMPLIED height %number; #IMPLIED width %number; #IMPLIED scale %number; #IMPLIED> diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 1ca51f28f..130f0d154 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -226,12 +226,6 @@ The following options are recognized: text flow around it. The specific behavior depends upon the browser or rendering software used. -``border`` : integer - The width of the image border, in pixels. For images that are - also hyperlink references (see the ``target`` option, below), - browsers often draw a border by default. Set ``:border: 0`` to - disable this default. - ``target`` : text (URI or reference name) Makes the image into a hyperlink reference ("clickable"). The option argument may be a URI (relative or absolute), or a diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 96d01aeab..7efb2588d 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -76,7 +76,6 @@ def image(name, arguments, options, content, lineno, image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, - 'border': directives.nonnegative_int, 'height': directives.nonnegative_int, 'width': directives.nonnegative_int, 'scale': directives.nonnegative_int, diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index e39f3c4e2..13f8c02c6 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -544,7 +544,7 @@ document (a document-wide table o

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    -
    ../../../docs/user/rst/images/title.png
    +
    ../../../docs/user/rst/images/title.png

    A figure directive:

    reStructuredText, the markup syntax
    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index df683cd6a..597408d23 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1119,7 +1119,7 @@ An image directive (also clickable -- a hyperlink reference): - + A figure directive:
    diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 6f3e447bc..b06a158d4 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -424,7 +424,6 @@ An image directive (also clickable -- a hyperlink reference): .. image:: ../../../docs/user/rst/images/title.png :class: class1 class2 :target: directives_ - :border: 0 A figure directive: -- cgit v1.2.1 From e6934cebf2e2786ae8a57c95ff2321969749cb71 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 14 May 2005 16:20:03 +0000 Subject: grammar git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3341 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 66a611350..cc1051315 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -138,7 +138,7 @@ Changes Since 0.3.7 - Added the ``field_name_limit`` & ``option_limit`` settings & support. - Added support for table stub columns. - - Added support for ``align`` attribute on ``figure`` elements. + - 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 @@ -162,10 +162,10 @@ Changes Since 0.3.7 * docs/ref/docutils.dtd: - - Added ``stub`` attribute to ``colspec`` element via the + - Added a ``stub`` attribute to the ``colspec`` element via the ``tbl.colspec.att`` parameter entity. - Allowed topic elements within sidebars - - Added ``align`` attribute to ``figure`` element. + - Added an ``align`` attribute to the ``figure`` element. Release 0.3.7 (2004-12-24) -- cgit v1.2.1 From 23969b82fe403cc4811537f5d42f8ef163326210 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 14 May 2005 16:30:08 +0000 Subject: note about "border": bad idea git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3342 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index cba560dca..fe74e54f4 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1121,7 +1121,7 @@ when used in a document. .. _unicode: http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes - - _`images.image`: "border"? + - _`images.image`: "border"? No, bad idea; use CSS instead. _`Units of measure`? (See `docutils-users, 2003-03-02 `__, and -- cgit v1.2.1 From 44343594a7b40dc30c9d2626eb05ce9c34f93703 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 16 May 2005 01:47:13 +0000 Subject: added \Dsetlistrightmargin macro; bottom-align images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3343 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 25892b94d..c76171e1f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -391,6 +391,16 @@ % Current hardcoded. \usepackage[latin1]{inputenc} +\providecommand{\Dsetlistrightmargin}{% + \ifthenelse{\lengthtest{\linewidth>10em}}{% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + }{% + % If the line is narrower than 10em, we don't remove any further + % space from the right. + \setlength{\rightmargin}{0pt}% + }% +} \providecommand{\Dresetlistdepth}{false} \providecommand{\Dmakelistenvironment}[3]{% % Make list environment with support for unlimited nesting and with @@ -419,8 +429,7 @@ \setlength{\topsep}{0pt}% % List should take 90% of total width. \setlength{\leftmargin}{0.05\linewidth}% - % Equal margins. - \setlength{\rightmargin}{\leftmargin}% + \Dsetlistrightmargin% #2% }{% #3% @@ -453,14 +462,7 @@ % % 1. First item. \setlength{\leftmargin}{2.5em}% - % Equal margins. - \ifthenelse{\lengthtest{\linewidth>10em}}{% - \setlength{\rightmargin}{\leftmargin}% - }{% - % If the line is narrower than 10em, we don't remove any further - % space from the right. - \setlength{\rightmargin}{0pt}% - }% + \Dsetlistrightmargin% \setlength{\itemsep}{\Ditemsep}% % Use counter recommended by Python module. \usecounter{#4}% @@ -898,7 +900,9 @@ % Parameters: % 1. Image width. % 2. Image path. - \begin{minipage}{#1}% + % Need to make bottom-alignment dependent on align attribute (add + % functional test first). + \begin{minipage}[b]{#1}% \ifthenelse{\equal{\Dinsidehalign}{true}}{ % Compensate for space previously added in \Dhalign, but not % entirely. -- cgit v1.2.1 From eacd0882f7e2aa5de5710ce6c403e4bcb5ee52f9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 16 May 2005 02:21:15 +0000 Subject: added \Dfloatimagetopmargin and \Dfloatimagebottommargin git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3344 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index c76171e1f..d94be959d 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -895,6 +895,8 @@ }% } \Dprovidelength{\Dfloatimagevmargin}{0pt} +\providecommand{\Dfloatimagetopmargin}{\Dfloatimagevmargin} +\providecommand{\Dfloatimagebottommargin}{\Dfloatimagevmargin} \providecommand{\Dwidthimage}[2]{% % Image with specified width. % Parameters: @@ -907,12 +909,12 @@ % Compensate for space previously added in \Dhalign, but not % entirely. \vspace*{2.5pt}% - \vspace*{\Dfloatimagevmargin}% + \vspace*{\Dfloatimagetopmargin}% }{}% \includegraphics[width=\linewidth,height=\textheight,keepaspectratio]{#2}% \ifthenelse{\equal{\Dinsidehalign}{true}}{% \vspace*{1.5pt}% - \vspace*{\Dfloatimagevmargin}% + \vspace*{\Dfloatimagebottommargin}% }{}% \end{minipage}% } -- cgit v1.2.1 From 71fd953aa28e39e38378c024839c7a8516f0868e Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 17 May 2005 13:04:56 +0000 Subject: Minor fix to underlining function, added more tests. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3345 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 6 ++- tools/editors/emacs/tests/tests-adjust-section.el | 55 ++++++++++++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 9fa83d057..1bac6ebbe 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -424,13 +424,17 @@ This is useful for filling list item paragraphs." (car rest-preferred-characters) ?=)) + ;; if there is a current indent, reuse it, otherwise use default + (if (= curindent 0) + (setq curindent rest-default-under-and-over-indent)) + (rest-update-section curchar (if (and current-prefix-arg (not (< (prefix-numeric-value current-prefix-arg) 0))) (if (eq init-style 'over-and-under) 'simple 'over-and-under) init-style) - rest-default-under-and-over-indent) + curindent) ) ;; else we're not switching characters, and there is some sectioning diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index a1fa9ec3d..43215fb98 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -5,7 +5,7 @@ ;; Regression tests for rest-adjust-section-title. ;; -(defvar rest-adjust-section-tests +(setq rest-adjust-section-tests '( (simple " @@ -133,7 +133,7 @@ Subtitle2 ~~~~~~~~~ " -2) +(nil nil)) (with-previous-text-rotating " @@ -157,12 +157,49 @@ Subtitle2 ========= " -3) +(nil nil nil)) - ) + (start-indented +" + Some Title@ + +" +" +================ + Some Title +================ + +") + + (switch-from-nothing +" +Some Title@ + +" +" +============ + Some Title +============ + +" (t)) + + (switch-from-over-and-under +" +============ + Some Title@ +============ +" +" +Some Title +========== + +" (t)) + +)) "A list of regression tests for the section update method.") - + + (defun regression-test-compare-expect-buffer (testlist fun) "Run the regression tests for the section adjusting method." @@ -171,6 +208,9 @@ Subtitle2 (specchar "@") ) (dolist (curtest testlist) + ;; print current text + (message (format "========= %s" (prin1-to-string (car curtest)))) + ;; prepare a buffer with the starting text, and move the cursor where ;; the special character is located (switch-to-buffer buf) @@ -180,8 +220,9 @@ Subtitle2 (delete-char 1) ;; run the section title update command n times - (dotimes (x (or (cadddr curtest) 1)) - (funcall fun)) + (dolist (x (or (cadddr curtest) (list nil))) + (let ((current-prefix-arg x)) + (funcall fun))) ;; compare the buffer output with the expected text (or (string= -- cgit v1.2.1 From ad515ddd08093c451941419471afc6e422ab55fb Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 18:08:14 +0000 Subject: Fixed bug with ":width: image" option of figure directive. Closing https://sourceforge.net/tracker/?func=detail&atid=422030&aid=1202510&group_id=38414 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3346 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 2 +- test/test_parsers/test_rst/test_directives/test_figures.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 7efb2588d..c9f793f4b 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -107,7 +107,7 @@ def figure(name, arguments, options, content, lineno, except (IOError, UnicodeError): pass else: - state.document.settings.record_dependencies.add(reference) + state.document.settings.record_dependencies.add(image_node['uri']) figure_node['width'] = i.size[0] elif figwidth is not None: figure_node['width'] = figwidth diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index 91fd91596..7e63fda16 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -10,6 +10,7 @@ Tests for images.py figure directives. """ +import os.path from __init__ import DocutilsTestSupport def suite(): @@ -17,6 +18,9 @@ def suite(): s.generateTests(totest) return s +mydir = 'test_parsers/test_rst/test_directives/' +biohazard = os.path.join(mydir, '../../../../docs/user/rst/images/biohazard.png') + totest = {} totest['figures'] = [ @@ -286,6 +290,15 @@ Testing for line-leaks:
    """], +["""\ +.. figure:: %s + :figwidth: image +""" % biohazard, +"""\ + +
    + +"""], ] -- cgit v1.2.1 From e8a50ca456b98d2a10a82a689cf6805c541b1244 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 18:17:33 +0000 Subject: Fixed bug with uppercase image targets. Closing https://sourceforge.net/tracker/index.php?func=detail&aid=1202510&group_id=38414&atid=422030 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3347 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 4 ++-- test/test_parsers/test_rst/test_directives/test_images.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index c9f793f4b..670f969a0 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -14,7 +14,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import nodes, utils from docutils.parsers.rst import directives, states -from docutils.nodes import whitespace_normalize_name +from docutils.nodes import fully_normalize_name from docutils.parsers.rst.roles import set_classes try: @@ -61,7 +61,7 @@ def image(name, arguments, options, content, lineno, reference_node = nodes.reference(refuri=data) elif target_type == 'refname': reference_node = nodes.reference(refname=data, - name=whitespace_normalize_name(options['target'])) + name=fully_normalize_name(options['target'])) state.document.note_refname(reference_node) else: # malformed target messages.append(data) # data is a system message diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index b35cab355..3e0c89344 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -357,6 +357,18 @@ u"""\ .. image:: picture.png :align: \xe4 """], +[""" +.. image:: test.png + :target: Uppercase_ + +.. _Uppercase: http://docutils.sourceforge.net/ +""", +"""\ + + + + +"""], ] -- cgit v1.2.1 From b430acac2e819818db28663b0934e39e757efef2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 18:35:35 +0000 Subject: added history entries for recent bug fixes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3348 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index cc1051315..096ffb9b7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -91,6 +91,9 @@ Changes Since 0.3.7 - "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: -- cgit v1.2.1 From 12184e807cb2b7c1e3bf2631f51c4bac838b0ad2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 20:36:16 +0000 Subject: added support for "border" class git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3349 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index d94be959d..d9fc58348 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -945,6 +945,9 @@ } +\providecommand{\DCborder}[1]{\fbox{#1}} + + % Need to replace with language-specific stuff. Maybe look at % csquotes.sty and ask the author for permission to use parts of it. \providecommand{\Dtextleftdblquote}{``} -- cgit v1.2.1 From 0892e2caf5da0a5b4a7a5916d9597ab8b2934abc Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 22:19:33 +0000 Subject: fixed collision with reST's inline markup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3350 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 096ffb9b7..ba98ee2e2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -93,7 +93,7 @@ Changes Since 0.3.7 "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. + (e.g. ``Name_``) in "target" option of "image" directive. * docutils/parsers/rst/directives/misc.py: -- cgit v1.2.1 From 4ae722d597317382b222737ecf0b898b224dddcd Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 18 May 2005 22:27:52 +0000 Subject: added SectSubTitle transform git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3351 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 10 ++ docs/ref/transforms.txt | 2 + docs/user/config.txt | 8 ++ docutils/readers/standalone.py | 13 ++- docutils/transforms/frontmatter.py | 182 +++++++++++++++++++++++++--------- test/test_transforms/test_doctitle.py | 37 ++++++- 6 files changed, 202 insertions(+), 50 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ba98ee2e2..ac312f6cb 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -121,6 +121,16 @@ Changes Since 0.3.7 * docutils/parsers/rst/languages/nl.py: Added to project; Dutch mappings by Martijn Pieters. +* docutils/readers/standalone.py: + + - Added ``--section-subtitle`` and ``--no-section-subtitle`` 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 diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 9e4687a72..079bedaaa 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -34,6 +34,8 @@ frontmatter.DocTitle standalone (r) 320 frontmatter.DocInfo standalone (r) 340 +frontmatter.SectSubTitle standalone (r) 350 + peps.Headers pep (r) 360 peps.Contents pep (r) 380 diff --git a/docs/user/config.txt b/docs/user/config.txt index e3e052aaf..c00d82133 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -463,6 +463,14 @@ _`doctitle_xform` Default: enabled (1). Options: ``--no-doc-title``. +_`sectsubtitle_xform` + + Enable or disable the promotion of the title of a lone subsection + to a subtitle (docutils.transforms.frontmatter.SectSubTitle). + + Default: disabled (0). Options: ``--section-subtitle, + --no-section-subtitle``. + [pep reader] ```````````` diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 63e618b51..4cdea3df8 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -37,7 +37,17 @@ class Reader(readers.Reader): 'default).', ['--no-doc-info'], {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1, - 'validator': frontend.validate_boolean}),)) + 'validator': frontend.validate_boolean}), + ('Activate the promotion of the title of a lone subsection to ' + 'a section subtitle (disabled by default).', + ['--section-subtitle'], + {'dest': 'sectsubtitle_xform', 'action': 'store_true', 'default': 0, + 'validator': frontend.validate_boolean}), + ('Deactivate the promotion of lone subsection titles.', + ['--no-section-subtitle'], + {'dest': 'sectsubtitle_xform', 'action': 'store_false', + 'validator': frontend.validate_boolean}), + )) config_section = 'standalone reader' config_section_dependencies = ('readers',) @@ -45,6 +55,7 @@ class Reader(readers.Reader): default_transforms = (references.Substitutions, references.PropagateTargets, frontmatter.DocTitle, + frontmatter.SectionSubTitle, frontmatter.DocInfo, references.AnonymousHyperlinks, references.IndirectHyperlinks, diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 22ecbbf25..cd8fb0188 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -5,13 +5,15 @@ # Copyright: This module has been placed in the public domain. """ -Transforms related to the front matter of a document (information -found before the main text): +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, and promote a remaining lone top-level section's title to the document subtitle. +- `SectionTitle`: Used to transform a lone subsection into a subtitle. + - `DocInfo`: Used to transform a bibliographic field list into docinfo elements. """ @@ -23,7 +25,100 @@ from docutils import nodes, utils from docutils.transforms import TransformError, Transform -class DocTitle(Transform): +class TitlePromoter(Transform): + + """ + Abstract base class for DocTitle and SectionSubTitle transforms. + """ + + def promote_title(self, node): + """ + Transform the following tree:: + + +
    + + ... + + into :: + + <node> + <title> + ... + + `node` is normally a document. + """ + # `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: + node.attributes.update(section.attributes) + # 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> + ... + """ + subsection, index = self.candidate_index(node) + if index is None: + return None + subtitle = nodes.subtitle() + # Transfer the subsection's attributes to the new subtitle: + # This causes trouble with list attributes! To do: Write a + # test case which catches direct access to the `attributes` + # dictionary and/or write a test case which shows problems in + # this particular case. + subtitle.attributes.update(subsection.attributes) + # We're losing the subtitle's attributes here! To do: Write a + # test case which shows this behavior. + # 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 @@ -107,54 +202,47 @@ class DocTitle(Transform): def apply(self): if not getattr(self.document.settings, 'doctitle_xform', 1): return - if self.promote_document_title(): - self.promote_document_subtitle() + if self.promote_title(self.document): + self.promote_subtitle(self.document) - def promote_document_title(self): - section, index = self.candidate_index() - if index is None: - return None - document = self.document - # Transfer the section's attributes to the document element (at root): - document.attributes.update(section.attributes) - document[:] = (section[:1] # section title - + document[:index] # everything that was in the - # document before the section - + section[1:]) # everything that was in the section - return 1 - def promote_document_subtitle(self): - subsection, index = self.candidate_index() - if index is None: - return None - subtitle = nodes.subtitle() - # Transfer the subsection's attributes to the new subtitle: - subtitle.attributes.update(subsection.attributes) - # Transfer the contents of the subsection's title to the subtitle: - subtitle[:] = subsection[0][:] - document = self.document - document[:] = (document[:1] # document title - + [subtitle] - # everything that was before the section: - + document[1:index] - # everything that was in the subsection: - + subsection[1:]) - return 1 +class SectionSubTitle(TitlePromoter): - def candidate_index(self): - """ - Find and return the promotion candidate and its index. + """ + This works like document subtitles, but for sections. For example, :: - Return (None, None) if no valid candidate was found. - """ - document = self.document - index = document.first_child_not_matching_class( - nodes.PreBibliographic) - if index is None or len(document) > (index + 1) or \ - not isinstance(document[index], nodes.section): - return None, None - else: - return document[index], index + <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(lambda n: + isinstance(n, 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): diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index c196c38ec..0e2050494 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -11,7 +11,7 @@ Tests for docutils.transforms.frontmatter.DocTitle. """ from __init__ import DocutilsTestSupport -from docutils.transforms.frontmatter import DocTitle +from docutils.transforms.frontmatter import DocTitle, SectionSubTitle from docutils.parsers.rst import Parser @@ -23,7 +23,7 @@ def suite(): totest = {} -totest['section_headers'] = ((DocTitle,), [ +totest['section_headers'] = ((DocTitle, SectionSubTitle), [ ["""\ .. test title promotion @@ -188,6 +188,39 @@ substitution_definition. This title should be the document title despite the substitution_definition. """], +["""\ +This is no doc title. + +=============== + Section Title +=============== + +Subtitle +======== + +----------------- + Another Section +----------------- + +Another Subtitle +---------------- + +""", +"""\ +<document source="test data"> + <paragraph> + This is no doc title. + <section ids="section-title" names="section title"> + <title> + Section Title + <subtitle ids="subtitle" names="subtitle"> + Subtitle + <section ids="another-section" names="another section"> + <title> + Another Section + <subtitle ids="another-subtitle" names="another subtitle"> + Another Subtitle +"""], ]) -- cgit v1.2.1 From 60dfd2224bbb89c00c32a2258c99ad78bc52939a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 18 May 2005 22:31:15 +0000 Subject: removed test for ":figwidth: image" because it has different output depending on whether PIL is installed or not; need to write another test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3352 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_directives/test_figures.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_figures.py b/test/test_parsers/test_rst/test_directives/test_figures.py index 7e63fda16..91fd91596 100755 --- a/test/test_parsers/test_rst/test_directives/test_figures.py +++ b/test/test_parsers/test_rst/test_directives/test_figures.py @@ -10,7 +10,6 @@ Tests for images.py figure directives. """ -import os.path from __init__ import DocutilsTestSupport def suite(): @@ -18,9 +17,6 @@ def suite(): s.generateTests(totest) return s -mydir = 'test_parsers/test_rst/test_directives/' -biohazard = os.path.join(mydir, '../../../../docs/user/rst/images/biohazard.png') - totest = {} totest['figures'] = [ @@ -290,15 +286,6 @@ Testing for line-leaks: <figure> <image uri="picture.png"> """], -["""\ -.. figure:: %s - :figwidth: image -""" % biohazard, -"""\ -<document source="test data"> - <figure width="16"> - <image uri="test_parsers/test_rst/test_directives/../../../../docs/user/rst/images/biohazard.png"> -"""], ] -- cgit v1.2.1 From caa4d0fc6528ad55bdd96434d7970ecc86931199 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 19 May 2005 00:49:14 +0000 Subject: renamed command-line options for SectSubTitle transform (plural reads better); tweaked test text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3353 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++-- docs/user/config.txt | 4 ++-- docutils/readers/standalone.py | 8 ++++---- test/test_transforms/test_doctitle.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ac312f6cb..178bfc47a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -123,8 +123,8 @@ Changes Since 0.3.7 * docutils/readers/standalone.py: - - Added ``--section-subtitle`` and ``--no-section-subtitle`` options - to activate or deactivate the SectSubTitle transform. + - Added ``--section-subtitles`` and ``--no-section-subtitles`` + options to activate or deactivate the SectSubTitle transform. * docutils/transforms/frontmatter.py: diff --git a/docs/user/config.txt b/docs/user/config.txt index c00d82133..63725cf73 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -468,8 +468,8 @@ _`sectsubtitle_xform` Enable or disable the promotion of the title of a lone subsection to a subtitle (docutils.transforms.frontmatter.SectSubTitle). - Default: disabled (0). Options: ``--section-subtitle, - --no-section-subtitle``. + Default: disabled (0). Options: ``--section-subtitles, + --no-section-subtitles``. [pep reader] diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 4cdea3df8..c7772aa48 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -38,13 +38,13 @@ class Reader(readers.Reader): ['--no-doc-info'], {'dest': 'docinfo_xform', 'action': 'store_false', 'default': 1, 'validator': frontend.validate_boolean}), - ('Activate the promotion of the title of a lone subsection to ' - 'a section subtitle (disabled by default).', - ['--section-subtitle'], + ('Activate the promotion of lone subsection titles to ' + 'section subtitles (disabled by default).', + ['--section-subtitles'], {'dest': 'sectsubtitle_xform', 'action': 'store_true', 'default': 0, 'validator': frontend.validate_boolean}), ('Deactivate the promotion of lone subsection titles.', - ['--no-section-subtitle'], + ['--no-section-subtitles'], {'dest': 'sectsubtitle_xform', 'action': 'store_false', 'validator': frontend.validate_boolean}), )) diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 0e2050494..3a672d1c2 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -189,7 +189,7 @@ substitution_definition. substitution_definition. """], ["""\ -This is no doc title. +(Because of this paragraph, the following is not a doc title.) =============== Section Title @@ -209,7 +209,7 @@ Another Subtitle """\ <document source="test data"> <paragraph> - This is no doc title. + (Because of this paragraph, the following is not a doc title.) <section ids="section-title" names="section title"> <title> Section Title -- cgit v1.2.1 From 77418191497fce93725befddcacb8a39c8869050 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 May 2005 22:27:23 +0000 Subject: more thorough figure testing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3354 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../expected/standalone_rst_html4css1.html | 25 ++++++++++++++-- test/functional/expected/standalone_rst_latex.tex | 28 ++++++++++++++++- .../expected/standalone_rst_pseudoxml.txt | 32 ++++++++++++++++++-- test/functional/input/data/standard.txt | 35 ++++++++++++++++++++-- 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 13f8c02c6..dcbe16a80 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -546,8 +546,8 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>An image directive (also clickable -- a hyperlink reference):</p> <div class="image class1 class2 image-reference"><a class="reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a></div> <p>A figure directive:</p> -<div align="left" class="figclass1 figclass2 figure"> -<div class="image class1 class2"><img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></div> +<div align="right" class="figclass1 figclass2 figure"> +<div class="image class1 class2"><img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> <p class="caption">A figure is an image with a caption and/or a legend:</p> <div class="legend"> <table border="1" class="docutils"> @@ -570,6 +570,27 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph is also part of the legend.</p> </div> </div> +<p>This paragraph might flow around the figure...</p> +<p>A centered figure:</p> +<div align="center" class="figure"> +<div class="image"><img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> +<p class="caption">This is the caption.</p> +<div class="legend"> +<p>This is the legend.</p> +<p>The legend may consist of several paragraphs.</p> +</div> +</div> +<p>This paragraph might flow around the figure...</p> +<p>A left-aligned figure:</p> +<div align="left" class="figure"> +<div class="image"><img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> +<p class="caption">This is the caption.</p> +<div class="legend"> +<p>This is the legend.</p> +<p>The legend may consist of several paragraphs.</p> +</div> +</div> +<p>This paragraph might flow around the figure...</p> </div> <div class="section" id="admonitions"> <h3><a class="toc-backref" href="#id64" name="admonitions">2.14.3   Admonitions</a></h3> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 5e937878c..368146eb0 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -864,7 +864,7 @@ An image directive (also clickable -{}- a hyperlink reference): A figure directive: \begin{figure}[htbp]\begin{center} -\includegraphics{../../../docs/user/rst/images/title.png} +\includegraphics{../../../docs/user/rst/images/biohazard.png} \caption{A figure is an image with a caption and/or a legend:}{\small \begin{longtable}[c]{|p{0.16\locallinewidth}|p{0.56\locallinewidth}|} \hline @@ -891,6 +891,32 @@ Well it is, isn't it? This paragraph is also part of the legend. }\end{center}\end{figure} +This paragraph might flow around the figure... + +A centered figure: +\begin{figure}[htbp]\begin{center} + +\includegraphics{../../../docs/user/rst/images/biohazard.png} +\caption{This is the caption.}{\small +This is the legend. + +The legend may consist of several paragraphs. +}\end{center}\end{figure} + +This paragraph might flow around the figure... + +A left-aligned figure: +\begin{figure}[htbp]\begin{center} + +\includegraphics{../../../docs/user/rst/images/biohazard.png} +\caption{This is the caption.}{\small +This is the legend. + +The legend may consist of several paragraphs. +}\end{center}\end{figure} + +This paragraph might flow around the figure... + %___________________________________________________________________________ diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 597408d23..92c7eccfe 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1122,8 +1122,8 @@ <image classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> <paragraph> A figure directive: - <figure align="left" classes="figclass1 figclass2"> - <image alt="reStructuredText, the markup syntax" classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> + <figure align="right" classes="figclass1 figclass2"> + <image alt="reStructuredText, the markup syntax" classes="class1 class2" uri="../../../docs/user/rst/images/biohazard.png" width="50"> <caption> A figure is an image with a caption and/or a legend: <legend> @@ -1155,6 +1155,34 @@ Well it is, isn't it? <paragraph> This paragraph is also part of the legend. + <paragraph> + This paragraph might flow around the figure... + <paragraph> + A centered figure: + <figure align="center"> + <image uri="../../../docs/user/rst/images/biohazard.png" width="50"> + <caption> + This is the caption. + <legend> + <paragraph> + This is the legend. + <paragraph> + The legend may consist of several paragraphs. + <paragraph> + This paragraph might flow around the figure... + <paragraph> + A left-aligned figure: + <figure align="left"> + <image uri="../../../docs/user/rst/images/biohazard.png" width="50"> + <caption> + This is the caption. + <legend> + <paragraph> + This is the legend. + <paragraph> + The legend may consist of several paragraphs. + <paragraph> + This paragraph might flow around the figure... <section ids="admonitions" names="admonitions"> <title auto="1" refid="id64"> <generated classes="sectnum"> diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index b06a158d4..2759d88e0 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -427,11 +427,12 @@ An image directive (also clickable -- a hyperlink reference): A figure directive: -.. figure:: ../../../docs/user/rst/images/title.png +.. figure:: ../../../docs/user/rst/images/biohazard.png :figclass: figclass1 figclass2 :class: class1 class2 :alt: reStructuredText, the markup syntax - :align: left + :align: right + :width: 50 A figure is an image with a caption and/or a legend: @@ -445,6 +446,36 @@ A figure directive: This paragraph is also part of the legend. +This paragraph might flow around the figure... + +A centered figure: + +.. figure:: ../../../docs/user/rst/images/biohazard.png + :align: center + :width: 50 + + This is the caption. + + This is the legend. + + The legend may consist of several paragraphs. + +This paragraph might flow around the figure... + +A left-aligned figure: + +.. figure:: ../../../docs/user/rst/images/biohazard.png + :align: left + :width: 50 + + This is the caption. + + This is the legend. + + The legend may consist of several paragraphs. + +This paragraph might flow around the figure... + Admonitions ``````````` -- cgit v1.2.1 From 6570a5fef9123233156b518e2e0a5164e6411410 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 May 2005 22:35:39 +0000 Subject: added to-do list entry for figwidth test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3355 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index fe74e54f4..2dd958920 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -677,6 +677,9 @@ __ rst/alternatives.html#or-not-to-do * Add (functional) tests for untested roles. +* Add test for ":figwidth: image" option of "figure" directive. (Test + code needs to check if PIL is available on the system.) + * The parser doesn't know anything about double-width characters such as Chinese hanza & Japanese kanji/kana. Also, it's dependent on whitespace and punctuation as markup delimiters, which may not be -- cgit v1.2.1 From d7cf3789302b13092b7eeef61fbf0573a11b7af4 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 May 2005 23:25:18 +0000 Subject: documented different traceback default for programmatic use git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3356 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index 63725cf73..de08d7960 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -356,9 +356,12 @@ _`traceback` reports. Exceptions are allowed to propagate, instead of being caught and reported (in a user-friendly way) by Docutils. - Default: disabled (None). Options: ``--traceback, + Default: disabled (None) unless Docutils is run programmatically + using the `Publisher Interface`_. Options: ``--traceback, --no-traceback``. + .. _Publisher Interface: ../api/publisher.html + _`warning_stream` Path to a file for the output of system messages (warnings) [#pwd]_. -- cgit v1.2.1 From b9e9b91de245c0bba4bf150665474806b6924e01 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 20 May 2005 23:51:58 +0000 Subject: restored alphabetical order git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3357 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index de08d7960..d72ab621d 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -309,6 +309,18 @@ _`output_encoding_error_handler` Default: "strict". Options: ``--output-encoding-error-handler, --output-encoding, -o``. +_`record_dependencies` + + Path to a file to which Docutils writes a list of files the input + file(s) depends on [#dependencies]_, e.g. due to file + inclusion. [#pwd]_ The format is one filename per line. This + option is particularly useful in conjunction with programs like + ``make``. + + Set to ``-`` in order to write dependencies to stdout. + + Default: None. Option: ``--record-dependencies``. + _`report_level` Verbosity threshold at or above which system messages are reported. @@ -368,18 +380,6 @@ _`warning_stream` Default: stderr (None). Options: ``--warnings``. -_`record_dependencies` - - Path to a file to which Docutils writes a list of files the input - file(s) depends on [#dependencies]_, e.g. due to file - inclusion. [#pwd]_ The format is one filename per line. This - option is particularly useful in conjunction with programs like - ``make``. - - Set to ``-`` in order to write dependencies to stdout. - - Default: None. Option: ``--record-dependencies``. - [parsers] --------- -- cgit v1.2.1 From 3600f164d1078d31b98a31f9dbd878b6e2b7bf11 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 21 May 2005 00:00:25 +0000 Subject: added --id-prefix and --auto-id-prefix options git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3358 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 14 ++++++++++++++ docutils/frontend.py | 3 +++ docutils/nodes.py | 5 +++-- test/test_nodes.py | 27 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index d72ab621d..a99bc5572 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -143,6 +143,13 @@ Some knowledge of Python_ is assumed for some attributes. Settings in the "[general]" section are always applied. +_`auto_id_prefix` + Prefix prepended to all auto-generated IDs generated within the + document, after id_prefix_. + + Default: "id". Options: ``--auto-id-prefix`` (hidden, intended + mainly for programmatic use). + _`datestamp` Include a time/datestamp in the document footer. Contains a format string for Python's ``time.strftime``. See the `time @@ -249,6 +256,13 @@ _`halt_level` Default: severe (4). Options: ``--halt, --strict``. +_`id_prefix` + Prefix prepended to all IDs generated within the document. See + also auto_id_prefix_. + + Default: "" (empty). Options: ``--id-prefix`` (hidden, intended + mainly for programmatic use). + _`input_encoding` The text encoding for input. diff --git a/docutils/frontend.py b/docutils/frontend.py index d84aa55f3..7cba1706f 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -436,6 +436,9 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ['--version', '-V'], {'action': 'version'}), ('Show this help message and exit.', ['--help', '-h'], {'action': 'help'}), + # Typically not useful for non-programmatical use. + (SUPPRESS_HELP, ['--id-prefix'], {'default': ''}), + (SUPPRESS_HELP, ['--auto-id-prefix'], {'default': 'id'}), # Hidden options, for development use only: (SUPPRESS_HELP, ['--dump-settings'], {'action': 'store_true'}), (SUPPRESS_HELP, ['--dump-internals'], {'action': 'store_true'}), diff --git a/docutils/nodes.py b/docutils/nodes.py index 5a8cd7c55..700b509d3 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -841,13 +841,14 @@ class document(Root, Structural, Element): msgnode += msg if not node['ids']: for name in node['names']: - id = make_id(name) + id = self.settings.id_prefix + make_id(name) if id and not self.ids.has_key(id): break else: id = '' while not id or self.ids.has_key(id): - id = 'id%s' % self.id_start + id = (self.settings.id_prefix + + self.settings.auto_id_prefix + str(self.id_start)) self.id_start += 1 node['ids'].append(id) self.ids[id] = node diff --git a/test/test_nodes.py b/test/test_nodes.py index faeb61eb7..ce2115c0e 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -230,6 +230,33 @@ class MiscFunctionTests(unittest.TestCase): normed = nodes.fully_normalize_name(input) self.assertEquals(normed, output) + def test_set_id_default(self): + # Default prefixes. + document = utils.new_document('test') + # From name. + element = nodes.Element(names=['test']) + document.set_id(element) + self.assertEquals(element['ids'], ['test']) + # Auto-generated. + element = nodes.Element() + document.set_id(element) + self.assertEquals(element['ids'], ['id1']) + + def test_set_id_custom(self): + # Custom prefixes. + document = utils.new_document('test') + # Change settings. + document.settings.id_prefix = 'prefix' + document.settings.auto_id_prefix = 'auto' + # From name. + element = nodes.Element(names=['test']) + document.set_id(element) + self.assertEquals(element['ids'], ['prefixtest']) + # Auto-generated. + element = nodes.Element() + document.set_id(element) + self.assertEquals(element['ids'], ['prefixauto1']) + if __name__ == '__main__': unittest.main() -- cgit v1.2.1 From 45c6b5e8d79755d798d4385f52029cad1f1c80cd Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 21 May 2005 00:27:12 +0000 Subject: added "(provide 'restructuredtext)" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3359 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 1bac6ebbe..fe39265b2 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -591,3 +591,6 @@ column is used (fill-column vs. end of previous/next line)." (defalias 'reST-title-char-p 'rest-title-char-p) (defalias 'reST-forward-title 'rest-forward-section) (defalias 'reST-backward-title 'rest-backward-section) + + +(provide 'restructuredtext) -- cgit v1.2.1 From 051dda33ce2b163d5595485c191af6c879b3b890 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 21 May 2005 00:31:39 +0000 Subject: added provide command for rst-mode as well git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3360 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst-mode.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/editors/emacs/rst-mode.el b/tools/editors/emacs/rst-mode.el index cb3c20148..8fc14e4a5 100644 --- a/tools/editors/emacs/rst-mode.el +++ b/tools/editors/emacs/rst-mode.el @@ -695,4 +695,6 @@ entered.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(provide 'rst-mode) + ;;; rst-mode.el ends here -- cgit v1.2.1 From 1232c391483e50564e1e6cc810ccdbe04ad310d1 Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 09:15:24 +0000 Subject: Fix tables starting with more than one multirow. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3361 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docutils/writers/latex2e.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 178bfc47a..bfb221e5b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -159,6 +159,7 @@ Changes Since 0.3.7 * 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. diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 9f883bb13..3a90efb08 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1216,7 +1216,10 @@ class LaTeXTranslator(nodes.NodeVisitor): # if the firstrow is a multirow, this actually is the second row. # this gets hairy if rowspans follow each other. if self.active_table.get_rowspan(0): - self.body.append(' & ') + count = 0 + while self.active_table.get_rowspan(count): + count += 1 + self.body.append(' & ') self.active_table.visit_entry() # increment cell count else: self.body.append(' & ') -- cgit v1.2.1 From 60b348491b95eff14dbc894db703b0175d3b3dd6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 12:01:41 +0000 Subject: added test for rowspanning tables with the LaTeX writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3362 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../expected/standalone_rst_html4css1.html | 9 ++-- test/functional/expected/standalone_rst_latex.tex | 48 ++++++++++++++++++++++ .../expected/standalone_rst_pseudoxml.txt | 14 ++----- test/functional/input/data/table_rowspan.txt | 6 +-- test/functional/input/standalone_rst_latex.txt | 1 + 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index dcbe16a80..b2c113964 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -822,12 +822,9 @@ Fifth test in HTML.<br />Line two.</div> <tr><td>body row 2</td> <td rowspan="2">Cells may span rows.</td> -<td rowspan="2"><ul class="first last simple"> -<li>Table cells</li> -<li>contain</li> -<li>body elements.</li> -</ul> -</td> +<td rowspan="2">Another +rowspanning +cell.</td> </tr> <tr><td>body row 3</td> </tr> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 368146eb0..f618b05c5 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -208,6 +208,8 @@ reStructuredText construct. \item {} \href{\#colspanning-tables}{2.18~~~Colspanning tables} +\item {} \href{\#rowspanning-tables}{2.19~~~Rowspanning tables} + \end{list} \item {} \href{\#tests-for-the-latex-writer}{3~~~Tests for the LaTeX writer} @@ -1254,6 +1256,52 @@ True \end{longtable} +%___________________________________________________________________________ + +\hypertarget{rowspanning-tables}{} +\pdfbookmark[1]{2.19~~~Rowspanning tables}{rowspanning-tables} +\subsection*{2.19~~~Rowspanning tables} + +Here's a table with cells spanning several rows: + +\begin{longtable}[c]{|p{0.30\locallinewidth}|p{0.16\locallinewidth}|p{0.23\locallinewidth}|} +\hline +\textbf{ +Header row, column 1 +(header rows optional) +} & \textbf{ +Header 2 +} & \textbf{ +Header 3 +} \\ +\hline +\endhead + +body row 1, column 1 + & +column 2 + & +column 3 + \\ +\hline + +body row 2 + & \multirow{2}{0.16\locallinewidth}{ +Cells may +span rows. +} & \multirow{2}{0.23\locallinewidth}{ +Another +rowspanning +cell. +} \\ +\cline{1-1} + +body row 3 + & \\ +\hline +\end{longtable} + + %___________________________________________________________________________ \hypertarget{tests-for-the-latex-writer}{} diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 92c7eccfe..38167aa22 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1542,16 +1542,10 @@ Cells may span rows. <entry morerows="1"> - <bullet_list bullet="-"> - <list_item> - <paragraph> - Table cells - <list_item> - <paragraph> - contain - <list_item> - <paragraph> - body elements. + <paragraph> + Another + rowspanning + cell. <row> <entry> <paragraph> diff --git a/test/functional/input/data/table_rowspan.txt b/test/functional/input/data/table_rowspan.txt index 0ccb0f71d..5df3109c4 100644 --- a/test/functional/input/data/table_rowspan.txt +++ b/test/functional/input/data/table_rowspan.txt @@ -9,7 +9,7 @@ Here's a table with cells spanning several rows: +========================+============+==================+ | body row 1, column 1 | column 2 | column 3 | +------------------------+------------+------------------+ -| body row 2 | Cells may | - Table cells | -+------------------------+ span rows. | - contain | -| body row 3 | | - body elements. | +| body row 2 | Cells may | Another | ++------------------------+ span rows. | rowspanning | +| body row 3 | | cell. | +------------------------+------------+------------------+ diff --git a/test/functional/input/standalone_rst_latex.txt b/test/functional/input/standalone_rst_latex.txt index a44810d9f..09a4f8890 100644 --- a/test/functional/input/standalone_rst_latex.txt +++ b/test/functional/input/standalone_rst_latex.txt @@ -1,5 +1,6 @@ .. include:: data/standard.txt .. include:: data/table_colspan.txt +.. include:: data/table_rowspan.txt Tests for the LaTeX writer -- cgit v1.2.1 From 0a9a7c9ed49f0a3320ffeba38df3a06a3424ad2f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 23:41:17 +0000 Subject: some updates of doc files from CVS to SVN git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3363 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/enthought-plan.txt | 11 ++++++----- docs/dev/testing.txt | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/dev/enthought-plan.txt b/docs/dev/enthought-plan.txt index e37bb0ded..0ab0d3c83 100644 --- a/docs/dev/enthought-plan.txt +++ b/docs/dev/enthought-plan.txt @@ -91,12 +91,13 @@ Repository ========== If possible, all software and documentation files will be stored in -the CVS repository of Docutils and/or the base project, which are all -publicly-available via anonymous pserver access. +the Subversion repository of Docutils and/or the base project, which +are all publicly-available via anonymous pserver access. -The Docutils project is very open about granting CVS write access; so -far, everyone who asked has been given access. Any Enthought staff -member who would like CVS write access will get it. +The Docutils project is very open about granting Subversion write +access; so far, everyone who asked has been given access. Any +Enthought staff member who would like Subversion write access will get +it. If either Epydoc or HappyDoc is chosen as the base platform, I will ask the project's administrator for CVS access for myself and any diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index 53faff37e..c3e9486c6 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -169,7 +169,7 @@ match the expected output anymore, the test will fail. If this is the case and you made an intentional change, check the actual output for validity and correctness, copy it to ``functional/expected/`` (overwriting the old expected output), and -commit the change to CVS. +commit the change. .. _default configuration file: -- cgit v1.2.1 From 4e18a9066509d7a767315773806789e589fb49ac Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 23:44:08 +0000 Subject: documented ignoring of functional test config files which start with an underscore git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3364 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/testing.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index c3e9486c6..cc4f4881d 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -118,7 +118,8 @@ The Testing Process ------------------- When running ``test_functional.py``, all config files in -``functional/tests/`` are processed. +``functional/tests/`` are processed. (Config files whose names begin +with an underscore are ignored.) For example, ``functional/tests/some_test.py`` could read like this:: -- cgit v1.2.1 From addb725de29a5e58a7c82d3d070c9a0b2b20704a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 23:58:09 +0000 Subject: added information about working directory git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3365 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/testing.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index cc4f4881d..9feac9c6a 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -119,7 +119,8 @@ The Testing Process When running ``test_functional.py``, all config files in ``functional/tests/`` are processed. (Config files whose names begin -with an underscore are ignored.) +with an underscore are ignored.) The current working directory is +always Docutils' main test directory (``test/``). For example, ``functional/tests/some_test.py`` could read like this:: @@ -132,6 +133,8 @@ For example, ``functional/tests/some_test.py`` could read like this:: parser_name = "rst" writer_name = "html" settings_overrides['output-encoding'] = 'utf-8' + # Relative to main ``test/`` directory. + settings_overrides['stylesheet_path'] = '../tools/stylesheets/default.css' The two variables ``test_source`` and ``test_destination`` contain the input file name (relative to ``functional/input/``) and the output -- cgit v1.2.1 From e2e8e1fc7284f27455d69622344e976fde8094fc Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 25 May 2005 23:59:45 +0000 Subject: added defaults file for standalone_rst_... tests git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3366 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/tests/_standalone_rst_defaults.py | 6 ++++++ test/functional/tests/standalone_rst_html4css1.py | 6 +++--- test/functional/tests/standalone_rst_latex.py | 4 ++-- test/functional/tests/standalone_rst_pseudoxml.py | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 test/functional/tests/_standalone_rst_defaults.py diff --git a/test/functional/tests/_standalone_rst_defaults.py b/test/functional/tests/_standalone_rst_defaults.py new file mode 100644 index 000000000..b51704929 --- /dev/null +++ b/test/functional/tests/_standalone_rst_defaults.py @@ -0,0 +1,6 @@ +# Keyword parameters passed to publish_file. +reader_name = "standalone" +parser_name = "rst" + +# Settings. +settings_overrides['sectsubtitle_xform'] = 1 diff --git a/test/functional/tests/standalone_rst_html4css1.py b/test/functional/tests/standalone_rst_html4css1.py index c7a2b7301..54252e83f 100644 --- a/test/functional/tests/standalone_rst_html4css1.py +++ b/test/functional/tests/standalone_rst_html4css1.py @@ -1,12 +1,12 @@ +execfile('functional/tests/_standalone_rst_defaults.py') + # Source and destination file names. test_source = "standalone_rst_html4css1.txt" test_destination = "standalone_rst_html4css1.html" # Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" writer_name = "html4css1" -# Settings +# Settings. settings_overrides['stylesheet'] = None settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" diff --git a/test/functional/tests/standalone_rst_latex.py b/test/functional/tests/standalone_rst_latex.py index a39bf6df1..f0c40b75a 100644 --- a/test/functional/tests/standalone_rst_latex.py +++ b/test/functional/tests/standalone_rst_latex.py @@ -1,8 +1,8 @@ +execfile('functional/tests/_standalone_rst_defaults.py') + # Source and destination file names. test_source = "standalone_rst_latex.txt" test_destination = "standalone_rst_latex.tex" # Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" writer_name = "latex" diff --git a/test/functional/tests/standalone_rst_pseudoxml.py b/test/functional/tests/standalone_rst_pseudoxml.py index 4df832f64..05be80899 100644 --- a/test/functional/tests/standalone_rst_pseudoxml.py +++ b/test/functional/tests/standalone_rst_pseudoxml.py @@ -1,8 +1,8 @@ +execfile('functional/tests/_standalone_rst_defaults.py') + # Source and destination file names. test_source = "standalone_rst_html4css1.txt" test_destination = "standalone_rst_pseudoxml.txt" # Keyword parameters passed to publish_file. -reader_name = "standalone" -parser_name = "rst" writer_name = "pseudoxml" -- cgit v1.2.1 From 2c3a254f2a8e5e6a66fee2426b626fa8a853491b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 26 May 2005 00:44:13 +0000 Subject: added support and test for section subtitles git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3367 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 13 ++++++++++++- docutils/writers/latex2e.py | 8 +++++--- test/functional/expected/standalone_rst_html4css1.html | 13 +++++++------ test/functional/expected/standalone_rst_latex.tex | 2 ++ test/functional/expected/standalone_rst_pseudoxml.txt | 12 +++++++----- test/functional/input/data/standard.txt | 2 ++ tools/stylesheets/default.css | 9 ++++++++- 7 files changed, 43 insertions(+), 16 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5130bf1d4..1a7d44f0a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1206,6 +1206,12 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) self.context.append('</h2>\n') self.in_document_title = len(self.body) + elif isinstance(node.parent, nodes.section): + tag = 'h%s' % (self.section_level + self.initial_header_level - 1) + self.body.append( + self.starttag(node, tag, '', CLASS='section-subtitle') + + self.starttag({}, 'span', '', CLASS='section-subtitle')) + self.context.append('</span></%s>\n' % tag) def depart_subtitle(self, node): self.body.append(self.context.pop()) @@ -1354,9 +1360,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.context.append('</h1>\n') self.in_document_title = len(self.body) else: + assert isinstance(node.parent, nodes.section) h_level = self.section_level + self.initial_header_level - 1 + atts = {} + if (len(node.parent) >= 2 and + isinstance(node.parent[1], nodes.subtitle)): + atts['CLASS'] = 'with-subtitle' self.body.append( - self.starttag(node, 'h%s' % h_level, '')) + self.starttag(node, 'h%s' % h_level, '', **atts)) atts = {} if node.parent['ids']: atts['name'] = node.parent['ids'][0] diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 3a90efb08..dc7df9731 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1815,14 +1815,16 @@ class LaTeXTranslator(nodes.NodeVisitor): if isinstance(node.parent, nodes.sidebar): self.body.append('~\\\\\n\\textbf{') self.context.append('}\n\\smallskip\n') - else: + elif isinstance(node.parent, nodes.document): self.title = self.title + \ '\\\\\n\\large{%s}\n' % self.encode(node.astext()) raise nodes.SkipNode + elif isinstance(node.parent, nodes.section): + self.body.append('\\textbf{') + self.context.append('}\\vspace{0.2cm}\n\n\\noindent ') def depart_subtitle(self, node): - if isinstance(node.parent, nodes.sidebar): - self.body.append(self.context.pop()) + self.body.append(self.context.pop()) def visit_system_message(self, node): if node['level'] < self.document.reporter.report_level: diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index b2c113964..3666d6e18 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -140,7 +140,8 @@ They are transformed from section titles after parsing. --> <div class="section" id="structural-elements"> <h1><a class="toc-backref" href="#id25" name="structural-elements">1   Structural Elements</a></h1> <div class="section" id="section-title"> -<h2><a class="toc-backref" href="#id26" name="section-title">1.1   Section Title</a></h2> +<h2 class="with-subtitle"><a class="toc-backref" href="#id26" name="section-title">1.1   Section Title</a></h2> +<h2 class="section-subtitle" id="section-subtitle"><span class="section-subtitle">Section Subtitle</span></h2> <p>That's it, the text just above this line.</p> </div> <div class="section" id="empty-section"> @@ -924,19 +925,19 @@ section, "Docutils System Messages":</p> <div class="system-messages section"> <h1><a>Docutils System Messages</a></h1> <div class="system-message" id="id19"> -<p class="system-message-title">System Message: <a name="id19">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 98); <em><a href="#id20">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id19">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 100); <em><a href="#id20">backlink</a></em></p> Undefined substitution referenced: "problematic".</div> <div class="system-message" id="id69"> -<p class="system-message-title">System Message: <a name="id69">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 352); <em><a href="#id70">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id69">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 354); <em><a href="#id70">backlink</a></em></p> Unknown target name: "5".</div> <div class="system-message" id="id71"> -<p class="system-message-title">System Message: <a name="id71">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 361); <em><a href="#id72">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id71">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 363); <em><a href="#id72">backlink</a></em></p> Unknown target name: "nonexistent".</div> <div class="system-message" id="id73"> -<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 388); <em><a href="#id74">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 390); <em><a href="#id74">backlink</a></em></p> Unknown target name: "hyperlink reference without a target".</div> <div class="system-message" id="id75"> -<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 401); <em><a href="#id76">backlink</a></em></p> +<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 403); <em><a href="#id76">backlink</a></em></p> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index f618b05c5..ec682aa52 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -238,7 +238,9 @@ reStructuredText construct. \hypertarget{section-title}{} \pdfbookmark[1]{1.1~~~Section Title}{section-title} \subsection*{1.1~~~Section Title} +\textbf{Section Subtitle}\vspace{0.2cm} +\noindent That's it, the text just above this line. diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 38167aa22..1c21abc9a 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -326,6 +326,8 @@ <generated classes="sectnum"> 1.1    Section Title + <subtitle ids="section-subtitle" names="section subtitle"> + Section Subtitle <paragraph> That's it, the text just above this line. <section ids="empty-section" names="empty section"> @@ -1707,18 +1709,18 @@ <section classes="system-messages"> <title> Docutils System Messages - <system_message backrefs="id20" ids="id19" level="3" line="98" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id20" ids="id19" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id70" ids="id69" level="3" line="352" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id70" ids="id69" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id72" ids="id71" level="3" line="361" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id72" ids="id71" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id74" ids="id73" level="3" line="388" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id74" ids="id73" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id76" ids="id75" level="3" line="401" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id76" ids="id75" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 2759d88e0..a4a75b078 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -65,6 +65,8 @@ Structural Elements Section Title ------------- +Section Subtitle +```````````````` That's it, the text just above this line. diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 2cfc4c892..cec78e53b 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -14,7 +14,7 @@ Default cascading style sheet for the HTML output of Docutils. .first { margin-top: 0 ! important } -.last { +.last, .with-subtitle { margin-bottom: 0 ! important } .hidden { @@ -125,6 +125,10 @@ div.system-message p.system-message-title { div.topic { margin: 2em } +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + h1.title { text-align: center } @@ -219,6 +223,9 @@ span.pre { span.problematic { color: red } +span.section-subtitle { + font-size: 80% } + table.citation { border-left: solid thin gray } -- cgit v1.2.1 From c47a6a229e99e9ac7044eb477ff26cda7c64fbac Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 26 May 2005 10:51:39 +0000 Subject: added explanatory comment about span.section-subtitle git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3368 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index cec78e53b..608aad487 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -224,6 +224,7 @@ span.problematic { color: red } span.section-subtitle { + /* font-size relative to parent (<h#> element) */ font-size: 80% } table.citation { -- cgit v1.2.1 From 7d1537cefc9c0291d0ebeb8762709bd6a4aa3241 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 26 May 2005 11:04:17 +0000 Subject: added history entries for section subtitle support in writers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3369 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index bfb221e5b..d578e7403 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -156,6 +156,7 @@ Changes Since 0.3.7 - 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: @@ -167,6 +168,7 @@ Changes Since 0.3.7 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/null.py: Added to project; a do-nothing Writer. -- cgit v1.2.1 From 8691ba2bdfae4c01a7bbbdfb8ae4fe8824efb4f9 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 26 May 2005 11:39:39 +0000 Subject: added "see also" references git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3370 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index a99bc5572..1b52511b4 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -407,7 +407,8 @@ Docutils currently supports only one parser, for reStructuredText. _`file_insertion_enabled` Enable or disable directives that insert the contents of external files, such as the "include_" & "raw_". A "warning" system - message (including the directive text) is inserted instead. + message (including the directive text) is inserted instead. (See + also raw_enabled_ for another security-relevant setting.) Default: enabled (1). Options: ``--file-insertion-enabled, --no-file-insertion``. @@ -429,7 +430,9 @@ _`pep_base_url` _`raw_enabled` Enable or disable the "raw_" directive. A "warning" system - message (including the directive text) is inserted instead. + message (including the directive text) is inserted instead. (See + also file_insertion_enabled_ for another security-relevant + setting.) Default: enabled (1). Options: ``--raw-enabled, --no-raw``. @@ -583,7 +586,8 @@ _`embed_stylesheet` _`field_name_limit` The maximum width (in characters) for one-column field names. Longer field names will span an entire row of the table used to - render the field list. 0 indicates "no limit". + render the field list. 0 indicates "no limit". See also + option_limit_. Default: 14 characters. Option: ``--field-name-limit``. @@ -611,7 +615,8 @@ _`initial_header_level` _`option_limit` The maximum width (in characters) for options in option lists. Longer options will span an entire row of the table used to render - the option list. 0 indicates "no limit". + the option list. 0 indicates "no limit". See also + field_name_limit_. Default: 14 characters. Option: ``--option-limit``. -- cgit v1.2.1 From e78956c8fc478dc7ef264531983024e8269130ea Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 26 May 2005 21:21:48 +0000 Subject: Release 0.3.9: set version number to 0.3.9 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3374 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- setup.py | 2 +- test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/expected/misc_rst_html4css1.html | 2 +- test/functional/expected/pep_html.html | 2 +- test/functional/expected/standalone_rst_html4css1.html | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 662f0a097..8484967f5 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.8' +__version__ = '0.3.9' """``major.minor.micro`` version number. The micro number is bumped for API changes, for new functionality, and for interim project releases. The minor number is bumped whenever there is a significant project release. The major diff --git a/setup.py b/setup.py index 218650b30..6fc4879b3 100755 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ into useful formats, such as HTML, XML, and LaTeX. For input Docutils supports reStructuredText, an easy-to-read, what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'url': 'http://docutils.sourceforge.net/', - 'version': '0.3.8', + 'version': '0.3.9', 'author': 'David Goodger', 'author_email': 'goodger@users.sourceforge.net', 'license': 'public domain, Python, BSD, GPL (see COPYING.txt)', diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 184417b5e..df3de8cef 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" /> +<meta name="generator" content="Docutils 0.3.9: http://docutils.sourceforge.net/" /> <title> diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index f5e7aaa78..f961650ae 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -3,7 +3,7 @@ - + diff --git a/test/functional/expected/misc_rst_html4css1.html b/test/functional/expected/misc_rst_html4css1.html index 9301f6686..324152872 100644 --- a/test/functional/expected/misc_rst_html4css1.html +++ b/test/functional/expected/misc_rst_html4css1.html @@ -3,7 +3,7 @@ - + diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index 00d7d1d2b..a1b9f2791 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -8,7 +8,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! --> - + PEP 100 -- Test PEP diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 3666d6e18..bc06486a2 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -3,7 +3,7 @@ - + reStructuredText Test Document -- cgit v1.2.1 From ae8ef9f0962000f94e643940da8d495097141f1a Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 26 May 2005 21:22:16 +0000 Subject: Release 0.3.9: closed "Changes Since ..." section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3375 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index d578e7403..2542a4019 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -11,8 +11,8 @@ .. contents:: -Changes Since 0.3.7 -=================== +Release 0.3.9 (2005-05-26) +========================== * General: -- cgit v1.2.1 From da24d3d9d27f18e38f4bb345f1f9965e985391a8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 26 May 2005 21:33:24 +0000 Subject: added __future__ statement to avoid warnings about nested scopes with Python 2.1. Sorry David, there's just no other quick way I can avoid this. ;-) And making named functions out of the lambdas would look terrible... git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3376 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 7f8baaf3f..aee2c9f6f 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -15,6 +15,8 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' +from __future__ import nested_scopes + import re import os.path from types import ListType -- cgit v1.2.1 From 63fff375aa144a601b0e9588f1868f1b15c21703 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 26 May 2005 22:52:48 +0000 Subject: Release 0.3.9: set version number to 0.3.10 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3379 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 +- setup.py | 2 +- test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/expected/misc_rst_html4css1.html | 2 +- test/functional/expected/pep_html.html | 2 +- test/functional/expected/standalone_rst_html4css1.html | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 8484967f5..10bc7fd46 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -51,7 +51,7 @@ Subpackages: __docformat__ = 'reStructuredText' -__version__ = '0.3.9' +__version__ = '0.3.10' """``major.minor.micro`` version number. The micro number is bumped for API changes, for new functionality, and for interim project releases. The minor number is bumped whenever there is a significant project release. The major diff --git a/setup.py b/setup.py index 6fc4879b3..cb737ef7d 100755 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ into useful formats, such as HTML, XML, and LaTeX. For input Docutils supports reStructuredText, an easy-to-read, what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'url': 'http://docutils.sourceforge.net/', - 'version': '0.3.9', + 'version': '0.3.10', 'author': 'David Goodger', 'author_email': 'goodger@users.sourceforge.net', 'license': 'public domain, Python, BSD, GPL (see COPYING.txt)', diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index df3de8cef..42236c729 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -3,7 +3,7 @@ - + diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index f961650ae..3b8b36a89 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -3,7 +3,7 @@ - + diff --git a/test/functional/expected/misc_rst_html4css1.html b/test/functional/expected/misc_rst_html4css1.html index 324152872..aeaa58e87 100644 --- a/test/functional/expected/misc_rst_html4css1.html +++ b/test/functional/expected/misc_rst_html4css1.html @@ -3,7 +3,7 @@ - + diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index a1b9f2791..f65f5d875 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -8,7 +8,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! --> - + PEP 100 -- Test PEP diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index bc06486a2..f0ec8afb2 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -3,7 +3,7 @@ - + reStructuredText Test Document -- cgit v1.2.1 From 6999f93edbcb3f3cf6d735f2987dd1f8bbd3e130 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 26 May 2005 22:53:55 +0000 Subject: Release 0.3.9: added empty "Changes Since 0.3.9" section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3380 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 2542a4019..f5a6e653d 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -11,6 +11,10 @@ .. contents:: +Changes Since 0.3.9 +=================== + + Release 0.3.9 (2005-05-26) ========================== -- cgit v1.2.1 From caf8da4ece842aa51365a61dde28e0206fbc4b93 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 27 May 2005 20:46:54 +0000 Subject: moved section "Web Access" to the top git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3384 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index ade960c12..e22b0d428 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -23,6 +23,13 @@ Subversion is exhaustively documented in the `Subversion Book`_ Accessing the Repository ======================== +Web Access +---------- + +The repository can be browsed and examined via the web at +http://svn.berlios.de/viewcvs/docutils/. + + Anonymous Access ---------------- @@ -143,13 +150,6 @@ your shell account. password. -Web Access ----------- - -The repository can be browsed and examined via the web at -http://svn.berlios.de/viewcvs/docutils/. - - Repository Layout ================= -- cgit v1.2.1 From 4cdf5b9a94efda7e196720509ac9d16b50b70a4f Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 27 May 2005 22:50:24 +0000 Subject: added borderless class for images; removed angle brackets which cause problems when embedding the style sheet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3391 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 608aad487..c79647380 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -138,6 +138,9 @@ h2.subtitle { hr.docutils { width: 75% } +img.borderless { + border: 0 } + ol.simple, ul.simple { margin-bottom: 1em } @@ -224,7 +227,7 @@ span.problematic { color: red } span.section-subtitle { - /* font-size relative to parent ( element) */ + /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { -- cgit v1.2.1 From fa2db94c8f7c89a8ca41639eaf7925dc5506eaca Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 27 May 2005 23:26:21 +0000 Subject: moved mailing-lists.txt to docs/user so that it is included in the Docutils distribution git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3393 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 1 + docs/user/mailing-lists.txt | 108 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 docs/user/mailing-lists.txt diff --git a/docs/index.txt b/docs/index.txt index 230761c10..1d8449a97 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -82,6 +82,7 @@ Docutils-general: * `Docutils Front-End Tools `__ * `Docutils Configuration Files `__ * `Docutils LaTeX Writer `__ +* `Docutils Mailing Lists `__ `reStructuredText `_: diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt new file mode 100644 index 000000000..e033f0cb8 --- /dev/null +++ b/docs/user/mailing-lists.txt @@ -0,0 +1,108 @@ +========================= + Docutils_ Mailing Lists +========================= + +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + + +All discussion about Docutils takes place on mailing lists. + +There are four different lists with traffic related to Docutils. If +unsure, use the **Docutils-users** mailing list: + + +Docutils-users +-------------- + +The Docutils-users mailing list is a place to discuss any issues +related to the usage of Docutils and reStructuredText. (Please be +sure to check the FAQ_ first.) + +There are three possibilities to **read and post** messages on the +mailing lists; use the one you feel most comfortable with. + +* Using an `email subscription`__. This is the traditional way; you + will receive all messages sent to the mailing list via email. + + __ http://lists.sourceforge.net/lists/listinfo/docutils-users + +* Using Gmane's `web interface`__. To post a message, click "post" or + "followup" in the drop-down menu on the right. + + __ http://news.gmane.org/gmane.text.docutils.user + +* If you prefer using a newsreader, you can also use Gmane's `NNTP + interface`__ (gmane.text.docutils.user on news.gmane.org). + + __ nntp://news.gmane.org/gmane.text.docutils.user. + +**If you do not wish to subscribe,** you can also just send an email +to Docutils-users@lists.sourceforge.net. Please note in your email +that you are not subscribed (to make sure that you receive copies +[CCs] of any replies). + +The first time you post a message without being subscribed (also when +posting via Gmane), you will receive an email with the subject "Your +message to Docutils-users awaits moderator approval"; this is done to +prevent spam to the mailing lists. Your message will usually be +approved within a few hours. To avoid duplicates, please do not +resend your message using a different email address. + + +Doc-SIG +------- + +The "Python Documentation Special Interest Group" (Doc-SIG) mailing +list is occasionally used to discuss the usage of Docutils for Python +documentation. + +This mailing list can be accessed via `email subscription`__, web__ or +news__ (gmane.comp.python.documentation) as well. You must be +subscribed in order to post messages to this mailing list. + +__ http://mail.python.org/mailman/listinfo/doc-sig +__ http://news.gmane.org/gmane.comp.python.documentation +__ nntp://news.gmane.org/gmane.comp.python.documentation + + +Docutils-develop +---------------- + +Discussions about developing and extending Docutils take place on the +Docutils-develop mailing list. + +You can access this list via `email subscription`__, web__ or news__ +(gmane.text.docutils.devel); the posting address is +Docutils-develop@lists.sourceforge.net. + +__ http://lists.sourceforge.net/lists/listinfo/docutils-develop +__ http://news.gmane.org/gmane.text.docutils.devel +__ nntp://news.gmane.org/gmane.text.docutils.devel + +Docutils-checkins +----------------- + +All check-ins to the `Subversion repository`_ cause a "check-in email" +to the Docutils-checkins list. In order to stay informed about +current development, developers are advised to monitor this mailing +list as well. + + +This mailing list is for reading only; please direct any discussion +about the check-ins to Docutils-develop. (For your convenience, the +Reply-To header of all check-in emails points to Docutils-develop.) + +This mailing list is accessible via `email subscription`__, web__ or +news__ (gmane.text.docutils.cvs) as well. + +__ http://lists.sourceforge.net/lists/listinfo/docutils-checkins +__ http://news.gmane.org/gmane.text.docutils.cvs +__ nntp://news.gmane.org/gmane.text.docutils.cvs + +.. _Subversion repository: http://docutils.sf.net/docs/dev/repository.html +.. _Docutils: http://docutils.sourceforge.net/ +.. _FAQ: http://docutils.sourceforge.net/FAQ.html -- cgit v1.2.1 From 5817462e98504cbdf9be51649639273ed604c739 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 27 May 2005 23:30:32 +0000 Subject: updated rst-roles howto to match new "classes" list attribute git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3394 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/rst-roles.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/howto/rst-roles.txt b/docs/howto/rst-roles.txt index f271bff9d..f8ce08bca 100644 --- a/docs/howto/rst-roles.txt +++ b/docs/howto/rst-roles.txt @@ -199,8 +199,10 @@ Here is the implementation of the role:: prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] # Base URL mainly used by inliner.rfc_reference, so this is correct: - ref = inliner.rfc_url % rfcnum - node = nodes.reference(rawtext, 'RFC ' + text, refuri=ref, **options) + ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum + set_classes(options) + node = nodes.reference(rawtext, 'RFC ' + utils.unescape(text), refuri=ref, + **options) return [node], [] register_canonical_role('rfc-reference', rfc_reference_role) @@ -218,7 +220,9 @@ Noteworthy in the code above are: the "refuri" attribute of a "reference" element. 3. The ``options`` function parameter, a dictionary, may contain a - "class" customization attribute; it is passed through to the - "reference" element node constructor. + "class" customization attribute; it is interpreted and replaced + with a "classes" attribute by the ``set_classes()`` function. The + resulting "classes" attribute is passed through to the "reference" + element node constructor. .. _RFCs: http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=rfc&action=Search&sourceid=Mozilla-search -- cgit v1.2.1 From b7b2f9f3ecf1b3877314db63d09242dfe71b41fc Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 28 May 2005 00:30:02 +0000 Subject: replaced references to the mailing lists with references to the new "mailing-lists" document git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3396 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 15 +++------------ FAQ.txt | 17 +++-------------- README.txt | 33 ++++++++++++--------------------- docs/api/runtime-settings.txt | 4 ++-- docs/dev/policies.txt | 19 +++---------------- docs/dev/release.txt | 4 ++-- docs/ref/rst/directives.txt | 10 ++++++---- docs/ref/rst/roles.txt | 6 ++++-- docs/user/rst/quickstart.txt | 9 +++------ docs/user/tools.txt | 12 ++++-------- docutils/core.py | 3 ++- 11 files changed, 44 insertions(+), 88 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 4e97af5a1..b7a4e1d1b 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -46,8 +46,8 @@ First, make sure it's a new bug: documentation_ (don't forget the FAQ_!) and `mailing list archives`_ for evidence that it should behave the way you expect. -If you're not sure, please ask on the -docutils-users@lists.sourceforge.net [1]_ mailing list first. +If you're not sure, please ask on the Docutils-users_ mailing list +first. If it's a new bug, the most important thing you can do is to write a simple description and a recipe that reproduces the bug. Try to @@ -92,16 +92,6 @@ Thank you! (This section was inspired by the `Subversion project's`__ BUGS__ file.) -.. [1] Due to overwhelming amounts of spam, the - docutils-users@lists.sourceforge.net mailing list has been set up - for subscriber posting only. Non-subscribers who post to - docutils-users will receive a message with "Subject: Your message - to Docutils-users awaits moderator approval". Legitimate messages - are accepted and posted as soon as possible (a list administrator - must verify the message manually). If you'd like to subscribe to - docutils-users, please visit - . - __ http://subversion.tigris.org/ __ http://svn.collab.net/viewcvs/svn/trunk/BUGS?view=markup @@ -110,6 +100,7 @@ __ http://svn.collab.net/viewcvs/svn/trunk/BUGS?view=markup .. _documentation: docs/ .. _FAQ: FAQ.html .. _mailing list archives: http://docutils.sf.net/#mailing-lists +.. _Docutils-users: docs/user/mailing-lists.html#docutils-users .. _SourceForge Bug Tracker: http://sourceforge.net/tracker/?group_id=38414&atid=422030 diff --git a/FAQ.txt b/FAQ.txt index 43ca284a4..67a343120 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -17,23 +17,12 @@ This is a work in progress. Please feel free to ask questions and/or -provide answers; `send email`__ to the `Docutils-Users mailing list`__ -[1]_. Project members should feel free to edit the source text file +provide answers; send email to the `Docutils-users`_ mailing list. +Project members should feel free to edit the source text file directly. -.. [1] Due to overwhelming amounts of spam, the - docutils-users@lists.sourceforge.net mailing list has been set up - for subscriber posting only. Non-subscribers who post to - docutils-users will receive a message with "Subject: Your message - to Docutils-users awaits moderator approval". Legitimate messages - are accepted and posted as soon as possible (a list administrator - must verify the message manually). If you'd like to subscribe to - docutils-users, please visit - . - .. _let us know: -__ mailto:docutils-users@lists.sourceforge.net -__ http://lists.sourceforge.net/lists/listinfo/docutils-users +.. _Docutils-users: docs/user/mailing-lists.html#docutils-users Docutils diff --git a/README.txt b/README.txt index ad860dced..dff191e9e 100644 --- a/README.txt +++ b/README.txt @@ -320,10 +320,11 @@ 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 email`_ -[2]_. Please include all relevant output, information about your -operating system, Python version, and Docutils version. To see the -Docutils version, use these commands in the shell:: +If any of the tests fail, please `open a bug report`_, `send email`_, +or post a message via the `web interface`_. Please include all +relevant output, information about your operating system, Python +version, and Docutils version. To see the Docutils version, use these +commands in the shell:: cd ../tools ./quicktest.py --version @@ -336,29 +337,19 @@ Windows users type these commands:: .. _open a bug report: http://sourceforge.net/tracker/?group_id=38414&atid=422030 .. _send email: mailto:docutils-users@lists.sourceforge.net - ?subject=Docutils%20test%20suite%20failure + ?subject=Test%20suite%20failure +.. _web interface: http://post.gmane.org/post.php + ?group=gmane.text.docutils.user&subject=Test+suite+failure Getting Help ============ If you have questions or need assistance with Docutils or -reStructuredText, please `post a message`_ to the `Docutils-Users -mailing list`_ [2]_. - -.. [2] Due to overwhelming amounts of spam, the - docutils-users@lists.sourceforge.net mailing list has been set up - for subscriber posting only. Non-subscribers who post to - docutils-users will receive a message with "Subject: Your message - to Docutils-users awaits moderator approval". Legitimate messages - are accepted and posted as soon as possible (a list administrator - must verify the message manually). If you'd like to subscribe to - docutils-users, please visit - . - -.. _post a message: mailto:docutils-users@lists.sourceforge.net -.. _Docutils-Users mailing list: - http://lists.sourceforge.net/lists/listinfo/docutils-users +reStructuredText, please post a message to the Docutils-users_ mailing +list. + +.. _Docutils-users: docs/user/mailing-lists.html#docutils-users .. diff --git a/docs/api/runtime-settings.txt b/docs/api/runtime-settings.txt index d6b8997cd..0da1ae6d9 100644 --- a/docs/api/runtime-settings.txt +++ b/docs/api/runtime-settings.txt @@ -176,7 +176,7 @@ application calls one of ``publish_file``, ``publish_string``, or which implements a generic programmatic interface. Although an application may also call ``publish_programmatically`` directly, it is not recommended (if it does seem to be necessary, please write to the -`Docutils-Develop mailing list`_). +Docutils-develop_ mailing list). ``publish_programmatically`` accepts the same `convenience function parameters`_ as ``publish_cmdline``. Where things differ is that @@ -189,4 +189,4 @@ up the runtime settings. .. copy & modify the list from command-line tools? -.. _Docutils-Develop mailing list: docutils-develop@lists.sf.net +.. _Docutils-develop: ../users/mailing-lists.html#docutils-develop diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 99eade2e7..f21ed470e 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -306,22 +306,9 @@ meaning. There are two ways to keep the Docutils code accessible: Mailing Lists ============= -Developers should subscribe to the mailing lists: - -* The `Python Documentation Special Interest Group (Doc-SIG) mailing - list`__ for high-level discussions on syntax, strategy, and design - (email to Doc-SIG@python.org). -* Docutils-develop__, for implementation discussions - (email to docutils-develop@lists.sourceforge.net). -* Docutils-checkins__, to monitor Subversion check-in messages - (automatically generated; normally read-only). -* Docutils-users__, to monitor and help out with usage issues and bug - reports. - -__ http://mail.python.org/mailman/listinfo/doc-sig -__ http://lists.sourceforge.net/lists/listinfo/docutils-develop -__ http://lists.sourceforge.net/lists/listinfo/docutils-checkins -__ http://lists.sourceforge.net/lists/listinfo/docutils-users +Developers are recommended to subscribe to all `mailing lists`_. + +.. _mailing lists:: ../user/mailing-lists.html The Sandbox diff --git a/docs/dev/release.txt b/docs/dev/release.txt index 7ae12af88..fd941e5d3 100644 --- a/docs/dev/release.txt +++ b/docs/dev/release.txt @@ -15,7 +15,7 @@ sandbox/felixwiemann/release.sh. "Not covered" means that you aren't even reminded of them. Note: The release.sh script needs to be updated to reflect the recent move to Subversion!) -* **Announce a checkin freeze on Docutils-develop. Post a list of +* **Announce a check-in freeze on Docutils-develop. Post a list of major changes since the last release and ask for additions.** .. _CHANGES.txt: @@ -137,7 +137,7 @@ updated to reflect the recent move to Subversion!) * **Send announcement email to:** * docutils-develop@lists.sourceforge.net (also announcing the end - of the checkin freeze) + of the check-in freeze) * docutils-users@lists.sourceforge.net * doc-sig@python.org * python-announce@python.org diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 130f0d154..603b89b98 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -612,8 +612,10 @@ that begins in one physical paragraph and ends in another. sequence of elements, or you may get unexpected results. If you happen to need a generic block-level container, please - describe your use-case in an email to - docutils-users@lists.sourceforge.net. + describe your use-case in an email to the Docutils-users_ mailing + list. + + .. _Docutils-users: ../../user/mailing-lists.html#docutils-users Compound paragraphs are typically rendered as multiple distinct text blocks, with the possibility of variations to emphasize their logical @@ -1224,8 +1226,8 @@ Raw Data Pass-Through If you often need to use the "raw" directive or a "raw"-derived interpreted text role, that is a sign either of overuse/abuse or that functionality may be missing from reStructuredText. Please - describe your situation in email to - docutils-users@lists.sourceforge.net. + describe your situation in an email to the Docutils-users_ mailing + list. The "raw" directive indicates non-reStructuredText data that is to be passed untouched to the Writer. The names of the output formats are diff --git a/docs/ref/rst/roles.txt b/docs/ref/rst/roles.txt index a911cf469..1cb2e540b 100644 --- a/docs/ref/rst/roles.txt +++ b/docs/ref/rst/roles.txt @@ -276,8 +276,10 @@ must be used to obtain a ``title_reference`` element. If you often need to use "raw"-derived interpreted text roles or the "raw" directive, that is a sign either of overuse/abuse or that functionality may be missing from reStructuredText. Please - describe your situation in email to - docutils-users@lists.sourceforge.net. + describe your situation in an email to the Docutils-users_ mailing + list. + + .. _Docutils-users: ../../user/mailing-lists.html#docutils-user The "raw" role indicates non-reStructuredText data that is to be passed untouched to the Writer. It is the inline equivalent of the diff --git a/docs/user/rst/quickstart.txt b/docs/user/rst/quickstart.txt index bf6b21275..735dcf512 100644 --- a/docs/user/rst/quickstart.txt +++ b/docs/user/rst/quickstart.txt @@ -375,16 +375,13 @@ user reference is a good place to go next. For complete details, the `reStructuredText Markup Specification`_ is the place to go [#]_. Users who have questions or need assistance with Docutils or -reStructuredText should `post a message`_ to the `Docutils-Users -mailing list`_. The `Docutils project web site`_ has more -information. +reStructuredText should post a message to the Docutils-users_ mailing +list. .. [#] If that relative link doesn't work, try the master document: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html. .. _reStructuredText Markup Specification: ../../ref/rst/restructuredtext.html -.. _post a message: mailto:docutils-users@lists.sourceforge.net -.. _Docutils-Users mailing list: - http://lists.sourceforge.net/lists/listinfo/docutils-users +.. _Docutils-users: ../mailing-lists.html#docutils-users .. _Docutils project web site: http://docutils.sourceforge.net/ diff --git a/docs/user/tools.txt b/docs/user/tools.txt index ab31e0917..9cd136988 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -44,14 +44,10 @@ Getting Help First, try the "``--help``" option each front-end tool has. Users who have questions or need assistance with Docutils or -reStructuredText should `post a message`_ to the `Docutils-Users -mailing list`_. The `Docutils project web site`_ has more -information. - -.. _post a message: mailto:docutils-users@lists.sourceforge.net -.. _Docutils-Users mailing list: - http://lists.sourceforge.net/lists/listinfo/docutils-users -.. _Docutils project web site: http://docutils.sourceforge.net/ +reStructuredText should post a message to the Docutils-users_ mailing +list. + +.. _Docutils-users: mailing-lists.html#docutils-users The Tools diff --git a/docutils/core.py b/docutils/core.py index 4cb9d7ec3..f31c3011a 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -421,7 +421,8 @@ def publish_programmatically(source_class, source, source_path, Applications should not need to call this function directly. If it does seem to be necessary to call this function directly, please write to the - docutils-develop@lists.sourceforge.net mailing list. + Docutils-develop mailing list + . Parameters: -- cgit v1.2.1 From 470195b45aa54c6f651cb107c038218090b05653 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 28 May 2005 01:22:12 +0000 Subject: fixed links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3398 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/api/runtime-settings.txt | 2 +- docs/howto/i18n.txt | 2 +- docs/peps/pep-0256.txt | 2 +- docs/peps/pep-0258.txt | 2 +- docs/peps/pep-0287.txt | 2 +- docs/user/config.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api/runtime-settings.txt b/docs/api/runtime-settings.txt index 0da1ae6d9..2d60aa3e1 100644 --- a/docs/api/runtime-settings.txt +++ b/docs/api/runtime-settings.txt @@ -189,4 +189,4 @@ up the runtime settings. .. copy & modify the list from command-line tools? -.. _Docutils-develop: ../users/mailing-lists.html#docutils-develop +.. _Docutils-develop: ../user/mailing-lists.html#docutils-develop diff --git a/docs/howto/i18n.txt b/docs/howto/i18n.txt index e3d97502a..4a5b1de5a 100644 --- a/docs/howto/i18n.txt +++ b/docs/howto/i18n.txt @@ -59,7 +59,7 @@ is "en" for English. Examples of module names include ``en.py``, of hyphens, to conform to Python naming rules. .. _RFC 1766: http://www.faqs.org/rfcs/rfc1766.html -.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html +.. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html .. _ISO 3166: http://www.iso.ch/iso/en/prods-services/iso3166ma/ 02iso-3166-code-lists/index.html diff --git a/docs/peps/pep-0256.txt b/docs/peps/pep-0256.txt index 42c1bada9..1e5e87e35 100644 --- a/docs/peps/pep-0256.txt +++ b/docs/peps/pep-0256.txt @@ -246,7 +246,7 @@ References and Footnotes .. _Literate Programming: http://www.literateprogramming.com/ -.. _POD: http://www.perldoc.com/perl5.6/pod/perlpod.html +.. _POD: http://perldoc.perl.org/perlpod.html .. _Javadoc: http://java.sun.com/j2se/javadoc/ diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 4aaeecf3a..7779411a6 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -969,7 +969,7 @@ stylist code will lower the barrier considerably. .. _Docutils Python Source DTD: http://docutils.sourceforge.net/docs/dev/pysource.dtd -.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html +.. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html .. _Python Doc-SIG: http://www.python.org/sigs/doc-sig/ diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index d22efe224..18b3abfa7 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -757,7 +757,7 @@ __ http://www.python.org/doc/Humor.html#zen .. _TeX: http://www.tug.org/interest.html -.. _Perl POD: http://www.perldoc.com/perl5.6/pod/perlpod.html +.. _Perl POD: http://perldoc.perl.org/perlpod.html .. _JavaDoc: http://java.sun.com/j2se/javadoc/ diff --git a/docs/user/config.txt b/docs/user/config.txt index 1b52511b4..66ad39234 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -903,7 +903,7 @@ _`_source` Default: stdin (None). No command-line options. -.. _ISO 639: http://lcweb.loc.gov/standards/iso639-2/englangn.html +.. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html .. [#pwd] Path relative to the working directory of the process at launch. -- cgit v1.2.1 From 03e444a1ba0af10974dce90d058328365d356e0c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 28 May 2005 13:20:48 +0000 Subject: started links document git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3399 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/user/links.txt diff --git a/docs/user/links.txt b/docs/user/links.txt new file mode 100644 index 000000000..2102fac7d --- /dev/null +++ b/docs/user/links.txt @@ -0,0 +1,18 @@ +================= + Docutils_ Links +================= + +:Revision: $Revision $ +:Date: $Date $ +:Copyright: This document has been placed in the public domain. + +.. _Docutils: http://docutils.sourceforge.net/ + +The most current version of this document can always be found at +http://docutils.sourceforge.net/docs/user/links.html. + +* rest2web__ is a tool for creating web sites with reStructuredText. + + __ http://article.gmane.org/gmane.text.docutils.user/2006 + +* to be continued... -- cgit v1.2.1 From 453b70a30a2a182d5498dabed978c4b7ff997cea Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 28 May 2005 14:16:21 +0000 Subject: fixed revision and date git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3400 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 2102fac7d..466f8a8ee 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -2,8 +2,8 @@ Docutils_ Links ================= -:Revision: $Revision $ -:Date: $Date $ +:Revision: $Revision$ +:Date: $Date$ :Copyright: This document has been placed in the public domain. .. _Docutils: http://docutils.sourceforge.net/ -- cgit v1.2.1 From 1c2ca6555cd55bec2fa4a4207a24a2c1d16b9234 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 06:53:02 +0000 Subject: updated links; removed note about possibly outdated docs -- that's obvious git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3404 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/index.txt b/docs/index.txt index 1d8449a97..bffe3942d 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -9,13 +9,10 @@ :Copyright: This document has been placed in the public domain. The latest working documents may be accessed individually below, or -from the ``docs`` directory of the `development snapshots`__. They -are also distributed with the `latest project release package`__, but -those may not be completely up to date. +from the ``docs`` directory of the `Docutils distribution`_. -__ http://docutils.sourceforge.net/#development-snapshots -__ http://docutils.sourceforge.net/#project-releases .. _Docutils: http://docutils.sourceforge.net/ +.. _Docutils distribution: http://docutils.sourceforge.net/#download .. contents:: -- cgit v1.2.1 From 68a56749937e7fec298936ae25f9b559e79ac43d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 07:23:10 +0000 Subject: updated, polished and shortened README git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3405 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 65 ++++++++++++++++---------------------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/README.txt b/README.txt index dff191e9e..184cb557f 100644 --- a/README.txt +++ b/README.txt @@ -87,11 +87,11 @@ Support for the following sources is planned: Releases & Snapshots ==================== -Putting together an official "Release" of Docutils is a significant -effort, so it isn't done that often. In the meantime, the Subversion -snapshots always contain the latest code and documentation, usually -updated within an hour of changes being committed to the repository, -and usually bug-free: +While we are trying to follow a "release early & often" policy, +features are added very frequently. Since the code in the Subversion +repository is usually in a bug-free state, we recommend that you use +the current snapshot (which is usually updated within an hour of +changes being committed to the repository): * Snapshot of Docutils code, documentation, front-end tools, and tests: http://docutils.sf.net/docutils-snapshot.tgz @@ -99,14 +99,11 @@ and usually bug-free: * Snapshot of the Sandbox (experimental, contributed code): http://docutils.sf.net/docutils-sandbox-snapshot.tgz -* Snapshot of web files (the files that generate the web site): - http://docutils.sf.net/docutils-web-snapshot.tgz - To keep up to date on the latest developments, download fresh copies of the snapshots regularly. New functionality is being added weekly, -sometimes daily. (There's also the Subversion repository, and a -mailing list for check-in messages. See the web site [address above] -or docs/dev/policies.txt for details.) +sometimes daily. (There's also the `Subversion repository`_.) + +.. _Subversion repository: docs/dev/repository.html Requirements @@ -119,11 +116,6 @@ http://www.python.org/. The `Python Imaging Library`, or PIL, is used for some image manipulation operations if it is installed. -Docutils uses Greg Ward's Optik_/optparse option processing package. -It is included in the Docutils distribution. Python 2.3 and later -come with optparse in the standard library; in this case, the Docutils -copy is not installed. - .. [1] Python 2.1 may be used providing the compiler package is installed. The compiler package can be found in the Tools/ directory of Python 2.1's source distribution. @@ -185,10 +177,10 @@ Project Files & Directories Installation ============ -The first step is to expand the ``.tar.gz`` or ``.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. +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. @@ -208,13 +200,16 @@ GNU/Linux, BSDs, Unix, Mac OS X, etc. the complete path, such as /usr/local/bin/python. You may need root permissions to complete this step. -You can also just run install.py; it does the same thing. + You can also just run install.py; it does the same thing. Windows ------- -1. Open a DOS box (Command Shell, MSDOS Prompt, or whatever they're +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:: @@ -225,32 +220,6 @@ Windows \python setup.py install -If your system is set up to run Python when you double-click on .py -files, you can run install.py to do the same as the above. - - -Mac OS 8/9 ----------- - -1. Open the folder containing the expanded archive. - -2. Double-click on the file "setup.py", which should be a "Python - module" file. - - If the file isn't a "Python module", the line endings are probably - also wrong, and you will need to set up your system to recognize - ".py" file extensions as Python files. See - http://gotools.sourceforge.net/mac/python.html for detailed - instructions. Once set up, it's easiest to start over by expanding - the archive again. - -3. The distutils options window will appear. From the "Command" popup - list choose "install", click "Add", then click "OK". - -If install.py is a "Python module" (see step 2 above if it isn't), you -can run it (double-click) instead of the above. The distutils options -window will not appear. - Usage ===== -- cgit v1.2.1 From 9affc6ea9a0edc59b17073716ac6dbc365ba1981 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 07:24:54 +0000 Subject: updated links and text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3406 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 9 +++++---- FAQ.txt | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index b7a4e1d1b..a51c9ac5f 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -34,9 +34,9 @@ First, make sure it's a new bug: * Are you using the very latest version of Docutils? The bug may have already been fixed. Please get the latest version of Docutils from - CVS_ or from the `development snapshot`_ and check again. Even if - your bug has not been fixed, others probably have, and you're better - off with the most up-to-date code. + the repository_ or from the current snapshot_ and check again. Even + if your bug has not been fixed, others probably have, and you're + better off with the most up-to-date code. If you don't have time to check the latest snapshot, please report the bug anyway. We'd rather tell you that it's already fixed than @@ -96,7 +96,8 @@ __ http://subversion.tigris.org/ __ http://svn.collab.net/viewcvs/svn/trunk/BUGS?view=markup .. _CVS: http://sourceforge.net/cvs/?group_id=38414 -.. _development snapshot: http://docutils.sf.net/#development-snapshot +.. _repository: docs/dev/repository.html +.. _snapshot: http://docutils.sourceforge.net/#download .. _documentation: docs/ .. _FAQ: FAQ.html .. _mailing list archives: http://docutils.sf.net/#mailing-lists diff --git a/FAQ.txt b/FAQ.txt index 67a343120..714067e3d 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -102,7 +102,7 @@ Although useful and relatively stable, Docutils is experimental code, with APIs and architecture subject to change. Our highest priority is to fix bugs as they are reported. So the -latest code from CVS (or `development snapshots`_) is almost always +latest code from the repository_ (or the snapshots_) is almost always the most stable (bug-free) as well as the most featureful. @@ -110,13 +110,13 @@ What is the Docutils project release policy? -------------------------------------------- It's "release early & often". We also have automatically-generated -`development snapshots`_ which always contain the latest code from -CVS. As the project matures, we may formalize on a +snapshots_ which always contain the latest code from the repository_. +As the project matures, we may formalize on a stable/development-branch scheme, but we're not using anything like that yet. -.. _development snapshots: - http://docutils.sourceforge.net/#development-snapshots +.. _repository: docs/dev/repository.html +.. _snapshots: http://docutils.sourceforge.net/#download reStructuredText -- cgit v1.2.1 From a48dba4be1b81ae0b130d4fa8dcacddc86c4c803 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 07:30:03 +0000 Subject: removed uninteresting information at the start; some more polishment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3407 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.txt b/README.txt index 184cb557f..15205d36c 100644 --- a/README.txt +++ b/README.txt @@ -11,12 +11,6 @@ .. contents:: -Thank you for downloading the Python Docutils project archive. As -this is a work in progress, please check the project website for -updated working files (snapshots). This project should be considered -highly experimental; APIs are subject to change at any time. - - Quick-Start =========== @@ -38,9 +32,7 @@ complete details. See `Releases & Snapshots`_ below for details. 3. Unpack the tarball in a temporary directory (**not** directly in - Python's ``site-packages``) and install with the standard :: - - python setup.py install + Python's ``site-packages``) and run ``install.py``. See Installation_ below for details. @@ -59,7 +51,8 @@ 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 TeX. Support for the following sources has been implemented: +XML, and LaTeX. Support for the following sources has been +implemented: * Standalone files. @@ -68,8 +61,7 @@ XML, and TeX. Support for the following sources has been implemented: Support for the following sources is planned: * Inline documentation from Python modules and packages, extracted - with namespace context. **This is the focus of the current - development effort.** + with namespace context. * Email (RFC-822 headers, quoted excerpts, signatures, MIME parts). -- cgit v1.2.1 From d412180dc51d316654dce051ff669022a07dabc7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 07:58:10 +0000 Subject: applied patch to fix broken set_conditions method; closing https://sourceforge.net/tracker/?func=detail&atid=422030&aid=1210637&group_id=38414 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3408 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/utils.py b/docutils/utils.py index a28b5326d..1d77d38d8 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -130,7 +130,7 @@ class Reporter: if stream is None: stream = sys.stderr self.stream = stream - self.debug = debug + self.debug_flag = debug def attach_observer(self, observer): """ -- cgit v1.2.1 From 56fef30d6ecc31031ff4a82cad41d4da444d1822 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 12:42:43 +0000 Subject: moved aux. tags for multiple IDs *inside* the element which carries the ID git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3409 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 16 +++++++++++----- test/functional/expected/standalone_rst_html4css1.html | 10 +++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1a7d44f0a..22eedf4f3 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -7,10 +7,10 @@ """ Simple HyperText Markup Language document tree Writer. -The output conforms to the HTML 4.01 Transitional DTD and to the Extensible -HTML version 1.0 Transitional DTD (*almost* strict). The output contains a -minimum of formatting information. A cascading style sheet ("default.css" by -default) is required for proper viewing with a modern graphical browser. +The output conforms to the XHTML version 1.0 Transitional DTD +(*almost* strict). The output contains a minimum of formatting +information. A cascading style sheet ("default.css" by default) is +required for proper viewing with a modern graphical browser. """ __docformat__ = 'reStructuredText' @@ -311,7 +311,13 @@ class HTMLTranslator(nodes.NodeVisitor): if node.get('ids'): atts['id'] = node['ids'][0] for id in node['ids'][1:]: - prefix.append('' % id) + if infix: + # Empty tag. + prefix.append('' % id) + else: + # Non-empty tag. We place the auxiliary + # tag *inside* the element. + suffix += '' % id if atts.has_key('id') and tagname in self.named_tags: atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index f0ec8afb2..928fb8801 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -21,9 +21,9 @@ Document header
    -
    -

    reStructuredText Test Document

    -

    Examples of Syntax Constructs

    +
    +

    reStructuredText Test Document

    +

    Examples of Syntax Constructs

    @@ -494,8 +494,8 @@ rendered separately and differently from footnotes.

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    -
    -

    2.13   Targets

    +
    +

    2.13   Targets

    This paragraph is pointed to by the explicit "example" target. A reference can be found under Inline Markup, above. Inline hyperlink targets are also possible.

    -- cgit v1.2.1 From b420a45b82cdbf20cd36de98690e4e15235c80e6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 12:51:35 +0000 Subject: added functional test for image with multiple IDs; somethings *really* broken there, both in the transforms and in the HTML writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3410 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_html4css1.html | 4 +++- test/functional/expected/standalone_rst_latex.tex | 4 ++++ test/functional/expected/standalone_rst_pseudoxml.txt | 6 ++++++ test/functional/input/data/standard.txt | 7 +++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 928fb8801..abfdcbfe7 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -546,7 +546,9 @@ document (a document-wide table o

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png
    -

    A figure directive:

    +

    Image with multiple IDs:

    +
    ../../../docs/user/rst/images/title.png
    +

    A figure directive:

    reStructuredText, the markup syntax

    A figure is an image with a caption and/or a legend:

    diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index ec682aa52..3abaf8a9e 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -865,6 +865,10 @@ document (a document-wide \href{\#table-of-contents}{table of contents}). An image directive (also clickable -{}- a hyperlink reference): \href{\#directives}{\includegraphics{../../../docs/user/rst/images/title.png}} +Image with multiple IDs: + +\includegraphics{../../../docs/user/rst/images/title.png} + A figure directive: \begin{figure}[htbp]\begin{center} diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 1c21abc9a..b1cce6c09 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1123,6 +1123,12 @@ + Image with multiple IDs: + + + + + A figure directive:
    diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index a4a75b078..cfcc6e7f7 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -427,6 +427,13 @@ An image directive (also clickable -- a hyperlink reference): :class: class1 class2 :target: directives_ +Image with multiple IDs: + +.. _image target 1: +.. _image target 2: +.. _image target 3: +.. image:: ../../../docs/user/rst/images/title.png + A figure directive: .. figure:: ../../../docs/user/rst/images/biohazard.png -- cgit v1.2.1 From c61ca0c471901af237277d5700c4c22b04e4d3d3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 29 May 2005 19:22:10 +0000 Subject: added version suffix for snapshots git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3411 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 2 ++ docutils/frontend.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/__init__.py b/docutils/__init__.py index 10bc7fd46..fbac8caad 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -58,6 +58,8 @@ number is bumped whenever there is a significant project release. The major number will be bumped when the project is feature-complete, and perhaps if there is a major change in the design.""" +__version_suffix__ = '' +"""Version suffix for snapshots (e.g. ', 2005-05-29, r3410').""" class ApplicationError(StandardError): pass class DataError(ApplicationError): pass diff --git a/docutils/frontend.py b/docutils/frontend.py index 7cba1706f..39ca62b85 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -462,7 +462,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): config_section = 'general' - version_template = '%%prog (Docutils %s)' % docutils.__version__ + version_template = ('%%prog (Docutils %s%s)' + % (docutils.__version__, docutils.__version_suffix__)) """Default version message.""" def __init__(self, components=(), defaults=None, read_config_files=None, -- cgit v1.2.1 From 0967ac7c8663c1b4555a05067cdbc3194b526fe5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 31 May 2005 21:11:09 +0000 Subject: added target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3414 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 2dd958920..abcb2e66b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -680,9 +680,9 @@ __ rst/alternatives.html#or-not-to-do * Add test for ":figwidth: image" option of "figure" directive. (Test code needs to check if PIL is available on the system.) -* The parser doesn't know anything about double-width characters such - as Chinese hanza & Japanese kanji/kana. Also, it's dependent on - whitespace and punctuation as markup delimiters, which may not be +* The parser doesn't know anything about _`double-width characters` + such as Chinese hanza & Japanese kanji/kana. Also, it's dependent + on whitespace and punctuation as markup delimiters, which may not be applicable in these languages. Python 2.4 introduces the function ``unicodedata.east_asian_width``, -- cgit v1.2.1 From 09bd939d15ae77a5e53274cdf27ee6bd8587553b Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 1 Jun 2005 00:56:39 +0000 Subject: correction git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3415 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/latex.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user/latex.txt b/docs/user/latex.txt index d66586bc7..ce8447692 100644 --- a/docs/user/latex.txt +++ b/docs/user/latex.txt @@ -219,8 +219,8 @@ Images Images are included in LaTeX by the graphicx package. The supported image formats depend on the used driver (dvi, dvips, pdftex, ...). -pdf-image inclusion in pdf files fails, specify ``--graphicx-option=pdftex`` -or ``--graphicx-option=auto``. +If pdf-image inclusion in pdf files fails, specify +``--graphicx-option=pdftex`` or ``--graphicx-option=auto``. Commands directly to LaTeX -- cgit v1.2.1 From e10b9dee23a956499f61c0bd3d8a3c4233c754c3 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 1 Jun 2005 13:52:43 +0000 Subject: Added validator to tab_width setting, with test. Closes SF bug #1212515, report from Wu Wei. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3416 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++++ THANKS.txt | 1 + docutils/parsers/rst/__init__.py | 3 ++- test/data/config_1.txt | 1 + test/test_settings.py | 1 + 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index f5a6e653d..3e6282d19 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,6 +14,11 @@ Changes Since 0.3.9 =================== +* docutils/parsers/rst/__init__.py: + + - Added validator to tab_width setting, with test. Closes SF bug + #1212515, report from Wu Wei. + Release 0.3.9 (2005-05-26) ========================== diff --git a/THANKS.txt b/THANKS.txt index 26b6e9114..9dd6015f2 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -130,6 +130,7 @@ donations, tasty treats, and related projects: * Martin von Loewis * Greg Ward * Barry Warsaw +* Wu Wei * Edward Welbourne * Felix Wiemann * Ka-Ping Yee diff --git a/docutils/parsers/rst/__init__.py b/docutils/parsers/rst/__init__.py index 30825d7c4..ff1d7b4f8 100644 --- a/docutils/parsers/rst/__init__.py +++ b/docutils/parsers/rst/__init__.py @@ -105,7 +105,8 @@ class Parser(docutils.parsers.Parser): 'validator': frontend.validate_url_trailing_slash}), ('Set number of spaces for tab expansion (default 8).', ['--tab-width'], - {'metavar': '', 'type': 'int', 'default': 8}), + {'metavar': '', 'type': 'int', 'default': 8, + 'validator': frontend.validate_nonnegative_int}), ('Remove spaces before footnote references.', ['--trim-footnote-reference-space'], {'action': 'store_true', 'validator': frontend.validate_boolean}), diff --git a/test/data/config_1.txt b/test/data/config_1.txt index f94074a8a..b19a213b3 100644 --- a/test/data/config_1.txt +++ b/test/data/config_1.txt @@ -10,6 +10,7 @@ generator: true [restructuredtext parser] trim-footnote-reference-space: 1 +tab-width = 8 [html4css1 writer] diff --git a/test/test_settings.py b/test/test_settings.py index 2a17c6eef..4226af580 100755 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -57,6 +57,7 @@ class ConfigFileTests(unittest.TestCase): 'source_link': 1, 'stylesheet': None, 'stylesheet_path': fixpath('data/stylesheets/pep.css'), + 'tab_width': 8, 'template': fixpath('data/pep-html-template'), 'trim_footnote_reference_space': 1}, 'two': {'footnote_references': 'superscript', -- cgit v1.2.1 From 78ed5de20eb3c06ef02efd5710145321fc40596f Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 1 Jun 2005 14:44:50 +0000 Subject: docutils.__version_details__ renamed from .__version_suffix__ git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3417 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++++ docs/dev/release.txt | 6 ++++++ docutils/__init__.py | 7 ++++--- docutils/core.py | 7 ++++--- docutils/frontend.py | 4 ++-- test/alltests.py | 5 +++-- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 3e6282d19..1fe8b1092 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,6 +14,11 @@ Changes Since 0.3.9 =================== +* docutils/__init__.py: + + - Added ``__version_details__`` attribute to describe code source + (repository/snapshot/release). + * docutils/parsers/rst/__init__.py: - Added validator to tab_width setting, with test. Closes SF bug diff --git a/docs/dev/release.txt b/docs/dev/release.txt index fd941e5d3..b242720d0 100644 --- a/docs/dev/release.txt +++ b/docs/dev/release.txt @@ -24,6 +24,9 @@ updated to reflect the recent move to Subversion!) (e.g. CHANGES.txt) to have it at hand when you need it for posting announcements or pasting it into forms.** +* Change ``__version_details__`` in docutils/docutils/__init__.py to + "release" (from "repository"). + * Bump the _`version number` in the following files: + docutils/setup.py @@ -126,6 +129,9 @@ updated to reflect the recent move to Subversion!) * Register with PyPI (``python setup.py register``). +* Restore ``__version_details__`` in docutils/docutils/__init__.py to + "repository" (from "release"). + * Bump the `version number`_ again. * Add a new empty section "Changes Since ..." in HISTORY.txt. diff --git a/docutils/__init__.py b/docutils/__init__.py index fbac8caad..eeb54a413 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -13,7 +13,7 @@ Package Structure Modules: - __init__.py: Contains component base classes, exception classes, and - Docutils `__version__`. + Docutils version information. - core.py: Contains the ``Publisher`` class and ``publish_*()`` convenience functions. @@ -58,8 +58,9 @@ number is bumped whenever there is a significant project release. The major number will be bumped when the project is feature-complete, and perhaps if there is a major change in the design.""" -__version_suffix__ = '' -"""Version suffix for snapshots (e.g. ', 2005-05-29, r3410').""" +__version_details__ = 'repository' +"""Extra version details (e.g. 'snapshot 2005-05-29, r3410' or 'release'), +modified automatically.""" class ApplicationError(StandardError): pass class DataError(ApplicationError): pass diff --git a/docutils/core.py b/docutils/core.py index f31c3011a..302c39eb2 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -18,7 +18,7 @@ __docformat__ = 'reStructuredText' import sys import pprint -from docutils import __version__, SettingsSpec +from docutils import __version__, __version_details__, SettingsSpec from docutils import frontend, io, utils, readers, writers from docutils.frontend import OptionParser @@ -237,9 +237,10 @@ class Publisher: print >>sys.stderr, ("""\ Exiting due to error. Use "--traceback" to diagnose. Please report errors to . -Include "--traceback" output, Docutils version (%s), +Include "--traceback" output, Docutils version (%s [%s]), Python version (%s), your OS type & version, and the -command line used.""" % (__version__, sys.version.split()[0])) +command line used.""" % (__version__, __version_details__, + sys.version.split()[0])) def report_SystemMessage(self, error): print >>sys.stderr, ('Exiting due to level-%s (%s) system message.' diff --git a/docutils/frontend.py b/docutils/frontend.py index 39ca62b85..8a85133e7 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -462,8 +462,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): config_section = 'general' - version_template = ('%%prog (Docutils %s%s)' - % (docutils.__version__, docutils.__version_suffix__)) + version_template = ('%%prog (Docutils %s [%s])' + % (docutils.__version__, docutils.__version_details__)) """Default version message.""" def __init__(self, components=(), defaults=None, read_config_files=None, diff --git a/test/alltests.py b/test/alltests.py index 4092d38a6..03c85e4ce 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -74,8 +74,9 @@ sys.stdout = sys.stderr = Tee('alltests.out') import package_unittest -print ('Testing Docutils %s with Python %s on %s at %s' - % (docutils.__version__, sys.version.split()[0], +print ('Testing Docutils %s %s with Python %s on %s at %s' + % (docutils.__version__, docutils.__version_details__, + sys.version.split()[0], time.strftime('%Y-%m-%d'), time.strftime('%H:%M:%S'))) sys.stdout.flush() -- cgit v1.2.1 From 8e0b54fa689b16798b6ca213bad39fca17954438 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 1 Jun 2005 21:45:03 +0000 Subject: added idea for document splitting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3422 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index abcb2e66b..361a82c6d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -250,7 +250,7 @@ General * Think about _`large documents` made up of multiple subdocument files. Issues: continuity (`persistent sequences`_ above), cross-references (`name-to-id mapping file`_ above and `targets in - other documents`_ below). + other documents`_ below), splitting (`document splitting`_ below). When writing a book, the author probably wants to split it up into files, perhaps one per chapter (but perhaps even more detailed). @@ -1683,11 +1683,36 @@ Unimplemented Transforms (HTML only? Initially, yes. Eventually, anything should be splittable.) - Idea: insert a "destination" attribute into the root element of each - split-out document, containing the path/filename. The Output object - or Writer will recognize this attribute and split out the files - accordingly. Must allow for common headers & footers, prev/next, - breadcrumbs, etc. + Ideas: + + - Insert a "destination" attribute into the root element of each + split-out document, containing the path/filename. The Output + object or Writer will recognize this attribute and split out the + files accordingly. Must allow for common headers & footers, + prev/next, breadcrumbs, etc. + + - Transform a single-root document into a document containing + multiple subdocuments, recursively. The content model of the + "document" element would have to change to:: + + + + (I.e., add the last line -- 0 or more document elements.) + + Let's look at the case of hierarchical (directories and files) + HTML output. Each document element containing further document + elements would correspond to a directory (with an index.html file + for the content preceding the subdocuments). Each document + element containing no subdocuments (i.e., structure model elements + only) corresponds to a concrete file with no directory. + + The natural transform would be to map sections to subdocuments, + but possibly only a given number of levels deep. * _`Navigation` -- cgit v1.2.1 From 22c3eea83b579527fee2d6f37045fe7220e01400 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 2 Jun 2005 16:12:26 +0000 Subject: added rest2web git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3424 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FAQ.txt b/FAQ.txt index 714067e3d..bfa8442b2 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -668,6 +668,10 @@ you like. If you adapt it to use Docutils/reStructuredText, please consider contributing the code to Docutils or `let us know`_ and we'll keep a list here. +One reST-specific web templating system is `rest2web +`_, a tool for +automatically building websites, or parts of websites. + .. _ht2html: http://ht2html.sourceforge.net/ .. _YAPTU: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52305 -- cgit v1.2.1 From 58ac1f3ebac3963da6499457920fb94296ab24de Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 3 Jun 2005 20:46:33 +0000 Subject: tweaked header git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3425 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/alltests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/alltests.py b/test/alltests.py index 03c85e4ce..9c5d8b0aa 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -74,7 +74,7 @@ sys.stdout = sys.stderr = Tee('alltests.out') import package_unittest -print ('Testing Docutils %s %s with Python %s on %s at %s' +print ('Testing Docutils %s [%s] with Python %s on %s at %s' % (docutils.__version__, docutils.__version_details__, sys.version.split()[0], time.strftime('%Y-%m-%d'), time.strftime('%H:%M:%S'))) -- cgit v1.2.1 From 5095d1c0d6811a2180da6528e929347c10fc123e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 3 Jun 2005 23:52:18 +0000 Subject: added clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3426 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 57362c5db..6d21934b4 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2213,6 +2213,8 @@ Replacement text __ http://developer.java.sun.com/developer/earlyAccess/ j2eecas/ + The "replace_" directive has been implemented. + Comments ```````` @@ -2815,6 +2817,7 @@ Markup errors are handled according to the specification in `PEP .. _HTML Techniques for Web Content Accessibility Guidelines: http://www.w3.org/TR/WCAG10-HTML-TECHS/#link-text .. _image: directives.html#image +.. _replace: directives.html#replace .. _meta: directives.html#meta .. _figure: directives.html#figure .. _admonition: directives.html#admonitions -- cgit v1.2.1 From c1312b37ba8887cf092065cb09f3d09ee034ac31 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 4 Jun 2005 04:01:58 +0000 Subject: added "default-role" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3427 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++ docs/ref/rst/directives.txt | 43 +++++++++++ docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/misc.py | 22 ++++++ docutils/parsers/rst/languages/af.py | 1 + docutils/parsers/rst/languages/ca.py | 1 + docutils/parsers/rst/languages/cs.py | 1 + docutils/parsers/rst/languages/de.py | 1 + docutils/parsers/rst/languages/en.py | 1 + docutils/parsers/rst/languages/eo.py | 1 + docutils/parsers/rst/languages/es.py | 1 + docutils/parsers/rst/languages/fi.py | 1 + docutils/parsers/rst/languages/fr.py | 1 + docutils/parsers/rst/languages/it.py | 1 + docutils/parsers/rst/languages/nl.py | 1 + docutils/parsers/rst/languages/pt_br.py | 1 + docutils/parsers/rst/languages/ru.py | 1 + docutils/parsers/rst/languages/sk.py | 1 + docutils/parsers/rst/languages/sv.py | 1 + docutils/parsers/rst/languages/zh_tw.py | 1 + .../test_rst/test_directives/test_default_role.py | 84 ++++++++++++++++++++++ 21 files changed, 170 insertions(+) create mode 100755 test/test_parsers/test_rst/test_directives/test_default_role.py diff --git a/HISTORY.txt b/HISTORY.txt index 1fe8b1092..f862d4896 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -24,6 +24,10 @@ Changes Since 0.3.9 - Added validator to tab_width setting, with test. Closes SF bug #1212515, report from Wu Wei. +* docutils/parsers/rst/directives/misc.py: + + - Added the "default-role" directive. + Release 0.3.9 (2005-05-26) ========================== diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 603b89b98..d336a48dd 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1542,6 +1542,49 @@ details. .. _reStructuredText Interpreted Text Roles: roles.html +.. _default-role: + +Setting the Default Interpreted Text Role +========================================= + +:Directive Type: "default-role" +:Doctree Element: None; affects subsequent parsing. +:Directive Arguments: One, optional (new default role name). +:Directive Options: None. +:Directive Content: None. + +(New in Docutils 0.3.8) + +The "default-role" directive sets the default interpreted text role, +the role that is used for interpreted text without an explicit role. +For example, after setting the default role like this:: + + .. default-role:: subscript + +any subsequent use of implicit-role interpreted text in the document +will use the "subscript" role:: + + An example of a `default` role. + +This will be parsed into the following document tree fragment:: + + + An example of a + + default + role. + +Custom roles may be used (see the "role_" directive above), but it +must have been declared in a document before it can be set as the +default role. See the `reStructuredText Interpreted Text Roles`_ +document for details of built-in roles. + +The directive may be used without an argument to restore the initial +default interpreted text role, which is application-dependent. The +initial default interpreted text role of the standard reStructuredText +parser is "title-reference". + + Restructuredtext-Test-Directive =============================== diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 8e9f42284..1db0c76e0 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -131,6 +131,7 @@ _directive_registry = { 'unicode': ('misc', 'unicode_directive'), 'class': ('misc', 'class_directive'), 'role': ('misc', 'role'), + 'default-role': ('misc', 'default_role'), 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} """Mapping of directive name to (module name, function name). The directive name is canonical & must be lowercase. Language-dependent names are defined diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 7bae832d2..7007546df 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -329,6 +329,28 @@ def role(name, arguments, options, content, lineno, role.content = 1 +def default_role(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Set the default interpreted text role.""" + if not arguments: + if roles._roles.has_key(''): + # restore the "default" default role + del roles._roles[''] + return [] + role_name = arguments[0] + role, messages = roles.role( + role_name, state_machine.language, lineno, state.reporter) + if role is None: + error = state.reporter.error( + 'Unknown interpreted text role "%s".' % role_name, + nodes.literal_block(block_text, block_text), line=lineno) + return messages + [error] + roles._roles[''] = role + # @@@ should this be local to the document, not the parser? + return messages + +default_role.arguments = (0, 1, 0) + def directive_test_function(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """This directive is useful only for testing purposes.""" diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 9dddae716..7304f153b 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -53,6 +53,7 @@ directives = { 'unicode': 'unicode', # should this be translated? unikode 'klas': 'class', 'role (translation required)': 'role', + 'default-role (translation required)': 'default-role', 'inhoud': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/ca.py b/docutils/parsers/rst/languages/ca.py index 9fdce400d..691887325 100644 --- a/docutils/parsers/rst/languages/ca.py +++ b/docutils/parsers/rst/languages/ca.py @@ -58,6 +58,7 @@ directives = { u'unicode': 'unicode', u'classe': 'class', u'rol': 'role', + u'default-role (translation required)': 'default-role', u'contingut': 'contents', u'numsec': 'sectnum', u'numeraci\u00F3-de-seccions': 'sectnum', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 7163cbf8f..24087badf 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -54,6 +54,7 @@ directives = { u'unicode (translation required)': 'unicode', u't\u0159\u00EDda': 'class', u'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'obsah': 'contents', u'sectnum (translation required)': 'sectnum', u'section-numbering (translation required)': 'sectnum', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 9431f0e9d..56cca5c5b 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -56,6 +56,7 @@ directives = { 'unicode': 'unicode', 'klasse': 'class', 'rolle': 'role', + u'default-role (translation required)': 'default-role', 'inhalt': 'contents', 'kapitel-nummerierung': 'sectnum', 'abschnitts-nummerierung': 'sectnum', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 63ddcb1b9..46822b891 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -54,6 +54,7 @@ directives = { 'unicode': 'unicode', 'class': 'class', 'role': 'role', + 'default-role': 'default-role', 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 069fea45e..99b6d6970 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -60,6 +60,7 @@ directives = { u'unicode': 'unicode', u'klaso': 'class', u'rolo': 'role', + u'default-role (translation required)': 'default-role', u'enhavo': 'contents', u'seknum': 'sectnum', u'sekcia-numerado': 'sectnum', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 5f0a094da..726d97e88 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -62,6 +62,7 @@ directives = { u'unicode': 'unicode', u'clase': 'class', u'rol': 'role', + u'default-role (translation required)': 'default-role', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index c60444e3f..ba159cc70 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -52,6 +52,7 @@ directives = { u'unicode': u'unicode', u'luokka': u'class', u'rooli': u'role', + u'default-role (translation required)': 'default-role', u'sis\u00e4llys': u'contents', u'kappale': u'sectnum', u'header (translation required)': 'header', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index 8b9cb04de..acb8d35e6 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -56,6 +56,7 @@ directives = { u'unicode': 'unicode', u'classe': 'class', u'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'sommaire': 'contents', u'table-des-mati\u00E8res': 'contents', u'sectnum': 'sectnum', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index ee31b42ae..f3afd2d35 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -53,6 +53,7 @@ directives = { 'unicode': 'unicode', 'classe': 'class', 'ruolo': 'role', + u'default-role (translation required)': 'default-role', 'indice': 'contents', 'contenuti': 'contents', 'seznum': 'sectnum', diff --git a/docutils/parsers/rst/languages/nl.py b/docutils/parsers/rst/languages/nl.py index 35942ca05..273828062 100644 --- a/docutils/parsers/rst/languages/nl.py +++ b/docutils/parsers/rst/languages/nl.py @@ -55,6 +55,7 @@ directives = { 'unicode': 'unicode', 'klasse': 'class', 'rol': 'role', + u'default-role (translation required)': 'default-role', 'inhoud': 'contents', 'sectnum': 'sectnum', 'sectie-nummering': 'sectnum', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 6f5d4cc6b..8a2534923 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -54,6 +54,7 @@ directives = { 'unicode': 'unicode', 'classe': 'class', 'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'\u00EDndice': 'contents', 'numsec': 'sectnum', u'numera\u00E7\u00E3o-de-se\u00E7\u00F5es': 'sectnum', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 4ccca658c..23a842399 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -45,6 +45,7 @@ directives = { u'image', u'\u043a\u043b\u0430\u0441\u0441': u'class', u'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'\u043d\u043e\u043c\u0435\u0440-\u0440\u0430\u0437\u0434\u0435\u043b\u0430': u'sectnum', u'\u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f-\u0440\u0430\u0437' diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index 2ba849700..e58296280 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -53,6 +53,7 @@ directives = { u'unicode': 'unicode', u'class (translation required)': 'class', u'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'obsah': 'contents', u'\xe8as\x9d': 'sectnum', u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index d6f6fba46..59d13f699 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -53,6 +53,7 @@ directives = { u'unicode': 'unicode', u'class (translation required)': 'class', u'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', u'inneh\u00e5ll': 'contents', u'sektionsnumrering': 'sectnum', u'target-notes (translation required)': 'target-notes', diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 15f253114..3eaea044a 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -54,6 +54,7 @@ directives = { 'unicode (translation required)': 'unicode', 'class (translation required)': 'class', 'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', 'contents (translation required)': 'contents', 'sectnum (translation required)': 'sectnum', 'section-numbering (translation required)': 'sectnum', diff --git a/test/test_parsers/test_rst/test_directives/test_default_role.py b/test/test_parsers/test_rst/test_directives/test_default_role.py new file mode 100755 index 000000000..fc9343247 --- /dev/null +++ b/test/test_parsers/test_rst/test_directives/test_default_role.py @@ -0,0 +1,84 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for misc.py "default-role" directive. +""" + +from __init__ import DocutilsTestSupport + + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +totest['default-role'] = [ +["""\ +.. default-role:: subscript + +This is a `subscript`. +""", +"""\ + + + This is a \n\ + + subscript + . +"""], +["""\ +Must define a custom role before using it. + +.. default-role:: custom +""", +"""\ + + + Must define a custom role before using it. + + + No role entry for "custom" in module "docutils.parsers.rst.languages.en". + Trying "custom" as canonical role name. + + + Unknown interpreted text role "custom". + + .. default-role:: custom +"""], +["""\ +.. role:: custom +.. default-role:: custom + +This text uses the `default role`. + +.. default-role:: + +Returned the `default role` to its standard default. +""", +"""\ + + + This text uses the \n\ + + default role + . + + Returned the \n\ + + default role + to its standard default. +"""], +] + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 8190158763b3afc33a14d0674e7364fc2d2d26f6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 4 Jun 2005 04:08:25 +0000 Subject: updated & corrected docs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3428 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 +- docs/user/rst/cheatsheet.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index d336a48dd..dde952b7d 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1553,7 +1553,7 @@ Setting the Default Interpreted Text Role :Directive Options: None. :Directive Content: None. -(New in Docutils 0.3.8) +(New in Docutils 0.3.10) The "default-role" directive sets the default interpreted text role, the role that is used for interpreted text without an explicit role. diff --git a/docs/user/rst/cheatsheet.txt b/docs/user/rst/cheatsheet.txt index 03eddf814..7ae1d55f5 100644 --- a/docs/user/rst/cheatsheet.txt +++ b/docs/user/rst/cheatsheet.txt @@ -100,6 +100,7 @@ replace Replacement text for substitution definitions unicode Unicode character code conversion for substitution defs class Set a "class" attribute on the next element role Create a custom interpreted text role [0.3.2] +default-role Set the default interpreted text role [0.3.10] ================ ============================================================ Interpreted Text Role Quick Reference -- cgit v1.2.1 From 1e84e4a9faaecb92e19f35d4597db8d208490132 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 4 Jun 2005 19:05:59 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3429 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 361a82c6d..4f4509dfc 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1508,8 +1508,8 @@ Others are merely convenience features, like "RFC". All supported interpreted text roles must already be known to the Parser when they are encountered in a document. Whether pre-defined in core/client code, or in the document, doesn't matter; the roles -just need to have already been declared. Adding a new role often -involves adding a new element to the DTD and may require extensive +just need to have already been declared. Adding a new role may +involve adding a new element to the DTD and may require extensive support, therefore such additions should be well thought-out. There should be a limited number of roles. @@ -1530,7 +1530,7 @@ any knowledge of the Python-Reader origin of these elements. * Alan Jaffray suggested (and I agree) that it would be sensible to: - have a directive and/or command-line option to specify a default - role for interpreted text + role for interpreted text (done) - allow the reST processor to take an argument for the default role (this will be subsumed by the above via the runtime settings mechanism) -- cgit v1.2.1 From 5dd123325ec534de16ee060bf1723a8fa5bb33d7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 15:12:08 +0000 Subject: added a "Hacker's Guide" containing a first overview of Docutils' architecture git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3431 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/hacking.txt | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.txt | 1 + 2 files changed, 211 insertions(+) create mode 100644 docs/dev/hacking.txt diff --git a/docs/dev/hacking.txt b/docs/dev/hacking.txt new file mode 100644 index 000000000..d98823ba0 --- /dev/null +++ b/docs/dev/hacking.txt @@ -0,0 +1,210 @@ +.. -*- coding: utf-8 -*- + +========================== + Docutils_ Hacker's Guide +========================== + +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + +:Abstract: This is the introduction to Docutils for all persons who + want to extend Docutils in some way. +:Prerequisites: You have used reStructuredText_ and played around with + the `Docutils front-end tools`_ before. Some (basic) Python + knowledge is certainly helpful (though not necessary, strictly + speaking). + +.. _Docutils: http://docutils.sourceforge.net/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _Docutils front-end tools: ../user/tools.html + +.. contents:: + + +Overview of the Docutils Architecture +===================================== + +To give you an understanding of the Docutils architecture, we'll dive +right into the internals using a practical example. + +Consider the following reStructuredText file:: + + My *favorite* language is Python_. + + .. _Python: http://www.python.org/ + +Using the ``rst2html.py`` front-end tool, you would get an HTML output +which looks like this:: + + [uninteresting HTML code removed] + +
    +

    My favorite language is Python.

    +
    + + + +While this looks very simple, it's enough to illustrate all internal +processing stages of Docutils. Let's see how this document is +processed from the reStructuredText source to the final HTML output: + +Reading the Document +-------------------- + +The **Reader** reads the document from the source file and passes it +to the parser (see below). The default reader is the standalone +reader (``docutils/readers/standalone.py``) which just reads the input +data from a single text file. Unless you want to do really fancy +things, there is no need to change that. + +Since you probably won't need to touch readers, we will just move on +to the next stage: + +Parsing the Document +-------------------- + +The **Parser** analyzes the the input document and creates a **node +tree** representation. In this case we are using the +**reStructuredText parser** (``docutils/parsers/rst/__init__.py``). +To see what that node tree looks like, we call ``quicktest.py`` (which +can be found in the ``tools/`` directory of the Docutils distribution) +with our example file (``test.txt``) as first parameter (Windows users +might need to type ``python quicktest.py test.txt``):: + + $ quicktest.py test.txt + + + My + + favorite + language is + + Python + . + + +Let us now examine the node tree: + +The top-level node is ``document``. It has a ``source`` attribute +whose value is ``text.txt``. There are two children: A ``paragraph`` +node and a ``target`` node. The ``paragraph`` in turn has children: A +text node ("My "), an ``emphasis`` node, a text node (" language is "), +a ``reference`` node, and again a ``Text`` node ("."). + +These node types (``document``, ``paragraph``, ``emphasis``, etc.) are +all defined in ``docutils/nodes.py``. The node types are internally +arranged as a class hierarchy (for example, both ``emphasis`` and +``reference`` have the common superclass ``Inline``). To get an +overview of the node class hierarchy, use epydoc (type ``epydoc +nodes.py``) and look at the class hierarchy tree. + +Transforming the Document +------------------------- + +In the node tree above, the ``reference`` node does not contain the +target URI (``http://www.python.org/``) yet. + +Assigning the target URI (from the ``target`` node) to the +``reference`` node is *not* done by the parser (the parser only +translates the input document into a node tree). + +Instead, it's done by a **Transform**. In this case (resolving a +reference), it's done by the ``ExternalTargets`` transform in +``docutils/transforms/references.py``. + +In fact, there are quite a lot of Transforms, which do various useful +things like creating the table of contents, applying substitution +references or resolving auto-numbered footnotes. + +The Transforms are applied after parsing. To see how the node tree +has changed after applying the Transforms, we use the +``rst2pseudoxml.py`` tool: + +.. parsed-literal:: + + $ rst2pseudoxml.py test.txt + + + My + + favorite + language is + + Python + . + + +For our small test document, the only change is that the ``refname`` +attribute of the reference has been replaced by a ``refuri`` +attribute—the reference has been resolved. + +While this does not look very exciting, transforms are a powerful tool +to apply any kind of transformation on the node tree. + +By the way, you can also get a "real" XML representation of the node +tree by using ``rst2xml.py`` instead of ``rst2pseudoxml.py``. + +Writing the Document +-------------------- + +To get an HTML document out of the node tree, we use a **Writer**, the +HTML writer in this case (``docutils/writers/html4css1.py``). + +The writer receives the node tree and returns the output document. +For HTML output, we can test this using the ``rst2html.py`` tool:: + + $ rst2html.py test.txt + + + + + + + + + + +
    +

    My favorite language is Python.

    +
    + + + +So here we finally have our HTML output. The actual document contents +are in the fourth-last line. Note, by the way, that the HTML writer +did not render the (invisible) ``target`` node—only the ``paragraph`` +node and its children appear in the HTML output. + + +Extending Docutils +================== + +Now you'll ask, "how do I actually extend Docutils?" + +First of all, once you are clear about *what* you want to achieve, you +have to decide *where* to implement it—in the Parser (e.g. by adding a +directive or role to the reStructuredText parser), as a Transform, or +in the Writer. There is often one obvious choice among those three +(Parser, Transform, Writer). If you are unsure, ask on the +Docutils-develop_ mailing list. + +In order to find out how to start, it is often helpful to look at +similar features which are already implemented. For example, if you +want to add a new directive to the reStructuredText parser, look at +the implementation of a similar directive in +``docutils/parsers/rst/directives/``. + + +What Now? +========= + +This document is not complete. Many topics could (and should) be +covered here. To find out with which topics we should write about +first, we are awaiting *your* feedback. So please ask your questions +on the Docutils-develop_ mailing list. + + +.. _Docutils-develop: ../user/mailing-lists.html#docutils-develop diff --git a/docs/index.txt b/docs/index.txt index bffe3942d..67849d393 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -179,6 +179,7 @@ __ http://www.python.org/peps/pep-0287.html Docutils-general: +* `Docutils Hacker's Guide `__ * `Docutils To Do List `__ * `Docutils Project Policies `__ * `Docutils Web Site `__ -- cgit v1.2.1 From 2a162380e977d3862d42986cbbd470bbbe6a463e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 15:21:24 +0000 Subject: correction git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3432 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/mailing-lists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt index e033f0cb8..c7ce909cf 100644 --- a/docs/user/mailing-lists.txt +++ b/docs/user/mailing-lists.txt @@ -89,8 +89,7 @@ Docutils-checkins All check-ins to the `Subversion repository`_ cause a "check-in email" to the Docutils-checkins list. In order to stay informed about current development, developers are advised to monitor this mailing -list as well. - +list. This mailing list is for reading only; please direct any discussion about the check-ins to Docutils-develop. (For your convenience, the -- cgit v1.2.1 From 19a93281192f747b7b9ebf20da4b779e4ec1c8e1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 19:04:41 +0000 Subject: added ^2 and ^3 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3433 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index aee2c9f6f..4992ed3f4 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -289,6 +289,8 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): unicode_map = { u'\u00A0': '~', + u'\u00B2': '$^2$', + u'\u00B3': '$^3$', u'\u2009': '{\\,}', u'\u2013': '{--}', u'\u2014': '{---}', -- cgit v1.2.1 From 684ed18e5cd24430f5b444f016689d9e8ed34dd3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 19:05:33 +0000 Subject: added clear properties for footer div and aligned images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3434 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index c79647380..73cc7bcd0 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -83,6 +83,7 @@ div.figure { margin-left: 2em } div.footer, div.header { + clear: both; font-size: smaller } div.line-block { @@ -138,6 +139,9 @@ h2.subtitle { hr.docutils { width: 75% } +img[align] { + clear: both } + img.borderless { border: 0 } -- cgit v1.2.1 From a862180aebdaa82e6169aa0ee42bf029be48575c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 19:05:58 +0000 Subject: added posting statistics from Gmane git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3435 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/mailing-lists.txt | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt index c7ce909cf..e1083fc9a 100644 --- a/docs/user/mailing-lists.txt +++ b/docs/user/mailing-lists.txt @@ -18,6 +18,18 @@ unsure, use the **Docutils-users** mailing list: Docutils-users -------------- +.. image:: http://gmane.org/plot-rate.php?width=300&height=150& + group=gmane.text.docutils.user& + title=Posting+rate+for+Docutils-users + :target: http://gmane.org/plot-rate.php?width=600&height=300& + group=gmane.text.docutils.user& + title=Posting+rate+for+Docutils-users + :alt: Posting rate for Docutils-users + :width: 300 + :height: 150 + :align: right + :class: borderless + The Docutils-users mailing list is a place to discuss any issues related to the usage of Docutils and reStructuredText. (Please be sure to check the FAQ_ first.) @@ -56,6 +68,18 @@ resend your message using a different email address. Doc-SIG ------- +.. image:: http://gmane.org/plot-rate.php?width=300&height=150& + group=gmane.comp.python.documentation& + title=Posting+rate+for+Doc-SIG + :target: http://gmane.org/plot-rate.php?width=600&height=300& + group=gmane.comp.python.documentation& + title=Posting+rate+for+Doc-SIG + :alt: Posting rate for Doc-SIG + :width: 300 + :height: 150 + :align: right + :class: borderless + The "Python Documentation Special Interest Group" (Doc-SIG) mailing list is occasionally used to discuss the usage of Docutils for Python documentation. @@ -72,6 +96,18 @@ __ nntp://news.gmane.org/gmane.comp.python.documentation Docutils-develop ---------------- +.. image:: http://gmane.org/plot-rate.php?width=300&height=150& + group=gmane.text.docutils.devel& + title=Posting+rate+for+Docutils-develop + :target: http://gmane.org/plot-rate.php?width=600&height=300& + group=gmane.text.docutils.devel& + title=Posting+rate+for+Docutils-develop + :alt: Posting rate for Docutils-develop + :width: 300 + :height: 150 + :align: right + :class: borderless + Discussions about developing and extending Docutils take place on the Docutils-develop mailing list. @@ -83,9 +119,22 @@ __ http://lists.sourceforge.net/lists/listinfo/docutils-develop __ http://news.gmane.org/gmane.text.docutils.devel __ nntp://news.gmane.org/gmane.text.docutils.devel + Docutils-checkins ----------------- +.. image:: http://gmane.org/plot-rate.php?width=300&height=150& + group=gmane.text.docutils.cvs& + title=Posting+rate+for+Docutils-checkins + :target: http://gmane.org/plot-rate.php?width=600&height=300& + group=gmane.text.docutils.cvs& + title=Posting+rate+for+Docutils-checkins + :alt: Posting rate for Docutils-checkins + :width: 300 + :height: 150 + :align: right + :class: borderless + All check-ins to the `Subversion repository`_ cause a "check-in email" to the Docutils-checkins list. In order to stay informed about current development, developers are advised to monitor this mailing -- cgit v1.2.1 From bcea223d684bff8c8344421ca3a0540313e9bd3e Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 19:33:33 +0000 Subject: added note about developers who already have CVS write-access on SF.net git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3436 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index e22b0d428..7a3cfde60 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -3,6 +3,7 @@ ========================== :Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de :Revision: $Revision$ :Date: $Date$ :Copyright: This document has been placed in the public domain. @@ -60,6 +61,12 @@ type :: Developer Access ---------------- +(Developers who had write-access for Docutils' CVS repository on +SourceForge.net should `register at BerliOS`__ and send an email with +their BerliOS user name to `Felix Wiemann `_.) + +__ https://developer.berlios.de/account/register.php + If you are a developer, you get read-write access via ``svn+ssh://username@svn.berlios.de/svnroot/repos/docutils/``, where ``username`` is your BerliOS user name. So to retrieve a working -- cgit v1.2.1 From f3bb5b2325061a52c7de10c726defec34e1d893f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 21:30:29 +0000 Subject: fixed target bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3437 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 3 ++- test/functional/expected/standalone_rst_html4css1.html | 4 ++-- test/functional/expected/standalone_rst_pseudoxml.txt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 7d1aa29e8..9a7479c5f 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -84,7 +84,8 @@ class PropagateTargets(Transform): target['ids'] = [] target['names'] = [] self.document.note_refid(target) - self.document.note_internal_target(next_node) + if isinstance(next_node, nodes.target): + self.document.note_internal_target(next_node) class AnonymousHyperlinks(Transform): diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index abfdcbfe7..954d3daf7 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -547,8 +547,8 @@ document (a document-wide table o

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png

    Image with multiple IDs:

    -
    ../../../docs/user/rst/images/title.png
    -

    A figure directive:

    +
    ../../../docs/user/rst/images/title.png
    +

    A figure directive:

    reStructuredText, the markup syntax

    A figure is an image with a caption and/or a legend:

    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index b1cce6c09..80fd02bd6 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1127,8 +1127,8 @@ - - + + A figure directive:
    -- cgit v1.2.1 From 94919da6a00f847aa507ec658f7edeb8676381f0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 5 Jun 2005 23:05:51 +0000 Subject: added possibility to pass node classes to node.traverse() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3438 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++++++ test/test_nodes.py | 1 + 2 files changed, 12 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 700b509d3..e9cecf7bc 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -23,11 +23,14 @@ hierarchy. __docformat__ = 'reStructuredText' +from __future__ import nested_scopes + import sys import os import re import copy import warnings +import inspect import xml.dom.minidom from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType @@ -175,6 +178,11 @@ class Node: * the siblings of the parent (if ascend is true) and their descendants (if also descend is true), and so on + If `condition` is not None, the iterable contains only nodes + for which ``condition(node)`` is true. If `condition` is a + node class ``cls``, it is equivalent to ``lambda n: + isinstance(n, cls)``. + If ascend is true, assume siblings to be true as well. For example, given the following tree:: @@ -198,6 +206,9 @@ class Node: r = [] if ascend: siblings=1 + if inspect.isclass(condition) and issubclass(condition, Node): + node_class = condition + condition = lambda n: isinstance(n, node_class) if include_self and (condition is None or condition(self)): r.append(self) if descend and len(self.children): diff --git a/test/test_nodes.py b/test/test_nodes.py index ce2115c0e..3889a19be 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -163,6 +163,7 @@ class MiscTests(unittest.TestCase): self.testlist.append(e[0][1][0]) self.assertEquals(list(e[0].traverse(condition=self.not_in_testlist)), [e[0]]) + self.assertEquals(list(e.traverse(nodes.TextElement)), [e[0][1]]) def test_next_node(self): e = nodes.Element() -- cgit v1.2.1 From 9061c56e4edac24c8e7adbe7aa6131578af9f040 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 6 Jun 2005 01:20:35 +0000 Subject: added "local" class to local TOCs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3439 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/parts.py | 2 ++ docutils/writers/latex2e.py | 6 +++--- test/functional/expected/standalone_rst_html4css1.html | 2 +- test/functional/expected/standalone_rst_pseudoxml.txt | 2 +- test/test_parsers/test_rst/test_directives/test_contents.py | 4 ++-- test/test_transforms/test_contents.py | 6 +++--- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docutils/parsers/rst/directives/parts.py b/docutils/parsers/rst/directives/parts.py index 37a32a963..2a1a092a4 100644 --- a/docutils/parsers/rst/directives/parts.py +++ b/docutils/parsers/rst/directives/parts.py @@ -56,6 +56,8 @@ def contents(name, arguments, options, content, lineno, title = nodes.title('', language.labels['contents']) topic = nodes.topic(classes=['contents']) topic['classes'] += options.get('class', []) + if options.has_key('local'): + topic['classes'].append('local') if title: name = title.astext() topic += title diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index dc7df9731..0522ce0aa 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -946,14 +946,14 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append( '\\end{quote}\n') def visit_bullet_list(self, node): - if self.topic_classes == ['contents']: + if 'contents' in self.topic_classes: if not self.use_latex_toc: self.body.append( '\\begin{list}{}{}\n' ) else: self.body.append( '\\begin{itemize}\n' ) def depart_bullet_list(self, node): - if self.topic_classes == ['contents']: + if 'contents' in self.topic_classes: if not self.use_latex_toc: self.body.append( '\\end{list}\n' ) else: @@ -1708,7 +1708,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_paragraph(self, node): index = node.parent.index(node) - if not (self.topic_classes == ['contents'] or + if not ('contents' in self.topic_classes or (isinstance(node.parent, nodes.compound) and index > 0 and not isinstance(node.parent[index - 1], nodes.paragraph) and diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 954d3daf7..73f60588b 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -522,7 +522,7 @@ this: `Duplicate

    2.14   Directives

    -
    +
    • 2.14.1   Document Parts
    • 2.14.2   Images
    • diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 80fd02bd6..62f923a03 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1048,7 +1048,7 @@ 2.14    Directives - + diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index e2b5f29a2..6d6d0f3e2 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -101,7 +101,7 @@ totest['contents'] = [ """, """\ - + .. internal attributes: .transform: docutils.transforms.parts.Contents @@ -132,7 +132,7 @@ totest['contents'] = [ """, """\ - + Table of Contents <pending> diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index 0871aa8f0..c96764343 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -258,7 +258,7 @@ Paragraph 4. <section ids="title-1" names="title 1"> <title> Title 1 - <topic classes="contents" ids="contents" names="contents"> + <topic classes="contents local" ids="contents" names="contents"> <bullet_list> <list_item> <paragraph> @@ -303,7 +303,7 @@ Paragraph. """, """\ <document source="test data"> - <topic classes="contents" ids="contents" names="contents"> + <topic classes="contents local" ids="contents" names="contents"> <bullet_list> <list_item> <paragraph> @@ -404,7 +404,7 @@ Paragraph 3. <sidebar> <title> Contents - <topic classes="contents" ids="contents" names="contents"> + <topic classes="contents local" ids="contents" names="contents"> <bullet_list> <list_item> <paragraph> -- cgit v1.2.1 From 59d18be8f7244e4440b846cb5fe45e226d594f1a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 01:21:23 +0000 Subject: new LaTeX writer: added TOC support git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3440 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 19 +++++++++ tools/stylesheets/latex.tex | 94 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 4992ed3f4..c96be14d1 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -405,6 +405,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): isinstance(node.parent[1], nodes.subtitle)) and 'true' or 'false')) + def before_generated(self, node): + if 'sectnum' in node['classes']: + node[0] = node[0].strip() + literal_block = 0 def visit_literal_block(self, node): @@ -429,6 +433,21 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): in node.astext().splitlines(0)]), newline='\n') raise nodes.SkipChildren + def before_topic(self, node): + if 'contents' in node['classes']: + for bullet_list in list(node.traverse(nodes.bullet_list)): + p = bullet_list.parent + if isinstance(p, nodes.list_item): + p.parent.insert(p.parent.index(p) + 1, bullet_list) + del p[1] + for paragraph in node.traverse(nodes.paragraph): + paragraph.attributes.update(paragraph[0].attributes) + paragraph[:] = paragraph[0] + paragraph.parent['tocrefid'] = paragraph['refid'] + node['contents'] = 1 + else: + node['contents'] = 0 + bullet_list_level = 0 def visit_bullet_list(self, node): diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index d9fc58348..aa14e7801 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -56,7 +56,7 @@ \providecommand{\Dmakebox}[1]{% % Make a centered, frameless box. Useful e.g. for block quotes. % Do not use minipages here, but create pseudo-lists to allow - % page-breaking. (Don't uses KOMA-script's addmargin environment + % page-breaking. (Don't use KOMA-script's addmargin environment % because it messes up bullet lists.) \Dmakelistenvironment{}{}{% \setlength{\parskip}{0pt}% @@ -147,6 +147,7 @@ % Targets. \Dprovidelength{\Dorgbaselineskip}{0pt} \providecommand{\DAids}[5]{% + \label{##3}% \ifthenelse{\equal{##4}{footnotereference}}{% {% \renewcommand{\HyperRaiseLinkDefault}{% @@ -346,12 +347,16 @@ \providecommand{\Dvisitdocument}{\begin{document}\noindent} \providecommand{\Ddepartdocument}{\end{document}} \providecommand{\DNtopic}[1]{% - \par% - \Dmakebox{% - %% % Close with \par because otherwise LaTeX wouldn't notice the - %% % changed \baselineskip (due to the font size change). - %% {\small#1\par}% + \ifthenelse{\equal{\DcurrentNtopicAcontents}{1}}{% + \addtocounter{Dtoclevel}{1}% + \vspace{1em}% + \par\noindent% #1% + \addtocounter{Dtoclevel}{-1}% + \renewcommand{\Dnextparindent}{\noindent}% + }{% + \par\noindent% + \Dmakebox{#1}% }% } \providecommand{\Dformatrubric}[1]{\textbf{#1}} @@ -362,9 +367,45 @@ \providecommand{\Dbullet}{} \providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} -\providecommand{\DNbulletlist}[1]{\Dmakelistenvironment{\Dbullet}{}{#1}} - -\providecommand{\DNlistitem}[1]{\item{#1}} +\providecommand{\DNbulletlist}[1]{% + \Difinsidetoc{% + \addtocounter{Dtoclevel}{1}% + \addtolength{\Dtocindent}{\Dtocsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% + \addtocounter{Dtoclevel}{-1}% + }{% + \Dmakelistenvironment{\Dbullet}{}{#1}% + }% +} +\renewcommand{\@pnumwidth}{2.2em} +\providecommand{\DNlistitem}[1]{% + \Difinsidetoc{% + \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{% + \par\addvspace{1em}% + % Group taken from scrartcl.cls and modified: + \begingroup% + \parindent0pt% + \rightskip\@pnumwidth% + \parfillskip-\@pnumwidth% + \leavevmode\sectfont% + \advance\leftskip\@tempdima% + \hskip-\leftskip% + {#1}\nobreak\hfil\nobreak\hb@xt@\@pnumwidth{\hss% + \pageref{\DcurrentNlistitemAtocrefid}% + }\par% + \endgroup% + }{% + \@dottedtocline{0}{\Dtocindent}{0em}{#1}{% + \pageref{\DcurrentNlistitemAtocrefid}% + }% + }% + }{% + \item{#1}% + }% +} \providecommand{\DNenumeratedlist}[1]{#1} \newcounter{Dsectionlevel} \providecommand{\Dvisitsectionhook}{} @@ -953,6 +994,41 @@ \providecommand{\Dtextleftdblquote}{``} \providecommand{\Dtextrightdblquote}{''} +% Table of contents: +\Dprovidelength{\Dtocininitialsectnumwidth}{2.4em} +\Dprovidelength{\Dtocadditionalsectnumwidth}{0.7em} +% Level inside a table of contents. While this is at -1, we are not +% inside a TOC. +\Dprovidecounter{Dtoclevel}% +\setcounter{Dtoclevel}{-1} +\providecommand{\Dlocaltoc}{false}% +\providecommand{\DNtopicClocal}[1]{% + \renewcommand{\Dlocaltoc}{true}% + \addtolength{\Dtocsectnumwidth}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-2\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocindent}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{-2\Dtocadditionalsectnumwidth}% + \renewcommand{\Dlocaltoc}{false}% +} +\Dprovidelength{\Dtocindent}{0pt}% +\Dprovidelength{\Dtocsectnumwidth}{\Dtocininitialsectnumwidth} +% Compensate for one additional TOC indentation space so that the +% top-level is unindented. +\addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth} +\addtolength{\Dtocindent}{-\Dtocsectnumwidth} +\providecommand{\Difinsidetoc}[2]{% + \ifthenelse{\not\equal{\theDtoclevel}{-1}}{#1}{#2}% +} +\providecommand{\DNgeneratedCsectnum}[1]{% + \Difinsidetoc{% + % Section number inside TOC. + \makebox[\Dtocsectnumwidth][l]{#1}% + }{% + % Section number inside section title. + #1\quad% + }% +} %\usepackage{fixmath} %\usepackage{amsmath} -- cgit v1.2.1 From c196d1b588df3465000a0d836fc55eb9c11baed2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 13:05:49 +0000 Subject: removed <div>s around images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3441 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 44 +++++++++------------- test/functional/expected/dangerous.html | 2 +- .../expected/standalone_rst_html4css1.html | 10 ++--- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 22eedf4f3..2e5fa69af 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -888,24 +888,20 @@ class HTMLTranslator(nodes.NodeVisitor): del atts['scale'] if not atts.has_key('alt'): atts['alt'] = atts['src'] - if isinstance(node.parent, nodes.TextElement): - self.context.append('') + if atts.has_key('align'): + atts['align'] = self.attval(atts['align']) + atts['class'] = 'align-%s' % atts['align'] + if (isinstance(node.parent, nodes.TextElement) or + (isinstance(node.parent, nodes.reference) and + not isinstance(node.parent.parent, nodes.TextElement))): + # Inline context or surrounded by <a>...</a>. + suffix = '' else: - div_atts = self.image_div_atts(node) - self.body.append(self.starttag({}, 'div', '', **div_atts)) - self.context.append('</div>\n') - self.body.append(self.emptytag(node, 'img', '', **atts)) - - def image_div_atts(self, image_node): - div_atts = {} - div_atts['class'] = ' '.join(['image'] + image_node['classes']) - if image_node.attributes.has_key('align'): - div_atts['align'] = self.attval(image_node.attributes['align']) - div_atts['class'] += ' align-%s' % div_atts['align'] - return div_atts + suffix = '\n' + self.body.append(self.emptytag(node, 'img', suffix, **atts)) def depart_image(self, node): - self.body.append(self.context.pop()) + pass def visit_important(self, node): self.visit_admonition(node, 'important') @@ -1116,14 +1112,6 @@ class HTMLTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_reference(self, node): - if isinstance(node.parent, nodes.TextElement): - self.context.append('') - else: # contains an image - assert len(node) == 1 and isinstance(node[0], nodes.image) - div_atts = self.image_div_atts(node[0]) - div_atts['class'] += ' image-reference' - self.body.append(self.starttag({}, 'div', '', **div_atts)) - self.context.append('</div>\n') if node.has_key('refuri'): href = node['refuri'] if ( self.settings.cloak_email_addresses @@ -1134,12 +1122,16 @@ class HTMLTranslator(nodes.NodeVisitor): assert node.has_key('refid'), \ 'References must have "refuri" or "refid" attribute.' href = '#' + node['refid'] - self.body.append(self.starttag(node, 'a', '', CLASS='reference', - href=href)) + atts = {'href': href, 'class': 'reference'} + if not isinstance(node.parent, nodes.TextElement): + assert len(node) == 1 and isinstance(node[0], nodes.image) + atts['class'] += ' image-reference' + self.body.append(self.starttag(node, 'a', '', **atts)) def depart_reference(self, node): self.body.append('</a>') - self.body.append(self.context.pop()) + if not isinstance(node.parent, nodes.TextElement): + self.body.append('\n') self.in_mailto = 0 def visit_revision(self, node): diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 42236c729..779ea9479 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -59,7 +59,7 @@ </pre> </div> <div class="figure"> -<div class="image"><img alt="picture.png" src="picture.png" /></div> +<img alt="picture.png" src="picture.png" /> </div> </div> </body> diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 73f60588b..280a9f1e5 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -545,12 +545,12 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <div class="section" id="images"> <h3><a class="toc-backref" href="#id63" name="images">2.14.2   Images</a></h3> <p>An image directive (also clickable -- a hyperlink reference):</p> -<div class="image class1 class2 image-reference"><a class="reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a></div> +<a class="reference image-reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a> <p>Image with multiple IDs:</p> -<div class="image"><span id="image-target-2"></span><span id="image-target-1"></span><img alt="../../../docs/user/rst/images/title.png" id="image-target-3" ids="image-target-3 image-target-2 image-target-1" name="image-target-3" names="image target 3 image target 2 image target 1" src="../../../docs/user/rst/images/title.png" /></div> +<span id="image-target-2"></span><span id="image-target-1"></span><img alt="../../../docs/user/rst/images/title.png" id="image-target-3" ids="image-target-3 image-target-2 image-target-1" name="image-target-3" names="image target 3 image target 2 image target 1" src="../../../docs/user/rst/images/title.png" /> <p>A figure directive:</p> <div align="right" class="figclass1 figclass2 figure"> -<div class="image class1 class2"><img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> +<img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" width="50" /> <p class="caption">A figure is an image with a caption and/or a legend:</p> <div class="legend"> <table border="1" class="docutils"> @@ -576,7 +576,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph might flow around the figure...</p> <p>A centered figure:</p> <div align="center" class="figure"> -<div class="image"><img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /> <p class="caption">This is the caption.</p> <div class="legend"> <p>This is the legend.</p> @@ -586,7 +586,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph might flow around the figure...</p> <p>A left-aligned figure:</p> <div align="left" class="figure"> -<div class="image"><img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /></div> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /> <p class="caption">This is the caption.</p> <div class="legend"> <p>This is the legend.</p> -- cgit v1.2.1 From bee3ce552cfb22f986282b9a1f4a625496f4bbfd Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 13:09:07 +0000 Subject: improved stylesheet; made it compatible to IE git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3442 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/default.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index 73cc7bcd0..abfcbce7a 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -139,8 +139,11 @@ h2.subtitle { hr.docutils { width: 75% } -img[align] { - clear: both } +img.align-left { + clear: left } + +img.align-right { + clear: right } img.borderless { border: 0 } -- cgit v1.2.1 From 488f267dde33c01264ded78b61298a1b06b877f3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 13:20:22 +0000 Subject: fixed wrong propagation of attributes to img elements in HTML git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3443 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 33 +++++++++++----------- .../expected/standalone_rst_html4css1.html | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 2e5fa69af..74d3de874 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -860,14 +860,15 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_admonition() def visit_image(self, node): - atts = node.non_default_attributes() - if atts.has_key('classes'): - del atts['classes'] # prevent duplication with node attrs - atts['src'] = atts['uri'] - del atts['uri'] - if atts.has_key('scale'): - if Image and not (atts.has_key('width') - and atts.has_key('height')): + atts = {} + atts['src'] = node['uri'] + if node.has_key('width'): + atts['width'] = node['width'] + if node.has_key('height'): + atts['height'] = node['height'] + if node.has_key('scale'): + if Image and not (node.has_key('width') + and node.has_key('height')): try: im = Image.open(str(atts['src'])) except (IOError, # Source image can't be found or opened @@ -880,16 +881,14 @@ class HTMLTranslator(nodes.NodeVisitor): atts['height'] = im.size[1] del im if atts.has_key('width'): - atts['width'] = int(round(atts['width'] - * (float(atts['scale']) / 100))) + atts['width'] = int(round(node['width'] + * (float(node['scale']) / 100))) if atts.has_key('height'): - atts['height'] = int(round(atts['height'] - * (float(atts['scale']) / 100))) - del atts['scale'] - if not atts.has_key('alt'): - atts['alt'] = atts['src'] - if atts.has_key('align'): - atts['align'] = self.attval(atts['align']) + atts['height'] = int(round(node['height'] + * (float(node['scale']) / 100))) + atts['alt'] = node.get('alt', atts['src']) + if node.has_key('align'): + atts['align'] = self.attval(node['align']) atts['class'] = 'align-%s' % atts['align'] if (isinstance(node.parent, nodes.TextElement) or (isinstance(node.parent, nodes.reference) and diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 280a9f1e5..ba5d7784d 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -547,7 +547,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>An image directive (also clickable -- a hyperlink reference):</p> <a class="reference image-reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a> <p>Image with multiple IDs:</p> -<span id="image-target-2"></span><span id="image-target-1"></span><img alt="../../../docs/user/rst/images/title.png" id="image-target-3" ids="image-target-3 image-target-2 image-target-1" name="image-target-3" names="image target 3 image target 2 image target 1" src="../../../docs/user/rst/images/title.png" /> +<span id="image-target-2"></span><span id="image-target-1"></span><img alt="../../../docs/user/rst/images/title.png" id="image-target-3" name="image-target-3" src="../../../docs/user/rst/images/title.png" /> <p>A figure directive:</p> <div align="right" class="figclass1 figclass2 figure"> <img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" width="50" /> -- cgit v1.2.1 From 0de11999bef7fde228766a0e501a6141d32d28a6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 22:42:28 +0000 Subject: replaced code copied from KOMA-script by self-written code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3444 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index aa14e7801..f01ed437c 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -384,19 +384,11 @@ \providecommand{\DNlistitem}[1]{% \Difinsidetoc{% \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{% - \par\addvspace{1em}% - % Group taken from scrartcl.cls and modified: - \begingroup% - \parindent0pt% - \rightskip\@pnumwidth% - \parfillskip-\@pnumwidth% - \leavevmode\sectfont% - \advance\leftskip\@tempdima% - \hskip-\leftskip% - {#1}\nobreak\hfil\nobreak\hb@xt@\@pnumwidth{\hss% - \pageref{\DcurrentNlistitemAtocrefid}% - }\par% - \endgroup% + {% + \par\addvspace{1em}\noindent% + \sectfont% + #1\hfill\pageref{\DcurrentNlistitemAtocrefid}% + }% }{% \@dottedtocline{0}{\Dtocindent}{0em}{#1}{% \pageref{\DcurrentNlistitemAtocrefid}% -- cgit v1.2.1 From 8f54a134c2eb666aa932353dc46b66aa9fa961c2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 23:27:42 +0000 Subject: fixed some spacing problems git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3445 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index f01ed437c..6a74b7b0f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -369,13 +369,7 @@ \providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} \providecommand{\DNbulletlist}[1]{% \Difinsidetoc{% - \addtocounter{Dtoclevel}{1}% - \addtolength{\Dtocindent}{\Dtocsectnumwidth}% - \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% - #1% - \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% - \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% - \addtocounter{Dtoclevel}{-1}% + \Dtocbulletlist{#1}% }{% \Dmakelistenvironment{\Dbullet}{}{#1}% }% @@ -435,6 +429,7 @@ }% } \providecommand{\Dresetlistdepth}{false} +\Dprovidelength{\Doriginallabelsep}{\labelsep} \providecommand{\Dmakelistenvironment}[3]{% % Make list environment with support for unlimited nesting and with % reasonable default lengths. Parameters: @@ -462,6 +457,7 @@ \setlength{\topsep}{0pt}% % List should take 90% of total width. \setlength{\leftmargin}{0.05\linewidth}% + \setlength{\labelsep}{\Doriginallabelsep}% \Dsetlistrightmargin% #2% }{% @@ -546,6 +542,7 @@ \Dprovidelength{\Drealfieldnamewidth}{0pt} \providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}} \providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}} +\Dprovidelength{\Dparskiptemp}{0pt} \providecommand{\Dtabularlistfield}[1]{% {% % This only saves field name and field body in \Dsavefieldname and @@ -567,11 +564,17 @@ }{% \item% \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}% + \setlength{\Dparskiptemp}{\parskip}% \ifthenelse{% \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% - }{~\newline}{}% + }{% + \mbox{}\par% + \setlength{\parskip}{0pt}% + }{}% \Dsavefieldbody% - \@finalstrut\@arstrutbox% + \setlength{\parskip}{\Dparskiptemp}% + %XXX Why did we need this? + %\@finalstrut\@arstrutbox% }% \par% }% @@ -641,9 +644,6 @@ } \providecommand{\DNdefinitionlist}[1]{% - % XXX Replace with a generic list, so we don't have to hack around - % spacing problems with \vspace and \hspace. - \vspace{-2em}% \begin{description}% \parskip0pt% #1% @@ -1021,6 +1021,15 @@ #1\quad% }% } +\providecommand{\Dtocbulletlist}[1]{% + \addtocounter{Dtoclevel}{1}% + \addtolength{\Dtocindent}{\Dtocsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% + \addtocounter{Dtoclevel}{-1}% +} %\usepackage{fixmath} %\usepackage{amsmath} -- cgit v1.2.1 From 7181a95e2bae1fbbf5e5b0f78c5abedfbb1908c1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 23:39:25 +0000 Subject: fixed more spacing problems git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3446 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 1 + tools/stylesheets/latex.tex | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index c96be14d1..10ffc319e 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -352,6 +352,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if self.literal_block: # Replace newlines with real newlines. text = text.replace('\n', '\mbox{}\\\\') + text += r'\Dfinalstrut' firstspace = '~' else: firstspace = '{ }' diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 6a74b7b0f..a5e5692f3 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -457,6 +457,9 @@ \setlength{\topsep}{0pt}% % List should take 90% of total width. \setlength{\leftmargin}{0.05\linewidth}% + \ifthenelse{\lengthtest{\leftmargin<1.8em}}{% + \setlength{\leftmargin}{1.8em}% + }{}% \setlength{\labelsep}{\Doriginallabelsep}% \Dsetlistrightmargin% #2% @@ -468,7 +471,8 @@ }% \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% } -\providecommand{\DAlastitem}[5]{#5\@finalstrut\@arstrutbox} +\providecommand{\Dfinalstrut}{\@finalstrut\@arstrutbox} +\providecommand{\DAlastitem}[5]{#5\Dfinalstrut} \Dprovidelength{\Ditemsep}{0pt} \providecommand{\Dmakeenumeratedlist}[6]{% -- cgit v1.2.1 From a2da7dc08f353e141dd3a58387c5a8f35bdc9cbf Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 6 Jun 2005 23:46:40 +0000 Subject: do not indent literal blocks inside a table git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3447 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index a5e5692f3..2a5689cf3 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -332,7 +332,12 @@ %\providecommand{\DNliteralblock}[1]{\begin{quote}\ttfamily\raggedright#1\end{quote}} \providecommand{\DNliteralblock}[1]{% - \Dmakelistenvironment{}{}{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + \setlength{\leftmargin}{0pt}% + }{}% + \setlength{\rightmargin}{0pt}% + }{% \raggedright\item\noindent\nohyphens{\textnhtt{#1}}% }% } -- cgit v1.2.1 From 93f2fe0cba6b389dc708a9032117c96491de5e35 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 Jun 2005 00:57:43 +0000 Subject: moved \Dfinalstrut into the stylesheet where it belongs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3448 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 1 - tools/stylesheets/latex.tex | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 10ffc319e..c96be14d1 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -352,7 +352,6 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if self.literal_block: # Replace newlines with real newlines. text = text.replace('\n', '\mbox{}\\\\') - text += r'\Dfinalstrut' firstspace = '~' else: firstspace = '{ }' diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 2a5689cf3..64d56ac59 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -338,7 +338,7 @@ }{}% \setlength{\rightmargin}{0pt}% }{% - \raggedright\item\noindent\nohyphens{\textnhtt{#1}}% + \raggedright\item\noindent\nohyphens{\textnhtt{#1\Dfinalstrut}}% }% } \providecommand{\DNdoctestblock}[1]{% -- cgit v1.2.1 From 7ccac8221c559ac7fab0428807919c6831b6c848 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 7 Jun 2005 22:13:33 +0000 Subject: removed mailing list statistics; they are distracting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3450 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/mailing-lists.txt | 48 --------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt index e1083fc9a..de4aff3de 100644 --- a/docs/user/mailing-lists.txt +++ b/docs/user/mailing-lists.txt @@ -18,18 +18,6 @@ unsure, use the **Docutils-users** mailing list: Docutils-users -------------- -.. image:: http://gmane.org/plot-rate.php?width=300&height=150& - group=gmane.text.docutils.user& - title=Posting+rate+for+Docutils-users - :target: http://gmane.org/plot-rate.php?width=600&height=300& - group=gmane.text.docutils.user& - title=Posting+rate+for+Docutils-users - :alt: Posting rate for Docutils-users - :width: 300 - :height: 150 - :align: right - :class: borderless - The Docutils-users mailing list is a place to discuss any issues related to the usage of Docutils and reStructuredText. (Please be sure to check the FAQ_ first.) @@ -68,18 +56,6 @@ resend your message using a different email address. Doc-SIG ------- -.. image:: http://gmane.org/plot-rate.php?width=300&height=150& - group=gmane.comp.python.documentation& - title=Posting+rate+for+Doc-SIG - :target: http://gmane.org/plot-rate.php?width=600&height=300& - group=gmane.comp.python.documentation& - title=Posting+rate+for+Doc-SIG - :alt: Posting rate for Doc-SIG - :width: 300 - :height: 150 - :align: right - :class: borderless - The "Python Documentation Special Interest Group" (Doc-SIG) mailing list is occasionally used to discuss the usage of Docutils for Python documentation. @@ -96,18 +72,6 @@ __ nntp://news.gmane.org/gmane.comp.python.documentation Docutils-develop ---------------- -.. image:: http://gmane.org/plot-rate.php?width=300&height=150& - group=gmane.text.docutils.devel& - title=Posting+rate+for+Docutils-develop - :target: http://gmane.org/plot-rate.php?width=600&height=300& - group=gmane.text.docutils.devel& - title=Posting+rate+for+Docutils-develop - :alt: Posting rate for Docutils-develop - :width: 300 - :height: 150 - :align: right - :class: borderless - Discussions about developing and extending Docutils take place on the Docutils-develop mailing list. @@ -123,18 +87,6 @@ __ nntp://news.gmane.org/gmane.text.docutils.devel Docutils-checkins ----------------- -.. image:: http://gmane.org/plot-rate.php?width=300&height=150& - group=gmane.text.docutils.cvs& - title=Posting+rate+for+Docutils-checkins - :target: http://gmane.org/plot-rate.php?width=600&height=300& - group=gmane.text.docutils.cvs& - title=Posting+rate+for+Docutils-checkins - :alt: Posting rate for Docutils-checkins - :width: 300 - :height: 150 - :align: right - :class: borderless - All check-ins to the `Subversion repository`_ cause a "check-in email" to the Docutils-checkins list. In order to stay informed about current development, developers are advised to monitor this mailing -- cgit v1.2.1 From 6ecc583cff7fe89314c304dbdb3281a645c91b6b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 8 Jun 2005 13:28:20 +0000 Subject: added blog git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3452 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/FAQ.txt b/FAQ.txt index bfa8442b2..756fedc38 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -403,6 +403,7 @@ Are there any Weblog (Blog) projects that use reStructuredText syntax? With no implied endorsement or recommendation, and in no particular order: +* `Firedrop <http://www.voidspace.org.uk/python/firedrop2/>`__ * `Python Desktop Server <http://pyds.muensterland.org/>`__ * `PyBloxsom <http://roughingit.subtlehints.net/pyblosxom/>`__ * `rst2ht <http://www.rutherfurd.net/articles/rst-ht2html.html>`__ -- cgit v1.2.1 From 8aa5605c667d2b86b3ad0b41f3209720e2b3eae0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 8 Jun 2005 13:49:42 +0000 Subject: added emphasis and clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3453 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index f21ed470e..2bede5ffd 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -84,11 +84,16 @@ Conventions`_ PEPs, with the following clarifications and extensions: "note_explicit_target", "explicit_target"). If in doubt, use underscores. -* Avoid functional constructs (lambda, filter, map, etc.). Use list +* Avoid lambda expressions, which are inherently difficult to + understand. Named functions are preferable and superior: they're + faster (no run-time compilation), and well-chosen names serve to + document and aid understanding. + +* Avoid functional constructs (filter, map, etc.). Use list comprehensions instead. -* Avoid ``from __future__ import`` constructs; we don't want them in - production code. +* Avoid ``from __future__ import`` constructs. They are inappropriate + for production code. * Use 'single quotes' for string literals, and """triple double quotes""" for docstrings. -- cgit v1.2.1 From cec037b796bfbd3481a37b0691c68a96f56ba0d9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 8 Jun 2005 14:08:21 +0000 Subject: removed "from __future__ import" statements and lambda expressions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3454 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 10 ++++------ docutils/parsers/rst/states.py | 19 +++++++++++++------ docutils/transforms/frontmatter.py | 3 +-- docutils/transforms/parts.py | 4 ++-- docutils/writers/newlatex2e.py | 25 +++++++++++++++---------- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index e9cecf7bc..03e65200a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -23,8 +23,6 @@ hierarchy. __docformat__ = 'reStructuredText' -from __future__ import nested_scopes - import sys import os import re @@ -180,8 +178,8 @@ class Node: If `condition` is not None, the iterable contains only nodes for which ``condition(node)`` is true. If `condition` is a - node class ``cls``, it is equivalent to ``lambda n: - isinstance(n, cls)``. + node class ``cls``, it is equivalent to a function consisting + of ``return isinstance(node, cls)``. If ascend is true, assume siblings to be true as well. @@ -208,7 +206,8 @@ class Node: siblings=1 if inspect.isclass(condition) and issubclass(condition, Node): node_class = condition - condition = lambda n: isinstance(n, node_class) + def condition(node, node_class=node_class): + return isinstance(node, node_class) if include_self and (condition is None or condition(self)): r.append(self) if descend and len(self.children): @@ -230,7 +229,6 @@ class Node: node = node.parent return r - def next_node(self, condition=None, include_self=0, descend=1, siblings=0, ascend=0): """ diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 1ee9dc6f2..b7a359159 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -984,6 +984,16 @@ class Inliner: '__': anonymous_reference} +def _loweralpha_to_int(s, _zero=(ord('a')-1)): + return ord(s) - _zero + +def _upperalpha_to_int(s, _zero=(ord('A')-1)): + return ord(s) - _zero + +def _lowerroman_to_int(s): + return roman.fromRoman(s.upper()) + + class Body(RSTState): """ @@ -1006,12 +1016,9 @@ class Body(RSTState): 'lowerroman': '[ivxlcdm]+', 'upperroman': '[IVXLCDM]+',} enum.converters = {'arabic': int, - 'loweralpha': - lambda s, zero=(ord('a')-1): ord(s) - zero, - 'upperalpha': - lambda s, zero=(ord('A')-1): ord(s) - zero, - 'lowerroman': - lambda s: roman.fromRoman(s.upper()), + 'loweralpha': _loweralpha_to_int, + 'upperalpha': _upperalpha_to_int, + 'lowerroman': _lowerroman_to_int, 'upperroman': roman.fromRoman} enum.sequenceregexps = {} diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index cd8fb0188..6fe6860e3 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -236,8 +236,7 @@ class SectionSubTitle(TitlePromoter): def apply(self): if not getattr(self.document.settings, 'sectsubtitle_xform', 1): return - for section in self.document.traverse(lambda n: - isinstance(n, nodes.section)): + 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 diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index 0feb74409..ff6a0e550 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -121,8 +121,8 @@ class Contents(Transform): 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( - lambda n: isinstance(n, nodes.reference)) is None): + 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': diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index c96be14d1..dd82851ee 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -15,8 +15,6 @@ LaTeX2e document tree Writer. __docformat__ = 'reStructuredText' -from __future__ import nested_scopes - import re import os.path from types import ListType @@ -352,11 +350,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if self.literal_block: # Replace newlines with real newlines. text = text.replace('\n', '\mbox{}\\\\') - firstspace = '~' + replace_fn = self.encode_replace_for_literal_block_spaces else: - firstspace = '{ }' - text = re.sub(r'\s+', lambda m: firstspace + - '~' * (len(m.group()) - 1), text) + replace_fn = self.encode_replace_for_inline_literal_spaces + text = re.sub(r'\s+', replace_fn, text) # Protect hyphens; if we don't, line breaks will be # possible at the hyphens and even the \textnhtt macro # from the hyphenat package won't change that. @@ -380,6 +377,12 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): else: return text + def encode_replace_for_literal_block_spaces(self, match): + return '~' * len(match.group()) + + def encode_replace_for_inline_literal_spaces(self, match): + return '{ }' + '~' * len(match.group() - 1) + def astext(self): return '\n'.join(self.header) + (''.join(self.body)) @@ -647,11 +650,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): document = node # Move IDs into TextElements. This won't work for images. # Need to review this. - for node in document.traverse(lambda n: isinstance(n, nodes.Element)): + for node in document.traverse(nodes.Element): if node.has_key('ids') and not isinstance(node, nodes.TextElement): - next_text_element = node.next_node( - lambda n: isinstance(n, nodes.TextElement)) + next_text_element = node.next_node(nodes.TextElement) if next_text_element: next_text_element['ids'].extend(node['ids']) node['ids'] = [] @@ -739,6 +741,9 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # Horizontally aligned image or figure. node.get('align', None) in ('left', 'center', 'right')) + def is_visible(self, node): + return not self.is_invisible(node) + def needs_space(self, node): # Return true if node is a visible block-level element. return ((isinstance(node, nodes.Body) or @@ -765,7 +770,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # Next sibling. next_node = node.next_node( ascend=0, siblings=1, descend=0, - condition=lambda n: not self.is_invisible(n)) + condition=self.is_visible) if self.needs_space(next_node): # Insert space. if isinstance(next_node, nodes.paragraph): -- cgit v1.2.1 From 61075e34557635f6facec931b31da5ec3b04243c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 9 Jun 2005 17:32:17 +0000 Subject: added "title" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3455 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 +- docs/ref/rst/directives.txt | 15 +++++++++++++++ docs/user/config.txt | 8 ++++++++ docs/user/rst/cheatsheet.txt | 1 + docutils/frontend.py | 5 ++++- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/misc.py | 7 +++++++ docutils/parsers/rst/languages/af.py | 1 + docutils/parsers/rst/languages/ca.py | 1 + docutils/parsers/rst/languages/cs.py | 1 + docutils/parsers/rst/languages/de.py | 1 + docutils/parsers/rst/languages/en.py | 1 + docutils/parsers/rst/languages/eo.py | 1 + docutils/parsers/rst/languages/es.py | 1 + docutils/parsers/rst/languages/fi.py | 1 + docutils/parsers/rst/languages/fr.py | 1 + docutils/parsers/rst/languages/it.py | 1 + docutils/parsers/rst/languages/nl.py | 1 + docutils/parsers/rst/languages/pt_br.py | 1 + docutils/parsers/rst/languages/ru.py | 1 + docutils/parsers/rst/languages/sk.py | 1 + docutils/parsers/rst/languages/sv.py | 1 + docutils/parsers/rst/languages/zh_tw.py | 1 + docutils/writers/html4css1.py | 18 ++++++++++++------ 24 files changed, 65 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index f862d4896..da344722a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -26,7 +26,7 @@ Changes Since 0.3.9 * docutils/parsers/rst/directives/misc.py: - - Added the "default-role" directive. + - Added the "default-role" and "title" directives. Release 0.3.9 (2005-05-26) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index dde952b7d..a0102f9e1 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -634,6 +634,21 @@ The following option is recognized: class_ directive below. +Title +===== + +:Directive Type: "title" +:Doctree Element: None. +:Directive Arguments: 1, required (the title text). +:Directive Options: None. +:Directive Content: None. + +The "title" directive specifies the document title as metadata, which +does not become part of the document body. It overrides a +document-supplied title. For example, in HTML output the metadata +document title appears in the title bar of the browser window. + + -------- Tables -------- diff --git a/docs/user/config.txt b/docs/user/config.txt index 66ad39234..fd75a16df 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -369,6 +369,14 @@ _`strict_visitor` Default: disabled (None). Option: ``--strict-visitor`` (hidden, for development use only). +-`title` + The document title as metadata, which does not become part of the + document body. It overrides a document-supplied title. For + example, in HTML output the metadata document title appears in the + title bar of the browser window. + + Default: none. Option: ``--title``. + _`toc_backlinks` Enable backlinks from section titles to table of contents entries ("entry"), to the top of the TOC ("top"), or disable ("none"). diff --git a/docs/user/rst/cheatsheet.txt b/docs/user/rst/cheatsheet.txt index 7ae1d55f5..2142d9ce0 100644 --- a/docs/user/rst/cheatsheet.txt +++ b/docs/user/rst/cheatsheet.txt @@ -101,6 +101,7 @@ unicode Unicode character code conversion for substitution defs class Set a "class" attribute on the next element role Create a custom interpreted text role [0.3.2] default-role Set the default interpreted text role [0.3.10] +title Set the metadata document title [0.3.10] ================ ============================================================ Interpreted Text Role Quick Reference diff --git a/docutils/frontend.py b/docutils/frontend.py index 8a85133e7..679a648be 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -282,7 +282,10 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): settings_spec = ( 'General Docutils Options', None, - (('Include a "Generated by Docutils" credit and link at the end ' + (('Specify the document title as metadata (not part of the document ' + 'body). Overrides a document-provided title. There is no default.', + ['--title'], {}), + ('Include a "Generated by Docutils" credit and link at the end ' 'of the document.', ['--generator', '-g'], {'action': 'store_true', 'validator': validate_boolean}), diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 1db0c76e0..d78a3b9c1 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -132,6 +132,7 @@ _directive_registry = { 'class': ('misc', 'class_directive'), 'role': ('misc', 'role'), 'default-role': ('misc', 'default_role'), + 'title': ('misc', 'title'), 'restructuredtext-test-directive': ('misc', 'directive_test_function'),} """Mapping of directive name to (module name, function name). The directive name is canonical & must be lowercase. Language-dependent names are defined diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 7007546df..798512eeb 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -351,6 +351,13 @@ def default_role(name, arguments, options, content, lineno, default_role.arguments = (0, 1, 0) +def title(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + state_machine.document.settings.title = arguments[0] + return [] + +title.arguments = (1, 0, 1) + def directive_test_function(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """This directive is useful only for testing purposes.""" diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index 7304f153b..e8fa9cbb8 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -54,6 +54,7 @@ directives = { 'klas': 'class', 'role (translation required)': 'role', 'default-role (translation required)': 'default-role', + 'title (translation required)': 'title', 'inhoud': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/ca.py b/docutils/parsers/rst/languages/ca.py index 691887325..d534ecfbc 100644 --- a/docutils/parsers/rst/languages/ca.py +++ b/docutils/parsers/rst/languages/ca.py @@ -59,6 +59,7 @@ directives = { u'classe': 'class', u'rol': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'contingut': 'contents', u'numsec': 'sectnum', u'numeraci\u00F3-de-seccions': 'sectnum', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index 24087badf..cf3fbf132 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -55,6 +55,7 @@ directives = { u't\u0159\u00EDda': 'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'obsah': 'contents', u'sectnum (translation required)': 'sectnum', u'section-numbering (translation required)': 'sectnum', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 56cca5c5b..7bf72c149 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -57,6 +57,7 @@ directives = { 'klasse': 'class', 'rolle': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', 'inhalt': 'contents', 'kapitel-nummerierung': 'sectnum', 'abschnitts-nummerierung': 'sectnum', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 46822b891..2c9e78737 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -55,6 +55,7 @@ directives = { 'class': 'class', 'role': 'role', 'default-role': 'default-role', + 'title': 'title', 'contents': 'contents', 'sectnum': 'sectnum', 'section-numbering': 'sectnum', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 99b6d6970..d324e2201 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -61,6 +61,7 @@ directives = { u'klaso': 'class', u'rolo': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'enhavo': 'contents', u'seknum': 'sectnum', u'sekcia-numerado': 'sectnum', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 726d97e88..8d864afb6 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -63,6 +63,7 @@ directives = { u'clase': 'class', u'rol': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index ba159cc70..bf175081e 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -53,6 +53,7 @@ directives = { u'luokka': u'class', u'rooli': u'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'sis\u00e4llys': u'contents', u'kappale': u'sectnum', u'header (translation required)': 'header', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index acb8d35e6..b75cad50b 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -57,6 +57,7 @@ directives = { u'classe': 'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'sommaire': 'contents', u'table-des-mati\u00E8res': 'contents', u'sectnum': 'sectnum', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index f3afd2d35..e28f3ec00 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -54,6 +54,7 @@ directives = { 'classe': 'class', 'ruolo': 'role', u'default-role (translation required)': 'default-role', + 'title (translation required)': 'title', 'indice': 'contents', 'contenuti': 'contents', 'seznum': 'sectnum', diff --git a/docutils/parsers/rst/languages/nl.py b/docutils/parsers/rst/languages/nl.py index 273828062..7ade5d721 100644 --- a/docutils/parsers/rst/languages/nl.py +++ b/docutils/parsers/rst/languages/nl.py @@ -56,6 +56,7 @@ directives = { 'klasse': 'class', 'rol': 'role', u'default-role (translation required)': 'default-role', + 'title (translation required)': 'title', 'inhoud': 'contents', 'sectnum': 'sectnum', 'sectie-nummering': 'sectnum', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index 8a2534923..ba02538fd 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -55,6 +55,7 @@ directives = { 'classe': 'class', 'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'\u00EDndice': 'contents', 'numsec': 'sectnum', u'numera\u00E7\u00E3o-de-se\u00E7\u00F5es': 'sectnum', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 23a842399..61a8f2297 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -46,6 +46,7 @@ directives = { u'\u043a\u043b\u0430\u0441\u0441': u'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'\u043d\u043e\u043c\u0435\u0440-\u0440\u0430\u0437\u0434\u0435\u043b\u0430': u'sectnum', u'\u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f-\u0440\u0430\u0437' diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index e58296280..b47e6228d 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -54,6 +54,7 @@ directives = { u'class (translation required)': 'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'obsah': 'contents', u'\xe8as\x9d': 'sectnum', u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 59d13f699..11697ec55 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -54,6 +54,7 @@ directives = { u'class (translation required)': 'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', u'inneh\u00e5ll': 'contents', u'sektionsnumrering': 'sectnum', u'target-notes (translation required)': 'target-notes', diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 3eaea044a..664aaf6ea 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -55,6 +55,7 @@ directives = { 'class (translation required)': 'class', 'role (translation required)': 'role', u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', 'contents (translation required)': 'contents', 'sectnum (translation required)': 'sectnum', 'section-numbering (translation required)': 'sectnum', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 74d3de874..e2f36721f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -631,8 +631,12 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_document(self, node): # empty or untitled document? if not len(node) or not isinstance(node[0], nodes.title): - # for XHTML conformance, modulo IE6 appeasement: - self.head.append('<title>\n') + if self.settings.title: + self.head.append('%s\n' + % self.encode(self.settings.title)) + else: + # for XHTML conformance, modulo IE6 appeasement: + self.head.append('\n') def depart_document(self, node): self.fragment.extend(self.body) @@ -1348,11 +1352,13 @@ class HTMLTranslator(nodes.NodeVisitor): self.starttag(node, 'caption', '')) check_id = 1 close_tag = '\n' - elif self.section_level == 0: + elif self.section_level == 0: # document title assert node.parent is self.document - # document title - self.head.append('%s\n' - % self.encode(node.astext())) + if self.settings.title: + title = self.settings.title + else: + title = node.astext() + self.head.append('%s\n' % self.encode(title)) self.body.append(self.starttag(node, 'h1', '', CLASS='title')) self.context.append('\n') self.in_document_title = len(self.body) -- cgit v1.2.1 From dbab7e3441e11bf2bed00c53314191aefa808eed Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 9 Jun 2005 17:37:49 +0000 Subject: removed item; done with "title" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3456 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4f4509dfc..5d6186b2a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1774,9 +1774,6 @@ HTML Writer * Add a tool tip ("title" attribute?) to footnote back-links identifying them as such. Text in Docutils language module. -* Add an option to restrict the document title to only, - and not include it in the document body. Subtitle? - * Insert a comment at the top of HTML files that describes how to deal with the broken servers w.r.t. encodings? Perhaps something like this: -- cgit v1.2.1 From d161fd862fb3bbec9472ee5f9e26e63ef5cac692 Mon Sep 17 00:00:00 2001 From: richieadler <richieadler@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 02:29:03 +0000 Subject: translation for "default-role" and "title" directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3457 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/eo.py | 4 ++-- docutils/parsers/rst/languages/es.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index d324e2201..316b98e03 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -60,8 +60,8 @@ directives = { u'unicode': 'unicode', u'klaso': 'class', u'rolo': 'role', - u'default-role (translation required)': 'default-role', - u'title (translation required)': 'title', + u'preterlasita-rolo': 'default-role', + u'titolo': 'title', u'enhavo': 'contents', u'seknum': 'sectnum', u'sekcia-numerado': 'sectnum', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index 8d864afb6..d2f650b14 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -62,8 +62,10 @@ directives = { u'unicode': 'unicode', u'clase': 'class', u'rol': 'role', - u'default-role (translation required)': 'default-role', - u'title (translation required)': 'title', + u'rol-por-omision': 'default-role', + u'rol-por-omisi\u00f3n': 'default-role', + u'titulo': 'title', + u't\u00edtulo': 'title', u'contenido': 'contents', u'numseccion': 'sectnum', u'numsecci\u00f3n': 'sectnum', -- cgit v1.2.1 From 0183754c655e85b1fb02527b358b6f419fbad01e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 21:23:23 +0000 Subject: Updated URL; David Carlisle says this one is newer, and it contains a copyright notice. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3458 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/unicode2rstsubs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/unicode2rstsubs.py b/tools/unicode2rstsubs.py index d5e259863..20f88153d 100755 --- a/tools/unicode2rstsubs.py +++ b/tools/unicode2rstsubs.py @@ -19,7 +19,7 @@ wide-Unicode characters in the set. The input file, unicode.xml, is maintained as part of the MathML 2 Recommentation XML source, and is available at -<http://www.w3.org/Math/characters/unicode.xml> (as of 2003-06-22). +<http://www.w3.org/2003/entities/xml/unicode.xml>. """ import sys -- cgit v1.2.1 From 8854faf14796e27439bf730aef34b0c4e96546da Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 21:37:49 +0000 Subject: git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3460 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 121 ++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index dd82851ee..c046d6d30 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -258,59 +258,59 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def language_label(self, docutil_label): return self.language.labels[docutil_label] - # To do: Use unimap.py from TeXML instead. Have to deal with - # legal cruft before, because it's LPGL. - character_map_string = r""" - \ \textbackslash - { \{ - } \} - $ \$ - & \& - % \% - # \# - [ [ - ] ] - - - - ` ` - ' ' - , , - " " - | \textbar - < \textless - > \textgreater - ^ \textasciicircum - ~ \textasciitilde - _ \Dtextunderscore - """ - #special_map = {'\n': ' ', '\r': ' ', '\t': ' ', '\v': ' ', '\f': ' '} - unicode_map = { - u'\u00A0': '~', - u'\u00B2': '$^2$', - u'\u00B3': '$^3$', - u'\u2009': '{\\,}', - u'\u2013': '{--}', - u'\u2014': '{---}', - u'\u2018': '`', - u'\u2019': '\'', - u'\u201A': ',', - u'\u201C': '``', - u'\u201D': "''", - u'\u201E': ',,', - u'\u2020': '{\\dag}', - u'\u2021': '{\\ddag}', - u'\u2026': '{\\dots}', - u'\u2122': '{\\texttrademark}', - u'\u21d4': '{$\\Leftrightarrow$}', + # Get comprehensive Unicode map. + from unimap import map as unicode_map + # Fix problems with unimap.py. + unicode_map.update({ + # We have AE or T1 encoding, so "``" etc. work. The macros + # from unimap.py may *not* work. + u'\u201C': '{``}', + u'\u201D': "{''}", + u'\u201E': '{,,}', + }) + + character_map = { + '\\': r'{\textbackslash}', + '{': r'{\{}', + '}': r'{\}}', + '$': r'{\$}', + '&': r'{\&}', + '%': r'{\%}', + '#': r'{\#}', + '[': r'{[}', + ']': r'{]}', + '-': r'{-}', + '`': r'{`}', + "'": r"{'}", + ',': r'{,}', + '"': r'{"}', + '|': r'{\textbar}', + '<': r'{\textless}', + '>': r'{\textgreater}', + '^': r'{\textasciicircum}', + '~': r'{\textasciitilde}', + '_': r'{\Dtextunderscore}', } - - character_map = {} - for pair in character_map_string.strip().split('\n'): - char, replacement = pair.split() - character_map[char] = replacement character_map.update(unicode_map) #character_map.update(special_map) + + # `att_map` is for encoding attributes. According to + # <http://www-h.eng.cam.ac.uk/help/tpl/textprocessing/teTeX/latex/latex2e-html/ltx-164.html>, + # the following characters are special: # $ % & ~ _ ^ \ { } + # These work without special treatment in macro parameters: + # $, &, ~, _, ^ + att_map = {'#': '\\#', + '%': '\\%', + # We cannot do anything about backslashes. + '\\': '', + '{': '\\{', + '}': '\\}', + # The quotation mark may be redefined by babel. + '"': '"{}', + } + att_map.update(unicode_map) def encode(self, text, attval=0): """ @@ -319,23 +319,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): If attval is true, preserve as much as possible verbatim (used in attribute value encoding). """ - if not attval: - get = self.character_map.get + if attval: + get = self.att_map.get else: - # According to - # <http://www-h.eng.cam.ac.uk/help/tpl/textprocessing/teTeX/latex/latex2e-html/ltx-164.html>, - # the following characters are special: # $ % & ~ _ ^ \ { } - # These work without special treatment in macro parameters: - # $, &, ~, _, ^ - get = {'#': '\\#', - '%': '\\%', - # We cannot do anything about backslashes. - '\\': '', - '{': '\\{', - '}': '\\}', - # The quotation mark may be redefined by babel. - '"': '"{}', - }.get + get = self.character_map.get text = ''.join([get(c, c) for c in text]) if (self.literal_block or self.inline_literal) and not attval: # NB: We can have inline literals within literal blocks. @@ -366,11 +353,11 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): text = re.sub(r'\s+', '{ }', text) # Replace double quotes with macro calls. L = [] - for part in text.split('"'): + for part in text.split(self.character_map['"']): if L: # Insert quote. - L.append(self.left_quote and r'\Dtextleftdblquote' or - r'\Dtextrightdblquote') + L.append(self.left_quote and r'{\Dtextleftdblquote}' + or r'{\Dtextrightdblquote}') self.left_quote = not self.left_quote L.append(part) return ''.join(L) -- cgit v1.2.1 From 07b04a382707611535d284d11e211af605e85c90 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 21:41:00 +0000 Subject: added mapping of unicode characters to LaTeX equivalents; David, is the license at the top OK? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3461 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/unicode_latex.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docutils/writers/unicode_latex.py diff --git a/docutils/writers/unicode_latex.py b/docutils/writers/unicode_latex.py new file mode 100644 index 000000000..35f671ced --- /dev/null +++ b/docutils/writers/unicode_latex.py @@ -0,0 +1,25 @@ +# Revision: $Revision$ +# Date: $Date$ +# +# This is a mapping of Unicode characters to LaTeX +# equivalents. The information has been extracted from +# <http://www.w3.org/2003/entities/xml/unicode.xml>. +# The extraction has been done by the "create_unimap.py" +# script written by Felix Wiemann. +# +# This file may be used and distributed under the terms +# set forth in the original copyright notice of +# unicode.xml. +# +# Original copyright notice of unicode.xml follows: +# +# +# $Id$ +# +# Copyright David Carlisle, Sebastian Rahtz 1998-2003 +# +# Use and distribution of this file are permitted under the terms of the <a +# href="http://www.w3.org/Consortium/Legal/copyright-software-19980720" +# >W3C Software Notice and License</a>. + +unicode_map = {u'\u0302': '{\\^}', u'\u2785': '{\\ding{197}}', u'\u2a87': '$\\lneq$', u'\U0001d68f': '$\\mathtt{f}$', u'\U0001d50e': '$\\mathfrak{K}$', u'\u2297': '$\\otimes$', u'\u0116': '{\\.{E}}', u'\u0418': '{\\cyrchar\\CYRI}', u'\u271a': '{\\ding{58}}', u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', u'\U0001d624': '$\\mathsfsl{c}$', u'\xab': '{\\guillemotleft}', u'\u03ad': '$\\acute{\\epsilon}$', u'\u222c': '$\\int\\!\\int$', u'\U0001d5b9': '$\\mathsf{Z}$', u'\U0001d438': '$\\mathsl{E}$', u'\U0001d73a': '$\\mathbit{\\Epsilon}$', u'\u21c1': '$\\rightharpoondown$', u'\u04c3': '{\\cyrchar\\CYRKHK}', u'\u2644': '{\\saturn}', u'\u2788': '{\\ding{200}}', u'\U0001d6cf': '$\\mathbf{\\Xi}$', u'\U0001d54e': '$\\mathbb{W}$', u'\u22d7': '$\\gtrdot$', u'\u2156': '$\\textfrac{2}{5}$', u'\u0458': '{\\cyrchar\\cyrje}', u'\u275a': '{\\ding{122}}', u'\U0001d4e3': '$\\mathmit{T}$', u'\U0001d7e5': '$\\mathsf{3}$', u'\U0001d664': '$\\mathsfbfsl{o}$', u'\xeb': '{\\"{e}}', u'\u026c': '$\\Elzbtdl$', u'\U0001d5f9': '$\\mathsfbf{l}$', u'\U0001d478': '$\\mathbit{Q}$', u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', u'\u0101': '{\\={a}}', u'\u0403': "{\\cyrchar{\\'\\CYRG}}", u'\u2a07': '$\\ElzInf$', u'\u2986': '$\\Elroang$', u'\u300b': '$\\ElsevierGlyph{300B}$', u'\u2116': '{\\cyrchar\\textnumero}', u'\U0001d60f': '$\\mathsfsl{H}$', u'\U0001d58e': '$\\mathslbb{i}$', u'\u2217': '${_\\ast}$', u'\u2196': '$\\nwarrow$', u'\u2519': '$\\Elzsqfnw$', u'\u0498': '{\\cyrchar\\CYRZDSC}', u'\u279a': '{\\ding{218}}', u'\U0001d423': '$\\mathbf{j}$', u'\U0001d725': '$\\mathbit{\\Kappa}$', u'\u22ac': '$\\nvdash$', u'\U0001d539': '$\\mathbb{B}$', u'\U0001d4b8': '$\\mathscr{c}$', u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', u'\u0141': '{\\L}', u'\xc0': '{\\`{A}}', u'\u0443': '{\\cyrchar\\cyru}', u'\u03c2': '$\\varsigma$', u'\u2745': '{\\ding{101}}', u'\U0001d64f': '$\\mathsfbfsl{T}$', u'\U0001d5ce': '$\\mathsf{u}$', u'\u0322': '{\\Elzrh}', u'\u2257': '$\\circeq$', u'\u04d8': '{\\cyrchar\\CYRSCHWA}', u'\u2254': '{:=}', u'\U0001d463': '$\\mathsl{v}$', u'\u027a': '$\\Elztrnrl$', u'\U0001d765': '$\\mathsfbf{\\Pi}$', u'\U0001d6e4': '$\\mathsl{\\Gamma}$', u'\u02d0': '$\\Elzlmrk$', u'\u22ec': '$\\ntrianglelefteq$', u'\u266f': '$\\sharp$', u'\U0001d579': '$\\mathslbb{N}$', u'\U0001d4f8': '$\\mathmit{o}$', u'\U0001d7fa': '$\\mathtt{4}$', u'\u0100': '{\\={A}}', u'\u2202': '$\\partial$', u'\u2704': '{\\ding{36}}', u'\U0001d78f': '{\\mathsfbf{\\varpi}}', u'\U0001d40e': '$\\mathbf{O}$', u'\u0397': '$\\Eta$', u'\u2016': '$\\Vert$', u'\u0499': '{\\cyrchar\\cyrzdsc}', u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', u'\u025b': '$\\varepsilon$', u'\U0001d5a3': '$\\mathsf{D}$', u'\U0001d724': '$\\mathbit{\\Iota}$', u'\u015d': '{\\^{s}}', u'\u21ab': '$\\looparrowleft$', u'\u22ad': '$\\nvDash$', u'\u27af': '{\\ding{239}}', u'\u042e': '{\\cyrchar\\CYRYU}', u'\U0001d4b9': '$\\mathscr{d}$', u'\U0001d538': '$\\mathbb{A}$', u'\U0001d63a': '$\\mathsfsl{y}$', u'\xc1': "{\\'{A}}", u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', u'\u25c3': '$\\triangleleft$', u'\u2242': '$\\ElsevierGlyph{2242}$', u'\u2744': '{\\ding{100}}', u'\u0136': '{\\c{K}}', u'\U0001d7cf': '$\\mathbf{1}$', u'\U0001d44e': '$\\mathsl{a}$', u'\u030f': '{\\cyrchar\\C}', u'\u04d9': '{\\cyrchar\\cyrschwa}', u'\U0001d5e3': '$\\mathsfbf{P}$', u'\U0001d6e5': '$\\mathsl{\\Delta}$', u'\U0001d764': '$O$', u'\u22ed': '$\\ntrianglerighteq$', u'\u046e': '{\\cyrchar\\CYRKSI}', u'\u2970': '$\\RoundImplies$', u'\U0001d4f9': '$\\mathmit{p}$', u'\U0001d578': '$\\mathslbb{M}$', u'\U0001d67a': '$\\mathtt{K}$', u'\u2282': '$\\subset$', u'\u2605': '{\\ding{72}}', u'\u2784': '{\\ding{196}}', u'\U0001d70f': '$\\mathsl{\\Tau}$', u'\U0001d48e': '$\\mathbit{m}$', u'\u0419': '{\\cyrchar\\CYRISHRT}', u'\U0001d523': '$\\mathfrak{f}$', u'\U0001d625': '$\\mathsfsl{d}$', u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', u'\u012b': '{\\={\\i}}', u'\u222d': '$\\int\\!\\int\\!\\int$', u'\u03ac': "{\\'{$\\alpha$}}", u'\u272f': '{\\ding{79}}', u'\u04ae': '{\\cyrchar\\CYRY}', u'\U0001d439': '$\\mathsl{F}$', u'\U0001d5b8': '$\\mathsf{Y}$', u'\U0001d6ba': '$\\mathbf{\\Sigma}$', u'\u21c0': '$\\rightharpoonup$', u'\u22c2': '$\\bigcap$', u'\u2645': '{\\uranus}', u'\U0001d74f': '$\\partial$', u'\U0001d4ce': '$\\mathscr{y}$', u'\xd6': '{\\"{O}}', u'\u0459': '{\\cyrchar\\cyrlje}', u'\u25d8': '$\\Elzrvbull$', u'\u295b': '$\\RightTeeVector$', u'\u227b': '$\\succ$', u'\U0001d563': '$\\mathbb{r}$', u'\U0001d665': '$\\mathsfbfsl{p}$', u'\U0001d7e4': '$\\mathsf{2}$', u'\u016b': '{\\={u}}', u'\u026d': '$\\Elzrtll$', u'\U0001d479': '$\\mathbit{R}$', u'\U0001d5f8': '$\\mathsfbf{k}$', u'\U0001d6fa': '$\\mathsl{\\Omega}$', u'\u2200': '$\\forall$', u'\u2102': '$\\mathbb{C}$', u'\u0404': '{\\cyrchar\\CYRIE}', u'\u0156': '{\\c{R}}', u'\U0001d48f': '$\\mathbit{n}$', u'\U0001d70e': '$\\mathsl{\\Sigma}$', u'\u2316': '$\\mathchar"2208$', u'\u2799': '{\\ding{217}}', u'\U0001d6a3': '$\\mathtt{z}$', u'\U0001d5a5': '$\\mathsf{F}$', u'\U0001d424': '$\\mathbf{k}$', u'\u22ab': '$\\VDash$', u'\u21ad': '$\\leftrightsquigarrow$', u'\u04af': '{\\cyrchar\\cyry}', u'\u272e': '{\\ding{78}}', u'\u02e9': '{\\tone{11}}', u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', u'\U0001d638': '$\\mathsfsl{w}$', u'\u03c1': '$\\rho$', u'\u2240': '$\\wr$', u'\u0142': '{\\l}', u'\u0444': '{\\cyrchar\\cyrf}', u'\U0001d4cf': '$\\mathscr{z}$', u'\U0001d74e': '$\\mathbit{\\Omega}$', u'\xd7': '{\\texttimes}', u'\U0001d6e3': '$\\mathsl{\\Beta}$', u'\U0001d5e5': '$\\mathsfbf{R}$', u'\U0001d464': '$\\mathsl{w}$', u'\u22eb': '$\\ntriangleright$', u'\U0001d7f9': '$\\mathtt{3}$', u'\U0001d678': '$\\mathtt{I}$', u'\U0001d57a': '$\\mathslbb{O}$', u'\u02c8': '$\\Elzverts$', u'\u0301': "{\\'}", u'\u2280': '$\\not\\prec$', u'\U0001d40f': '$\\mathbf{P}$', u'\u226c': '$\\between$', u'\u0396': '$\\Zeta$', u'\u2719': '{\\ding{57}}', u'\u03c4': '$\\tau$', u'\U0001d623': '$\\mathsfsl{b}$', u'\U0001d525': '$\\mathfrak{h}$', u'\u222b': '$\\int$', u'\u212d': '$\\mathfrak{C}$', u'\xac': '$\\lnot$', u'\u042f': '{\\cyrchar\\CYRYA}', u'\u27ae': '{\\ding{238}}', u'\u2ab0': '$\\succeq$', u'\U0001d739': '$\\mathbit{\\Delta}$', u'\U0001d6b8': '$\\mathbf{\\Rho}$', u'\U0001d5ba': '$\\mathsf{a}$', u'\u22c0': '$\\ElsevierGlyph{22C0}$', u'\u2643': '{\\jupiter}', u'\u21c2': '$\\downharpoonright$', u'\u04c4': '{\\cyrchar\\cyrkhk}', u'\U0001d44f': '$\\mathsl{b}$', u'\U0001d7ce': '$\\mathbf{0}$', u'\u2057': "$''''$", u'\u03d6': '$\\varpi$', u'\u2759': '{\\ding{121}}', u'\u295d': '$\\RightDownTeeVector$', u'\U0001d663': '$\\mathsfbfsl{n}$', u'\U0001d565': '$\\mathbb{t}$', u'\U0001d4e4': '$\\mathmit{U}$', u'\u226b': '$\\gg$', u'\u016d': '{\\u{u}}', u'\xec': '{\\`{\\i}}', u'\u046f': '{\\cyrchar\\cyrksi}', u'\U0001d779': '$\\mathsfbf{\\Kappa}$', u'\U0001d6f8': '$\\mathsl{\\Chi}$', u'\U0001d5fa': '$\\mathsfbf{m}$', u'\u2281': '$\\not\\succ$', u'\u0300': '{\\`}', u'\u2783': '{\\ding{195}}', u'\u2002': '{\\hspace{0.6em}}', u'\u2a06': '$\\Elxsqcup$', u'\U0001d58f': '$\\mathslbb{j}$', u'\U0001d60e': '$\\mathsfsl{G}$', u'\u2197': '$\\nearrow$', u'\u2216': '$\\setminus$', u'\u2718': '{\\ding{56}}', u'\u041a': '{\\cyrchar\\CYRK}', u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', u'\u02da': '{\\r{}}', u'\U0001d4a5': '$\\mathscr{J}$', u'\U0001d524': '$\\mathfrak{g}$', u'\u03ab': '$\\mathrm{\\ddot{Y}}$', u'\xad': '$\\-$', u'\u212c': '$\\mathscr{B}$', u'\u25af': '$\\Elzvrecto$', u'\U0001d6b9': '{\\mathbf{\\vartheta}}', u'\U0001d738': '$\\mathbit{\\Gamma}$', u'\U0001d43a': '$\\mathsl{G}$', u'\u22c1': '$\\ElsevierGlyph{22C1}$', u'\u0461': '{\\cyrchar\\cyromega}', u'\U0001d5cf': '$\\mathsf{v}$', u'\U0001d64e': '$\\mathsfbfsl{S}$', u'\u2256': '$\\eqcirc$', u'\u2265': '$\\geq$', u'\u045a': '{\\cyrchar\\cyrnje}', u'\u295c': '$\\RightUpTeeVector$', u'\U0001d7e3': '$\\mathsf{1}$', u'\U0001d4e5': '$\\mathmit{V}$', u'\U0001d564': '$\\mathbb{s}$', u'\xed': "{\\'{\\i}}", u'\u016c': '{\\u{U}}', u'\u25ef': '$\\bigcirc$', u'\u266e': '$\\natural$', u'\U0001d6f9': '$\\mathsl{\\Psi}$', u'\U0001d778': '$\\mathsfbf{\\Iota}$', u'\U0001d47a': '$\\mathbit{S}$', u'\u2201': '$\\complement$', u'\u2703': '{\\ding{35}}', u'\u0405': '{\\cyrchar\\CYRDZE}', u'\u2a86': '$\\gtrapprox$', u'\U0001d50f': '$\\mathfrak{L}$', u'\U0001d68e': '$\\mathtt{e}$', u'\u0117': '{\\.{e}}', u'\u0296': '$\\Elzinglst$', u'\u2798': '{\\ding{216}}', u'\u049a': '{\\cyrchar\\CYRKDSC}', u'\u299c': '$\\Angle$', u'\U0001d723': '$\\mathbit{\\Theta}$', u'\U0001d425': '$\\mathbf{l}$', u'\U0001d5a4': '$\\mathsf{E}$', u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', u'\u21ac': '$\\looparrowright$', u'\U0001d639': '$\\mathsfsl{x}$', u'\U0001d7b8': '$O$', u'\u2241': '$\\not\\sim$', u'\u03c0': '$\\pi$', u'\u2743': '{\\ding{99}}', u'\xc2': '{\\^{A}}', u'\u0445': '{\\cyrchar\\cyrh}', u'\u2947': '$\\Elzrarrx$', u'\u2ac6': '$\\supseteqq$', u'\u2423': '{\\textvisiblespace}', u'\U0001d54f': '$\\mathbb{X}$', u'\U0001d6ce': '$N$', u'\u2157': '$\\textfrac{3}{5}$', u'\u22d6': '$\\lessdot$', u'\u29dc': '$\\ElsevierGlyph{E372}$', u'\u22d1': '$\\Supset$', u'\U0001d763': '$\\mathsfbf{\\Xi}$', u'\U0001d465': '$\\mathsl{x}$', u'\U0001d5e4': '$\\mathsfbf{Q}$', u'\U0001d679': '$\\mathtt{J}$', u'\U0001d7f8': '$\\mathtt{2}$', u'\U0001d4fa': '$\\mathmit{q}$', u'\u2702': '{\\ding{34}}', u'\u2204': '$\\nexists$', u'\U0001d48b': '$\\mathbit{j}$', u'\U0001d78d': '{\\mathsfbf{\\phi}}', u'\U0001d60c': '$\\mathsfsl{E}$', u'\u2199': '$\\swarrow$', u'\u2018': '{`}', u'\U0001d5a1': '$\\mathsf{B}$', u'\U0001d420': '$\\mathbf{g}$', u'\U0001d722': '$\\mathbit{\\Eta}$', u'\u04ab': '{\\cyrchar\\cyrsdsc}', u'\u27ad': '{\\ding{237}}', u'\u22af': '$\\nVDash$', u'\u015c': '{\\^{S}}', u'\u2a34': '$\\ElsevierGlyph{E25E}$', u'\U0001d6b7': '$\\mathbf{\\Pi}$', u'\U0001d536': '$\\mathfrak{y}$', u'\u0440': '{\\cyrchar\\cyrr}', u'\xc3': '{\\~{A}}', u'\u2742': '{\\ding{98}}', u'\u03c5': '$\\upsilon$', u'\u2244': '$\\not\\simeq$', u'\U0001d4cb': '$\\mathscr{v}$', u'\U0001d64c': '$\\mathsfbfsl{Q}$', u'\u0462': '{\\cyrchar\\CYRYAT}', u'\u295e': '$\\DownLeftTeeVector$', u'\U0001d5e1': '$\\mathsfbf{N}$', u'\U0001d460': '$\\mathsl{s}$', u'\U0001d762': '$N$', u'\u22ef': '$\\cdots$', u'\u016e': '{\\r{U}}', u'\U0001d6f7': '$\\mathsl{\\Phi}$', u'\U0001d576': '$\\mathslbb{K}$', u'\u0480': '{\\cyrchar\\CYRKOPPA}', u'\u2003': '{\\hspace{1em}}', u'\u2782': '{\\ding{194}}', u'\u2305': '{\\barwedge}', u'\u2284': '$\\not\\subset$', u'\U0001d40b': '$\\mathbf{L}$', u'\U0001d70d': '$\\mathsl{\\varsigma}$', u'\U0001d68c': '$\\mathtt{c}$', u'\u2119': '$\\mathbb{P}$', u'\u039a': '$\\Kappa$', u'\U0001d521': '$\\mathfrak{d}$', u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', u'\u042b': '{\\cyrchar\\CYRERY}', u'\u272d': '{\\ding{77}}', u'\u222f': '$\\surfintegral$', u'\u21ae': '$\\nleftrightarrow$', u'\U0001d637': '$\\mathsfsl{v}$', u'\U0001d5b6': '$\\mathsf{W}$', u'\u04c0': '{\\cyrchar\\CYRpalochka}', u'\u22c4': '$\\diamond$', u'\U0001d44b': '$\\mathsl{X}$', u'\U0001d74d': '$\\mathbit{\\Psi}$', u'\U0001d6cc': '$\\mathbf{\\Lambda}$', u'\u22cc': '$\\rightthreetimes$', u'\u2159': '$\\textfrac{1}{6}$', u'\xd8': '{\\O}', u'\u03da': '$\\Stigma$', u'\u2a5f': '$\\Elzminhat$', u'\U0001d561': '$\\mathbb{p}$', u'\U0001d4e0': '$\\mathmit{Q}$', u'\U0001d7e2': '$\\mathsf{0}$', u'\u226f': '$\\not>$', u'\U0001d677': '$\\mathtt{H}$', u'\U0001d5f6': '$\\mathsfbf{i}$', u'\u0481': '{\\cyrchar\\cyrkoppa}', u'\u2285': '$\\not\\supset$', u'\u0304': '{\\=}', u'\U0001d58b': '$\\mathslbb{f}$', u'\U0001d68d': '$\\mathtt{d}$', u'\U0001d70c': '$\\mathsl{\\Rho}$', u'\u0416': '{\\cyrchar\\CYRZH}', u'\u2118': '$\\wp$', u'\u221a': '$\\surd$', u'\U0001d520': '$\\mathfrak{c}$', u'\U0001d622': '$\\mathsfsl{a}$', u'\u272c': '{\\ding{76}}', u'\u03af': '$\\acute{\\iota}$', u'\u2ab5': '$\\precneqq$', u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', u'\U0001d436': '$\\mathsl{C}$', u'\u21c3': '$\\downharpoonleft$', u'\u2642': '{\\male}', u'\u22c5': '$\\cdot$', u'\U0001d5cb': '$\\mathsf{r}$', u'\U0001d6cd': '$M$', u'\U0001d74c': '$\\mathbit{\\Chi}$', u'\u0456': '{\\cyrchar\\cyrii}', u'\xd9': '{\\`{U}}', u'\u2158': '$\\textfrac{4}{5}$', u'\u225a': '$\\ElsevierGlyph{225A}$', u'\U0001d4e1': '$\\mathmit{R}$', u'\U0001d560': '$\\mathbb{o}$', u'\U0001d662': '$\\mathsfbfsl{m}$', u'\U0001d7f7': '$\\mathtt{1}$', u'\U0001d476': '$\\mathbit{O}$', u'\u0401': '{\\cyrchar\\CYRYO}', u'\u0103': '{\\u{a}}', u'\u2205': '$\\varnothing$', u'\u2a8a': '$\\gnapprox$', u'\U0001d60d': '$\\mathsfsl{F}$', u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', u'\u2717': '{\\ding{55}}', u'\u0496': '{\\cyrchar\\CYRZHDSC}', u'\u2019': "{'}", u'\u2198': '$\\searrow$', u'\u229a': '$\\circledcirc$', u'\U0001d421': '$\\mathbf{h}$', u'\U0001d5a0': '$\\mathsf{A}$', u'\U0001d6a2': '$\\mathtt{y}$', u'\u27ac': '{\\ding{236}}', u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', u'\xae': '{\\textregistered}', u'\u2933': '$\\ElsevierGlyph{E21C}$', u'\u2a35': '$\\ElsevierGlyph{E25E}$', u'\U0001d737': '$\\mathbit{\\Beta}$', u'\U0001d4b6': '$\\mathscr{a}$', u'\u0441': '{\\cyrchar\\cyrs}', u'\u0143': "{\\'{N}}", u'\u2245': '$\\cong$', u'\u2277': '$\\gtrless$', u'\U0001d54b': '$\\mathbb{T}$', u'\U0001d64d': '$\\mathsfbfsl{R}$', u'\u22da': '$\\lesseqgtr$', u'\U0001d461': '$\\mathsl{t}$', u'\U0001d5e0': '$\\mathsfbf{M}$', u'\U0001d6e2': '$\\mathsl{\\Alpha}$', u'\u2127': '$\\mho$', u'\u266d': '$\\flat$', u'\xee': '{\\^{\\i}}', u'\u2a75': '$\\Equal$', u'\U0001d777': '$\\mathsfbf{\\Theta}$', u'\U0001d4f6': '$\\mathmit{m}$', u'\u2781': '{\\ding{193}}', u'\u2283': '$\\supset$', u'\u2004': '{\\hspace{0.33em}}', u'\u2a08': '$\\ElzSup$', u'\U0001d68b': '$\\mathtt{b}$', u'\U0001d58d': '$\\mathslbb{h}$', u'\U0001d40c': '$\\mathbf{M}$', u'\u01f5': "{\\'{g}}", u'\u0497': '{\\cyrchar\\cyrzhdsc}', u'\u2716': '{\\ding{54}}', u'\u0399': '$\\Iota$', u'\u2218': '$\\circ$', u'\u211a': '$\\mathbb{Q}$', u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', u'\U0001d620': '$\\mathsfsl{Y}$', u'\U0001d522': '$\\mathfrak{e}$', u'\u23b0': '$\\lmoustache$', u'\u25ad': '$\\fbox{~~}$', u'\u042c': '{\\cyrchar\\CYRSFTSN}', u'\xaf': '{\\textasciimacron}', u'\u29b5': '$\\ElsevierGlyph{E260}$', u'\U0001d4b7': '$\\mathscr{b}$', u'\U0001d736': '$\\mathbit{\\Alpha}$', u'\u2640': '{\\venus}', u'\u22c3': '$\\bigcup$', u'\u21c5': '$\\dblarrowupdown$', u'\U0001d6cb': '$\\mathbf{\\Kappa}$', u'\U0001d5cd': '$\\mathsf{t}$', u'\U0001d44c': '$\\mathsl{Y}$', u'\u2756': '{\\ding{118}}', u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', u'\u215a': '$\\textfrac{5}{6}$', u'\U0001d7e1': '$\\mathbb{9}$', u'\U0001d660': '$\\mathsfbfsl{k}$', u'\U0001d562': '$\\mathbb{q}$', u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', u'\xef': '{\\"{\\i}}', u'\U0001d4f7': '$\\mathmit{n}$', u'\U0001d776': '$\\mathsfbf{\\Eta}$', u'\u2701': '{\\ding{33}}', u'\u2203': '$\\exists$', u'\u0105': '{\\k{a}}', u'\u2a88': '$\\gneq$', u'\U0001d60b': '$\\mathsfsl{D}$', u'\U0001d50d': '$\\mathfrak{J}$', u'\U0001d48c': '$\\mathbit{k}$', u'\u0417': '{\\cyrchar\\CYRZ}', u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', u'\u2298': '$\\oslash$', u'\u219a': '$\\nleftarrow$', u'\U0001d721': '$\\mathbit{\\Zeta}$', u'\U0001d6a0': '$\\mathtt{w}$', u'\U0001d5a2': '$\\mathsf{C}$', u'\u04ac': '{\\cyrchar\\CYRTDSC}', u'\u03ae': '$\\acute{\\eta}$', u'\U0001d437': '$\\mathsl{D}$', u'\U0001d7b6': '$N$', u'\u2741': '{\\ding{97}}', u'\u2243': '$\\simeq$', u'\u25c2': '$\\blacktriangleleft$', u'\u0145': '{\\c{N}}', u'\xc4': '{\\"{A}}', u'\U0001d64b': '$\\mathsfbfsl{P}$', u'\u29ca': '$\\ElzLap$', u'\U0001d54d': '$\\mathbb{V}$', u'\U0001d4cc': '$\\mathscr{w}$', u'\u0457': '{\\cyrchar\\cyryi}', u'\u0278': '{\\textphi}', u'\u22d8': '$\\verymuchless$', u'\u21da': '$\\Lleftarrow$', u'\U0001d761': '$M$', u'\U0001d6e0': '{\\mathbf{\\varrho}}', u'\U0001d5e2': '$\\mathsfbf{O}$', u'\U0001d477': '$\\mathbit{P}$', u'\U0001d7f6': '$\\mathtt{0}$', u'\u0402': '{\\cyrchar\\CYRDJE}', u'\u0104': '{\\k{A}}', u'\u2a89': '$\\lnapprox$', u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', u'\U0001d48d': '$\\mathbit{l}$', u'\u2299': '$\\odot$', u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', u'\u201a': '{,}', u'\U0001d6a1': '$\\mathtt{x}$', u'\U0001d720': '$\\mathbit{\\Epsilon}$', u'\U0001d422': '$\\mathbf{i}$', u'\u0306': '{\\u}', u'\u27ab': '{\\ding{235}}', u'\u04ad': '{\\cyrchar\\cyrtdsc}', u'\u222e': '$\\oint$', u'\U0001d5b7': '$\\mathsf{X}$', u'\U0001d636': '$\\mathsfsl{u}$', u'\U0001d6de': '{\\mathbf{\\varkappa}}', u'\u2740': '{\\ding{96}}', u'\u03c3': '$\\sigma$', u'\u0442': '{\\cyrchar\\cyrt}', u'\xc5': '{\\AA}', u'\u0144': "{\\'{n}}", u'\U0001d4cd': '$\\mathscr{x}$', u'\U0001d54c': '$\\mathbb{U}$', u'\u25d7': '{\\ding{119}}', u'\u22d9': '$\\verymuchgreater$', u'\u2a5e': '$\\perspcorrespond$', u'\U0001d6e1': '{\\mathbf{\\varpi}}', u'\U0001d760': '$\\mathsfbf{\\Lambda}$', u'\U0001d462': '$\\mathsl{u}$', u'\u2122': '{\\texttrademark}', u'\u02e6': '{\\tone{44}}', u'\u226e': '$\\not<$', u'\U0001d5f7': '$\\mathsfbf{j}$', u'\U0001d676': '$\\mathtt{G}$', u'\u2780': '{\\ding{192}}', u'\u0303': '{\\~}', u'\u0482': '{\\cyrchar\\cyrthousands}', u'\u2005': '{\\hspace{0.25em}}', u'\U0001d70b': '$\\mathsl{\\Pi}$', u'\U0001d40d': '$\\mathbf{N}$', u'\U0001d58c': '$\\mathslbb{g}$', u'\u2219': '$\\bullet$', u'\u0398': '$\\Theta$', u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', u'\U0001d621': '$\\mathsfsl{Z}$', u'\u2271': '$\\not\\geq$', u'\U0001d4a2': '$\\mathscr{G}$', u'\u272b': '{\\ding{75}}', u'\u042d': '{\\cyrchar\\CYREREV}', u'\u212f': '$\\mathscr{e}$', u'\u22ae': '$\\nVdash$', u'\U0001d537': '$\\mathfrak{z}$', u'\U0001d6b6': '$O$', u'\u21c4': '$\\rightleftarrows$', u'\U0001d74b': '$\\mathbit{\\Phi}$', u'\U0001d44d': '$\\mathsl{Z}$', u'\U0001d5cc': '$\\mathsf{s}$', u'\u0259': '$\\Elzschwa$', u'\xda': "{\\'{U}}", u'\u295f': '$\\DownRightTeeVector$', u'\U0001d661': '$\\mathsfbfsl{l}$', u'\U0001d7e0': '$\\mathbb{8}$', u'\U0001d4e2': '$\\mathmit{S}$', u'\u046d': '{\\cyrchar\\cyriotbyus}', u'\u016f': '{\\r{u}}', u'\u22ee': '$\\vdots$', u'\u29f4': '$\\RuleDelayed$', u'\U0001d577': '$\\mathslbb{L}$', u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', u'\u0287': '$\\Elztrnt$', u'\u0106': "{\\'{C}}", u'\u0408': '{\\cyrchar\\CYRJE}', u'\U0001d493': '$\\mathbit{r}$', u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', u'\U0001d614': '$\\mathsfsl{M}$', u'\u039d': '$N$', u'\U0001d5a9': '$\\mathsf{J}$', u'\U0001d428': '$\\mathbf{o}$', u'\U0001d72a': '$O$', u'\u21b1': '$\\Rsh$', u'\u2030': '{\\textperthousand}', u'\u04b3': '{\\cyrchar\\cyrhdsc}', u'\u27b5': '{\\ding{245}}', u'\U0001d6bf': '$\\mathbf{\\Psi}$', u'\U0001d53e': '$\\mathbb{G}$', u'\u030a': '{\\r}', u'\u22c7': '$\\divideontimes$', u'\u0146': '{\\c{n}}', u'\u0448': '{\\cyrchar\\cyrsh}', u'\u274a': '{\\ding{106}}', u'\U0001d4d3': '$\\mathmit{D}$', u'\U0001d7d5': '$\\mathbf{7}$', u'\U0001d654': '$\\mathsfbfsl{Y}$', u'\u2956': '$\\DownLeftVectorBar$', u'\u20db': '$\\dddot$', u'\u03dd': '$\\digamma$', u'\u225c': '$\\triangleq$', u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', u'\U0001d5e9': '$\\mathsfbf{V}$', u'\U0001d468': '$\\mathbit{A}$', u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', u'\u27f5': '$\\longleftarrow$', u'\U0001d6ff': '$\\mathsl{\\Delta}$', u'\U0001d57e': '$\\mathslbb{S}$', u'\u2207': '$\\nabla$', u'\u0488': '{\\cyrchar\\cyrhundredthousands}', u'\u278a': '{\\ding{202}}', u'\U0001d413': '$\\mathbf{T}$', u'\U0001d715': '$\\partial$', u'\U0001d694': '$\\mathtt{k}$', u'\u201b': '$\\Elzreapos$', u'\u231d': '$\\urcorner$', u'\u0158': '{\\v{R}}', u'\U0001d529': '$\\mathfrak{l}$', u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', u'\u2131': '$\\mathscr{F}$', u'\xb0': '{\\textdegree}', u'\u0433': '{\\cyrchar\\cyrg}', u'\u03b2': '$\\beta$', u'\u2735': '{\\ding{85}}', u'\u011e': '{\\u{G}}', u'\U0001d63f': '$\\mathsfbfsl{D}$', u'\U0001d5be': '$\\mathsf{e}$', u'\u2941': '$\\Elorarr$', u'\u2247': '$\\not\\cong$', u'\u21c6': '$\\leftrightarrows$', u'\u24c8': '$\\circledS$', u'\U0001d453': '$\\mathsl{f}$', u'\U0001d755': '{\\mathbit{\\varpi}}', u'\U0001d6d4': '$\\mathbf{\\Sigma}$', u'\u02dc': '{\\texttildelow}', u'\U0001d569': '$\\mathbb{x}$', u'\U0001d4e8': '$\\mathmit{Y}$', u'\U0001d7ea': '$\\mathsf{8}$', u'\u0171': '{\\H{u}}', u'\xf0': '{\\dh}', u'\U0001d67f': '$\\mathtt{P}$', u'\U0001d5fe': '$\\mathsfbf{q}$', u'\u232a': '$\\rangle$', u'\u2006': '{\\hspace{0.166em}}', u'\u0489': '{\\cyrchar\\cyrmillions}', u'\U0001d593': '$\\mathslbb{n}$', u'\u0282': '$\\Elzrtls$', u'\U0001d695': '$\\mathtt{l}$', u'\U0001d714': '$\\mathsl{\\Omega}$', u'\u02d8': '{\\textasciibreve}', u'\u219b': '$\\nrightarrow$', u'\u229d': '$\\circleddash$', u'\u231c': '$\\ulcorner$', u'\u279f': '{\\ding{223}}', u'\u041e': '{\\cyrchar\\CYRO}', u'\U0001d4a9': '$\\mathscr{N}$', u'\U0001d528': '$\\mathfrak{k}$', u'\U0001d62a': '$\\mathsfsl{i}$', u'\xb1': '$\\pm$', u'\u2130': '$\\mathscr{E}$', u'\u25b3': '$\\bigtriangleup$', u'\u2232': '$\\ElsevierGlyph{2232}$', u'\u2734': '{\\ding{84}}', u'\u010b': '{\\.{c}}', u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', u'\U0001d43e': '$\\mathsl{K}$', u'\u2940': '$\\Elolarr$', u'\u03c7': '$\\chi$', u'\u264a': '{\\gemini}', u'\U0001d5d3': '$\\mathsf{z}$', u'\U0001d6d5': '$\\mathbf{\\Tau}$', u'\U0001d754': '{\\mathbit{\\varrho}}', u'\u21db': '$\\Rrightarrow$', u'\u02dd': '{\\H{}}', u'\u045e': '{\\cyrchar\\cyrushrt}', u'\U0001d4e9': '$\\mathmit{Z}$', u'\U0001d568': '$\\mathbb{w}$', u'\u29eb': '$\\blacklozenge$', u'\U0001d66a': '$\\mathsfbfsl{u}$', u'\U0001d63c': '$\\mathsfbfsl{A}$', u'\xf1': '{\\~{n}}', u'\u0170': '{\\H{U}}', u'\u2272': '$\\lessequivlnt$', u'\U0001d7ff': '$\\mathtt{9}$', u'\U0001d47e': '$\\mathbit{W}$', u'\u2980': '$\\Elztfnc$', u'\u0307': '{\\.}', u'\u0409': '{\\cyrchar\\CYRLJE}', u'\U0001d513': '$\\mathfrak{P}$', u'\U0001d615': '$\\mathsfsl{N}$', u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', u'\u211b': '$\\mathscr{R}$', u'\u221d': '$\\propto$', u'\u039c': '$M$', u'\u271f': '{\\ding{63}}', u'\u049e': '{\\cyrchar\\CYRKHCRS}', u'\U0001d429': '$\\mathbf{p}$', u'\U0001d5a8': '$\\mathsf{I}$', u'\U0001d6aa': '$\\mathbf{\\Gamma}$', u'\u2a2d': '$\\ElsevierGlyph{E25C}$', u'\u2031': '{\\textpertenthousand}', u'\u21b0': '$\\Lsh$', u'\u22b2': '$\\vartriangleleft$', u'\u27b4': '{\\ding{244}}', u'\U0001d73f': '$\\mathbit{\\Kappa}$', u'\U0001d4be': '$\\mathscr{i}$', u'\xc6': '{\\AE}', u'\u0449': '{\\cyrchar\\cyrshch}', u'\U0001d553': '$\\mathbb{b}$', u'\U0001d655': '$\\mathsfbfsl{Z}$', u'\U0001d7d4': '$\\mathbf{6}$', u'\u215b': '$\\textfrac{1}{8}$', u'\u03dc': '$\\Digamma$', u'\u27a4': '{\\ding{228}}', u'\U0001d469': '$\\mathbit{B}$', u'\U0001d5e8': '$\\mathsfbf{U}$', u'\U0001d6ea': '$\\mathsl{\\Iota}$', u'\u212b': '{\\AA}', u'\U0001d77f': '$\\mathsfbf{\\Pi}$', u'\U0001d4fe': '$\\mathmit{u}$', u'\u2306': '$\\perspcorrespond$', u'\u2789': '{\\ding{201}}', u'\U0001d693': '$\\mathtt{j}$', u'\U0001d595': '$\\mathslbb{p}$', u'\U0001d414': '$\\mathbf{U}$', u'\u229b': '$\\circledast$', u'\u219d': '$\\arrowwaveright$', u'\u201c': '{\\textquotedblleft}', u'\u049f': '{\\cyrchar\\cyrkhcrs}', u'\u271e': '{\\ding{62}}', u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', u'\U0001d628': '$\\mathsfsl{g}$', u'\U0001d52a': '$\\mathfrak{m}$', u'\u03b1': '$\\alpha$', u'\u2230': '$\\volintegral$', u'\u0132': '{IJ}', u'\u25b5': '$\\vartriangle$', u'\u0434': '{\\cyrchar\\cyrd}', u'\u015e': '{\\c{S}}', u'\U0001d4bf': '$\\mathscr{j}$', u'\U0001d73e': '$\\mathbit{\\Iota}$', u'\u2942': '$\\ElzRlarr$', u'\xc7': '{\\c{C}}', u'\u2648': '{\\aries}', u'\U0001d6d3': '$\\mathbf{\\varsigma}$', u'\U0001d5d5': '$\\mathsfbf{B}$', u'\U0001d454': '$\\mathsl{g}$', u'\u22db': '$\\gtreqless$', u'\u21dd': '$\\rightsquigarrow$', u'\u275e': '{\\ding{126}}', u'\U0001d7e9': '$\\mathsf{7}$', u'\U0001d668': '$\\mathsfbfsl{s}$', u'\u2aeb': '$\\ElsevierGlyph{E30D}$', u'\U0001d56a': '$\\mathbb{y}$', u'\u03f1': '$\\varrho$', u'\u0270': '$\\Elztrnmlr$', u'\u0172': '{\\k{U}}', u'\u0474': '{\\cyrchar\\CYRIZH}', u'\U0001d4ff': '$\\mathmit{v}$', u'\U0001d77e': '$O$', u'\u2007': '{\\hphantom{0}}', u'\u0386': "{\\'{A}}", u'\u2709': '{\\ding{41}}', u'\U0001d613': '$\\mathsfsl{L}$', u'\U0001d494': '$\\mathbit{s}$', u'\u211d': '$\\mathbb{R}$', u'\u041f': '{\\cyrchar\\CYRP}', u'\u279e': '{\\ding{222}}', u'\U0001d729': '$\\mathbit{\\Xi}$', u'\U0001d6a8': '$\\mathbf{\\Alpha}$', u'\U0001d5aa': '$\\mathsf{K}$', u'\u04b4': '{\\cyrchar\\CYRTETSE}', u'\U0001d43f': '$\\mathsl{L}$', u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', u'\u03c6': '$\\varphi$', u'\u2749': '{\\ding{105}}', u'\u25ca': '$\\lozenge$', u'\u03a3': '$\\Sigma$', u'\U0001d653': '$\\mathsfbfsl{X}$', u'\U0001d555': '$\\mathbb{d}$', u'\U0001d4d4': '$\\mathmit{E}$', u'\u225b': '$\\starequal$', u'\u215d': '$\\textfrac{5}{8}$', u'\u20dc': '$\\ddddot$', u'\u045f': '{\\cyrchar\\cyrdzhe}', u'\u0124': '{\\^{H}}', u'\U0001d769': '$\\mathsfbf{\\Tau}$', u'\U0001d6e8': '$\\mathsl{\\Eta}$', u'\U0001d5ea': '$\\mathsfbf{W}$', u'\u22f0': '$\\upslopeellipsis$', u'\U0001d47f': '$\\mathbit{X}$', u'\U0001d7fe': '$\\mathtt{8}$', u'\u2708': '{\\ding{40}}', u'\u040a': '{\\cyrchar\\CYRNJE}', u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', u'\U0001d495': '$\\mathbit{t}$', u'\U0001d514': '$\\mathfrak{Q}$', u'\u2a16': '$\\sqrint$', u'\u039b': '$\\Lambda$', u'\u211c': '$\\mathfrak{R}$', u'\u261e': '{\\ding{43}}', u'\U0001d6a9': '$\\mathbf{\\Beta}$', u'\U0001d728': '$N$', u'\U0001d42a': '$\\mathbf{q}$', u'\u27b3': '{\\ding{243}}', u'\u2032': "${'}$", u'\u04b5': '{\\cyrchar\\cyrtetse}', u'\U0001d5bf': '$\\mathsf{f}$', u'\U0001d63e': '$\\mathsfbfsl{C}$', u'\u21c7': '$\\leftleftarrows$', u'\u2246': '$\\approxnotequal$', u'\u2748': '{\\ding{104}}', u'\u044a': '{\\cyrchar\\cyrhrdsn}', u'\U0001d7d3': '$\\mathbf{5}$', u'\U0001d4d5': '$\\mathmit{F}$', u'\U0001d554': '$\\mathbb{c}$', u'\u2a56': '$\\ElOr$', u'\xdd': "{\\'{Y}}", u'\u215c': '$\\textfrac{3}{8}$', u'\U0001d6e9': '$\\mathsl{\\Theta}$', u'\U0001d768': '$\\mathsfbf{\\Sigma}$', u'\U0001d46a': '$\\mathbit{C}$', u'\u22f1': '$\\downslopeellipsis$', u'\U0001d5ff': '$\\mathsfbf{r}$', u'\U0001d67e': '$\\mathtt{O}$', u'\u0107': "{\\'{c}}", u'\u2286': '$\\subseteq$', u'\u226d': '$\\not\\kern-0.3em\\times$', u'\U0001d713': '$\\mathsl{\\Psi}$', u'\U0001d415': '$\\mathbf{V}$', u'\U0001d594': '$\\mathslbb{o}$', u'\u2a96': '$\\eqslantgtr$', u'\u201d': '{\\textquotedblright}', u'\u219c': '$\\arrowwaveright$', u'\U0001d7ee': '$\\mathsfbf{2}$', u'\U0001d629': '$\\mathsfsl{h}$', u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', u'\U0001d4aa': '$\\mathscr{O}$', u'\u2231': '$\\clwintegral$', u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', u'\u2733': '{\\ding{83}}', u'\xb2': '${^2}$', u'\u0435': '{\\cyrchar\\cyre}', u'\u25b4': '$\\blacktriangle$', u'\u019e': '{\\textnrleg}', u'\u011d': '{\\^{g}}', u'\U0001d6be': '$\\mathbf{\\Chi}$', u'\u010a': '{\\.{C}}', u'\u0147': '{\\v{N}}', u'\u22c6': '$\\star$', u'\u2649': '{\\taurus}', u'\U0001d753': '{\\mathbit{\\phi}}', u'\U0001d5d4': '$\\mathsfbf{A}$', u'\u2957': '$\\DownRightVectorBar$', u'\u02db': '{\\k{}}', u'\U0001d669': '$\\mathsfbfsl{t}$', u'\U0001d7e8': '$\\mathsf{6}$', u'\U0001d4ea': '$\\mathmit{a}$', u'\u0271': '$\\Elzltlmr$', u'\u03f0': '$\\varkappa$', u'\xf2': '{\\`{o}}', u'\U0001d57f': '$\\mathslbb{T}$', u'\U0001d6fe': '$\\mathsl{\\Gamma}$', u'\u2a04': '$\\Elxuplus$', u'\u2506': '$\\Elzdshfnc$', u'\u2008': '{\\hphantom{,}}', u'\u230a': '$\\lfloor$', u'\U0001d591': '$\\mathslbb{l}$', u'\U0001d410': '$\\mathbf{Q}$', u'\U0001d712': '$\\mathsl{\\Chi}$', u'\u2999': '$\\Elzddfnc$', u'\u049b': '{\\cyrchar\\cyrkdsc}', u'\u279d': '{\\ding{221}}', u'\u229f': '$\\boxminus$', u'\u211e': '$\\Elzxrat$', u'\U0001d526': '$\\mathfrak{i}$', u'\u2aaf': '$\\preceq$', u'\u25b1': '$\\ElsevierGlyph{E381}$', u'\u0430': '{\\cyrchar\\cyra}', u'\xb3': '${^3}$', u'\u2732': '{\\ding{82}}', u'\u03b5': '$\\epsilon$', u'\u2234': '$\\therefore$', u'\U0001d4bb': '$\\mathscr{f}$', u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', u'\u228b': '$\\supsetneq$', u'\xdc': '{\\"{U}}', u'\u21c9': '$\\rightrightarrows$', u'\U0001d5d1': '$\\mathsf{x}$', u'\U0001d450': '$\\mathsl{c}$', u'\U0001d752': '{\\mathbit{\\varkappa}}', u'\u22df': '$\\curlyeqsucc$', u'\u215e': '$\\textfrac{7}{8}$', u'\u0294': '$\\Elzglst$', u'\U0001d6e7': '$\\mathsl{\\Zeta}$', u'\U0001d566': '$\\mathbb{u}$', u'\u296e': '$\\UpEquilibrium$', u'\u0470': '{\\cyrchar\\CYRPSI}', u'\xf3': "{\\'{o}}", u'\u2274': '$\\ElsevierGlyph{2274}$', u'\U0001d4fb': '$\\mathmit{r}$', u'\U0001d7fd': '$\\mathtt{7}$', u'\U0001d67c': '$\\mathtt{M}$', u'\u0109': '{\\^{c}}', u'\u038a': "{\\'{}{I}}", u'\U0001d511': '$\\mathfrak{N}$', u'\U0001d490': '$\\mathbit{o}$', u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', u'\u041b': '{\\cyrchar\\CYRL}', u'\u271d': '{\\ding{61}}', u'\u0134': '{\\^{J}}', u'\u221f': '$\\rightangle$', u'\u219e': '$\\twoheadleftarrow$', u'\U0001d627': '$\\mathsfsl{f}$', u'\U0001d5a6': '$\\mathsf{G}$', u'\u2a2f': '$\\ElzTimes$', u'\u04b0': '{\\cyrchar\\CYRYHCRS}', u'\u2033': "${''}$", u'\u27b2': '{\\ding{242}}', u'\u0335': '{\\Elzxl}', u'\u22b4': '$\\trianglelefteq$', u'\U0001d43b': '$\\mathsl{H}$', u'\U0001d73d': '$\\mathbit{\\Theta}$', u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', u'\u2647': '{\\pluto}', u'\u25c6': '{\\ding{117}}', u'\u0149': "{'n}", u'\xc8': '{\\`{E}}', u'\u03ca': '$\\ddot{\\iota}$', u'\U0001d4d0': '$\\mathmit{A}$', u'\U0001d7d2': '$\\mathbf{4}$', u'\u2959': '$\\LeftDownVectorBar$', u'\u045b': '{\\cyrchar\\cyrtshe}', u'\u275d': '{\\ding{125}}', u'\u225f': '$\\ElsevierGlyph{225F}$', u'\U0001d667': '$\\mathsfbfsl{r}$', u'\U0001d5e6': '$\\mathsfbf{S}$', u'\u2571': '$\\diagup$', u'\U0001d47b': '$\\mathbit{T}$', u'\U0001d77d': '$\\mathsfbf{\\Xi}$', u'\U0001d6fc': '$\\mathsl{\\Alpha}$', u'\u22d4': '$\\pitchfork$', u'\u2a85': '$\\lessapprox$', u'\u2787': '{\\ding{199}}', u'\u0406': '{\\cyrchar\\CYRII}', u'\u0108': '{\\^{C}}', u'\U0001d491': '$\\mathbit{p}$', u'\U0001d510': '$\\mathfrak{M}$', u'\U0001d612': '$\\mathsfsl{K}$', u'\u271c': '{\\ding{60}}', u'\u039f': '$O$', u'\u201e': '{,,}', u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', u'\U0001d426': '$\\mathbf{m}$', u'\u04b1': '{\\cyrchar\\cyryhcrs}', u'\u21b3': '$\\ElsevierGlyph{21B3}$', u'\u22b5': '$\\trianglerighteq$', u'\U0001d5bb': '$\\mathsf{b}$', u'\U0001d6bd': '$\\mathbf{\\Phi}$', u'\U0001d73c': '$\\mathbit{\\Eta}$', u'\u2ac5': '$\\subseteqq$', u'\u0446': '{\\cyrchar\\cyrc}', u'\xc9': "{\\'{E}}", u'\u0148': '{\\v{n}}', u'\u224a': '$\\approxeq$', u'\U0001d4d1': '$\\mathmit{B}$', u'\U0001d550': '$\\mathbb{Y}$', u'\U0001d652': '$\\mathsfbfsl{W}$', u'\u010f': '{\\v{d}}', u'\u2958': '$\\LeftUpVectorBar$', u'\u028e': '$\\Elztrny$', u'\u275c': '{\\ding{124}}', u'\U0001d7e7': '$\\mathsf{5}$', u'\U0001d466': '$\\mathsl{y}$', u'\u0283': '$\\Elzesh$', u'\U0001d5fb': '$\\mathsfbf{n}$', u'\U0001d6fd': '$\\mathsl{\\Beta}$', u'\U0001d77c': '$N$', u'\u2a05': '$\\ElzThr$', u'\u2707': '{\\ding{39}}', u'\u2009': '{\\hspace{0.167em}}', u'\u028a': '$\\Elzpupsil$', u'\U0001d411': '$\\mathbf{R}$', u'\U0001d590': '$\\mathslbb{k}$', u'\U0001d692': '$\\mathtt{i}$', u'\u279c': '{\\ding{220}}', u'\u231f': '$\\lrcorner$', u'\U0001d727': '$M$', u'\U0001d4a6': '$\\mathscr{K}$', u'\u0431': '{\\cyrchar\\cyrb}', u'\u2133': '$\\mathscr{M}$', u'\u2235': '$\\because$', u'\u03b4': '$\\delta$', u'\U0001d53b': '$\\mathbb{D}$', u'\U0001d63d': '$\\mathsfbfsl{B}$', u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', u'\u2747': '{\\ding{103}}', u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', u'\u21c8': '$\\upuparrows$', u'\u22ca': '$\\rtimes$', u'\U0001d451': '$\\mathsl{d}$', u'\U0001d5d0': '$\\mathsf{w}$', u'\U0001d6d2': '$\\mathbf{\\Rho}$', u'\xde': '{\\TH}', u'\U0001d767': '{\\mathsfbf{\\vartheta}}', u'\U0001d4e6': '$\\mathmit{W}$', u'\u0471': '{\\cyrchar\\cyrpsi}', u'\u0173': '{\\k{u}}', u'\u2275': '$\\ElsevierGlyph{2275}$', u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', u'\U0001d57b': '$\\mathslbb{P}$', u'\U0001d67d': '$\\mathtt{N}$', u'\U0001d7fc': '$\\mathtt{6}$', u'\u2985': '$\\ElsevierGlyph{3018}$', u'\u2706': '{\\ding{38}}', u'\u0389': "{\\'{H}}", u'\u2208': '$\\in$', u'\u210a': '{\\mathscr{g}}', u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', u'\U0001d610': '$\\mathsfsl{I}$', u'\U0001d512': '$\\mathfrak{O}$', u'\u012f': '{\\k{i}}', u'\u041c': '{\\cyrchar\\CYRM}', u'\u231e': '$\\llcorner$', u'\U0001d726': '$\\mathbit{\\Lambda}$', u'\u27b1': '{\\ding{241}}', u'\u22b3': '$\\vartriangleright$', u'\u2034': "${'''}$", u'\U0001d6bb': '$\\mathbf{\\Tau}$', u'\U0001d5bd': '$\\mathsf{d}$', u'\U0001d43c': '$\\mathsl{I}$', u'\u04c7': '{\\cyrchar\\CYRNHK}', u'\u2746': '{\\ding{102}}', u'\u03c9': '$\\omega$', u'\u2248': '$\\approx$', u'\u014a': '{\\NG}', u'\U0001d7d1': '$\\mathbf{3}$', u'\U0001d650': '$\\mathsfbfsl{U}$', u'\U0001d552': '$\\mathbb{a}$', u'\u295a': '$\\LeftTeeVector$', u'\u045c': "{\\cyrchar{\\'\\cyrk}}", u'\xdf': '{\\ss}', u'\u0464': '{\\cyrchar\\CYRIOTE}', u'\u011a': '{\\v{E}}', u'\u0491': '{\\cyrchar\\cyrgup}', u'\U0001d4e7': '$\\mathmit{X}$', u'\U0001d766': '$\\mathsfbf{\\Rho}$', u'\u21f5': '$\\DownArrowUpArrow$', u'\u2295': '$\\oplus$', u'\U0001d6fb': '$\\mathsl{\\nabla}$', u'\U0001d5fd': '$\\mathsfbf{p}$', u'\U0001d47c': '$\\mathbit{U}$', u'\u2905': '$\\ElsevierGlyph{E212}$', u'\u0407': '{\\cyrchar\\CYRYI}', u'\u2786': '{\\ding{198}}', u'\u2309': '$\\rceil$', u'\u0288': '$\\Elzrtlt$', u'\U0001d711': '$\\mathsl{\\Phi}$', u'\U0001d690': '$\\mathtt{g}$', u'\U0001d592': '$\\mathslbb{m}$', u'\u261b': '{\\ding{42}}', u'\u049c': '{\\cyrchar\\CYRKVCRS}', u'\u039e': '$\\Xi$', u'\U0001d427': '$\\mathbf{n}$', u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', u'\u2731': '{\\ding{81}}', u'\u2233': '$\\ElsevierGlyph{2233}$', u'\u25b2': '{\\ding{115}}', u'\u2135': '$\\aleph$', u'\xb4': '{\\textasciiacute}', u'\U0001d63b': '$\\mathsfsl{z}$', u'\U0001d53d': '$\\mathbb{F}$', u'\u0447': '{\\cyrchar\\cyrch}', u'\u22c8': '$\\bowtie$', u'\u21ca': '$\\downdownarrows$', u'\U0001d751': '{\\mathbit{\\vartheta}}', u'\U0001d6d0': '$O$', u'\U0001d5d2': '$\\mathsf{y}$', u'\u205f': '{\\mkern4mu}', u'\u03de': '$\\Koppa$', u'\U0001d467': '$\\mathsl{z}$', u'\U0001d7e6': '$\\mathsf{4}$', u'\u2273': '$\\greaterequivlnt$', u'\u0175': '{\\^{w}}', u'\xf4': '{\\^{o}}', u'\u0128': '{\\~{I}}', u'\U0001d67b': '$\\mathtt{L}$', u'\U0001d57d': '$\\mathslbb{R}$', u'\U0001d4fc': '$\\mathmit{s}$', u'\u2606': '{\\ding{73}}', u'\u2289': '$\\not\\supseteq$', u'\u2308': '$\\lceil$', u'\u200a': '$\\mkern1mu$', u'\U0001d691': '$\\mathtt{h}$', u'\u2259': '$\\estimates$', u'\U0001d412': '$\\mathbf{S}$', u'\u279b': '{\\ding{219}}', u'\u049d': '{\\cyrchar\\cyrkvcrs}', u'\u221e': '$\\infty$', u'\U0001d5a7': '$\\mathsf{H}$', u'\U0001d626': '$\\mathsfsl{e}$', u'\u2a2e': '$\\ElsevierGlyph{E25D}$', u'\u2730': '{\\ding{80}}', u'\u03b3': '$\\gamma$', u'\u0432': '{\\cyrchar\\cyrv}', u'\xb5': '$\\mathrm{\\mu}$', u'\u2134': '$\\mathscr{o}$', u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', u'\U0001d4bd': '$\\mathscr{h}$', u'\U0001d53c': '$\\mathbb{E}$', u'\u2944': '$\\ElzrLarr$', u'\u2646': '{\\neptune}', u'\u22c9': '$\\ltimes$', u'\u010d': '{\\v{c}}', u'\U0001d6d1': '$\\mathbf{\\Pi}$', u'\U0001d750': '$\\in$', u'\U0001d452': '$\\mathsl{e}$', u'\U0001d78e': '{\\mathsfbf{\\varrho}}', u'\U0001d5e7': '$\\mathsfbf{T}$', u'\U0001d666': '$\\mathsfbfsl{q}$', u'\u2a6e': '$\\stackrel{*}{=}$', u'\u0472': '{\\cyrchar\\CYRFITA}', u'\xf5': '{\\~{o}}', u'\u0174': '{\\^{W}}', u'\U0001d7fb': '$\\mathtt{5}$', u'\U0001d4fd': '$\\mathmit{t}$', u'\U0001d57c': '$\\mathslbb{Q}$', u'\u2209': '$\\not\\in$', u'\u0388': "{\\'{E}}", u'\U0001d611': '$\\mathsfsl{J}$', u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', u'\U0001d492': '$\\mathbit{q}$', u'\u271b': '{\\ding{59}}', u'\u041d': '{\\cyrchar\\CYRN}', u'\u011f': '{\\u{g}}', u'\u229e': '$\\boxplus$', u'\U0001d527': '$\\mathfrak{j}$', u'\u04b2': '{\\cyrchar\\CYRHDSC}', u'\u2035': '$\\backprime$', u'\U0001d73b': '$\\mathbit{\\Zeta}$', u'\U0001d43d': '$\\mathsl{J}$', u'\U0001d5bc': '$\\mathsf{c}$', u'\u2249': '$\\not\\approx$', u'\u03c8': '$\\psi$', u'\xca': '{\\^{E}}', u'\U0001d651': '$\\mathsfbfsl{V}$', u'\u0279': '$\\Elztrnr$', u'\U0001d4d2': '$\\mathmit{C}$', u'\u275b': '{\\ding{123}}', u'\u015f': '{\\c{s}}', u'\u22de': '$\\curlyeqprec$', u'\U0001d567': '$\\mathbb{v}$', u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', u'\u296f': '$\\ReverseUpEquilibrium$', u'\U0001d77b': '$M$', u'\U0001d47d': '$\\mathbit{V}$', u'\U0001d5fc': '$\\mathsfbf{o}$', u'\U0001d483': '$\\mathbit{b}$', u'\U0001d785': '$\\mathsfbf{\\Phi}$', u'\U0001d604': '$\\mathsfbf{w}$', u'\u012d': '{\\u{\\i}}', u'\u220c': '$\\not\\ni$', u'\u20ac': '{\\mbox{\\texteuro}}', u'\ufb02': '{fl}', u'\U0001d599': '$\\mathslbb{t}$', u'\U0001d418': '$\\mathbf{Y}$', u'\U0001d71a': '{\\mathsl{\\varrho}}', u'\u2020': '{\\textdagger}', u'\u04a3': '{\\cyrchar\\cyrndsc}', u'\u2322': '$\\frown$', u'\u27a5': '{\\ding{229}}', u'\u2287': '$\\supseteq$', u'\u2926': '$\\ElsevierGlyph{E20A}$', u'\U0001d6af': '$\\mathbf{\\Theta}$', u'\U0001d52e': '$\\mathfrak{q}$', u'\u22b7': '$\\image$', u'\u2136': '$\\beth$', u'\u25b9': '$\\triangleright$', u'\u0438': '{\\cyrchar\\cyri}', u'\u273a': '{\\ding{90}}', u'\u2a3c': '$\\ElsevierGlyph{E259}$', u'\U0001d4c3': '$\\mathscr{n}$', u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', u'\U0001d644': '$\\mathsfbfsl{I}$', u'\xcb': '{\\"{E}}', u'\u03cd': '$\\acute{\\upsilon}$', u'\u224c': '$\\allequal$', u'\U0001d5d9': '$\\mathsfbf{F}$', u'\U0001d458': '$\\mathsl{k}$', u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', u'\u2060': '{\\nolinebreak}', u'\u0466': '{\\cyrchar\\CYRLYUS}', u'\U0001d6ef': '$\\mathsl{\\Xi}$', u'\U0001d56e': '$\\mathslbb{C}$', u'\u0176': '{\\^{Y}}', u'\u0478': '{\\cyrchar\\CYRUK}', u'\u277a': '{\\ding{186}}', u'\U0001d403': '$\\mathbf{D}$', u'\U0001d705': '$\\mathsl{\\Kappa}$', u'\U0001d684': '$\\mathtt{U}$', u'\u028c': '$\\Elzinvv$', u'\u01c2': '{\\textdoublepipe}', u'\U0001d519': '$\\mathfrak{V}$', u'\U0001d498': '$\\mathbit{w}$', u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', u'\u0121': '{\\.{g}}', u'\xa0': '$~$', u'\u0423': '{\\cyrchar\\CYRU}', u'\u2725': '{\\ding{69}}', u'\U0001d62f': '$\\mathsfsl{n}$', u'\U0001d5ae': '$\\mathsf{O}$', u'\u2237': '$\\Colon$', u'\u21b6': '$\\curvearrowleft$', u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', u'\u27ba': '{\\ding{250}}', u'\U0001d443': '$\\mathsl{P}$', u'\U0001d745': '$\\mathbit{\\Pi}$', u'\U0001d6c4': '$\\mathbf{\\Gamma}$', u'\u02cc': '$\\Elzverti$', u'\u264f': '{\\scorpio}', u'\u2951': '$\\LeftUpDownVector$', u'\U0001d559': '$\\mathbb{h}$', u'\U0001d4d8': '$\\mathmit{I}$', u'\U0001d7da': '$\\mathbb{2}$', u'\u0161': '{\\v{s}}', u'\xe0': '{\\`{a}}', u'\u2463': '{\\ding{175}}', u'\u2765': '{\\ding{165}}', u'\u22a7': '$\\truestate$', u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', u'\U0001d66f': '$\\mathsfbfsl{z}$', u'\U0001d5ee': '$\\mathsfbf{a}$', u'\u0277': '$\\Elzclomeg$', u'\u2464': '{\\ding{176}}', u'\u27fa': '$\\Longleftrightarrow$', u'\U0001d583': '$\\mathslbb{X}$', u'\U0001d685': '$\\mathtt{V}$', u'\U0001d704': '$\\mathsl{\\Iota}$', u'\u028d': '$\\Elzinvw$', u'\u030c': '{\\v}', u'\u278f': '{\\ding{207}}', u'\u040e': '{\\cyrchar\\CYRUSHRT}', u'\U0001d499': '$\\mathbit{x}$', u'\U0001d518': '$\\mathfrak{U}$', u'\U0001d61a': '$\\mathsfsl{S}$', u'\xa1': '{\\textexclamdown}', u'\u0120': '{\\.{G}}', u'\u2222': '$\\sphericalangle$', u'\u2724': '{\\ding{68}}', u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', u'\U0001d42e': '$\\mathbf{u}$', u'\u03b7': '$\\eta$', u'\u04b9': '{\\cyrchar\\cyrchvcrs}', u'\U0001d5c3': '$\\mathsf{j}$', u'\u228a': '$\\subsetneq$', u'\U0001d6c5': '$\\mathbf{\\Delta}$', u'\U0001d744': '$O$', u'\u21cb': '$\\leftrightharpoons$', u'\u22cd': '$\\backsimeq$', u'\u044e': '{\\cyrchar\\cyryu}', u'\u2950': '$\\DownLeftRightVector$', u'\U0001d4d9': '$\\mathmit{J}$', u'\U0001d558': '$\\mathbb{g}$', u'\U0001d65a': '$\\mathsfbfsl{e}$', u'\xe1': "{\\'{a}}", u'\u0160': '{\\v{S}}', u'\u2262': '$\\not\\equiv$', u'\u2764': '{\\ding{164}}', u'\u02e5': '{\\tone{55}}', u'\u0113': '{\\={e}}', u'\U0001d7ef': '$\\mathsfbf{3}$', u'\U0001d46e': '$\\mathbit{G}$', u'\u2afd': '${{/}\\!\\!{/}}$', u'\u0394': '$\\Delta$', u'\U0001d503': '$\\mathmit{z}$', u'\U0001d605': '$\\mathsfbf{x}$', u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', u'\u210b': '$\\mathscr{H}$', u'\u038c': "{\\'{}O}", u'\u270f': '{\\ding{47}}', u'\u048e': '{\\cyrchar\\CYRRTICK}', u'\U0001d419': '$\\mathbf{Z}$', u'\U0001d598': '$\\mathslbb{s}$', u'\U0001d69a': '$\\mathtt{q}$', u'\u2021': '{\\textdaggerdbl}', u'\u21a0': '$\\twoheadrightarrow$', u'\u22a2': '$\\vdash$', u'\u02c7': '{\\textasciicaron}', u'\U0001d72f': '$\\mathbit{\\Tau}$', u'\U0001d4ae': '$\\mathscr{S}$', u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', u'\xb6': '{\\textparagraph}', u'\u0439': '{\\cyrchar\\cyrishrt}', u'\u25b8': '$\\blacktriangleright$', u'\U0001d543': '$\\mathbb{L}$', u'\U0001d645': '$\\mathsfbfsl{J}$', u'\U0001d7c4': '$\\in$', u'\u014b': '{\\ng}', u'\u224d': '$\\asymp$', u'\u03cc': "{\\'{o}}", u'\u274f': '{\\ding{111}}', u'\u29d0': '$\\RightTriangleBar$', u'\U0001d459': '$\\mathsl{l}$', u'\U0001d5d8': '$\\mathsfbf{E}$', u'\U0001d6da': '$\\mathbf{\\Omega}$', u'\u22e2': '$\\not\\sqsubseteq$', u'\u2665': '{\\ding{170}}', u'\U0001d76f': '$\\mathsfbf{\\nabla}$', u'\U0001d4ee': '$\\mathmit{e}$', u'\xf6': '{\\"{o}}', u'\u0479': '{\\cyrchar\\cyruk}', u'\u2a7d': '$\\leqslant$', u'\U0001d683': '$\\mathtt{T}$', u'\U0001d585': '$\\mathslbb{Z}$', u'\U0001d404': '$\\mathbf{E}$', u'\u028b': '$\\Elzpscrv$', u'\u048f': '{\\cyrchar\\cyrrtick}', u'\u270e': '{\\ding{46}}', u'\u2a10': '$\\ElsevierGlyph{E395}$', u'\u2912': '$\\UpArrowBar$', u'\u0192': '$f$', u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', u'\U0001d618': '$\\mathsfsl{Q}$', u'\U0001d51a': '$\\mathfrak{W}$', u'\xdb': '{\\^{U}}', u'\u03a1': '$\\Rho$', u'\u2220': '$\\angle$', u'\u0122': '{\\c{G}}', u'\u0424': '{\\cyrchar\\CYRF}', u'\u0133': '{ij}', u'\U0001d4af': '$\\mathscr{T}$', u'\U0001d72e': '$\\mathbit{\\Sigma}$', u'\xb7': '$\\cdot$', u'\u0336': '{\\Elzbar}', u'\u27b9': '{\\ding{249}}', u'\U0001d6c3': '$\\mathbf{\\Beta}$', u'\U0001d5c5': '$\\mathsf{l}$', u'\U0001d444': '$\\mathsl{Q}$', u'\u22cb': '$\\leftthreetimes$', u'\u21cd': '$\\nLeftarrow$', u'\u010c': '{\\v{C}}', u'\u2952': '$\\LeftVectorBar$', u'\U0001d7d9': '$\\mathbb{1}$', u'\U0001d658': '$\\mathsfbfsl{c}$', u'\U0001d55a': '$\\mathbb{i}$', u'\u2260': '$\\not =$', u'\u0162': '{\\c{T}}', u'\u02e7': '{\\tone{33}}', u'\U0001d4ef': '$\\mathmit{f}$', u'\U0001d76e': '$\\mathsfbf{\\Omega}$', u'\xf7': '$\\div$', u'\u2468': '{\\ding{180}}', u'\u27f9': '$\\Longrightarrow$', u'\U0001d603': '$\\mathsfbf{v}$', u'\U0001d505': '$\\mathfrak{B}$', u'\U0001d484': '$\\mathbit{c}$', u'\u220b': '$\\ni$', u'\u210d': '$\\mathbb{H}$', u'\u040f': '{\\cyrchar\\CYRDZHE}', u'\u278e': '{\\ding{206}}', u'\U0001d719': '{\\mathsl{\\phi}}', u'\U0001d698': '$\\mathtt{o}$', u'\U0001d59a': '$\\mathslbb{u}$', u'\u0321': '$\\Elzpalh$', u'\u22a0': '$\\boxtimes$', u'\u21a2': '$\\leftarrowtail$', u'\u04a4': '{\\cyrchar\\CYRNG}', u'\U0001d42f': '$\\mathbf{v}$', u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', u'\u03b6': '$\\zeta$', u'\u2739': '{\\ding{89}}', u'\U0001d643': '$\\mathsfbfsl{H}$', u'\u224b': '$\\tildetrpl$', u'\u014d': '{\\={o}}', u'\xcc': '{\\`{I}}', u'\u044f': '{\\cyrchar\\cyrya}', u'\U0001d759': '$\\mathsfbf{\\Delta}$', u'\U0001d6d8': '$\\mathbf{\\Chi}$', u'\U0001d5da': '$\\mathsfbf{G}$', u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', u'\u2663': '{\\ding{168}}', u'\u0153': '{\\oe}', u'\U0001d46f': '$\\mathbit{H}$', u'\u227c': '$\\preccurlyeq$', u'\u0467': '{\\cyrchar\\cyrlyus}', u'\u03f6': '$\\backepsilon$', u'\u2779': '{\\ding{185}}', u'\u297d': '$\\ElsevierGlyph{E215}$', u'\U0001d783': '$\\mathsfbf{\\Tau}$', u'\U0001d485': '$\\mathbit{d}$', u'\U0001d504': '$\\mathfrak{A}$', u'\u210c': '$\\mathfrak{H}$', u'\u260e': '{\\ding{37}}', u'\U0001d699': '$\\mathtt{p}$', u'\U0001d718': '{\\mathsl{\\varkappa}}', u'\U0001d41a': '$\\mathbf{a}$', u'\u22a1': '$\\boxdot$', u'\u27a3': '{\\ding{227}}', u'\u2022': '{\\textbullet}', u'\u04a5': '{\\cyrchar\\cyrng}', u'\U0001d5af': '$\\mathsf{P}$', u'\U0001d62e': '$\\mathsfsl{m}$', u'\u21b7': '$\\curvearrowright$', u'\u2738': '{\\ding{88}}', u'\u043a': '{\\cyrchar\\cyrk}', u'\U0001d7c3': '$\\partial$', u'\U0001d4c5': '$\\mathscr{p}$', u'\U0001d544': '$\\mathbb{M}$', u'\u03cb': '$\\ddot{\\upsilon}$', u'\xcd': "{\\'{I}}", u'\u014c': '{\\={O}}', u'\u25cf': '{\\ding{108}}', u'\u264e': '{\\libra}', u'\U0001d6d9': '$\\mathbf{\\Psi}$', u'\U0001d758': '$\\mathsfbf{\\Gamma}$', u'\U0001d45a': '$\\mathsl{m}$', u'\u0111': '{\\dj}', u'\U0001d5ef': '$\\mathsfbf{b}$', u'\U0001d66e': '$\\mathsfbfsl{y}$', u'\u2276': '$\\lessgtr$', u'\u2778': '{\\ding{184}}', u'\u047a': '{\\cyrchar\\CYROMEGARND}', u'\u297c': '$\\ElsevierGlyph{E214}$', u'\U0001d703': '$\\mathsl{\\Theta}$', u'\U0001d405': '$\\mathbf{F}$', u'\U0001d584': '$\\mathslbb{Y}$', u'\u230b': '$\\rfloor$', u'\U0001d619': '$\\mathsfsl{R}$', u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', u'\U0001d49a': '$\\mathbit{y}$', u'\u2221': '$\\measuredangle$', u'\u03a0': '$\\Pi$', u'\u2723': '{\\ding{67}}', u'\xa2': '{\\textcent}', u'\u0425': '{\\cyrchar\\CYRH}', u'\u2927': '$\\ElsevierGlyph{E211}$', u'\U0001d52f': '$\\mathfrak{r}$', u'\U0001d6ae': '$\\mathbf{\\Eta}$', u'\u2137': '$\\gimel$', u'\u22b6': '$\\original$', u'\u27b8': '{\\ding{248}}', u'\u04ba': '{\\cyrchar\\CYRSHHA}', u'\u03f4': '{\\textTheta}', u'\U0001d743': '$\\mathbit{\\Xi}$', u'\U0001d445': '$\\mathsl{R}$', u'\U0001d5c4': '$\\mathsf{k}$', u'\u21cc': '$\\rightleftharpoons$', u'\U0001d659': '$\\mathsfbfsl{d}$', u'\U0001d7d8': '$\\mathbb{0}$', u'\U0001d4da': '$\\mathmit{K}$', u'\u2261': '$\\equiv$', u'\u03e0': '$\\Sampi$', u'\u2763': '{\\ding{163}}', u'\xe2': '{\\^{a}}', u'\u0465': '{\\cyrchar\\cyriote}', u'\U0001d56f': '$\\mathslbb{D}$', u'\U0001d6ee': '$N$', u'\u0177': '{\\^{y}}', u'\u27f8': '$\\Longleftarrow$', u'\U0001d581': '$\\mathslbb{V}$', u'\U0001d400': '$\\mathbf{A}$', u'\U0001d702': '$\\mathsl{\\Eta}$', u'\u0256': '$\\Elzrtld$', u'\u278d': '{\\ding{205}}', u'\u228f': '$\\sqsubset$', u'\u010e': '{\\v{D}}', u'\U0001d697': '$\\mathtt{n}$', u'\U0001d516': '$\\mathfrak{S}$', u'\u3018': '$\\ElsevierGlyph{3018}$', u'\u25a1': '$\\square$', u'\u0131': '{\\i}', u'\xa3': '{\\textsterling}', u'\u2722': '{\\ding{66}}', u'\u03a5': '$\\Upsilon$', u'\u2224': '$\\nmid$', u'\U0001d4ab': '$\\mathscr{P}$', u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', u'\U0001d62c': '$\\mathsfsl{k}$', u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', u'\U0001d5c1': '$\\mathsf{h}$', u'\U0001d440': '$\\mathsl{M}$', u'\U0001d742': '$N$', u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', u'\u264c': '{\\leo}', u'\u22cf': '$\\curlywedge$', u'\u014e': '{\\u{O}}', u'\u2a54': '$\\ElzOr$', u'\U0001d6d7': '$\\mathbf{\\Phi}$', u'\U0001d556': '$\\mathbb{e}$', u'\u2460': '{\\ding{172}}', u'\xe3': '{\\~{a}}', u'\u2762': '{\\ding{162}}', u'\u2264': '$\\leq$', u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', u'\U0001d4eb': '$\\mathmit{b}$', u'\U0001d7ed': '$\\mathsfbf{1}$', u'\U0001d66c': '$\\mathsfbfsl{w}$', u'\u0195': '{\\texthvlig}', u'\U0001d501': '$\\mathmit{x}$', u'\U0001d480': '$\\mathbit{Y}$', u'\U0001d782': '$\\mathsfbf{\\Sigma}$', u'\u040b': '{\\cyrchar\\CYRTSHE}', u'\u270d': '{\\ding{45}}', u'\u220f': '$\\prod$', u'\U0001d617': '$\\mathsfsl{P}$', u'\U0001d596': '$\\mathslbb{q}$', u'\u04a0': '{\\cyrchar\\CYRKBEAK}', u'\u27a2': '{\\ding{226}}', u'\u22a4': '$\\top$', u'\u2929': '$\\ElsevierGlyph{E20F}$', u'\U0001d42b': '$\\mathbf{r}$', u'\U0001d72d': '{\\mathbit{O}}', u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', u'\u04c8': '{\\cyrchar\\cyrnhk}', u'\u0139': "{\\'{L}}", u'\xb8': '{\\c{}}', u'\u03ba': '$\\kappa$', u'\u2a3f': '$\\amalg$', u'\U0001d541': '$\\mathbb{J}$', u'\U0001d4c0': '$\\mathscr{k}$', u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', u'\u044b': '{\\cyrchar\\cyrery}', u'\u274d': '{\\ding{109}}', u'\u224f': '$\\bumpeq$', u'\u21ce': '$\\nLeftrightarrow$', u'\U0001d657': '$\\mathsfbfsl{b}$', u'\U0001d5d6': '$\\mathsfbf{C}$', u'\u04e0': '{\\cyrchar\\CYRABHDZE}', u'\U0001d46b': '$\\mathbit{D}$', u'\U0001d76d': '$\\mathsfbf{\\Psi}$', u'\U0001d6ec': '$\\mathsl{\\Lambda}$', u'\u0179': "{\\'{Z}}", u'\xf8': '{\\o}', u'\U0001d481': '$\\mathbit{Z}$', u'\U0001d500': '$\\mathmit{w}$', u'\U0001d602': '$\\mathsfbf{u}$', u'\u270c': '{\\ding{44}}', u'\u038f': "$\\mathrm{'\\Omega}$", u'\u2993': '$<\\kern-0.58em($', u'\u2a95': '$\\eqslantless$', u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', u'\U0001d416': '$\\mathbf{W}$', u'\u04a1': '{\\cyrchar\\cyrkbeak}', u'\u21a3': '$\\rightarrowtail$', u'\u22a5': '$\\perp$', u'\u2928': '$\\ElsevierGlyph{E20E}$', u'\U0001d5ab': '$\\mathsf{L}$', u'\u2a2a': '$\\ElsevierGlyph{E25B}$', u'\U0001d6ad': '$\\mathbf{\\Zeta}$', u'\U0001d72c': '$\\mathbit{\\Rho}$', u'\u27b7': '{\\ding{247}}', u'\u0436': '{\\cyrchar\\cyrzh}', u'\xb9': '${^1}$', u'\u2138': '$\\daleth$', u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', u'\u030b': '{\\H}', u'\U0001d4c1': '$\\mathscr{l}$', u'\U0001d540': '$\\mathbb{I}$', u'\U0001d642': '$\\mathsfbfsl{G}$', u'\u25cb': '$\\bigcirc$', u'\U0001d7d7': '$\\mathbf{9}$', u'\U0001d456': '$\\mathsl{i}$', u'\u04e1': '{\\cyrchar\\cyrabhdze}', u'\u2662': '$\\diamond$', u'\u22e5': '$\\Elzsqspne$', u'\U0001d5eb': '$\\mathsfbf{X}$', u'\U0001d6ed': '$M$', u'\U0001d76c': '$\\mathsfbf{\\Chi}$', u'\u27f7': '$\\longleftrightarrow$', u'\xf9': '{\\`{u}}', u'\u0178': '{\\"{Y}}', u'\u227a': '$\\prec$', u'\U0001d401': '$\\mathbf{B}$', u'\U0001d580': '$\\mathslbb{U}$', u'\U0001d682': '$\\mathtt{S}$', u'\u2296': '$\\ominus$', u'\u278c': '{\\ding{204}}', u'\u2758': '{\\ding{120}}', u'\u2913': '$\\DownArrowBar$', u'\U0001d717': '{\\mathsl{\\vartheta}}', u'\U0001d496': '$\\mathbit{u}$', u'\u3019': '$\\ElsevierGlyph{3019}$', u'\u0421': '{\\cyrchar\\CYRS}', u'\u25a0': '{\\ding{110}}', u'\u0123': '{\\c{g}}', u'\u2225': '$\\parallel$', u'\u03a4': '$\\Tau$', u'\U0001d52b': '$\\mathfrak{n}$', u'\U0001d62d': '$\\mathsfsl{l}$', u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', u'\u2737': '{\\ding{87}}', u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', u'\u2039': '{\\guilsinglleft}', u'\u22ba': '$\\intercal$', u'\U0001d441': '$\\mathsl{N}$', u'\U0001d5c0': '$\\mathsf{g}$', u'\U0001d6c2': '$\\mathbf{\\Alpha}$', u'\u264d': '{\\virgo}', u'\xce': '{\\^{I}}', u'\u2953': '$\\RightVectorBar$', u'\u2a55': '$\\ElsevierGlyph{E36E}$', u'\U0001d757': '$\\mathsfbf{\\Beta}$', u'\U0001d4d6': '$\\mathmit{G}$', u'\u2461': '{\\ding{173}}', u'\u0163': '{\\c{t}}', u'\u0265': '$\\Elztrnh$', u'\U0001d56b': '$\\mathbb{z}$', u'\U0001d66d': '$\\mathsfbfsl{x}$', u'\u02d3': '$\\Elzsblhr$', u'\u2777': '{\\ding{183}}', u'\U0001d781': '$\\mathsfbf{\\varsigma}$', u'\U0001d600': '$\\mathsfbf{s}$', u'\U0001d502': '$\\mathmit{y}$', u'\u040c': "{\\cyrchar{\\'\\CYRK}}", u'\U0001d497': '$\\mathbit{v}$', u'\U0001d716': '$\\in$', u'\u27a1': '{\\ding{225}}', u'\u22a3': '$\\dashv$', u'\u2024': '{.}', u'\U0001d6ab': '$\\mathbf{\\Delta}$', u'\u292a': '$\\ElsevierGlyph{E210}$', u'\U0001d5ad': '$\\mathsf{N}$', u'\U0001d42c': '$\\mathbf{s}$', u'\u04b7': '{\\cyrchar\\cyrchrdsc}', u'\u2736': '{\\ding{86}}', u'\u03b9': '$\\iota$', u'\u2238': '$\\ElsevierGlyph{2238}$', u'\u013a': "{\\'{l}}", u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', u'\U0001d640': '$\\mathsfbfsl{E}$', u'\U0001d542': '$\\mathbb{K}$', u'\u0137': '{\\c{k}}', u'\u044c': '{\\cyrchar\\cyrsftsn}', u'\xcf': '{\\"{I}}', u'\U0001d4d7': '$\\mathmit{H}$', u'\U0001d756': '$\\mathsfbf{\\Alpha}$', u'\u2660': '{\\ding{171}}', u'\u22e3': '$\\not\\sqsupseteq$', u'\u0110': '{\\DJ}', u'\U0001d6eb': '$\\mathsl{\\Kappa}$', u'\U0001d5ed': '$\\mathsfbf{Z}$', u'\U0001d46c': '$\\mathbit{E}$', u'\u2776': '{\\ding{182}}', u'\u2278': '$\\notlessgreater$', u'\u017a': "{\\'{z}}", u'\U0001d701': '$\\mathsl{\\Zeta}$', u'\U0001d680': '$\\mathtt{Q}$', u'\U0001d582': '$\\mathslbb{W}$', u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', u'\u038e': "$\\mathrm{'Y}$", u'\U0001d417': '$\\mathbf{X}$', u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', u'\u2721': '{\\ding{65}}', u'\u2223': '$\\mid$', u'\u0125': '{\\^{h}}', u'\xa4': '{\\textcurrency}', u'\U0001d62b': '$\\mathsfsl{j}$', u'\U0001d52d': '$\\mathfrak{p}$', u'\U0001d4ac': '$\\mathscr{Q}$', u'\u0437': '{\\cyrchar\\cyrz}', u'\u27b6': '{\\ding{246}}', u'\u22b8': '$\\multimap$', u'\u21ba': '$\\circlearrowleft$', u'\U0001d741': '$M$', u'\U0001d6c0': '$\\mathbf{\\Omega}$', u'\U0001d5c2': '$\\mathsf{i}$', u'\u011c': '{\\^{G}}', u'\u264b': '{\\cancer}', u'\u04cc': '{\\cyrchar\\cyrchldsc}', u'\u03ce': '$\\acute{\\omega}$', u'\u2a53': '$\\ElzAnd$', u'\u2955': '$\\RightDownVectorBar$', u'\U0001d457': '$\\mathsl{j}$', u'\U0001d7d6': '$\\mathbf{8}$', u'\u2761': '{\\ding{161}}', u'\u0263': '$\\Elzpgamma$', u'\u0165': '{\\v{t}}', u'\xe4': '{\\"{a}}', u'\U0001d66b': '$\\mathsfbfsl{v}$', u'\U0001d56d': '$\\mathslbb{B}$', u'\U0001d4ec': '$\\mathmit{c}$', u'\u27f6': '$\\longrightarrow$', u'\U0001d681': '$\\mathtt{R}$', u'\U0001d700': '$\\mathsl{\\Epsilon}$', u'\U0001d402': '$\\mathbf{C}$', u'\u0157': '{\\c{r}}', u'\u278b': '{\\ding{203}}', u'\u048d': '{\\cyrchar\\cyrsemisftsn}', u'\U0001d597': '$\\mathslbb{r}$', u'\U0001d616': '$\\mathsfsl{O}$', u'\u301a': '$\\openbracketleft$', u'\u2720': '{\\ding{64}}', u'\u23a3': '$\\Elzdlcorn$', u'\u0422': '{\\cyrchar\\CYRT}', u'\xa5': '{\\textyen}', u'\u2124': '$\\mathbb{Z}$', u'\u0130': '{\\.{I}}', u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', u'\U0001d52c': '$\\mathfrak{o}$', u'\u2288': '$\\not\\subseteq$', u'\u22b9': '$\\hermitconjmatrix$', u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', u'\u203a': '{\\guilsinglright}', u'\U0001d6c1': '$\\mathbf{\\nabla}$', u'\U0001d740': '$\\mathbit{\\Lambda}$', u'\U0001d442': '$\\mathsl{O}$', u'\u21cf': '$\\nRightarrow$', u'\u224e': '$\\Bumpeq$', u'\u2954': '$\\RightUpVectorBar$', u'\U0001d5d7': '$\\mathsfbf{D}$', u'\U0001d656': '$\\mathsfbfsl{a}$', u'\u2465': '{\\ding{177}}', u'\u2462': '{\\ding{174}}', u'\xe5': '{\\aa}', u'\u0164': '{\\v{T}}', u'\U0001d7eb': '$\\mathsf{9}$', u'\U0001d4ed': '$\\mathmit{d}$', u'\U0001d56c': '$\\mathslbb{A}$', u'\u0115': '{\\u{e}}', u'\U0001d7ec': '$\\mathsfbf{0}$', u'\u2a7e': '$\\geqslant$', u'\U0001d601': '$\\mathsfbf{t}$', u'\U0001d780': '$\\mathsfbf{\\Rho}$', u'\U0001d482': '$\\mathbit{a}$', u'\u210f': '$\\hslash$', u'\u228e': '$\\uplus$', u'\u2994': '$\\ElsevierGlyph{E291}$', u'\U0001d517': '$\\mathfrak{T}$', u'\U0001d696': '$\\mathtt{m}$', u'\u27a0': '{\\ding{224}}', u'\u2323': '$\\smile$', u'\u04a2': '{\\cyrchar\\CYRNDSC}', u'\u2025': '{..}', u'\U0001d72b': '$\\mathbit{\\Pi}$', u'\U0001d42d': '$\\mathbf{t}$', u'\U0001d5ac': '$\\mathsf{M}$', u'\u03b8': '{\\texttheta}', u'\xba': '{\\textordmasculine}', u'\U0001d641': '$\\mathsfbfsl{F}$', u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', u'\U0001d4c2': '$\\mathscr{m}$', u'\u274b': '{\\ding{107}}', u'\u044d': '{\\cyrchar\\cyrerev}', u'\u014f': '{\\u{o}}', u'\u22ce': '$\\curlyvee$', u'\U0001d557': '$\\mathbb{f}$', u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', u'\U0001d76b': '$\\mathsfbf{\\Phi}$', u'\u27a6': '{\\ding{230}}', u'\U0001d46d': '$\\mathbit{F}$', u'\U0001d5ec': '$\\mathsfbf{Y}$', u'\u2252': '$\\fallingdotseq$', u'\u2279': '$\\notgreaterless$', u'\u0119': '{\\k{e}}', u'\xfa': "{\\'{u}}", u'\u01aa': '$\\eth$', u'\U0001d589': '$\\mathslbb{d}$', u'\U0001d408': '$\\mathbf{I}$', u'\U0001d70a': '$O$', u'\u2191': '$\\uparrow$', u'\u2010': '{-}', u'\u0493': '{\\cyrchar\\cyrghcrs}', u'\U0001d69f': '$\\mathtt{v}$', u'\U0001d51e': '$\\mathfrak{a}$', u'\u029e': '{\\textturnk}', u'\u02a7': '$\\Elztesh$', u'\u2126': '$\\Omega$', u'\u0428': '{\\cyrchar\\CYRSH}', u'\u272a': '{\\ding{74}}', u'\U0001d4b3': '$\\mathscr{X}$', u'\U0001d7b5': '$M$', u'\U0001d634': '$\\mathsfsl{s}$', u'\u2ab7': '$\\precapprox$', u'\u2936': '$\\ElsevierGlyph{E21A}$', u'\u0135': '{\\^{\\j}}', u'\xbb': '{\\guillemotright}', u'\u03bd': '$\\nu$', u'\u223c': '$\\sim$', u'\U0001d5c9': '$\\mathsf{p}$', u'\U0001d448': '$\\mathsl{U}$', u'\U0001d74a': '$\\mathbit{\\Upsilon}$', u'\u21d1': '$\\Uparrow$', u'\U0001d6df': '{\\mathbf{\\phi}}', u'\U0001d55e': '$\\mathbb{m}$', u'\u22e7': '$\\gnsim$', u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', u'\U0001d4f3': '$\\mathmit{j}$', u'\U0001d7f5': '$\\mathsfbf{9}$', u'\U0001d674': '$\\mathtt{E}$', u'\xfb': '{\\^{u}}', u'\u027c': '$\\Elzrl$', u'\U0001d509': '$\\mathfrak{F}$', u'\U0001d488': '$\\mathbit{g}$', u'\U0001d78a': '$\\in$', u'\u2a8c': '$\\gtreqqless$', u'\u2111': '$\\mathfrak{I}$', u'\u0413': '{\\cyrchar\\CYRG}', u'\u0392': '$\\Beta$', u'\u2715': '{\\ding{53}}', u'\u301b': '$\\openbracketright$', u'\U0001d61f': '$\\mathsfsl{X}$', u'\U0001d59e': '$\\mathslbb{y}$', u'\u2227': '$\\wedge$', u'\u21a6': '$\\mapsto$', u'\u04a8': '{\\cyrchar\\CYRABHHA}', u'\u27aa': '{\\ding{234}}', u'\U0001d433': '$\\mathbf{z}$', u'\u0272': '{\\Elzltln}', u'\U0001d735': '$\\mathbit{\\nabla}$', u'\U0001d6b4': '$N$', u'\u29b6': '$\\ElsevierGlyph{E61B}$', u'\u233d': '$\\ElsevierGlyph{E838}$', u'\u02bc': "{'}", u'\u263f': '{\\mercury}', u'\u25be': '$\\blacktriangledown$', u'\u0420': '{\\cyrchar\\CYRR}', u'\U0001d4c8': '$\\mathscr{s}$', u'\u2acc': '$\\supsetneqq$', u'\u0151': '{\\H{o}}', u'\xd0': '{\\DH}', u'\u0453': "{\\cyrchar{\\'\\cyrg}}", u'\u03d2': '$\\Upsilon$', u'\U0001d65f': '$\\mathsfbfsl{j}$', u'\U0001d5de': '$\\mathsfbf{K}$', u'\u2961': '$\\LeftDownTeeVector$', u'\u015a': "{\\'{S}}", u'\u2267': '$\\geqq$', u'\u04e8': '{\\cyrchar\\CYROTLD}', u'\U0001d473': '$\\mathbit{L}$', u'\U0001d775': '$\\mathsfbf{\\Zeta}$', u'\U0001d6f4': '$\\mathsl{\\Sigma}$', u'\u0155': "{\\'{r}}", u'\U0001d489': '$\\mathbit{h}$', u'\U0001d508': '$\\mathfrak{E}$', u'\U0001d60a': '$\\mathsfsl{C}$', u'\u2110': '$\\mathscr{I}$', u'\u2212': '{-}', u'\u2714': '{\\ding{52}}', u'\u012e': '{\\k{I}}', u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', u'\U0001d41e': '$\\mathbf{e}$', u'\u03a7': '$\\Chi$', u'\u2026': '{\\ldots}', u'\u04a9': '{\\cyrchar\\cyrabhha}', u'\U0001d5b3': '$\\mathsf{T}$', u'\U0001d6b5': '$\\mathbf{\\Xi}$', u'\U0001d734': '$\\mathbit{\\Omega}$', u'\u21bb': '$\\circlearrowright$', u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', u'\u043e': '{\\cyrchar\\cyro}', u'\U0001d4c9': '$\\mathscr{t}$', u'\u29cb': '$\\Elzdefas$', u'\U0001d64a': '$\\mathsfbfsl{O}$', u'\xd1': '{\\~{N}}', u'\u0150': '{\\H{O}}', u'\u0252': '$\\Elztrnsa$', u'\U0001d7df': '$\\mathbb{7}$', u'\U0001d45e': '$\\mathsl{q}$', u'\u2960': '$\\LeftUpTeeVector$', u'\u012c': '{\\u{I}}', u'\u04e9': '{\\cyrchar\\cyrotld}', u'\u266a': '{\\eighthnote}', u'\U0001d5f3': '$\\mathsfbf{f}$', u'\u2292': '$\\sqsupseteq$', u'\U0001d6f5': '$\\mathsl{\\Tau}$', u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', u'\u02e8': '{\\tone{22}}', u'\u27ff': '$\\sim\\joinrel\\leadsto$', u'\u047e': '{\\cyrchar\\CYROT}', u'\U0001d409': '$\\mathbf{J}$', u'\U0001d588': '$\\mathslbb{c}$', u'\U0001d68a': '$\\mathtt{a}$', u'\u2a0d': '$\\ElzCint$', u'\u2190': '$\\leftarrow$', u'\u0292': '$\\Elzyogh$', u'\u2794': '{\\ding{212}}', u'\u011b': '{\\v{e}}', u'\U0001d71f': '$\\mathbit{\\Delta}$', u'\U0001d49e': '$\\mathscr{C}$', u'\u29a0': '$\\Elzlpargt$', u'\u2aa2': '$\\NestedGreaterGreater$', u'\u0327': '{\\c}', u'\xa6': '{\\textbrokenbar}', u'\u0429': '{\\cyrchar\\CYRSHCH}', u'\u0273': '$\\Elzrtln$', u'\U0001d533': '$\\mathfrak{v}$', u'\U0001d635': '$\\mathsfsl{t}$', u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', u'\u013b': '{\\c{L}}', u'\u223d': '$\\backsim$', u'\u03bc': '$\\mu$', u'\u273f': '{\\ding{95}}', u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', u'\U0001d449': '$\\mathsl{V}$', u'\U0001d5c8': '$\\mathsf{o}$', u'\U0001d6ca': '$\\mathbf{\\Iota}$', u'\u21d0': '$\\Leftarrow$', u'\u02d2': '$\\Elzsbrhr$', u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', u'\U0001d4de': '$\\mathmit{O}$', u'\u0261': '{g}', u'\xe6': '{\\ae}', u'\u0469': '{\\cyrchar\\cyriotlyus}', u'\u25e8': '$\\Elzsqfr$', u'\U0001d573': '$\\mathslbb{H}$', u'\U0001d675': '$\\mathtt{F}$', u'\U0001d7f4': '$\\mathsfbf{8}$', u'\u017b': '{\\.{Z}}', u'\u027d': '$\\Elzrtlr$', u'\u277f': '{\\ding{191}}', u'\U0001d789': '$\\partial$', u'\U0001d608': '$\\mathsfsl{A}$', u'\u2a8b': '$\\lesseqqgtr$', u'\U0001d50a': '$\\mathfrak{G}$', u'\u0391': '$\\Alpha$', u'\u2210': '$\\coprod$', u'\u2112': '$\\mathscr{L}$', u'\u0414': '{\\cyrchar\\CYRD}', u'\U0001d49f': '$\\mathscr{D}$', u'\U0001d71e': '$\\mathbit{\\Gamma}$', u'\xa7': '{\\textsection}', u'\u27a9': '{\\ding{233}}', u'\U0001d6b3': '$M$', u'\U0001d5b5': '$\\mathsf{V}$', u'\U0001d434': '$\\mathsl{A}$', u'\u0308': '{\\"}', u'\u22bb': '$\\veebar$', u'\u21bd': '$\\leftharpoondown$', u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', u'\u273e': '{\\ding{94}}', u'\u0460': '{\\cyrchar\\CYROMEGA}', u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', u'\U0001d648': '$\\mathsfbfsl{M}$', u'\u2acb': '$\\subsetneqq$', u'\U0001d54a': '$\\mathbb{S}$', u'\u03d1': '{\\textvartheta}', u'\u0250': '$\\Elztrna$', u'\u0152': '{\\OE}', u'\u0454': '{\\cyrchar\\cyrie}', u'\U0001d4df': '$\\mathmit{P}$', u'\u0264': '$\\Elzpbgam$', u'\xe7': '{\\c{c}}', u'\U0001d710': '$\\mathsl{\\Upsilon}$', u'\u0102': '{\\u{A}}', u'\U0001d6f3': '{\\mathsl{\\vartheta}}', u'\U0001d5f5': '$\\mathsfbf{h}$', u'\U0001d474': '$\\mathbit{M}$', u'\u277e': '{\\ding{190}}', u'\ufb01': '{fi}', u'\U0001d709': '$\\mathsl{\\Xi}$', u'\U0001d688': '$\\mathtt{Y}$', u'\U0001d58a': '$\\mathslbb{e}$', u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', u'\u0290': '$\\Elzrtlz$', u'\u2192': '$\\rightarrow$', u'\u0494': '{\\cyrchar\\CYRGHK}', u'\u0129': '{\\~{\\i}}', u'\U0001d41f': '$\\mathbf{f}$', u'\U0001d79e': '$O$', u'\u03a6': '$\\Phi$', u'\u2729': '{\\ding{73}}', u'\u25aa': '$\\blacksquare$', u'\U0001d633': '$\\mathsfsl{r}$', u'\U0001d535': '$\\mathfrak{x}$', u'\U0001d4b4': '$\\mathscr{Y}$', u'\u223b': '$\\homothetic$', u'\u013d': '{\\v{L}}', u'\xbc': '{\\textonequarter}', u'\u043f': '{\\cyrchar\\cyrp}', u'\u27be': '{\\ding{254}}', u'\U0001d749': '$\\mathbit{\\Tau}$', u'\U0001d6c8': '$\\mathbf{\\Eta}$', u'\U0001d5ca': '$\\mathsf{q}$', u'\u22d0': '$\\Subset$', u'\u2653': '{\\pisces}', u'\u21d2': '$\\Rightarrow$', u'\u04d4': '{\\cyrchar\\CYRAE}', u'\U0001d45f': '$\\mathsl{r}$', u'\U0001d7de': '$\\mathbb{6}$', u'\u25ea': '$\\Elzsqfse$', u'\U0001d673': '$\\mathtt{D}$', u'\u22d2': '$\\Cap$', u'\U0001d575': '$\\mathslbb{J}$', u'\U0001d4f4': '$\\mathmit{k}$', u'\u027b': '$\\Elzrttrnr$', u'\u017d': '{\\v{Z}}', u'\xfc': '{\\"{u}}', u'\u047f': '{\\cyrchar\\cyrot}', u'\ufb00': '{ff}', u'\U0001d689': '$\\mathtt{Z}$', u'\U0001d708': '$N$', u'\U0001d40a': '$\\mathbf{K}$', u'\u2291': '$\\sqsubseteq$', u'\u2793': '{\\ding{211}}', u'\u0495': '{\\cyrchar\\cyrghk}', u'\u015b': "{\\'{s}}", u'\U0001d59f': '$\\mathslbb{z}$', u'\U0001d61e': '$\\mathsfsl{W}$', u'\u2aa1': '$\\NestedLessLess$', u'\u2226': '$\\nparallel$', u'\u042a': '{\\cyrchar\\CYRHRDSN}', u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', u'\U0001d4b5': '$\\mathscr{Z}$', u'\U0001d534': '$\\mathfrak{w}$', u'\u03bb': '$\\lambda$', u'\xbd': '{\\textonehalf}', u'\u013c': '{\\c{l}}', u'\u25bf': '$\\triangledown$', u'\u263e': '{\\rightmoon}', u'\U0001d6c9': '$\\mathbf{\\theta}$', u'\U0001d748': '$\\mathbit{\\Sigma}$', u'\U0001d44a': '$\\mathsl{W}$', u'\u02d1': '$\\Elzhlmrk$', u'\u04d5': '{\\cyrchar\\cyrae}', u'\U0001d5df': '$\\mathsfbf{L}$', u'\U0001d65e': '$\\mathsfbfsl{i}$', u'\u2266': '$\\leqq$', u'\u046a': '{\\cyrchar\\CYRBYUS}', u'\u2469': '{\\ding{181}}', u'\U0001d7f3': '$\\mathsfbf{7}$', u'\U0001d4f5': '$\\mathmit{l}$', u'\U0001d574': '$\\mathslbb{I}$', u'\xfd': "{\\'{y}}", u'\u017c': '{\\.{z}}', u'\U0001d609': '$\\mathsfsl{B}$', u'\U0001d788': '$\\mathsfbf{\\Omega}$', u'\U0001d48a': '$\\mathbit{i}$', u'\u2211': '$\\sum$', u'\u0390': '$\\acute{\\ddot{\\iota}}$', u'\u2713': '{\\ding{51}}', u'\u0415': '{\\cyrchar\\CYRE}', u'\U0001d51f': '$\\mathfrak{b}$', u'\U0001d69e': '$\\mathtt{u}$', u'\u0127': '$\\Elzxh$', u'\u27a8': '{\\ding{232}}', u'\u04aa': '{\\cyrchar\\CYRSDSC}', u'\U0001d733': '$\\mathbit{\\Psi}$', u'\U0001d435': '$\\mathsl{B}$', u'\U0001d5b4': '$\\mathsf{U}$', u'\u2937': '$\\ElsevierGlyph{E219}$', u'\u2ab6': '$\\succneqq$', u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', u'\u21bc': '$\\leftharpoonup$', u'\U0001d649': '$\\mathsfbfsl{N}$', u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', u'\U0001d4ca': '$\\mathscr{u}$', u'\u2251': '$\\doteqdot$', u'\u03d0': '{\\Pisymbol{ppi022}{87}}', u'\xd2': '{\\`{O}}', u'\u0455': '{\\cyrchar\\cyrdze}', u'\U0001d55f': '$\\mathbb{n}$', u'\u02a4': '$\\Elzdyogh$', u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', u'\u22e6': '$\\lnsim$', u'\u2669': '{\\quarternote}', u'\u227d': '$\\succcurlyeq$', u'\U0001d773': '$\\mathsfbf{\\Delta}$', u'\U0001d475': '$\\mathbit{N}$', u'\U0001d5f4': '$\\mathsfbf{g}$', u'\u2af6': '$\\Elztdcol$', u'\u0154': "{\\'{R}}", u'\U0001d687': '$\\mathtt{X}$', u'\u0410': '{\\cyrchar\\CYRA}', u'\u2712': '{\\ding{50}}', u'\u0395': '$\\Epsilon$', u'\u2214': '$\\dotplus$', u'\U0001d49b': '$\\mathbit{z}$', u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', u'\U0001d61c': '$\\mathsfsl{U}$', u'\u21a9': '$\\hookleftarrow$', u'\u032a': '$\\Elzsbbrg$', u'\U0001d5b1': '$\\mathsf{R}$', u'\U0001d430': '$\\mathbf{w}$', u'\U0001d732': '$\\mathbit{\\Chi}$', u'\u04bb': '{\\cyrchar\\cyrshha}', u'\u27bd': '{\\ding{253}}', u'\u013e': '{\\v{l}}', u'\U0001d6c7': '$\\mathbf{\\Zeta}$', u'\U0001d546': '$\\mathbb{O}$', u'\u294e': '$\\LeftRightVector$', u'\u25d1': '$\\Elzcirfr$', u'\xd3': "{\\'{O}}", u'\u2752': '{\\ding{114}}', u'\u03d5': '$\\phi$', u'\u0254': '$\\Elzopeno$', u'\U0001d4db': '$\\mathmit{L}$', u'\U0001d7dd': '$\\mathbb{5}$', u'\U0001d65c': '$\\mathsfbfsl{g}$', u'\u2666': '{\\ding{169}}', u'\U0001d5f1': '$\\mathsfbf{d}$', u'\U0001d470': '$\\mathbit{I}$', u'\U0001d772': '$\\mathsfbf{\\Gamma}$', u'\u017e': '{\\v{z}}', u'\U0001d607': '$\\mathsfbf{z}$', u'\U0001d586': '$\\mathslbb{a}$', u'\u2a0f': '$\\clockoint$', u'\u0490': '{\\cyrchar\\CYRGUP}', u'\u2013': '{\\textendash}', u'\u2792': '{\\ding{210}}', u'\u2315': '$\\recorder$', u'\u2294': '$\\sqcup$', u'\U0001d41b': '$\\mathbf{b}$', u'\U0001d71d': '$\\mathbit{\\Beta}$', u'\U0001d69c': '$\\mathtt{s}$', u'\u2129': '$\\ElsevierGlyph{2129}$', u'\xa8': '{\\textasciidieresis}', u'\u03aa': '$\\mathrm{\\ddot{I}}$', u'\U0001d531': '$\\mathfrak{t}$', u'\U0001d4b0': '$\\mathscr{U}$', u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', u'\u043b': '{\\cyrchar\\cyrl}', u'\u273d': '{\\ding{93}}', u'\u21be': '$\\upharpoonright$', u'\U0001d647': '$\\mathsfbfsl{L}$', u'\U0001d5c6': '$\\mathsf{m}$', u'\u02d4': '$\\Elzrais$', u'\U0001d45b': '$\\mathsl{n}$', u'\U0001d75d': '$\\mathsfbf{\\Theta}$', u'\U0001d6dc': '$\\in$', u'\u20a7': '{\\ensuremath{\\Elzpes}}', u'\u0169': '{\\~{u}}', u'\xe8': '{\\`{e}}', u'\U0001d571': '$\\mathslbb{F}$', u'\U0001d4f0': '$\\mathmit{g}$', u'\U0001d7f2': '$\\mathsfbf{6}$', u'\u047b': '{\\cyrchar\\cyromegarnd}', u'\u027e': '$\\Elzfhr$', u'\u277d': '{\\ding{189}}', u'\u227f': '$\\succapprox$', u'\ufb04': '{ffl}', u'\U0001d787': '$\\mathsfbf{\\Psi}$', u'\U0001d406': '$\\mathbf{G}$', u'\u0112': '{\\={E}}', u'\u0159': '{\\v{r}}', u'\u2193': '$\\downarrow$', u'\u0295': '$\\Elzreglst$', u'\U0001d59b': '$\\mathslbb{v}$', u'\U0001d69d': '$\\mathtt{t}$', u'\U0001d71c': '$\\mathbit{\\Alpha}$', u'\u23b1': '$\\rmoustache$', u'\u27a7': '{\\ding{231}}', u'\u0426': '{\\cyrchar\\CYRC}', u'\xa9': '{\\textcopyright}', u'\u2128': '$\\mathfrak{Z}$', u'\u222a': '$\\cup$', u'\U0001d4b1': '$\\mathscr{V}$', u'\U0001d530': '$\\mathfrak{s}$', u'\U0001d632': '$\\mathsfsl{q}$', u'\u273c': '{\\ding{92}}', u'\u03bf': '$o$', u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', u'\U0001d446': '$\\mathsl{S}$', u'\u21d3': '$\\Downarrow$', u'\u2652': '{\\aquarius}', u'\u02d5': '$\\Elzlow$', u'\U0001d5db': '$\\mathsfbf{H}$', u'\U0001d6dd': '{\\mathbf{\\vartheta}}', u'\U0001d75c': '$\\mathsfbf{\\Eta}$', u'\u2466': '{\\ding{178}}', u'\xe9': "{\\'{e}}", u'\u0168': '{\\~{U}}', u'\u226a': '$\\ll$', u'\U0001d4f1': '$\\mathmit{h}$', u'\U0001d570': '$\\mathslbb{E}$', u'\U0001d672': '$\\mathtt{C}$', u'\u277c': '{\\ding{188}}', u'\U0001d707': '$M$', u'\U0001d486': '$\\mathbit{e}$', u'\u0411': '{\\cyrchar\\CYRB}', u'\u2113': '$\\mathscr{l}$', u'\u026f': '$\\Elztrnm$', u'\U0001d51b': '$\\mathfrak{X}$', u'\U0001d61d': '$\\mathsfsl{V}$', u'\U0001d79c': '$N$', u'\u2923': '$\\ElsevierGlyph{E20C}$', u'\u2a25': '$\\ElsevierGlyph{E25A}$', u'\u2727': '{\\ding{71}}', u'\u04a6': '{\\cyrchar\\CYRPHK}', u'\u22aa': '$\\Vvdash$', u'\U0001d431': '$\\mathbf{x}$', u'\U0001d5b0': '$\\mathsf{Q}$', u'\U0001d6b2': '$\\mathbf{\\Lambda}$', u'\u2aba': '$\\succnapprox$', u'\u27bc': '{\\ding{252}}', u'\xbe': '{\\textthreequarters}', u'\U0001d747': '$\\mathbit{\\varsigma}$', u'\U0001d4c6': '$\\mathscr{q}$', u'\u0451': '{\\cyrchar\\cyryo}', u'\u25d0': '$\\Elzcirfl$', u'\u2153': '$\\textfrac{1}{3}$', u'\u2255': '$=:$', u'\U0001d55b': '$\\mathbb{j}$', u'\U0001d65d': '$\\mathsfbfsl{h}$', u'\U0001d7dc': '$\\mathbb{4}$', u'\u2767': '{\\ding{167}}', u'\u2250': '$\\doteq$', u'\u22ea': '$\\ntriangleleft$', u'\U0001d471': '$\\mathbit{J}$', u'\U0001d5f0': '$\\mathsfbf{c}$', u'\U0001d6f2': '$\\mathsl{\\Rho}$', u'\u27fc': '$\\longmapsto$', u'\xfe': '{\\th}', u'\U0001d487': '$\\mathbit{f}$', u'\U0001d706': '$\\mathsl{\\Lambda}$', u'\u2791': '{\\ding{209}}', u'\u2293': '$\\sqcap$', u'\u2195': '$\\updownarrow$', u'\u2014': '{\\textemdash}', u'\U0001d69b': '$\\mathtt{r}$', u'\U0001d59d': '$\\mathslbb{x}$', u'\U0001d41c': '$\\mathbf{c}$', u'\u04a7': '{\\cyrchar\\cyrphk}', u'\u2726': '{\\ding{70}}', u'\u03a9': '$\\Omega$', u'\u2228': '$\\vee$', u'\u012a': '{\\={I}}', u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', u'\U0001d630': '$\\mathsfsl{o}$', u'\U0001d532': '$\\mathfrak{u}$', u'\U0001d75e': '$\\mathsfbf{\\Iota}$', u'\u25bd': '$\\bigtriangledown$', u'\u043c': '{\\cyrchar\\cyrm}', u'\xbf': '{\\textquestiondown}', u'\U0001d4c7': '$\\mathscr{r}$', u'\U0001d746': '$\\mathbit{\\Rho}$', u'\u2650': '{\\sagittarius}', u'\u22d3': '$\\Cup$', u'\u21d5': '$\\Updownarrow$', u'\U0001d6db': '$\\partial$', u'\U0001d5dd': '$\\mathsfbf{J}$', u'\U0001d45c': '$\\mathsl{o}$', u'\u2766': '{\\ding{166}}', u'\u2268': '$\\lneqq$', u'\u016a': '{\\={U}}', u'\U0001d7f1': '$\\mathsfbf{5}$', u'\U0001d670': '$\\mathtt{A}$', u'\U0001d572': '$\\mathslbb{G}$', u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', u'\xff': '{\\"{y}}', u'\U0001d407': '$\\mathbf{H}$', u'\U0001d786': '$\\mathsfbf{\\Chi}$', u'\u2711': '{\\ding{49}}', u'\u2213': '$\\mp$', u'\u2115': '$\\mathbb{N}$', u'\u0118': '{\\k{E}}', u'\U0001d61b': '$\\mathsfsl{T}$', u'\U0001d49c': '$\\mathscr{A}$', u'\u2925': '$\\ElsevierGlyph{E20B}$', u'\u0427': '{\\cyrchar\\CYRCH}', u'\u2270': '$\\not\\leq$', u'\u2329': '$\\langle$', u'\u22a8': '$\\forcesextra$', u'\u21aa': '$\\hookrightarrow$', u'\U0001d731': '$\\mathbit{\\Phi}$', u'\U0001d6b0': '$\\mathbf{\\Iota}$', u'\U0001d5b2': '$\\mathsf{S}$', u'\u2ab8': '$\\succapprox$', u'\u04bc': '{\\cyrchar\\CYRABHCH}', u'\u03be': '$\\xi$', u'\U0001d447': '$\\mathsl{T}$', u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', u'\u2751': '{\\ding{113}}', u'\u2253': '$\\risingdotseq$', u'\u25d2': '$\\Elzcirfb$', u'\u2155': '$\\textfrac{1}{5}$', u'\xd4': '{\\^{O}}', u'\U0001d65b': '$\\mathsfbfsl{f}$', u'\U0001d55d': '$\\mathbb{l}$', u'\U0001d4dc': '$\\mathmit{M}$', u'\u2a63': '$\\ElsevierGlyph{225A}$', u'\u2467': '{\\ding{179}}', u'\U0001d7d0': '$\\mathbf{2}$', u'\u22e8': '$\\precedesnotsimilar$', u'\U0001d771': '$\\mathsfbf{\\Beta}$', u'\U0001d6f0': '$O$', u'\U0001d5f2': '$\\mathsfbf{e}$', u'\U0001d587': '$\\mathslbb{b}$', u'\U0001d606': '$\\mathsfbf{y}$', u'\u300a': '$\\ElsevierGlyph{300A}$', u'\u2710': '{\\ding{48}}', u'\u0393': '$\\Gamma$', u'\u0412': '{\\cyrchar\\CYRV}', u'\u0114': '{\\u{E}}', u'\U0001d79b': '$M$', u'\U0001d51c': '$\\mathfrak{Y}$', u'\u2924': '$\\ElsevierGlyph{E20D}$', u'\u22a9': '$\\Vdash$', u'\u0328': '{\\k}', u'\U0001d6b1': '$\\mathbf{\\Kappa}$', u'\U0001d730': '$\\mathbit{\\Upsilon}$', u'\U0001d432': '$\\mathbf{y}$', u'\u2ab9': '$\\precnapprox$', u'\u27bb': '{\\ding{251}}', u'\u04bd': '{\\cyrchar\\cyrabhch}', u'\u21bf': '$\\upharpoonleft$', u'\u223e': '$\\lazysinv$', u'\U0001d5c7': '$\\mathsf{n}$', u'\U0001d646': '$\\mathsfbfsl{K}$', u'\u29cf': '$\\LeftTriangleBar$', u'\u2750': '{\\ding{112}}', u'\u0452': '{\\cyrchar\\cyrdje}', u'\xd5': '{\\~{O}}', u'\u2154': '$\\textfrac{2}{3}$', u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', u'\U0001d7db': '$\\mathbb{3}$', u'\U0001d4dd': '$\\mathmit{N}$', u'\U0001d55c': '$\\mathbb{k}$', u'\u25e7': '$\\Elzsqfl$', u'\u2290': '$\\sqsupset$', u'\u22e9': '$\\succnsim$', u'\U0001d6f1': '$\\mathsl{\\Pi}$', u'\U0001d770': '$\\mathsfbf{\\Alpha}$', u'\U0001d472': '$\\mathbit{K}$', u'\u227e': '$\\precapprox$', u'\ufb03': '{ffi}', u'\U0001d507': '$\\mathfrak{D}$', u'\U0001d686': '$\\mathtt{W}$', u'\u02d9': '{\\textperiodcentered}', u'\u2790': '{\\ding{208}}', u'\u0492': '{\\cyrchar\\CYRGHCRS}', u'\u2015': '{\\rule{1em}{1pt}}', u'\u2194': '$\\leftrightarrow$', u'\U0001d71b': '{\\mathsl{\\varpi}}', u'\U0001d41d': '$\\mathbf{d}$', u'\U0001d59c': '$\\mathslbb{w}$', u'\u2229': '$\\cap$', u'\u03a8': '$\\Psi$', u'\xaa': '{\\textordfeminine}', u'\U0001d631': '$\\mathsfsl{p}$', u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', u'\U0001d4b2': '$\\mathscr{W}$', u'\u273b': '{\\ding{91}}', u'\u043d': '{\\cyrchar\\cyrn}', u'\u25bc': '{\\ding{116}}', u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', u'\u22be': '$\\rightanglearc$', u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', u'\u294f': '$\\RightUpDownVector$', u'\u2651': '{\\capricornus}', u'\u21d4': '$\\Leftrightarrow$', u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', u'\U0001d45d': '$\\mathsl{p}$', u'\U0001d5dc': '$\\mathsfbf{I}$', u'\u2269': '$\\gneqq$', u'\xea': '{\\^{e}}', u'\U0001d671': '$\\mathtt{B}$', u'\U0001d7f0': '$\\mathsfbf{4}$', u'\U0001d4f2': '$\\mathmit{i}$', u'\u277b': '{\\ding{187}}', u'\u047d': '{\\cyrchar\\cyromegatitlo}'} -- cgit v1.2.1 From c00d3aed224c4bf24d65dbf11533ddccb5935c09 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 21:42:41 +0000 Subject: restored original "Id" keyword from unicode.xml git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3462 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/unicode_latex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/unicode_latex.py b/docutils/writers/unicode_latex.py index 35f671ced..b311574d2 100644 --- a/docutils/writers/unicode_latex.py +++ b/docutils/writers/unicode_latex.py @@ -14,7 +14,7 @@ # Original copyright notice of unicode.xml follows: # # -# $Id$ +# $Id: unicode.xml,v 1.5 2003/12/08 15:02:15 davidc Exp $ # # Copyright David Carlisle, Sebastian Rahtz 1998-2003 # -- cgit v1.2.1 From cab1e343e4d2c78b1772aefcda352deb37514dbe Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 21:47:32 +0000 Subject: updated new latex writer to use unicode_latex map; this should have been the log message to r3460... git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3463 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 2 +- tools/stylesheets/latex.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index c046d6d30..791eedbe9 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -261,7 +261,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): #special_map = {'\n': ' ', '\r': ' ', '\t': ' ', '\v': ' ', '\f': ' '} # Get comprehensive Unicode map. - from unimap import map as unicode_map + from unicode_latex import unicode_map # Fix problems with unimap.py. unicode_map.update({ # We have AE or T1 encoding, so "``" etc. work. The macros diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 64d56ac59..f7991e875 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -420,7 +420,7 @@ \Dprovidelength{\Dlistspacing}{0.8\baselineskip} -% Current hardcoded. +% Currently hardcoded. \usepackage[latin1]{inputenc} \providecommand{\Dsetlistrightmargin}{% -- cgit v1.2.1 From 2052f8691d2367a4280276aac3ea874c666eb23e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 22:09:55 +0000 Subject: improved and commented settings_defaults git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3464 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 791eedbe9..dc89e18d6 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -30,7 +30,6 @@ class Writer(writers.Writer): settings_spec = ( 'LaTeX-Specific Options', - 'The LaTeX "--output-encoding" default is "latin-1:strict". ' 'Note that this LaTeX writer is still EXPERIMENTAL.', (('Specify a stylesheet file. The path is used verbatim to include ' 'the file. Overrides --stylesheet-path.', @@ -50,12 +49,18 @@ class Writer(writers.Writer): {'metavar': '<file>', 'overrides': 'user_stylesheet'}) ),) - settings_defaults = {'output_encoding': 'latin-1', - 'trim_footnote_reference_space': 1, - # Currently unsupported: - 'docinfo_xform': 0, - # During development: - 'traceback': 1} + settings_defaults = { + # Many Unicode characters are provided by unicode_latex.py. + 'output_encoding': 'ascii', + 'output_encoding_error_handler': 'strict', + # Since we are using superscript footnotes, it is necessary to + # trim whitespace in front of footnote references. + 'trim_footnote_reference_space': 1, + # Currently unsupported: + 'docinfo_xform': 0, + # During development: + 'traceback': 1 + } relative_path_settings = ('stylesheet_path',) -- cgit v1.2.1 From 5afbd171b3f913573b2353db912127c37af47694 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 10 Jun 2005 22:14:49 +0000 Subject: removed input encoding from LaTeX stylesheet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3465 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index f7991e875..7f176af7c 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -420,9 +420,6 @@ \Dprovidelength{\Dlistspacing}{0.8\baselineskip} -% Currently hardcoded. -\usepackage[latin1]{inputenc} - \providecommand{\Dsetlistrightmargin}{% \ifthenelse{\lengthtest{\linewidth>10em}}{% % Equal margins. -- cgit v1.2.1 From ac610390f0e3da3f10f8faf06017062c862c6e60 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 Jun 2005 03:17:27 +0000 Subject: removed implemented idea git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3466 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5d6186b2a..a806bc0cf 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1192,9 +1192,6 @@ when used in a document. - _`misc.include`: - - "encoding" option? Take default from runtime settings. Use - Input component to read it in? - - Option to select a range of lines? - Option to label lines? -- cgit v1.2.1 From 101c0cc376ffc7cf455b60b77ccf902f5dd35214 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 Jun 2005 03:18:08 +0000 Subject: added header comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3467 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/unicode2rstsubs.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/unicode2rstsubs.py b/tools/unicode2rstsubs.py index 20f88153d..bc86fe014 100755 --- a/tools/unicode2rstsubs.py +++ b/tools/unicode2rstsubs.py @@ -1,7 +1,7 @@ #! /usr/bin/env python # Author: David Goodger -# Contact: goodger@users.sourceforge.net +# Contact: goodger@python.org # Revision: $Revision$ # Date: $Date$ # Copyright: This program has been placed in the public domain. @@ -68,6 +68,14 @@ class CharacterEntitySetExtractor: unwanted_entity_sets = ['stix', # unknown, buggy set 'predefined'] + header = """\ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available at + <http://www.w3.org/2003/entities/xml/unicode.xml>. + Processed by unicode2rstsubs.py + (part of Docutils, http://docutils.sourceforge.net). +""" + def __init__(self, infile): self.infile = infile """Input unicode.xml file.""" @@ -165,6 +173,7 @@ class CharacterEntitySetExtractor: outname = set_name + '.txt' outfile = open(outname, 'w') print 'writing file "%s"' % outname + print >>outfile, self.header set = self.sets[set_name] entities = [(e.lower(), e) for e in set.keys()] entities.sort() -- cgit v1.2.1 From fef6420bfc5dd5707c417cf68e6404f316833bd2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 11 Jun 2005 23:03:19 +0000 Subject: moved \vspace out of image implementation so that when adding borders around images the \vspace is outside the border git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3468 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 7f176af7c..973414291 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -881,6 +881,8 @@ \providecommand{\Dinsidehalign}{false} +\newsavebox{\Dalignedimagebox} +\Dprovidelength{\Dalignedimagewidth}{0pt} \providecommand{\Dhalign}[2]{% % Horizontally align the contents to the left or right so that the % text flows around it. @@ -890,7 +892,22 @@ \renewcommand{\Dinsidehalign}{true}% % For some obscure reason \parpic consumes some vertical space. \vspace{-3pt}% - \parpic[#1]{#2}% + % Now we do something *really* ugly, but this enables us to wrap the + % image in a minipage while still allowing tight frames when + % class=border (see \DNimageCborder). + \sbox{\Dalignedimagebox}{#2}% + \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}% + % Now we do something *really* ugly. + \parpic[#1]{% + \begin{minipage}[b]{\Dalignedimagewidth}% + % Compensate for previously added space, but not entirely. + \vspace*{2.0pt}% + \vspace*{\Dfloatimagetopmargin}% + \usebox{\Dalignedimagebox}% + \vspace*{1.5pt}% + \vspace*{\Dfloatimagebottommargin}% + \end{minipage}% + }% \renewcommand{\Dinsidehalign}{false}% } @@ -944,16 +961,8 @@ % Need to make bottom-alignment dependent on align attribute (add % functional test first). \begin{minipage}[b]{#1}% - \ifthenelse{\equal{\Dinsidehalign}{true}}{ - % Compensate for space previously added in \Dhalign, but not - % entirely. - \vspace*{2.5pt}% - \vspace*{\Dfloatimagetopmargin}% - }{}% \includegraphics[width=\linewidth,height=\textheight,keepaspectratio]{#2}% \ifthenelse{\equal{\Dinsidehalign}{true}}{% - \vspace*{1.5pt}% - \vspace*{\Dfloatimagebottommargin}% }{}% \end{minipage}% } @@ -985,6 +994,8 @@ \providecommand{\DCborder}[1]{\fbox{#1}} +% No padding between image and border. +\providecommand{\DNimageCborder}[1]{\frame{#1}} % Need to replace with language-specific stuff. Maybe look at -- cgit v1.2.1 From d37a0a8fed7d6df884502b52da032379c5ff067b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 04:20:01 +0000 Subject: removed redundancy with "encoding" option description git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3469 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index a0102f9e1..6ea521ac1 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1197,9 +1197,6 @@ example:: If an included document fragment contains section structure, the title adornments must match those of the master document. -The text encoding of the master input source is used for included -files. - The following options are recognized: ``literal`` : flag (empty) -- cgit v1.2.1 From 138d15373cef34d6390f8f5a3b419088e09776cd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 04:20:35 +0000 Subject: tweaked git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3470 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/unicode2rstsubs.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/unicode2rstsubs.py b/tools/unicode2rstsubs.py index bc86fe014..abc85e48b 100755 --- a/tools/unicode2rstsubs.py +++ b/tools/unicode2rstsubs.py @@ -8,7 +8,7 @@ """ unicode2subfiles.py -- produce character entity files (reSructuredText -substitutions) from the MathML master unicode.xml file. +substitutions) from the W3C master unicode.xml file. This program extracts character entity and entity set information from a unicode.xml file and produces multiple reStructuredText files (in the current @@ -18,8 +18,8 @@ entity set; a second file with a "-wide.txt" suffix is produced if there are wide-Unicode characters in the set. The input file, unicode.xml, is maintained as part of the MathML 2 -Recommentation XML source, and is available at -<http://www.w3.org/2003/entities/xml/unicode.xml>. +Recommentation XML source, and is available from +<http://www.w3.org/2003/entities/xml/>. """ import sys @@ -70,10 +70,10 @@ class CharacterEntitySetExtractor: header = """\ .. This data file has been placed in the public domain. -.. Derived from the Unicode character mappings available at - <http://www.w3.org/2003/entities/xml/unicode.xml>. - Processed by unicode2rstsubs.py - (part of Docutils, http://docutils.sourceforge.net). +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. """ def __init__(self, infile): -- cgit v1.2.1 From ad8ed1d2dabfec3f3f0ab51f03355adc25cdb77d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 05:00:49 +0000 Subject: updated location git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3471 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 6ea521ac1..bdcf3ac1f 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -634,21 +634,6 @@ The following option is recognized: class_ directive below. -Title -===== - -:Directive Type: "title" -:Doctree Element: None. -:Directive Arguments: 1, required (the title text). -:Directive Options: None. -:Directive Content: None. - -The "title" directive specifies the document title as metadata, which -does not become part of the document body. It overrides a -document-supplied title. For example, in HTML output the metadata -document title appears in the title bar of the browser window. - - -------- Tables -------- @@ -1597,6 +1582,23 @@ initial default interpreted text role of the standard reStructuredText parser is "title-reference". +.. _title: + +Metadata Document Title +======================= + +:Directive Type: "title" +:Doctree Element: None. +:Directive Arguments: 1, required (the title text). +:Directive Options: None. +:Directive Content: None. + +The "title" directive specifies the document title as metadata, which +does not become part of the document body. It overrides a +document-supplied title. For example, in HTML output the metadata +document title appears in the title bar of the browser window. + + Restructuredtext-Test-Directive =============================== -- cgit v1.2.1 From 3b7a7200860068db23463a6a4246c19814012ee9 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 16:40:14 +0000 Subject: Added standard data file syntax to the "include" directive. Added docutils/parsers/rst/include/ directory; contains the standard data files, with character entity substitution definition sets as initial contents. Added docs/ref/rst/substitutions.txt: "reStructuredText Standard Substitution Definition Sets". Updated docs, tests, & setup.py. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3472 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 11 + docs/dev/todo.txt | 39 +- docs/index.txt | 2 + docs/ref/rst/directives.txt | 16 +- docs/ref/rst/substitutions.txt | 134 +++++ docutils/parsers/rst/directives/misc.py | 4 + docutils/parsers/rst/include/README.txt | 21 + docutils/parsers/rst/include/docutils.conf | 5 + docutils/parsers/rst/include/isoamsa.txt | 162 ++++++ docutils/parsers/rst/include/isoamsb.txt | 126 +++++ docutils/parsers/rst/include/isoamsc.txt | 29 ++ docutils/parsers/rst/include/isoamsn.txt | 96 ++++ docutils/parsers/rst/include/isoamso.txt | 62 +++ docutils/parsers/rst/include/isoamsr.txt | 191 +++++++ docutils/parsers/rst/include/isobox.txt | 46 ++ docutils/parsers/rst/include/isocyr1.txt | 73 +++ docutils/parsers/rst/include/isocyr2.txt | 32 ++ docutils/parsers/rst/include/isodia.txt | 20 + docutils/parsers/rst/include/isogrk1.txt | 55 ++ docutils/parsers/rst/include/isogrk2.txt | 26 + docutils/parsers/rst/include/isogrk3.txt | 52 ++ docutils/parsers/rst/include/isogrk4-wide.txt | 49 ++ docutils/parsers/rst/include/isogrk4.txt | 8 + docutils/parsers/rst/include/isolat1.txt | 68 +++ docutils/parsers/rst/include/isolat2.txt | 128 +++++ docutils/parsers/rst/include/isomfrk-wide.txt | 58 +++ docutils/parsers/rst/include/isomfrk.txt | 11 + docutils/parsers/rst/include/isomopf-wide.txt | 32 ++ docutils/parsers/rst/include/isomopf.txt | 13 + docutils/parsers/rst/include/isomscr-wide.txt | 58 +++ docutils/parsers/rst/include/isomscr.txt | 17 + docutils/parsers/rst/include/isonum.txt | 82 +++ docutils/parsers/rst/include/isopub.txt | 90 ++++ docutils/parsers/rst/include/isotech.txt | 168 +++++++ docutils/parsers/rst/include/mmlalias.txt | 554 +++++++++++++++++++++ docutils/parsers/rst/include/mmlextra-wide.txt | 113 +++++ docutils/parsers/rst/include/mmlextra.txt | 87 ++++ docutils/parsers/rst/include/xhtml1-lat1.txt | 102 ++++ docutils/parsers/rst/include/xhtml1-special.txt | 37 ++ docutils/parsers/rst/include/xhtml1-symbol.txt | 130 +++++ setup.py | 17 + .../test_rst/test_directives/test_include.py | 40 +- 42 files changed, 3027 insertions(+), 37 deletions(-) create mode 100644 docs/ref/rst/substitutions.txt create mode 100644 docutils/parsers/rst/include/README.txt create mode 100644 docutils/parsers/rst/include/docutils.conf create mode 100644 docutils/parsers/rst/include/isoamsa.txt create mode 100644 docutils/parsers/rst/include/isoamsb.txt create mode 100644 docutils/parsers/rst/include/isoamsc.txt create mode 100644 docutils/parsers/rst/include/isoamsn.txt create mode 100644 docutils/parsers/rst/include/isoamso.txt create mode 100644 docutils/parsers/rst/include/isoamsr.txt create mode 100644 docutils/parsers/rst/include/isobox.txt create mode 100644 docutils/parsers/rst/include/isocyr1.txt create mode 100644 docutils/parsers/rst/include/isocyr2.txt create mode 100644 docutils/parsers/rst/include/isodia.txt create mode 100644 docutils/parsers/rst/include/isogrk1.txt create mode 100644 docutils/parsers/rst/include/isogrk2.txt create mode 100644 docutils/parsers/rst/include/isogrk3.txt create mode 100644 docutils/parsers/rst/include/isogrk4-wide.txt create mode 100644 docutils/parsers/rst/include/isogrk4.txt create mode 100644 docutils/parsers/rst/include/isolat1.txt create mode 100644 docutils/parsers/rst/include/isolat2.txt create mode 100644 docutils/parsers/rst/include/isomfrk-wide.txt create mode 100644 docutils/parsers/rst/include/isomfrk.txt create mode 100644 docutils/parsers/rst/include/isomopf-wide.txt create mode 100644 docutils/parsers/rst/include/isomopf.txt create mode 100644 docutils/parsers/rst/include/isomscr-wide.txt create mode 100644 docutils/parsers/rst/include/isomscr.txt create mode 100644 docutils/parsers/rst/include/isonum.txt create mode 100644 docutils/parsers/rst/include/isopub.txt create mode 100644 docutils/parsers/rst/include/isotech.txt create mode 100644 docutils/parsers/rst/include/mmlalias.txt create mode 100644 docutils/parsers/rst/include/mmlextra-wide.txt create mode 100644 docutils/parsers/rst/include/mmlextra.txt create mode 100644 docutils/parsers/rst/include/xhtml1-lat1.txt create mode 100644 docutils/parsers/rst/include/xhtml1-special.txt create mode 100644 docutils/parsers/rst/include/xhtml1-symbol.txt diff --git a/HISTORY.txt b/HISTORY.txt index da344722a..da7835b6d 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,6 +14,9 @@ Changes Since 0.3.9 =================== +* setup.py: Added installation of data files in + ``docutils/parsers/rst/include/``. + * docutils/__init__.py: - Added ``__version_details__`` attribute to describe code source @@ -24,9 +27,17 @@ Changes Since 0.3.9 - Added validator to tab_width setting, with test. Closes SF bug #1212515, report from Wu Wei. +* docutils/parsers/rst/include/: Directory added to project; contains + standard data files for the "include" directive. Initial contents: + character entity substitution definition sets. + * docutils/parsers/rst/directives/misc.py: - Added the "default-role" and "title" directives. + - Added standard data file syntax to the "include" directive. + +* docs/ref/rst/substitutions.txt: "reStructuredText Standard + Substitution Definition Sets", added to project. Release 0.3.9 (2005-05-26) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a806bc0cf..016388305 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -905,11 +905,6 @@ __ rst/alternatives.html#or-not-to-do * Generalize the "target-notes" directive into a command-line option somehow? See docutils-develop 2003-02-13. -* Include the _`character entity substitution definition files` - `temporarily stored here <http://docutils.sf.net/tmp/charents/>`__, - perhaps in a ``docutils/parsers/rst/includes/`` directory. See - `misc.include`_ below. - * Should ^L (or something else in reST) be defined to mean force/suggest page breaks in whatever output we have? @@ -1196,38 +1191,12 @@ when used in a document. - Option to label lines? - - Default directory for "built-in includes", using the C syntax - ``<name>`` (as in ``#include <name>``)? - - Use C-preprocessor semantics for locating include files? - E.g., ``.. include:: file.txt`` will read another file into - the current one, relative to the current file's directory, - and ``.. include:: <standard>`` will read a standard include - file from ``docutils/include/``. (Should "quotes" be - required around non-standard include files?) - - -- http://sf.net/mailarchive/message.php?msg_id=1938401 - - I now think that ``docutils/parsers/rst/include/`` is a better - place for these files, since they're reStructuredText-specific. - - Keeping standard data files together with the package code makes - sense to me. It seems much less complex to implement than a - separate system data directory, such as ``/usr/share/docutils``. - Any reason a system data directory should be used? How does - Distutils handle data files? - - How about an environment variable, say RSTINCLUDEPATH or - RSTPATH? This could be combined with a setting/option to allow + - How about an environment variable, say RSTINCLUDEPATH or + RSTPATH, for standard includes (as in ``.. include:: <name>``)? + This could be combined with a setting/option to allow user-defined include directories. - For a specific application, see the discussion of `character - entity substitution definition files`_ above. - - Instead of C-include "<syntax>", perhaps a new "include-sys" - directive? - - - Add support for inclusion by URL:: + - Add support for inclusion by URL? :: .. include:: :url: http://www.example.org/inclusion.txt diff --git a/docs/index.txt b/docs/index.txt index 67849d393..c8a933ac7 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -119,6 +119,8 @@ reStructuredText_: * `reStructuredText Markup Specification <ref/rst/restructuredtext.html>`__ * `reStructuredText Directives <ref/rst/directives.html>`__ * `reStructuredText Interpreted Text Roles <ref/rst/roles.html>`__ +* `reStructuredText Standard Substitution Definition Sets + <ref/rst/substitutions.html>`_ Prehistoric: diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index bdcf3ac1f..cf5c20361 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1149,7 +1149,7 @@ Including an External Document Fragment :Directive Type: "include" :Doctree Elements: depend on data being included -:Directive Arguments: One, required. +:Directive Arguments: One, required (path to the file to include). :Directive Options: Possible. :Directive Content: None. @@ -1182,6 +1182,20 @@ example:: If an included document fragment contains section structure, the title adornments must match those of the master document. +Standard data files intended for inclusion in reStructuredText +documents are distributed with the Docutils source code, located in +the "docutils" package in the ``docutils/parsers/rst/include`` +directory. To access these files, use the special syntax for standard +"include" data files, angle brackets around the file name:: + + .. include:: <isonum.txt> + +The current set of standard "include" data files consists of sets of +substitution definitions. See `reStructuredText Standard Substitution +Definition Sets`__ for details of the available standard data files. + +__ substitutions.html + The following options are recognized: ``literal`` : flag (empty) diff --git a/docs/ref/rst/substitutions.txt b/docs/ref/rst/substitutions.txt new file mode 100644 index 000000000..3ddb71123 --- /dev/null +++ b/docs/ref/rst/substitutions.txt @@ -0,0 +1,134 @@ +======================================================== + reStructuredText Standard Substitution Definition Sets +======================================================== +:Author: David Goodger +:Contact: goodger@python.org +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + +.. contents:: + + +The data files described below contain sets of reStructuredText +`substitution definitions`__. They can be included in documents using +the `"include" directive's`__ special syntax for standard data files, +angle brackets around the file name:: + + .. include:: <filename.txt> + +__ restructuredtext.html#substitution-definitions +__ directives.html#include + +The definitions can then be used in documents using `substitution +references`__. For example, the copyright symbol is defined in +``isonum.txt`` as "copy":: + + .. include:: <isonum.txt> + + Copyright |copy| 2003 by John Q. Public, all rights reserved. + +__ restructuredtext.html#substitution-references + +Individual definitions can also be copied from these data files and +pasted into documents. This has two advantages: it removes +dependencies, and it saves processing of unused definitions. However, +multiple substitution definitions add clutter to the document. + +Substitution references require separation from the surrounding text +with whitespace or punctuation. To use a substitution without +intervening whitespace, you can use the disappearing-whitespace escape +sequence, backslash-space:: + + .. include:: isonum.txt + + Copyright |copy| 2003, BogusMegaCorp\ |trade|. + +Custom definitions may use the `"unicode" directive`__. Whitespace is +ignored and removed, effectively sqeezing together the text:: + + .. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN + .. |BogusMegaCorp (TM)| unicode:: BogusMegaCorp U+2122 + .. with trademark sign + + Copyright |copy| 2003, |BogusMegaCorp (TM)|. + +__ directives.html#unicode + +In addition, the "ltrim", "rtrim", and "trim" options may be used with +the "unicode" directive to automatically trim spaces from the left, +right, or both sides (respectively) of substitution references:: + + .. |---| unicode:: U+02014 .. em dash + :trim: + +The individual data files are stored with the Docutils source code in +the "docutils" package, in the ``docutils/parsers/rst/include`` +directory. + + +Character Entity Sets +===================== + +The following files contain substitution definitions corresponding to +XML character entity sets, from the following standards: ISO 8879 & +ISO 9573-13 (combined), MathML, and XHTML1. They were generated by +the ``tools/unicode2rstsubs.py`` program from the input file +unicode.xml__, which is maintained as part of the MathML 2 +Recommentation XML source. + +__ http://www.w3.org/2003/entities/xml/ + +================== ================================================== +Entity Set File Description +================== ================================================== +isoamsa.txt Added Mathematical Symbols: Arrows +isoamsb.txt Added Mathematical Symbols: Binary Operators +isoamsc.txt Added Mathematical Symbols: Delimiters +isoamsn.txt Added Mathematical Symbols: Negated Relations +isoamso.txt Added Mathematical Symbols: Ordinary +isoamsr.txt Added Mathematical Symbols: Relations +isobox.txt Box and Line Drawing +isocyr1.txt Russian Cyrillic +isocyr2.txt Non-Russian Cyrillic +isodia.txt Diacritical Marks +isogrk1.txt Greek Letters +isogrk2.txt Monotoniko Greek +isogrk3.txt Greek Symbols +isogrk4.txt [1]_ Alternative Greek Symbols +isolat1.txt Added Latin 1 +isolat2.txt Added Latin 2 +isomfrk.txt [1]_ Mathematical Fraktur +isomopf.txt [1]_ Mathematical Openface (Double-struck) +isomscr.txt [1]_ Mathematical Script +isonum.txt Numeric and Special Graphic +isopub.txt Publishing +isotech.txt General Technical +mmlalias.txt MathML aliases for entities from other sets +mmlextra.txt [1]_ Extra names added by MathML +xhtml4-lat1.txt XHTML Latin 1 +xhtml4-special.txt XHTML Special Characters +xhtml4-symbol.txt XHTML Mathematical, Greek and Symbolic Characters +================== ================================================== + +.. [1] There are ``*-wide.txt`` variants for each of these character + entity set files, containing characters outside of the Unicode + basic multilingual plane or BMP (wide-Unicode; code points greater + than U+FFFF). Most pre-built Python distributions are "narrow" and + do not support wide-Unicode characters. Python *can* be built with + wide-Unicode support though; consult the Python build instructions + for details. + +For example, the copyright symbol is defined as the XML character +entity ``©``. The equivalent reStructuredText substitution +reference (defined in both ``isonum.txt`` and ``xhtml1-lat1.txt``) is +``|copy|``. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 798512eeb..af206751f 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -21,6 +21,8 @@ except ImportError: urllib2 = None +standard_include_path = os.path.join(os.path.dirname(states.__file__), 'data') + def include(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Include a reST file as part of the content of this reST file.""" @@ -33,6 +35,8 @@ def include(name, arguments, options, content, lineno, lineno - state_machine.input_offset - 1) source_dir = os.path.dirname(os.path.abspath(source)) path = directives.path(arguments[0]) + if path.startswith('<') and path.endswith('>'): + path = os.path.join(standard_include_path, path[1:-1]) path = os.path.normpath(os.path.join(source_dir, path)) path = utils.relative_path(None, path) encoding = options.get('encoding', state.document.settings.input_encoding) diff --git a/docutils/parsers/rst/include/README.txt b/docutils/parsers/rst/include/README.txt new file mode 100644 index 000000000..af29691be --- /dev/null +++ b/docutils/parsers/rst/include/README.txt @@ -0,0 +1,21 @@ +============================================ + ``docutils/parsers/rst/include`` Directory +============================================ + +The individual data files are stored with the Docutils source code in +the "docutils" package, in the ``docutils/parsers/rst/include`` +directory. + +This directory contains standard data files intended for inclusion in +reStructuredText documents. To access these files, use the "include" +directive with the special syntax for standard "include" data files, +angle brackets around the file name:: + + .. include:: <isonum.txt> + +See the documentation for the `"include" directive`__ and +`reStructuredText Standard Substitution Definition Sets`__ for +details. + +__ http://docutils.sf.net/docs/ref/rst/directives.html#include +__ http://docutils.sf.net/docs/ref/rst/substitutions.html diff --git a/docutils/parsers/rst/include/docutils.conf b/docutils/parsers/rst/include/docutils.conf new file mode 100644 index 000000000..cdce8d629 --- /dev/null +++ b/docutils/parsers/rst/include/docutils.conf @@ -0,0 +1,5 @@ +# This configuration file is to prevent tools/buildhtml.py from +# processing text files in and below this directory. + +[buildhtml application] +prune: . diff --git a/docutils/parsers/rst/include/isoamsa.txt b/docutils/parsers/rst/include/isoamsa.txt new file mode 100644 index 000000000..e6f451800 --- /dev/null +++ b/docutils/parsers/rst/include/isoamsa.txt @@ -0,0 +1,162 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |angzarr| unicode:: U+0237C .. RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +.. |cirmid| unicode:: U+02AEF .. VERTICAL LINE WITH CIRCLE ABOVE +.. |cudarrl| unicode:: U+02938 .. RIGHT-SIDE ARC CLOCKWISE ARROW +.. |cudarrr| unicode:: U+02935 .. ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +.. |cularr| unicode:: U+021B6 .. ANTICLOCKWISE TOP SEMICIRCLE ARROW +.. |cularrp| unicode:: U+0293D .. TOP ARC ANTICLOCKWISE ARROW WITH PLUS +.. |curarr| unicode:: U+021B7 .. CLOCKWISE TOP SEMICIRCLE ARROW +.. |curarrm| unicode:: U+0293C .. TOP ARC CLOCKWISE ARROW WITH MINUS +.. |Darr| unicode:: U+021A1 .. DOWNWARDS TWO HEADED ARROW +.. |dArr| unicode:: U+021D3 .. DOWNWARDS DOUBLE ARROW +.. |darr2| unicode:: U+021CA .. DOWNWARDS PAIRED ARROWS +.. |ddarr| unicode:: U+021CA .. DOWNWARDS PAIRED ARROWS +.. |DDotrahd| unicode:: U+02911 .. RIGHTWARDS ARROW WITH DOTTED STEM +.. |dfisht| unicode:: U+0297F .. DOWN FISH TAIL +.. |dHar| unicode:: U+02965 .. DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +.. |dharl| unicode:: U+021C3 .. DOWNWARDS HARPOON WITH BARB LEFTWARDS +.. |dharr| unicode:: U+021C2 .. DOWNWARDS HARPOON WITH BARB RIGHTWARDS +.. |dlarr| unicode:: U+02199 .. SOUTH WEST ARROW +.. |drarr| unicode:: U+02198 .. SOUTH EAST ARROW +.. |duarr| unicode:: U+021F5 .. DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +.. |duhar| unicode:: U+0296F .. DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +.. |dzigrarr| unicode:: U+027FF .. LONG RIGHTWARDS SQUIGGLE ARROW +.. |erarr| unicode:: U+02971 .. EQUALS SIGN ABOVE RIGHTWARDS ARROW +.. |hArr| unicode:: U+021D4 .. LEFT RIGHT DOUBLE ARROW +.. |harr| unicode:: U+02194 .. LEFT RIGHT ARROW +.. |harrcir| unicode:: U+02948 .. LEFT RIGHT ARROW THROUGH SMALL CIRCLE +.. |harrw| unicode:: U+021AD .. LEFT RIGHT WAVE ARROW +.. |hoarr| unicode:: U+021FF .. LEFT RIGHT OPEN-HEADED ARROW +.. |imof| unicode:: U+022B7 .. IMAGE OF +.. |lAarr| unicode:: U+021DA .. LEFTWARDS TRIPLE ARROW +.. |Larr| unicode:: U+0219E .. LEFTWARDS TWO HEADED ARROW +.. |larr2| unicode:: U+021C7 .. LEFTWARDS PAIRED ARROWS +.. |larrbfs| unicode:: U+0291F .. LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND +.. |larrfs| unicode:: U+0291D .. LEFTWARDS ARROW TO BLACK DIAMOND +.. |larrhk| unicode:: U+021A9 .. LEFTWARDS ARROW WITH HOOK +.. |larrlp| unicode:: U+021AB .. LEFTWARDS ARROW WITH LOOP +.. |larrpl| unicode:: U+02939 .. LEFT-SIDE ARC ANTICLOCKWISE ARROW +.. |larrsim| unicode:: U+02973 .. LEFTWARDS ARROW ABOVE TILDE OPERATOR +.. |larrtl| unicode:: U+021A2 .. LEFTWARDS ARROW WITH TAIL +.. |lAtail| unicode:: U+0291B .. LEFTWARDS DOUBLE ARROW-TAIL +.. |latail| unicode:: U+02919 .. LEFTWARDS ARROW-TAIL +.. |lBarr| unicode:: U+0290E .. LEFTWARDS TRIPLE DASH ARROW +.. |lbarr| unicode:: U+0290C .. LEFTWARDS DOUBLE DASH ARROW +.. |ldca| unicode:: U+02936 .. ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS +.. |ldrdhar| unicode:: U+02967 .. LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +.. |ldrushar| unicode:: U+0294B .. LEFT BARB DOWN RIGHT BARB UP HARPOON +.. |ldsh| unicode:: U+021B2 .. DOWNWARDS ARROW WITH TIP LEFTWARDS +.. |lfisht| unicode:: U+0297C .. LEFT FISH TAIL +.. |lHar| unicode:: U+02962 .. LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN +.. |lhard| unicode:: U+021BD .. LEFTWARDS HARPOON WITH BARB DOWNWARDS +.. |lharu| unicode:: U+021BC .. LEFTWARDS HARPOON WITH BARB UPWARDS +.. |lharul| unicode:: U+0296A .. LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +.. |llarr| unicode:: U+021C7 .. LEFTWARDS PAIRED ARROWS +.. |llhard| unicode:: U+0296B .. LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +.. |loarr| unicode:: U+021FD .. LEFTWARDS OPEN-HEADED ARROW +.. |lrarr| unicode:: U+021C6 .. LEFTWARDS ARROW OVER RIGHTWARDS ARROW +.. |lrarr2| unicode:: U+021C6 .. LEFTWARDS ARROW OVER RIGHTWARDS ARROW +.. |lrhar| unicode:: U+021CB .. LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +.. |lrhar2| unicode:: U+021CB .. LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +.. |lrhard| unicode:: U+0296D .. RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +.. |lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS +.. |lurdshar| unicode:: U+0294A .. LEFT BARB UP RIGHT BARB DOWN HARPOON +.. |luruhar| unicode:: U+02966 .. LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP +.. |Map| unicode:: U+02905 .. RIGHTWARDS TWO-HEADED ARROW FROM BAR +.. |map| unicode:: U+021A6 .. RIGHTWARDS ARROW FROM BAR +.. |midcir| unicode:: U+02AF0 .. VERTICAL LINE WITH CIRCLE BELOW +.. |mumap| unicode:: U+022B8 .. MULTIMAP +.. |nearhk| unicode:: U+02924 .. NORTH EAST ARROW WITH HOOK +.. |neArr| unicode:: U+021D7 .. NORTH EAST DOUBLE ARROW +.. |nearr| unicode:: U+02197 .. NORTH EAST ARROW +.. |nesear| unicode:: U+02928 .. NORTH EAST ARROW AND SOUTH EAST ARROW +.. |nhArr| unicode:: U+021CE .. LEFT RIGHT DOUBLE ARROW WITH STROKE +.. |nharr| unicode:: U+021AE .. LEFT RIGHT ARROW WITH STROKE +.. |nlArr| unicode:: U+021CD .. LEFTWARDS DOUBLE ARROW WITH STROKE +.. |nlarr| unicode:: U+0219A .. LEFTWARDS ARROW WITH STROKE +.. |nrArr| unicode:: U+021CF .. RIGHTWARDS DOUBLE ARROW WITH STROKE +.. |nrarr| unicode:: U+0219B .. RIGHTWARDS ARROW WITH STROKE +.. |nrarrc| unicode:: U+02933 U+00338 .. WAVE ARROW POINTING DIRECTLY RIGHT with slash +.. |nrarrw| unicode:: U+0219D U+00338 .. RIGHTWARDS WAVE ARROW with slash +.. |nvHarr| unicode:: U+02904 .. LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE +.. |nvlArr| unicode:: U+02902 .. LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE +.. |nvrArr| unicode:: U+02903 .. RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE +.. |nwarhk| unicode:: U+02923 .. NORTH WEST ARROW WITH HOOK +.. |nwArr| unicode:: U+021D6 .. NORTH WEST DOUBLE ARROW +.. |nwarr| unicode:: U+02196 .. NORTH WEST ARROW +.. |nwnear| unicode:: U+02927 .. NORTH WEST ARROW AND NORTH EAST ARROW +.. |olarr| unicode:: U+021BA .. ANTICLOCKWISE OPEN CIRCLE ARROW +.. |orarr| unicode:: U+021BB .. CLOCKWISE OPEN CIRCLE ARROW +.. |origof| unicode:: U+022B6 .. ORIGINAL OF +.. |rAarr| unicode:: U+021DB .. RIGHTWARDS TRIPLE ARROW +.. |Rarr| unicode:: U+021A0 .. RIGHTWARDS TWO HEADED ARROW +.. |rarr2| unicode:: U+021C9 .. RIGHTWARDS PAIRED ARROWS +.. |rarrap| unicode:: U+02975 .. RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO +.. |rarrbfs| unicode:: U+02920 .. RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND +.. |rarrc| unicode:: U+02933 .. WAVE ARROW POINTING DIRECTLY RIGHT +.. |rarrfs| unicode:: U+0291E .. RIGHTWARDS ARROW TO BLACK DIAMOND +.. |rarrhk| unicode:: U+021AA .. RIGHTWARDS ARROW WITH HOOK +.. |rarrlp| unicode:: U+021AC .. RIGHTWARDS ARROW WITH LOOP +.. |rarrpl| unicode:: U+02945 .. RIGHTWARDS ARROW WITH PLUS BELOW +.. |rarrsim| unicode:: U+02974 .. RIGHTWARDS ARROW ABOVE TILDE OPERATOR +.. |Rarrtl| unicode:: U+02916 .. RIGHTWARDS TWO-HEADED ARROW WITH TAIL +.. |rarrtl| unicode:: U+021A3 .. RIGHTWARDS ARROW WITH TAIL +.. |rarrw| unicode:: U+0219D .. RIGHTWARDS WAVE ARROW +.. |rAtail| unicode:: U+0291C .. RIGHTWARDS DOUBLE ARROW-TAIL +.. |ratail| unicode:: U+0291A .. RIGHTWARDS ARROW-TAIL +.. |RBarr| unicode:: U+02910 .. RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW +.. |rBarr| unicode:: U+0290F .. RIGHTWARDS TRIPLE DASH ARROW +.. |rbarr| unicode:: U+0290D .. RIGHTWARDS DOUBLE DASH ARROW +.. |rdca| unicode:: U+02937 .. ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS +.. |rdldhar| unicode:: U+02969 .. RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN +.. |rdsh| unicode:: U+021B3 .. DOWNWARDS ARROW WITH TIP RIGHTWARDS +.. |rfisht| unicode:: U+0297D .. RIGHT FISH TAIL +.. |rHar| unicode:: U+02964 .. RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +.. |rhard| unicode:: U+021C1 .. RIGHTWARDS HARPOON WITH BARB DOWNWARDS +.. |rharu| unicode:: U+021C0 .. RIGHTWARDS HARPOON WITH BARB UPWARDS +.. |rharul| unicode:: U+0296C .. RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +.. |rlarr| unicode:: U+021C4 .. RIGHTWARDS ARROW OVER LEFTWARDS ARROW +.. |rlarr2| unicode:: U+021C4 .. RIGHTWARDS ARROW OVER LEFTWARDS ARROW +.. |rlhar| unicode:: U+021CC .. RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +.. |rlhar2| unicode:: U+021CC .. RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +.. |roarr| unicode:: U+021FE .. RIGHTWARDS OPEN-HEADED ARROW +.. |rrarr| unicode:: U+021C9 .. RIGHTWARDS PAIRED ARROWS +.. |rsh| unicode:: U+021B1 .. UPWARDS ARROW WITH TIP RIGHTWARDS +.. |ruluhar| unicode:: U+02968 .. RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP +.. |searhk| unicode:: U+02925 .. SOUTH EAST ARROW WITH HOOK +.. |seArr| unicode:: U+021D8 .. SOUTH EAST DOUBLE ARROW +.. |searr| unicode:: U+02198 .. SOUTH EAST ARROW +.. |seswar| unicode:: U+02929 .. SOUTH EAST ARROW AND SOUTH WEST ARROW +.. |simrarr| unicode:: U+02972 .. TILDE OPERATOR ABOVE RIGHTWARDS ARROW +.. |slarr| unicode:: U+02190 .. LEFTWARDS ARROW +.. |srarr| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |swarhk| unicode:: U+02926 .. SOUTH WEST ARROW WITH HOOK +.. |swArr| unicode:: U+021D9 .. SOUTH WEST DOUBLE ARROW +.. |swarr| unicode:: U+02199 .. SOUTH WEST ARROW +.. |swnwar| unicode:: U+0292A .. SOUTH WEST ARROW AND NORTH WEST ARROW +.. |Uarr| unicode:: U+0219F .. UPWARDS TWO HEADED ARROW +.. |uArr| unicode:: U+021D1 .. UPWARDS DOUBLE ARROW +.. |uarr2| unicode:: U+021C8 .. UPWARDS PAIRED ARROWS +.. |Uarrocir| unicode:: U+02949 .. UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE +.. |udarr| unicode:: U+021C5 .. UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +.. |udhar| unicode:: U+0296E .. UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +.. |ufisht| unicode:: U+0297E .. UP FISH TAIL +.. |uHar| unicode:: U+02963 .. UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +.. |uharl| unicode:: U+021BF .. UPWARDS HARPOON WITH BARB LEFTWARDS +.. |uharr| unicode:: U+021BE .. UPWARDS HARPOON WITH BARB RIGHTWARDS +.. |uuarr| unicode:: U+021C8 .. UPWARDS PAIRED ARROWS +.. |vArr| unicode:: U+021D5 .. UP DOWN DOUBLE ARROW +.. |varr| unicode:: U+02195 .. UP DOWN ARROW +.. |xhArr| unicode:: U+027FA .. LONG LEFT RIGHT DOUBLE ARROW +.. |xharr| unicode:: U+027F7 .. LONG LEFT RIGHT ARROW +.. |xlArr| unicode:: U+027F8 .. LONG LEFTWARDS DOUBLE ARROW +.. |xlarr| unicode:: U+027F5 .. LONG LEFTWARDS ARROW +.. |xmap| unicode:: U+027FC .. LONG RIGHTWARDS ARROW FROM BAR +.. |xrArr| unicode:: U+027F9 .. LONG RIGHTWARDS DOUBLE ARROW +.. |xrarr| unicode:: U+027F6 .. LONG RIGHTWARDS ARROW +.. |zigrarr| unicode:: U+021DD .. RIGHTWARDS SQUIGGLE ARROW diff --git a/docutils/parsers/rst/include/isoamsb.txt b/docutils/parsers/rst/include/isoamsb.txt new file mode 100644 index 000000000..05e68d99d --- /dev/null +++ b/docutils/parsers/rst/include/isoamsb.txt @@ -0,0 +1,126 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |ac| unicode:: U+0223E .. INVERTED LAZY S +.. |acE| unicode:: U+0223E U+00333 .. INVERTED LAZY S with double underline +.. |amalg| unicode:: U+02A3F .. AMALGAMATION OR COPRODUCT +.. |barvee| unicode:: U+022BD .. NOR +.. |Barwed| unicode:: U+02306 .. PERSPECTIVE +.. |barwed| unicode:: U+02305 .. PROJECTIVE +.. |bsolb| unicode:: U+029C5 .. SQUARED FALLING DIAGONAL SLASH +.. |Cap| unicode:: U+022D2 .. DOUBLE INTERSECTION +.. |capand| unicode:: U+02A44 .. INTERSECTION WITH LOGICAL AND +.. |capbrcup| unicode:: U+02A49 .. INTERSECTION ABOVE BAR ABOVE UNION +.. |capcap| unicode:: U+02A4B .. INTERSECTION BESIDE AND JOINED WITH INTERSECTION +.. |capcup| unicode:: U+02A47 .. INTERSECTION ABOVE UNION +.. |capdot| unicode:: U+02A40 .. INTERSECTION WITH DOT +.. |caps| unicode:: U+02229 U+0FE00 .. INTERSECTION with serifs +.. |ccaps| unicode:: U+02A4D .. CLOSED INTERSECTION WITH SERIFS +.. |ccups| unicode:: U+02A4C .. CLOSED UNION WITH SERIFS +.. |ccupssm| unicode:: U+02A50 .. CLOSED UNION WITH SERIFS AND SMASH PRODUCT +.. |coprod| unicode:: U+02210 .. N-ARY COPRODUCT +.. |Cup| unicode:: U+022D3 .. DOUBLE UNION +.. |cupbrcap| unicode:: U+02A48 .. UNION ABOVE BAR ABOVE INTERSECTION +.. |cupcap| unicode:: U+02A46 .. UNION ABOVE INTERSECTION +.. |cupcup| unicode:: U+02A4A .. UNION BESIDE AND JOINED WITH UNION +.. |cupdot| unicode:: U+0228D .. MULTISET MULTIPLICATION +.. |cupor| unicode:: U+02A45 .. UNION WITH LOGICAL OR +.. |cups| unicode:: U+0222A U+0FE00 .. UNION with serifs +.. |cuvee| unicode:: U+022CE .. CURLY LOGICAL OR +.. |cuwed| unicode:: U+022CF .. CURLY LOGICAL AND +.. |Dagger| unicode:: U+02021 .. DOUBLE DAGGER +.. |dagger| unicode:: U+02020 .. DAGGER +.. |diam| unicode:: U+022C4 .. DIAMOND OPERATOR +.. |divonx| unicode:: U+022C7 .. DIVISION TIMES +.. |eplus| unicode:: U+02A71 .. EQUALS SIGN ABOVE PLUS SIGN +.. |hercon| unicode:: U+022B9 .. HERMITIAN CONJUGATE MATRIX +.. |intcal| unicode:: U+022BA .. INTERCALATE +.. |iprod| unicode:: U+02A3C .. INTERIOR PRODUCT +.. |loplus| unicode:: U+02A2D .. PLUS SIGN IN LEFT HALF CIRCLE +.. |lotimes| unicode:: U+02A34 .. MULTIPLICATION SIGN IN LEFT HALF CIRCLE +.. |lthree| unicode:: U+022CB .. LEFT SEMIDIRECT PRODUCT +.. |ltimes| unicode:: U+022C9 .. LEFT NORMAL FACTOR SEMIDIRECT PRODUCT +.. |midast| unicode:: U+0002A .. ASTERISK +.. |minusb| unicode:: U+0229F .. SQUARED MINUS +.. |minusd| unicode:: U+02238 .. DOT MINUS +.. |minusdu| unicode:: U+02A2A .. MINUS SIGN WITH DOT BELOW +.. |ncap| unicode:: U+02A43 .. INTERSECTION WITH OVERBAR +.. |ncup| unicode:: U+02A42 .. UNION WITH OVERBAR +.. |oast| unicode:: U+0229B .. CIRCLED ASTERISK OPERATOR +.. |ocir| unicode:: U+0229A .. CIRCLED RING OPERATOR +.. |odash| unicode:: U+0229D .. CIRCLED DASH +.. |odiv| unicode:: U+02A38 .. CIRCLED DIVISION SIGN +.. |odot| unicode:: U+02299 .. CIRCLED DOT OPERATOR +.. |odsold| unicode:: U+029BC .. CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN +.. |ofcir| unicode:: U+029BF .. CIRCLED BULLET +.. |ogt| unicode:: U+029C1 .. CIRCLED GREATER-THAN +.. |ohbar| unicode:: U+029B5 .. CIRCLE WITH HORIZONTAL BAR +.. |olcir| unicode:: U+029BE .. CIRCLED WHITE BULLET +.. |olt| unicode:: U+029C0 .. CIRCLED LESS-THAN +.. |omid| unicode:: U+029B6 .. CIRCLED VERTICAL BAR +.. |ominus| unicode:: U+02296 .. CIRCLED MINUS +.. |opar| unicode:: U+029B7 .. CIRCLED PARALLEL +.. |operp| unicode:: U+029B9 .. CIRCLED PERPENDICULAR +.. |oplus| unicode:: U+02295 .. CIRCLED PLUS +.. |osol| unicode:: U+02298 .. CIRCLED DIVISION SLASH +.. |Otimes| unicode:: U+02A37 .. MULTIPLICATION SIGN IN DOUBLE CIRCLE +.. |otimes| unicode:: U+02297 .. CIRCLED TIMES +.. |otimesas| unicode:: U+02A36 .. CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT +.. |ovbar| unicode:: U+0233D .. APL FUNCTIONAL SYMBOL CIRCLE STILE +.. |plusacir| unicode:: U+02A23 .. PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE +.. |plusb| unicode:: U+0229E .. SQUARED PLUS +.. |pluscir| unicode:: U+02A22 .. PLUS SIGN WITH SMALL CIRCLE ABOVE +.. |plusdo| unicode:: U+02214 .. DOT PLUS +.. |plusdu| unicode:: U+02A25 .. PLUS SIGN WITH DOT BELOW +.. |pluse| unicode:: U+02A72 .. PLUS SIGN ABOVE EQUALS SIGN +.. |plussim| unicode:: U+02A26 .. PLUS SIGN WITH TILDE BELOW +.. |plustwo| unicode:: U+02A27 .. PLUS SIGN WITH SUBSCRIPT TWO +.. |prod| unicode:: U+0220F .. N-ARY PRODUCT +.. |race| unicode:: U+029DA .. LEFT DOUBLE WIGGLY FENCE +.. |roplus| unicode:: U+02A2E .. PLUS SIGN IN RIGHT HALF CIRCLE +.. |rotimes| unicode:: U+02A35 .. MULTIPLICATION SIGN IN RIGHT HALF CIRCLE +.. |rthree| unicode:: U+022CC .. RIGHT SEMIDIRECT PRODUCT +.. |rtimes| unicode:: U+022CA .. RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT +.. |sdot| unicode:: U+022C5 .. DOT OPERATOR +.. |sdotb| unicode:: U+022A1 .. SQUARED DOT OPERATOR +.. |setmn| unicode:: U+02216 .. SET MINUS +.. |simplus| unicode:: U+02A24 .. PLUS SIGN WITH TILDE ABOVE +.. |smashp| unicode:: U+02A33 .. SMASH PRODUCT +.. |solb| unicode:: U+029C4 .. SQUARED RISING DIAGONAL SLASH +.. |sqcap| unicode:: U+02293 .. SQUARE CAP +.. |sqcaps| unicode:: U+02293 U+0FE00 .. SQUARE CAP with serifs +.. |sqcup| unicode:: U+02294 .. SQUARE CUP +.. |sqcups| unicode:: U+02294 U+0FE00 .. SQUARE CUP with serifs +.. |ssetmn| unicode:: U+02216 .. SET MINUS +.. |sstarf| unicode:: U+022C6 .. STAR OPERATOR +.. |subdot| unicode:: U+02ABD .. SUBSET WITH DOT +.. |sum| unicode:: U+02211 .. N-ARY SUMMATION +.. |supdot| unicode:: U+02ABE .. SUPERSET WITH DOT +.. |timesb| unicode:: U+022A0 .. SQUARED TIMES +.. |timesbar| unicode:: U+02A31 .. MULTIPLICATION SIGN WITH UNDERBAR +.. |timesd| unicode:: U+02A30 .. MULTIPLICATION SIGN WITH DOT ABOVE +.. |top| unicode:: U+022A4 .. DOWN TACK +.. |tridot| unicode:: U+025EC .. WHITE UP-POINTING TRIANGLE WITH DOT +.. |triminus| unicode:: U+02A3A .. MINUS SIGN IN TRIANGLE +.. |triplus| unicode:: U+02A39 .. PLUS SIGN IN TRIANGLE +.. |trisb| unicode:: U+029CD .. TRIANGLE WITH SERIFS AT BOTTOM +.. |tritime| unicode:: U+02A3B .. MULTIPLICATION SIGN IN TRIANGLE +.. |uplus| unicode:: U+0228E .. MULTISET UNION +.. |veebar| unicode:: U+022BB .. XOR +.. |wedbar| unicode:: U+02A5F .. LOGICAL AND WITH UNDERBAR +.. |wreath| unicode:: U+02240 .. WREATH PRODUCT +.. |xcap| unicode:: U+022C2 .. N-ARY INTERSECTION +.. |xcirc| unicode:: U+025EF .. LARGE CIRCLE +.. |xcup| unicode:: U+022C3 .. N-ARY UNION +.. |xdtri| unicode:: U+025BD .. WHITE DOWN-POINTING TRIANGLE +.. |xodot| unicode:: U+02A00 .. N-ARY CIRCLED DOT OPERATOR +.. |xoplus| unicode:: U+02A01 .. N-ARY CIRCLED PLUS OPERATOR +.. |xotime| unicode:: U+02A02 .. N-ARY CIRCLED TIMES OPERATOR +.. |xsqcup| unicode:: U+02A06 .. N-ARY SQUARE UNION OPERATOR +.. |xuplus| unicode:: U+02A04 .. N-ARY UNION OPERATOR WITH PLUS +.. |xutri| unicode:: U+025B3 .. WHITE UP-POINTING TRIANGLE +.. |xvee| unicode:: U+022C1 .. N-ARY LOGICAL OR +.. |xwedge| unicode:: U+022C0 .. N-ARY LOGICAL AND diff --git a/docutils/parsers/rst/include/isoamsc.txt b/docutils/parsers/rst/include/isoamsc.txt new file mode 100644 index 000000000..343504d83 --- /dev/null +++ b/docutils/parsers/rst/include/isoamsc.txt @@ -0,0 +1,29 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |dlcorn| unicode:: U+0231E .. BOTTOM LEFT CORNER +.. |drcorn| unicode:: U+0231F .. BOTTOM RIGHT CORNER +.. |gtlPar| unicode:: U+02995 .. DOUBLE LEFT ARC GREATER-THAN BRACKET +.. |langd| unicode:: U+02991 .. LEFT ANGLE BRACKET WITH DOT +.. |lbrke| unicode:: U+0298B .. LEFT SQUARE BRACKET WITH UNDERBAR +.. |lbrksld| unicode:: U+0298F .. LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +.. |lbrkslu| unicode:: U+0298D .. LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +.. |lceil| unicode:: U+02308 .. LEFT CEILING +.. |lfloor| unicode:: U+0230A .. LEFT FLOOR +.. |lmoust| unicode:: U+023B0 .. UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +.. |lpargt| unicode:: U+029A0 .. SPHERICAL ANGLE OPENING LEFT +.. |lparlt| unicode:: U+02993 .. LEFT ARC LESS-THAN BRACKET +.. |ltrPar| unicode:: U+02996 .. DOUBLE RIGHT ARC LESS-THAN BRACKET +.. |rangd| unicode:: U+02992 .. RIGHT ANGLE BRACKET WITH DOT +.. |rbrke| unicode:: U+0298C .. RIGHT SQUARE BRACKET WITH UNDERBAR +.. |rbrksld| unicode:: U+0298E .. RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +.. |rbrkslu| unicode:: U+02990 .. RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +.. |rceil| unicode:: U+02309 .. RIGHT CEILING +.. |rfloor| unicode:: U+0230B .. RIGHT FLOOR +.. |rmoust| unicode:: U+023B1 .. UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +.. |rpargt| unicode:: U+02994 .. RIGHT ARC GREATER-THAN BRACKET +.. |ulcorn| unicode:: U+0231C .. TOP LEFT CORNER +.. |urcorn| unicode:: U+0231D .. TOP RIGHT CORNER diff --git a/docutils/parsers/rst/include/isoamsn.txt b/docutils/parsers/rst/include/isoamsn.txt new file mode 100644 index 000000000..5ff17291e --- /dev/null +++ b/docutils/parsers/rst/include/isoamsn.txt @@ -0,0 +1,96 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |gnap| unicode:: U+02A8A .. GREATER-THAN AND NOT APPROXIMATE +.. |gnE| unicode:: U+02269 .. GREATER-THAN BUT NOT EQUAL TO +.. |gne| unicode:: U+02A88 .. GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +.. |gnsim| unicode:: U+022E7 .. GREATER-THAN BUT NOT EQUIVALENT TO +.. |gvnE| unicode:: U+02269 U+0FE00 .. GREATER-THAN BUT NOT EQUAL TO - with vertical stroke +.. |lnap| unicode:: U+02A89 .. LESS-THAN AND NOT APPROXIMATE +.. |lnE| unicode:: U+02268 .. LESS-THAN BUT NOT EQUAL TO +.. |lne| unicode:: U+02A87 .. LESS-THAN AND SINGLE-LINE NOT EQUAL TO +.. |lnsim| unicode:: U+022E6 .. LESS-THAN BUT NOT EQUIVALENT TO +.. |lvnE| unicode:: U+02268 U+0FE00 .. LESS-THAN BUT NOT EQUAL TO - with vertical stroke +.. |nap| unicode:: U+02249 .. NOT ALMOST EQUAL TO +.. |napE| unicode:: U+02A70 U+00338 .. APPROXIMATELY EQUAL OR EQUAL TO with slash +.. |napid| unicode:: U+0224B U+00338 .. TRIPLE TILDE with slash +.. |ncong| unicode:: U+02247 .. NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +.. |ncongdot| unicode:: U+02A6D U+00338 .. CONGRUENT WITH DOT ABOVE with slash +.. |nequiv| unicode:: U+02262 .. NOT IDENTICAL TO +.. |ngE| unicode:: U+02267 U+00338 .. GREATER-THAN OVER EQUAL TO with slash +.. |nge| unicode:: U+02271 .. NEITHER GREATER-THAN NOR EQUAL TO +.. |nges| unicode:: U+02A7E U+00338 .. GREATER-THAN OR SLANTED EQUAL TO with slash +.. |nGg| unicode:: U+022D9 U+00338 .. VERY MUCH GREATER-THAN with slash +.. |ngsim| unicode:: U+02275 .. NEITHER GREATER-THAN NOR EQUIVALENT TO +.. |nGt| unicode:: U+0226B U+020D2 .. MUCH GREATER THAN with vertical line +.. |ngt| unicode:: U+0226F .. NOT GREATER-THAN +.. |nGtv| unicode:: U+0226B U+00338 .. MUCH GREATER THAN with slash +.. |nlE| unicode:: U+02266 U+00338 .. LESS-THAN OVER EQUAL TO with slash +.. |nle| unicode:: U+02270 .. NEITHER LESS-THAN NOR EQUAL TO +.. |nles| unicode:: U+02A7D U+00338 .. LESS-THAN OR SLANTED EQUAL TO with slash +.. |nLl| unicode:: U+022D8 U+00338 .. VERY MUCH LESS-THAN with slash +.. |nlsim| unicode:: U+02274 .. NEITHER LESS-THAN NOR EQUIVALENT TO +.. |nLt| unicode:: U+0226A U+020D2 .. MUCH LESS THAN with vertical line +.. |nlt| unicode:: U+0226E .. NOT LESS-THAN +.. |nltri| unicode:: U+022EA .. NOT NORMAL SUBGROUP OF +.. |nltrie| unicode:: U+022EC .. NOT NORMAL SUBGROUP OF OR EQUAL TO +.. |nLtv| unicode:: U+0226A U+00338 .. MUCH LESS THAN with slash +.. |nmid| unicode:: U+02224 .. DOES NOT DIVIDE +.. |npar| unicode:: U+02226 .. NOT PARALLEL TO +.. |npr| unicode:: U+02280 .. DOES NOT PRECEDE +.. |nprcue| unicode:: U+022E0 .. DOES NOT PRECEDE OR EQUAL +.. |npre| unicode:: U+02AAF U+00338 .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |nrtri| unicode:: U+022EB .. DOES NOT CONTAIN AS NORMAL SUBGROUP +.. |nrtrie| unicode:: U+022ED .. DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +.. |nsc| unicode:: U+02281 .. DOES NOT SUCCEED +.. |nsccue| unicode:: U+022E1 .. DOES NOT SUCCEED OR EQUAL +.. |nsce| unicode:: U+02AB0 U+00338 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |nsim| unicode:: U+02241 .. NOT TILDE +.. |nsime| unicode:: U+02244 .. NOT ASYMPTOTICALLY EQUAL TO +.. |nsmid| unicode:: U+02224 .. DOES NOT DIVIDE +.. |nspar| unicode:: U+02226 .. NOT PARALLEL TO +.. |nsqsube| unicode:: U+022E2 .. NOT SQUARE IMAGE OF OR EQUAL TO +.. |nsqsupe| unicode:: U+022E3 .. NOT SQUARE ORIGINAL OF OR EQUAL TO +.. |nsub| unicode:: U+02284 .. NOT A SUBSET OF +.. |nsubE| unicode:: U+02AC5 U+00338 .. SUBSET OF ABOVE EQUALS SIGN with slash +.. |nsube| unicode:: U+02288 .. NEITHER A SUBSET OF NOR EQUAL TO +.. |nsup| unicode:: U+02285 .. NOT A SUPERSET OF +.. |nsupE| unicode:: U+02AC6 U+00338 .. SUPERSET OF ABOVE EQUALS SIGN with slash +.. |nsupe| unicode:: U+02289 .. NEITHER A SUPERSET OF NOR EQUAL TO +.. |ntgl| unicode:: U+02279 .. NEITHER GREATER-THAN NOR LESS-THAN +.. |ntlg| unicode:: U+02278 .. NEITHER LESS-THAN NOR GREATER-THAN +.. |nvap| unicode:: U+0224D U+020D2 .. EQUIVALENT TO with vertical line +.. |nVDash| unicode:: U+022AF .. NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +.. |nVdash| unicode:: U+022AE .. DOES NOT FORCE +.. |nvDash| unicode:: U+022AD .. NOT TRUE +.. |nvdash| unicode:: U+022AC .. DOES NOT PROVE +.. |nvge| unicode:: U+02265 U+020D2 .. GREATER-THAN OR EQUAL TO with vertical line +.. |nvgt| unicode:: U+0003E U+020D2 .. GREATER-THAN SIGN with vertical line +.. |nvle| unicode:: U+02264 U+020D2 .. LESS-THAN OR EQUAL TO with vertical line +.. |nvlt| unicode:: U+0003C U+020D2 .. LESS-THAN SIGN with vertical line +.. |nvltrie| unicode:: U+022B4 U+020D2 .. NORMAL SUBGROUP OF OR EQUAL TO with vertical line +.. |nvrtrie| unicode:: U+022B5 U+020D2 .. CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line +.. |nvsim| unicode:: U+0223C U+020D2 .. TILDE OPERATOR with vertical line +.. |parsim| unicode:: U+02AF3 .. PARALLEL WITH TILDE OPERATOR +.. |prnap| unicode:: U+02AB9 .. PRECEDES ABOVE NOT ALMOST EQUAL TO +.. |prnE| unicode:: U+02AB5 .. PRECEDES ABOVE NOT EQUAL TO +.. |prnsim| unicode:: U+022E8 .. PRECEDES BUT NOT EQUIVALENT TO +.. |rnmid| unicode:: U+02AEE .. DOES NOT DIVIDE WITH REVERSED NEGATION SLASH +.. |scnap| unicode:: U+02ABA .. SUCCEEDS ABOVE NOT ALMOST EQUAL TO +.. |scnE| unicode:: U+02AB6 .. SUCCEEDS ABOVE NOT EQUAL TO +.. |scnsim| unicode:: U+022E9 .. SUCCEEDS BUT NOT EQUIVALENT TO +.. |simne| unicode:: U+02246 .. APPROXIMATELY BUT NOT ACTUALLY EQUAL TO +.. |solbar| unicode:: U+0233F .. APL FUNCTIONAL SYMBOL SLASH BAR +.. |subnE| unicode:: U+02ACB .. SUBSET OF ABOVE NOT EQUAL TO +.. |subne| unicode:: U+0228A .. SUBSET OF WITH NOT EQUAL TO +.. |supnE| unicode:: U+02ACC .. SUPERSET OF ABOVE NOT EQUAL TO +.. |supne| unicode:: U+0228B .. SUPERSET OF WITH NOT EQUAL TO +.. |vnsub| unicode:: U+02282 U+020D2 .. SUBSET OF with vertical line +.. |vnsup| unicode:: U+02283 U+020D2 .. SUPERSET OF with vertical line +.. |vsubnE| unicode:: U+02ACB U+0FE00 .. SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +.. |vsubne| unicode:: U+0228A U+0FE00 .. SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +.. |vsupnE| unicode:: U+02ACC U+0FE00 .. SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +.. |vsupne| unicode:: U+0228B U+0FE00 .. SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members diff --git a/docutils/parsers/rst/include/isoamso.txt b/docutils/parsers/rst/include/isoamso.txt new file mode 100644 index 000000000..65cc17e99 --- /dev/null +++ b/docutils/parsers/rst/include/isoamso.txt @@ -0,0 +1,62 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |ang| unicode:: U+02220 .. ANGLE +.. |ange| unicode:: U+029A4 .. ANGLE WITH UNDERBAR +.. |angmsd| unicode:: U+02221 .. MEASURED ANGLE +.. |angmsdaa| unicode:: U+029A8 .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT +.. |angmsdab| unicode:: U+029A9 .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT +.. |angmsdac| unicode:: U+029AA .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT +.. |angmsdad| unicode:: U+029AB .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT +.. |angmsdae| unicode:: U+029AC .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP +.. |angmsdaf| unicode:: U+029AD .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP +.. |angmsdag| unicode:: U+029AE .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN +.. |angmsdah| unicode:: U+029AF .. MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN +.. |angrtvb| unicode:: U+022BE .. RIGHT ANGLE WITH ARC +.. |angrtvbd| unicode:: U+0299D .. MEASURED RIGHT ANGLE WITH DOT +.. |bbrk| unicode:: U+023B5 .. BOTTOM SQUARE BRACKET +.. |bbrktbrk| unicode:: U+023B6 .. BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET +.. |bemptyv| unicode:: U+029B0 .. REVERSED EMPTY SET +.. |beth| unicode:: U+02136 .. BET SYMBOL +.. |boxbox| unicode:: U+029C9 .. TWO JOINED SQUARES +.. |bprime| unicode:: U+02035 .. REVERSED PRIME +.. |bsemi| unicode:: U+0204F .. REVERSED SEMICOLON +.. |cemptyv| unicode:: U+029B2 .. EMPTY SET WITH SMALL CIRCLE ABOVE +.. |cirE| unicode:: U+029C3 .. CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT +.. |cirscir| unicode:: U+029C2 .. CIRCLE WITH SMALL CIRCLE TO THE RIGHT +.. |comp| unicode:: U+02201 .. COMPLEMENT +.. |daleth| unicode:: U+02138 .. DALET SYMBOL +.. |demptyv| unicode:: U+029B1 .. EMPTY SET WITH OVERBAR +.. |ell| unicode:: U+02113 .. SCRIPT SMALL L +.. |empty| unicode:: U+02205 .. EMPTY SET +.. |emptyv| unicode:: U+02205 .. EMPTY SET +.. |gimel| unicode:: U+02137 .. GIMEL SYMBOL +.. |iiota| unicode:: U+02129 .. TURNED GREEK SMALL LETTER IOTA +.. |image| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |imath| unicode:: U+00131 .. LATIN SMALL LETTER DOTLESS I +.. |inodot| unicode:: U+00131 .. LATIN SMALL LETTER DOTLESS I +.. |jmath| unicode:: U+0006A .. LATIN SMALL LETTER J +.. |jnodot| unicode:: U+0006A .. LATIN SMALL LETTER J +.. |laemptyv| unicode:: U+029B4 .. EMPTY SET WITH LEFT ARROW ABOVE +.. |lltri| unicode:: U+025FA .. LOWER LEFT TRIANGLE +.. |lrtri| unicode:: U+022BF .. RIGHT TRIANGLE +.. |mho| unicode:: U+02127 .. INVERTED OHM SIGN +.. |nang| unicode:: U+02220 U+020D2 .. ANGLE with vertical line +.. |nexist| unicode:: U+02204 .. THERE DOES NOT EXIST +.. |oS| unicode:: U+024C8 .. CIRCLED LATIN CAPITAL LETTER S +.. |planck| unicode:: U+0210F .. PLANCK CONSTANT OVER TWO PI +.. |plankv| unicode:: U+0210F .. PLANCK CONSTANT OVER TWO PI +.. |raemptyv| unicode:: U+029B3 .. EMPTY SET WITH RIGHT ARROW ABOVE +.. |range| unicode:: U+029A5 .. REVERSED ANGLE WITH UNDERBAR +.. |real| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |sbsol| unicode:: U+0FE68 .. SMALL REVERSE SOLIDUS +.. |tbrk| unicode:: U+023B4 .. TOP SQUARE BRACKET +.. |trpezium| unicode:: U+0FFFD .. REPLACEMENT CHARACTER +.. |ultri| unicode:: U+025F8 .. UPPER LEFT TRIANGLE +.. |urtri| unicode:: U+025F9 .. UPPER RIGHT TRIANGLE +.. |vprime| unicode:: U+02032 .. PRIME +.. |vzigzag| unicode:: U+0299A .. VERTICAL ZIGZAG LINE +.. |weierp| unicode:: U+02118 .. SCRIPT CAPITAL P diff --git a/docutils/parsers/rst/include/isoamsr.txt b/docutils/parsers/rst/include/isoamsr.txt new file mode 100644 index 000000000..a3d03dab7 --- /dev/null +++ b/docutils/parsers/rst/include/isoamsr.txt @@ -0,0 +1,191 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |apE| unicode:: U+02A70 .. APPROXIMATELY EQUAL OR EQUAL TO +.. |ape| unicode:: U+0224A .. ALMOST EQUAL OR EQUAL TO +.. |apid| unicode:: U+0224B .. TRIPLE TILDE +.. |asymp| unicode:: U+02248 .. ALMOST EQUAL TO +.. |Barv| unicode:: U+02AE7 .. SHORT DOWN TACK WITH OVERBAR +.. |bcong| unicode:: U+0224C .. ALL EQUAL TO +.. |bepsi| unicode:: U+003F6 .. GREEK REVERSED LUNATE EPSILON SYMBOL +.. |bowtie| unicode:: U+022C8 .. BOWTIE +.. |bsim| unicode:: U+0223D .. REVERSED TILDE +.. |bsime| unicode:: U+022CD .. REVERSED TILDE EQUALS +.. |bsolhsub| unicode:: U+0005C U+02282 .. REVERSE SOLIDUS, SUBSET OF +.. |bump| unicode:: U+0224E .. GEOMETRICALLY EQUIVALENT TO +.. |bumpE| unicode:: U+02AAE .. EQUALS SIGN WITH BUMPY ABOVE +.. |bumpe| unicode:: U+0224F .. DIFFERENCE BETWEEN +.. |cire| unicode:: U+02257 .. RING EQUAL TO +.. |Colon| unicode:: U+02237 .. PROPORTION +.. |Colone| unicode:: U+02A74 .. DOUBLE COLON EQUAL +.. |colone| unicode:: U+02254 .. COLON EQUALS +.. |congdot| unicode:: U+02A6D .. CONGRUENT WITH DOT ABOVE +.. |csub| unicode:: U+02ACF .. CLOSED SUBSET +.. |csube| unicode:: U+02AD1 .. CLOSED SUBSET OR EQUAL TO +.. |csup| unicode:: U+02AD0 .. CLOSED SUPERSET +.. |csupe| unicode:: U+02AD2 .. CLOSED SUPERSET OR EQUAL TO +.. |cuepr| unicode:: U+022DE .. EQUAL TO OR PRECEDES +.. |cuesc| unicode:: U+022DF .. EQUAL TO OR SUCCEEDS +.. |cupre| unicode:: U+0227C .. PRECEDES OR EQUAL TO +.. |Dashv| unicode:: U+02AE4 .. VERTICAL BAR DOUBLE LEFT TURNSTILE +.. |dashv| unicode:: U+022A3 .. LEFT TACK +.. |easter| unicode:: U+02A6E .. EQUALS WITH ASTERISK +.. |ecir| unicode:: U+02256 .. RING IN EQUAL TO +.. |ecolon| unicode:: U+02255 .. EQUALS COLON +.. |eDDot| unicode:: U+02A77 .. EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW +.. |eDot| unicode:: U+02251 .. GEOMETRICALLY EQUAL TO +.. |efDot| unicode:: U+02252 .. APPROXIMATELY EQUAL TO OR THE IMAGE OF +.. |eg| unicode:: U+02A9A .. DOUBLE-LINE EQUAL TO OR GREATER-THAN +.. |egs| unicode:: U+02A96 .. SLANTED EQUAL TO OR GREATER-THAN +.. |egsdot| unicode:: U+02A98 .. SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE +.. |el| unicode:: U+02A99 .. DOUBLE-LINE EQUAL TO OR LESS-THAN +.. |els| unicode:: U+02A95 .. SLANTED EQUAL TO OR LESS-THAN +.. |elsdot| unicode:: U+02A97 .. SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE +.. |equest| unicode:: U+0225F .. QUESTIONED EQUAL TO +.. |equivDD| unicode:: U+02A78 .. EQUIVALENT WITH FOUR DOTS ABOVE +.. |erDot| unicode:: U+02253 .. IMAGE OF OR APPROXIMATELY EQUAL TO +.. |esdot| unicode:: U+02250 .. APPROACHES THE LIMIT +.. |Esim| unicode:: U+02A73 .. EQUALS SIGN ABOVE TILDE OPERATOR +.. |esim| unicode:: U+02242 .. MINUS TILDE +.. |fork| unicode:: U+022D4 .. PITCHFORK +.. |forkv| unicode:: U+02AD9 .. ELEMENT OF OPENING DOWNWARDS +.. |frown| unicode:: U+02322 .. FROWN +.. |gap| unicode:: U+02A86 .. GREATER-THAN OR APPROXIMATE +.. |gE| unicode:: U+02267 .. GREATER-THAN OVER EQUAL TO +.. |gEl| unicode:: U+02A8C .. GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +.. |gel| unicode:: U+022DB .. GREATER-THAN EQUAL TO OR LESS-THAN +.. |ges| unicode:: U+02A7E .. GREATER-THAN OR SLANTED EQUAL TO +.. |gescc| unicode:: U+02AA9 .. GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +.. |gesdot| unicode:: U+02A80 .. GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +.. |gesdoto| unicode:: U+02A82 .. GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +.. |gesdotol| unicode:: U+02A84 .. GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT +.. |gesl| unicode:: U+022DB U+0FE00 .. GREATER-THAN slanted EQUAL TO OR LESS-THAN +.. |gesles| unicode:: U+02A94 .. GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL +.. |Gg| unicode:: U+022D9 .. VERY MUCH GREATER-THAN +.. |gl| unicode:: U+02277 .. GREATER-THAN OR LESS-THAN +.. |gla| unicode:: U+02AA5 .. GREATER-THAN BESIDE LESS-THAN +.. |glE| unicode:: U+02A92 .. GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL +.. |glj| unicode:: U+02AA4 .. GREATER-THAN OVERLAPPING LESS-THAN +.. |gsdot| unicode:: U+022D7 .. GREATER-THAN WITH DOT +.. |gsim| unicode:: U+02273 .. GREATER-THAN OR EQUIVALENT TO +.. |gsime| unicode:: U+02A8E .. GREATER-THAN ABOVE SIMILAR OR EQUAL +.. |gsiml| unicode:: U+02A90 .. GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN +.. |Gt| unicode:: U+0226B .. MUCH GREATER-THAN +.. |gtcc| unicode:: U+02AA7 .. GREATER-THAN CLOSED BY CURVE +.. |gtcir| unicode:: U+02A7A .. GREATER-THAN WITH CIRCLE INSIDE +.. |gtdot| unicode:: U+022D7 .. GREATER-THAN WITH DOT +.. |gtquest| unicode:: U+02A7C .. GREATER-THAN WITH QUESTION MARK ABOVE +.. |gtrarr| unicode:: U+02978 .. GREATER-THAN ABOVE RIGHTWARDS ARROW +.. |homtht| unicode:: U+0223B .. HOMOTHETIC +.. |lap| unicode:: U+02A85 .. LESS-THAN OR APPROXIMATE +.. |lat| unicode:: U+02AAB .. LARGER THAN +.. |late| unicode:: U+02AAD .. LARGER THAN OR EQUAL TO +.. |lates| unicode:: U+02AAD U+0FE00 .. LARGER THAN OR slanted EQUAL +.. |ldot| unicode:: U+022D6 .. LESS-THAN WITH DOT +.. |lE| unicode:: U+02266 .. LESS-THAN OVER EQUAL TO +.. |lEg| unicode:: U+02A8B .. LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +.. |leg| unicode:: U+022DA .. LESS-THAN EQUAL TO OR GREATER-THAN +.. |les| unicode:: U+02A7D .. LESS-THAN OR SLANTED EQUAL TO +.. |lescc| unicode:: U+02AA8 .. LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +.. |lesdot| unicode:: U+02A7F .. LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +.. |lesdoto| unicode:: U+02A81 .. LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +.. |lesdotor| unicode:: U+02A83 .. LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT +.. |lesg| unicode:: U+022DA U+0FE00 .. LESS-THAN slanted EQUAL TO OR GREATER-THAN +.. |lesges| unicode:: U+02A93 .. LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL +.. |lg| unicode:: U+02276 .. LESS-THAN OR GREATER-THAN +.. |lgE| unicode:: U+02A91 .. LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL +.. |Ll| unicode:: U+022D8 .. VERY MUCH LESS-THAN +.. |lsim| unicode:: U+02272 .. LESS-THAN OR EQUIVALENT TO +.. |lsime| unicode:: U+02A8D .. LESS-THAN ABOVE SIMILAR OR EQUAL +.. |lsimg| unicode:: U+02A8F .. LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN +.. |Lt| unicode:: U+0226A .. MUCH LESS-THAN +.. |ltcc| unicode:: U+02AA6 .. LESS-THAN CLOSED BY CURVE +.. |ltcir| unicode:: U+02A79 .. LESS-THAN WITH CIRCLE INSIDE +.. |ltdot| unicode:: U+022D6 .. LESS-THAN WITH DOT +.. |ltlarr| unicode:: U+02976 .. LESS-THAN ABOVE LEFTWARDS ARROW +.. |ltquest| unicode:: U+02A7B .. LESS-THAN WITH QUESTION MARK ABOVE +.. |ltrie| unicode:: U+022B4 .. NORMAL SUBGROUP OF OR EQUAL TO +.. |mcomma| unicode:: U+02A29 .. MINUS SIGN WITH COMMA ABOVE +.. |mDDot| unicode:: U+0223A .. GEOMETRIC PROPORTION +.. |mid| unicode:: U+02223 .. DIVIDES +.. |mlcp| unicode:: U+02ADB .. TRANSVERSAL INTERSECTION +.. |models| unicode:: U+022A7 .. MODELS +.. |mstpos| unicode:: U+0223E .. INVERTED LAZY S +.. |Pr| unicode:: U+02ABB .. DOUBLE PRECEDES +.. |pr| unicode:: U+0227A .. PRECEDES +.. |prap| unicode:: U+02AB7 .. PRECEDES ABOVE ALMOST EQUAL TO +.. |prcue| unicode:: U+0227C .. PRECEDES OR EQUAL TO +.. |prE| unicode:: U+02AB3 .. PRECEDES ABOVE EQUALS SIGN +.. |pre| unicode:: U+02AAF .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +.. |prsim| unicode:: U+0227E .. PRECEDES OR EQUIVALENT TO +.. |prurel| unicode:: U+022B0 .. PRECEDES UNDER RELATION +.. |ratio| unicode:: U+02236 .. RATIO +.. |rtrie| unicode:: U+022B5 .. CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +.. |rtriltri| unicode:: U+029CE .. RIGHT TRIANGLE ABOVE LEFT TRIANGLE +.. |samalg| unicode:: U+02210 .. N-ARY COPRODUCT +.. |Sc| unicode:: U+02ABC .. DOUBLE SUCCEEDS +.. |sc| unicode:: U+0227B .. SUCCEEDS +.. |scap| unicode:: U+02AB8 .. SUCCEEDS ABOVE ALMOST EQUAL TO +.. |sccue| unicode:: U+0227D .. SUCCEEDS OR EQUAL TO +.. |scE| unicode:: U+02AB4 .. SUCCEEDS ABOVE EQUALS SIGN +.. |sce| unicode:: U+02AB0 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +.. |scsim| unicode:: U+0227F .. SUCCEEDS OR EQUIVALENT TO +.. |sdote| unicode:: U+02A66 .. EQUALS SIGN WITH DOT BELOW +.. |sfrown| unicode:: U+02322 .. FROWN +.. |simg| unicode:: U+02A9E .. SIMILAR OR GREATER-THAN +.. |simgE| unicode:: U+02AA0 .. SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN +.. |siml| unicode:: U+02A9D .. SIMILAR OR LESS-THAN +.. |simlE| unicode:: U+02A9F .. SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN +.. |smid| unicode:: U+02223 .. DIVIDES +.. |smile| unicode:: U+02323 .. SMILE +.. |smt| unicode:: U+02AAA .. SMALLER THAN +.. |smte| unicode:: U+02AAC .. SMALLER THAN OR EQUAL TO +.. |smtes| unicode:: U+02AAC U+0FE00 .. SMALLER THAN OR slanted EQUAL +.. |spar| unicode:: U+02225 .. PARALLEL TO +.. |sqsub| unicode:: U+0228F .. SQUARE IMAGE OF +.. |sqsube| unicode:: U+02291 .. SQUARE IMAGE OF OR EQUAL TO +.. |sqsup| unicode:: U+02290 .. SQUARE ORIGINAL OF +.. |sqsupe| unicode:: U+02292 .. SQUARE ORIGINAL OF OR EQUAL TO +.. |ssmile| unicode:: U+02323 .. SMILE +.. |Sub| unicode:: U+022D0 .. DOUBLE SUBSET +.. |subE| unicode:: U+02AC5 .. SUBSET OF ABOVE EQUALS SIGN +.. |subedot| unicode:: U+02AC3 .. SUBSET OF OR EQUAL TO WITH DOT ABOVE +.. |submult| unicode:: U+02AC1 .. SUBSET WITH MULTIPLICATION SIGN BELOW +.. |subplus| unicode:: U+02ABF .. SUBSET WITH PLUS SIGN BELOW +.. |subrarr| unicode:: U+02979 .. SUBSET ABOVE RIGHTWARDS ARROW +.. |subsim| unicode:: U+02AC7 .. SUBSET OF ABOVE TILDE OPERATOR +.. |subsub| unicode:: U+02AD5 .. SUBSET ABOVE SUBSET +.. |subsup| unicode:: U+02AD3 .. SUBSET ABOVE SUPERSET +.. |Sup| unicode:: U+022D1 .. DOUBLE SUPERSET +.. |supdsub| unicode:: U+02AD8 .. SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET +.. |supE| unicode:: U+02AC6 .. SUPERSET OF ABOVE EQUALS SIGN +.. |supedot| unicode:: U+02AC4 .. SUPERSET OF OR EQUAL TO WITH DOT ABOVE +.. |suphsol| unicode:: U+02283 U+0002F .. SUPERSET OF, SOLIDUS +.. |suphsub| unicode:: U+02AD7 .. SUPERSET BESIDE SUBSET +.. |suplarr| unicode:: U+0297B .. SUPERSET ABOVE LEFTWARDS ARROW +.. |supmult| unicode:: U+02AC2 .. SUPERSET WITH MULTIPLICATION SIGN BELOW +.. |supplus| unicode:: U+02AC0 .. SUPERSET WITH PLUS SIGN BELOW +.. |supsim| unicode:: U+02AC8 .. SUPERSET OF ABOVE TILDE OPERATOR +.. |supsub| unicode:: U+02AD4 .. SUPERSET ABOVE SUBSET +.. |supsup| unicode:: U+02AD6 .. SUPERSET ABOVE SUPERSET +.. |thkap| unicode:: U+02248 .. ALMOST EQUAL TO +.. |thksim| unicode:: U+0223C .. TILDE OPERATOR +.. |topfork| unicode:: U+02ADA .. PITCHFORK WITH TEE TOP +.. |trie| unicode:: U+0225C .. DELTA EQUAL TO +.. |twixt| unicode:: U+0226C .. BETWEEN +.. |Vbar| unicode:: U+02AEB .. DOUBLE UP TACK +.. |vBar| unicode:: U+02AE8 .. SHORT UP TACK WITH UNDERBAR +.. |vBarv| unicode:: U+02AE9 .. SHORT UP TACK ABOVE SHORT DOWN TACK +.. |VDash| unicode:: U+022AB .. DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +.. |Vdash| unicode:: U+022A9 .. FORCES +.. |vDash| unicode:: U+022A8 .. TRUE +.. |vdash| unicode:: U+022A2 .. RIGHT TACK +.. |Vdashl| unicode:: U+02AE6 .. LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL +.. |veebar| unicode:: U+022BB .. XOR +.. |vltri| unicode:: U+022B2 .. NORMAL SUBGROUP OF +.. |vprop| unicode:: U+0221D .. PROPORTIONAL TO +.. |vrtri| unicode:: U+022B3 .. CONTAINS AS NORMAL SUBGROUP +.. |Vvdash| unicode:: U+022AA .. TRIPLE VERTICAL BAR RIGHT TURNSTILE diff --git a/docutils/parsers/rst/include/isobox.txt b/docutils/parsers/rst/include/isobox.txt new file mode 100644 index 000000000..2304f8770 --- /dev/null +++ b/docutils/parsers/rst/include/isobox.txt @@ -0,0 +1,46 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |boxDL| unicode:: U+02557 .. BOX DRAWINGS DOUBLE DOWN AND LEFT +.. |boxDl| unicode:: U+02556 .. BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +.. |boxdL| unicode:: U+02555 .. BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +.. |boxdl| unicode:: U+02510 .. BOX DRAWINGS LIGHT DOWN AND LEFT +.. |boxDR| unicode:: U+02554 .. BOX DRAWINGS DOUBLE DOWN AND RIGHT +.. |boxDr| unicode:: U+02553 .. BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +.. |boxdR| unicode:: U+02552 .. BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +.. |boxdr| unicode:: U+0250C .. BOX DRAWINGS LIGHT DOWN AND RIGHT +.. |boxH| unicode:: U+02550 .. BOX DRAWINGS DOUBLE HORIZONTAL +.. |boxh| unicode:: U+02500 .. BOX DRAWINGS LIGHT HORIZONTAL +.. |boxHD| unicode:: U+02566 .. BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +.. |boxHd| unicode:: U+02564 .. BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +.. |boxhD| unicode:: U+02565 .. BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +.. |boxhd| unicode:: U+0252C .. BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +.. |boxHU| unicode:: U+02569 .. BOX DRAWINGS DOUBLE UP AND HORIZONTAL +.. |boxHu| unicode:: U+02567 .. BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +.. |boxhU| unicode:: U+02568 .. BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +.. |boxhu| unicode:: U+02534 .. BOX DRAWINGS LIGHT UP AND HORIZONTAL +.. |boxUL| unicode:: U+0255D .. BOX DRAWINGS DOUBLE UP AND LEFT +.. |boxUl| unicode:: U+0255C .. BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +.. |boxuL| unicode:: U+0255B .. BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +.. |boxul| unicode:: U+02518 .. BOX DRAWINGS LIGHT UP AND LEFT +.. |boxUR| unicode:: U+0255A .. BOX DRAWINGS DOUBLE UP AND RIGHT +.. |boxUr| unicode:: U+02559 .. BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +.. |boxuR| unicode:: U+02558 .. BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +.. |boxur| unicode:: U+02514 .. BOX DRAWINGS LIGHT UP AND RIGHT +.. |boxV| unicode:: U+02551 .. BOX DRAWINGS DOUBLE VERTICAL +.. |boxv| unicode:: U+02502 .. BOX DRAWINGS LIGHT VERTICAL +.. |boxVH| unicode:: U+0256C .. BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +.. |boxVh| unicode:: U+0256B .. BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +.. |boxvH| unicode:: U+0256A .. BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +.. |boxvh| unicode:: U+0253C .. BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +.. |boxVL| unicode:: U+02563 .. BOX DRAWINGS DOUBLE VERTICAL AND LEFT +.. |boxVl| unicode:: U+02562 .. BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +.. |boxvL| unicode:: U+02561 .. BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +.. |boxvl| unicode:: U+02524 .. BOX DRAWINGS LIGHT VERTICAL AND LEFT +.. |boxVR| unicode:: U+02560 .. BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +.. |boxVr| unicode:: U+0255F .. BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +.. |boxvR| unicode:: U+0255E .. BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +.. |boxvr| unicode:: U+0251C .. BOX DRAWINGS LIGHT VERTICAL AND RIGHT diff --git a/docutils/parsers/rst/include/isocyr1.txt b/docutils/parsers/rst/include/isocyr1.txt new file mode 100644 index 000000000..afee744cf --- /dev/null +++ b/docutils/parsers/rst/include/isocyr1.txt @@ -0,0 +1,73 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Acy| unicode:: U+00410 .. CYRILLIC CAPITAL LETTER A +.. |acy| unicode:: U+00430 .. CYRILLIC SMALL LETTER A +.. |Bcy| unicode:: U+00411 .. CYRILLIC CAPITAL LETTER BE +.. |bcy| unicode:: U+00431 .. CYRILLIC SMALL LETTER BE +.. |CHcy| unicode:: U+00427 .. CYRILLIC CAPITAL LETTER CHE +.. |chcy| unicode:: U+00447 .. CYRILLIC SMALL LETTER CHE +.. |Dcy| unicode:: U+00414 .. CYRILLIC CAPITAL LETTER DE +.. |dcy| unicode:: U+00434 .. CYRILLIC SMALL LETTER DE +.. |Ecy| unicode:: U+0042D .. CYRILLIC CAPITAL LETTER E +.. |ecy| unicode:: U+0044D .. CYRILLIC SMALL LETTER E +.. |Fcy| unicode:: U+00424 .. CYRILLIC CAPITAL LETTER EF +.. |fcy| unicode:: U+00444 .. CYRILLIC SMALL LETTER EF +.. |Gcy| unicode:: U+00413 .. CYRILLIC CAPITAL LETTER GHE +.. |gcy| unicode:: U+00433 .. CYRILLIC SMALL LETTER GHE +.. |HARDcy| unicode:: U+0042A .. CYRILLIC CAPITAL LETTER HARD SIGN +.. |hardcy| unicode:: U+0044A .. CYRILLIC SMALL LETTER HARD SIGN +.. |Icy| unicode:: U+00418 .. CYRILLIC CAPITAL LETTER I +.. |icy| unicode:: U+00438 .. CYRILLIC SMALL LETTER I +.. |IEcy| unicode:: U+00415 .. CYRILLIC CAPITAL LETTER IE +.. |iecy| unicode:: U+00435 .. CYRILLIC SMALL LETTER IE +.. |IOcy| unicode:: U+00401 .. CYRILLIC CAPITAL LETTER IO +.. |iocy| unicode:: U+00451 .. CYRILLIC SMALL LETTER IO +.. |Jcy| unicode:: U+00419 .. CYRILLIC CAPITAL LETTER SHORT I +.. |jcy| unicode:: U+00439 .. CYRILLIC SMALL LETTER SHORT I +.. |Kcy| unicode:: U+0041A .. CYRILLIC CAPITAL LETTER KA +.. |kcy| unicode:: U+0043A .. CYRILLIC SMALL LETTER KA +.. |KHcy| unicode:: U+00425 .. CYRILLIC CAPITAL LETTER HA +.. |khcy| unicode:: U+00445 .. CYRILLIC SMALL LETTER HA +.. |Lcy| unicode:: U+0041B .. CYRILLIC CAPITAL LETTER EL +.. |lcy| unicode:: U+0043B .. CYRILLIC SMALL LETTER EL +.. |Mcy| unicode:: U+0041C .. CYRILLIC CAPITAL LETTER EM +.. |mcy| unicode:: U+0043C .. CYRILLIC SMALL LETTER EM +.. |Ncy| unicode:: U+0041D .. CYRILLIC CAPITAL LETTER EN +.. |ncy| unicode:: U+0043D .. CYRILLIC SMALL LETTER EN +.. |numero| unicode:: U+02116 .. NUMERO SIGN +.. |Ocy| unicode:: U+0041E .. CYRILLIC CAPITAL LETTER O +.. |ocy| unicode:: U+0043E .. CYRILLIC SMALL LETTER O +.. |Pcy| unicode:: U+0041F .. CYRILLIC CAPITAL LETTER PE +.. |pcy| unicode:: U+0043F .. CYRILLIC SMALL LETTER PE +.. |Rcy| unicode:: U+00420 .. CYRILLIC CAPITAL LETTER ER +.. |rcy| unicode:: U+00440 .. CYRILLIC SMALL LETTER ER +.. |Scy| unicode:: U+00421 .. CYRILLIC CAPITAL LETTER ES +.. |scy| unicode:: U+00441 .. CYRILLIC SMALL LETTER ES +.. |SHCHcy| unicode:: U+00429 .. CYRILLIC CAPITAL LETTER SHCHA +.. |shchcy| unicode:: U+00449 .. CYRILLIC SMALL LETTER SHCHA +.. |SHcy| unicode:: U+00428 .. CYRILLIC CAPITAL LETTER SHA +.. |shcy| unicode:: U+00448 .. CYRILLIC SMALL LETTER SHA +.. |SOFTcy| unicode:: U+0042C .. CYRILLIC CAPITAL LETTER SOFT SIGN +.. |softcy| unicode:: U+0044C .. CYRILLIC SMALL LETTER SOFT SIGN +.. |Tcy| unicode:: U+00422 .. CYRILLIC CAPITAL LETTER TE +.. |tcy| unicode:: U+00442 .. CYRILLIC SMALL LETTER TE +.. |TScy| unicode:: U+00426 .. CYRILLIC CAPITAL LETTER TSE +.. |tscy| unicode:: U+00446 .. CYRILLIC SMALL LETTER TSE +.. |Ucy| unicode:: U+00423 .. CYRILLIC CAPITAL LETTER U +.. |ucy| unicode:: U+00443 .. CYRILLIC SMALL LETTER U +.. |Vcy| unicode:: U+00412 .. CYRILLIC CAPITAL LETTER VE +.. |vcy| unicode:: U+00432 .. CYRILLIC SMALL LETTER VE +.. |YAcy| unicode:: U+0042F .. CYRILLIC CAPITAL LETTER YA +.. |yacy| unicode:: U+0044F .. CYRILLIC SMALL LETTER YA +.. |Ycy| unicode:: U+0042B .. CYRILLIC CAPITAL LETTER YERU +.. |ycy| unicode:: U+0044B .. CYRILLIC SMALL LETTER YERU +.. |YUcy| unicode:: U+0042E .. CYRILLIC CAPITAL LETTER YU +.. |yucy| unicode:: U+0044E .. CYRILLIC SMALL LETTER YU +.. |Zcy| unicode:: U+00417 .. CYRILLIC CAPITAL LETTER ZE +.. |zcy| unicode:: U+00437 .. CYRILLIC SMALL LETTER ZE +.. |ZHcy| unicode:: U+00416 .. CYRILLIC CAPITAL LETTER ZHE +.. |zhcy| unicode:: U+00436 .. CYRILLIC SMALL LETTER ZHE diff --git a/docutils/parsers/rst/include/isocyr2.txt b/docutils/parsers/rst/include/isocyr2.txt new file mode 100644 index 000000000..fe09c015b --- /dev/null +++ b/docutils/parsers/rst/include/isocyr2.txt @@ -0,0 +1,32 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |DJcy| unicode:: U+00402 .. CYRILLIC CAPITAL LETTER DJE +.. |djcy| unicode:: U+00452 .. CYRILLIC SMALL LETTER DJE +.. |DScy| unicode:: U+00405 .. CYRILLIC CAPITAL LETTER DZE +.. |dscy| unicode:: U+00455 .. CYRILLIC SMALL LETTER DZE +.. |DZcy| unicode:: U+0040F .. CYRILLIC CAPITAL LETTER DZHE +.. |dzcy| unicode:: U+0045F .. CYRILLIC SMALL LETTER DZHE +.. |GJcy| unicode:: U+00403 .. CYRILLIC CAPITAL LETTER GJE +.. |gjcy| unicode:: U+00453 .. CYRILLIC SMALL LETTER GJE +.. |Iukcy| unicode:: U+00406 .. CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +.. |iukcy| unicode:: U+00456 .. CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +.. |Jsercy| unicode:: U+00408 .. CYRILLIC CAPITAL LETTER JE +.. |jsercy| unicode:: U+00458 .. CYRILLIC SMALL LETTER JE +.. |Jukcy| unicode:: U+00404 .. CYRILLIC CAPITAL LETTER UKRAINIAN IE +.. |jukcy| unicode:: U+00454 .. CYRILLIC SMALL LETTER UKRAINIAN IE +.. |KJcy| unicode:: U+0040C .. CYRILLIC CAPITAL LETTER KJE +.. |kjcy| unicode:: U+0045C .. CYRILLIC SMALL LETTER KJE +.. |LJcy| unicode:: U+00409 .. CYRILLIC CAPITAL LETTER LJE +.. |ljcy| unicode:: U+00459 .. CYRILLIC SMALL LETTER LJE +.. |NJcy| unicode:: U+0040A .. CYRILLIC CAPITAL LETTER NJE +.. |njcy| unicode:: U+0045A .. CYRILLIC SMALL LETTER NJE +.. |TSHcy| unicode:: U+0040B .. CYRILLIC CAPITAL LETTER TSHE +.. |tshcy| unicode:: U+0045B .. CYRILLIC SMALL LETTER TSHE +.. |Ubrcy| unicode:: U+0040E .. CYRILLIC CAPITAL LETTER SHORT U +.. |ubrcy| unicode:: U+0045E .. CYRILLIC SMALL LETTER SHORT U +.. |YIcy| unicode:: U+00407 .. CYRILLIC CAPITAL LETTER YI +.. |yicy| unicode:: U+00457 .. CYRILLIC SMALL LETTER YI diff --git a/docutils/parsers/rst/include/isodia.txt b/docutils/parsers/rst/include/isodia.txt new file mode 100644 index 000000000..ede6d9946 --- /dev/null +++ b/docutils/parsers/rst/include/isodia.txt @@ -0,0 +1,20 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |acute| unicode:: U+000B4 .. ACUTE ACCENT +.. |breve| unicode:: U+002D8 .. BREVE +.. |caron| unicode:: U+002C7 .. CARON +.. |cedil| unicode:: U+000B8 .. CEDILLA +.. |circ| unicode:: U+002C6 .. MODIFIER LETTER CIRCUMFLEX ACCENT +.. |dblac| unicode:: U+002DD .. DOUBLE ACUTE ACCENT +.. |die| unicode:: U+000A8 .. DIAERESIS +.. |dot| unicode:: U+002D9 .. DOT ABOVE +.. |grave| unicode:: U+00060 .. GRAVE ACCENT +.. |macr| unicode:: U+000AF .. MACRON +.. |ogon| unicode:: U+002DB .. OGONEK +.. |ring| unicode:: U+002DA .. RING ABOVE +.. |tilde| unicode:: U+002DC .. SMALL TILDE +.. |uml| unicode:: U+000A8 .. DIAERESIS diff --git a/docutils/parsers/rst/include/isogrk1.txt b/docutils/parsers/rst/include/isogrk1.txt new file mode 100644 index 000000000..434368a03 --- /dev/null +++ b/docutils/parsers/rst/include/isogrk1.txt @@ -0,0 +1,55 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Agr| unicode:: U+00391 .. GREEK CAPITAL LETTER ALPHA +.. |agr| unicode:: U+003B1 .. GREEK SMALL LETTER ALPHA +.. |Bgr| unicode:: U+00392 .. GREEK CAPITAL LETTER BETA +.. |bgr| unicode:: U+003B2 .. GREEK SMALL LETTER BETA +.. |Dgr| unicode:: U+00394 .. GREEK CAPITAL LETTER DELTA +.. |dgr| unicode:: U+003B4 .. GREEK SMALL LETTER DELTA +.. |EEgr| unicode:: U+00397 .. GREEK CAPITAL LETTER ETA +.. |eegr| unicode:: U+003B7 .. GREEK SMALL LETTER ETA +.. |Egr| unicode:: U+00395 .. GREEK CAPITAL LETTER EPSILON +.. |egr| unicode:: U+003B5 .. GREEK SMALL LETTER EPSILON +.. |Ggr| unicode:: U+00393 .. GREEK CAPITAL LETTER GAMMA +.. |ggr| unicode:: U+003B3 .. GREEK SMALL LETTER GAMMA +.. |Igr| unicode:: U+00399 .. GREEK CAPITAL LETTER IOTA +.. |igr| unicode:: U+003B9 .. GREEK SMALL LETTER IOTA +.. |Kgr| unicode:: U+0039A .. GREEK CAPITAL LETTER KAPPA +.. |kgr| unicode:: U+003BA .. GREEK SMALL LETTER KAPPA +.. |KHgr| unicode:: U+003A7 .. GREEK CAPITAL LETTER CHI +.. |khgr| unicode:: U+003C7 .. GREEK SMALL LETTER CHI +.. |Lgr| unicode:: U+0039B .. GREEK CAPITAL LETTER LAMDA +.. |lgr| unicode:: U+003BB .. GREEK SMALL LETTER LAMDA +.. |Mgr| unicode:: U+0039C .. GREEK CAPITAL LETTER MU +.. |mgr| unicode:: U+003BC .. GREEK SMALL LETTER MU +.. |Ngr| unicode:: U+0039D .. GREEK CAPITAL LETTER NU +.. |ngr| unicode:: U+003BD .. GREEK SMALL LETTER NU +.. |Ogr| unicode:: U+0039F .. GREEK CAPITAL LETTER OMICRON +.. |ogr| unicode:: U+003BF .. GREEK SMALL LETTER OMICRON +.. |OHgr| unicode:: U+003A9 .. GREEK CAPITAL LETTER OMEGA +.. |ohgr| unicode:: U+003C9 .. GREEK SMALL LETTER OMEGA +.. |Pgr| unicode:: U+003A0 .. GREEK CAPITAL LETTER PI +.. |pgr| unicode:: U+003C0 .. GREEK SMALL LETTER PI +.. |PHgr| unicode:: U+003A6 .. GREEK CAPITAL LETTER PHI +.. |phgr| unicode:: U+003C6 .. GREEK SMALL LETTER PHI +.. |PSgr| unicode:: U+003A8 .. GREEK CAPITAL LETTER PSI +.. |psgr| unicode:: U+003C8 .. GREEK SMALL LETTER PSI +.. |Rgr| unicode:: U+003A1 .. GREEK CAPITAL LETTER RHO +.. |rgr| unicode:: U+003C1 .. GREEK SMALL LETTER RHO +.. |sfgr| unicode:: U+003C2 .. GREEK SMALL LETTER FINAL SIGMA +.. |Sgr| unicode:: U+003A3 .. GREEK CAPITAL LETTER SIGMA +.. |sgr| unicode:: U+003C3 .. GREEK SMALL LETTER SIGMA +.. |Tgr| unicode:: U+003A4 .. GREEK CAPITAL LETTER TAU +.. |tgr| unicode:: U+003C4 .. GREEK SMALL LETTER TAU +.. |THgr| unicode:: U+00398 .. GREEK CAPITAL LETTER THETA +.. |thgr| unicode:: U+003B8 .. GREEK SMALL LETTER THETA +.. |Ugr| unicode:: U+003A5 .. GREEK CAPITAL LETTER UPSILON +.. |ugr| unicode:: U+003C5 .. GREEK SMALL LETTER UPSILON +.. |Xgr| unicode:: U+0039E .. GREEK CAPITAL LETTER XI +.. |xgr| unicode:: U+003BE .. GREEK SMALL LETTER XI +.. |Zgr| unicode:: U+00396 .. GREEK CAPITAL LETTER ZETA +.. |zgr| unicode:: U+003B6 .. GREEK SMALL LETTER ZETA diff --git a/docutils/parsers/rst/include/isogrk2.txt b/docutils/parsers/rst/include/isogrk2.txt new file mode 100644 index 000000000..fa59f968d --- /dev/null +++ b/docutils/parsers/rst/include/isogrk2.txt @@ -0,0 +1,26 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Aacgr| unicode:: U+00386 .. GREEK CAPITAL LETTER ALPHA WITH TONOS +.. |aacgr| unicode:: U+003AC .. GREEK SMALL LETTER ALPHA WITH TONOS +.. |Eacgr| unicode:: U+00388 .. GREEK CAPITAL LETTER EPSILON WITH TONOS +.. |eacgr| unicode:: U+003AD .. GREEK SMALL LETTER EPSILON WITH TONOS +.. |EEacgr| unicode:: U+00389 .. GREEK CAPITAL LETTER ETA WITH TONOS +.. |eeacgr| unicode:: U+003AE .. GREEK SMALL LETTER ETA WITH TONOS +.. |Iacgr| unicode:: U+0038A .. GREEK CAPITAL LETTER IOTA WITH TONOS +.. |iacgr| unicode:: U+003AF .. GREEK SMALL LETTER IOTA WITH TONOS +.. |idiagr| unicode:: U+00390 .. GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +.. |Idigr| unicode:: U+003AA .. GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +.. |idigr| unicode:: U+003CA .. GREEK SMALL LETTER IOTA WITH DIALYTIKA +.. |Oacgr| unicode:: U+0038C .. GREEK CAPITAL LETTER OMICRON WITH TONOS +.. |oacgr| unicode:: U+003CC .. GREEK SMALL LETTER OMICRON WITH TONOS +.. |OHacgr| unicode:: U+0038F .. GREEK CAPITAL LETTER OMEGA WITH TONOS +.. |ohacgr| unicode:: U+003CE .. GREEK SMALL LETTER OMEGA WITH TONOS +.. |Uacgr| unicode:: U+0038E .. GREEK CAPITAL LETTER UPSILON WITH TONOS +.. |uacgr| unicode:: U+003CD .. GREEK SMALL LETTER UPSILON WITH TONOS +.. |udiagr| unicode:: U+003B0 .. GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +.. |Udigr| unicode:: U+003AB .. GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +.. |udigr| unicode:: U+003CB .. GREEK SMALL LETTER UPSILON WITH DIALYTIKA diff --git a/docutils/parsers/rst/include/isogrk3.txt b/docutils/parsers/rst/include/isogrk3.txt new file mode 100644 index 000000000..efacd980b --- /dev/null +++ b/docutils/parsers/rst/include/isogrk3.txt @@ -0,0 +1,52 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |alpha| unicode:: U+003B1 .. GREEK SMALL LETTER ALPHA +.. |beta| unicode:: U+003B2 .. GREEK SMALL LETTER BETA +.. |chi| unicode:: U+003C7 .. GREEK SMALL LETTER CHI +.. |Delta| unicode:: U+00394 .. GREEK CAPITAL LETTER DELTA +.. |delta| unicode:: U+003B4 .. GREEK SMALL LETTER DELTA +.. |epsi| unicode:: U+003F5 .. GREEK LUNATE EPSILON SYMBOL +.. |epsis| unicode:: U+003F5 .. GREEK LUNATE EPSILON SYMBOL +.. |epsiv| unicode:: U+003B5 .. GREEK SMALL LETTER EPSILON +.. |eta| unicode:: U+003B7 .. GREEK SMALL LETTER ETA +.. |Gamma| unicode:: U+00393 .. GREEK CAPITAL LETTER GAMMA +.. |gamma| unicode:: U+003B3 .. GREEK SMALL LETTER GAMMA +.. |Gammad| unicode:: U+003DC .. GREEK LETTER DIGAMMA +.. |gammad| unicode:: U+003DD .. GREEK SMALL LETTER DIGAMMA +.. |iota| unicode:: U+003B9 .. GREEK SMALL LETTER IOTA +.. |kappa| unicode:: U+003BA .. GREEK SMALL LETTER KAPPA +.. |kappav| unicode:: U+003F0 .. GREEK KAPPA SYMBOL +.. |Lambda| unicode:: U+0039B .. GREEK CAPITAL LETTER LAMDA +.. |lambda| unicode:: U+003BB .. GREEK SMALL LETTER LAMDA +.. |mu| unicode:: U+003BC .. GREEK SMALL LETTER MU +.. |nu| unicode:: U+003BD .. GREEK SMALL LETTER NU +.. |Omega| unicode:: U+003A9 .. GREEK CAPITAL LETTER OMEGA +.. |omega| unicode:: U+003C9 .. GREEK SMALL LETTER OMEGA +.. |Phi| unicode:: U+003A6 .. GREEK CAPITAL LETTER PHI +.. |phi| unicode:: U+003D5 .. GREEK PHI SYMBOL +.. |phis| unicode:: U+003D5 .. GREEK PHI SYMBOL +.. |phiv| unicode:: U+003C6 .. GREEK SMALL LETTER PHI +.. |Pi| unicode:: U+003A0 .. GREEK CAPITAL LETTER PI +.. |pi| unicode:: U+003C0 .. GREEK SMALL LETTER PI +.. |piv| unicode:: U+003D6 .. GREEK PI SYMBOL +.. |Psi| unicode:: U+003A8 .. GREEK CAPITAL LETTER PSI +.. |psi| unicode:: U+003C8 .. GREEK SMALL LETTER PSI +.. |rho| unicode:: U+003C1 .. GREEK SMALL LETTER RHO +.. |rhov| unicode:: U+003F1 .. GREEK RHO SYMBOL +.. |Sigma| unicode:: U+003A3 .. GREEK CAPITAL LETTER SIGMA +.. |sigma| unicode:: U+003C3 .. GREEK SMALL LETTER SIGMA +.. |sigmav| unicode:: U+003C2 .. GREEK SMALL LETTER FINAL SIGMA +.. |tau| unicode:: U+003C4 .. GREEK SMALL LETTER TAU +.. |Theta| unicode:: U+00398 .. GREEK CAPITAL LETTER THETA +.. |theta| unicode:: U+003B8 .. GREEK SMALL LETTER THETA +.. |thetas| unicode:: U+003B8 .. GREEK SMALL LETTER THETA +.. |thetav| unicode:: U+003D1 .. GREEK THETA SYMBOL +.. |Upsi| unicode:: U+003D2 .. GREEK UPSILON WITH HOOK SYMBOL +.. |upsi| unicode:: U+003C5 .. GREEK SMALL LETTER UPSILON +.. |Xi| unicode:: U+0039E .. GREEK CAPITAL LETTER XI +.. |xi| unicode:: U+003BE .. GREEK SMALL LETTER XI +.. |zeta| unicode:: U+003B6 .. GREEK SMALL LETTER ZETA diff --git a/docutils/parsers/rst/include/isogrk4-wide.txt b/docutils/parsers/rst/include/isogrk4-wide.txt new file mode 100644 index 000000000..39a63075d --- /dev/null +++ b/docutils/parsers/rst/include/isogrk4-wide.txt @@ -0,0 +1,49 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |b.alpha| unicode:: U+1D6C2 .. MATHEMATICAL BOLD SMALL ALPHA +.. |b.beta| unicode:: U+1D6C3 .. MATHEMATICAL BOLD SMALL BETA +.. |b.chi| unicode:: U+1D6D8 .. MATHEMATICAL BOLD SMALL CHI +.. |b.Delta| unicode:: U+1D6AB .. MATHEMATICAL BOLD CAPITAL DELTA +.. |b.delta| unicode:: U+1D6C5 .. MATHEMATICAL BOLD SMALL DELTA +.. |b.epsi| unicode:: U+1D6C6 .. MATHEMATICAL BOLD SMALL EPSILON +.. |b.epsiv| unicode:: U+1D6DC .. MATHEMATICAL BOLD EPSILON SYMBOL +.. |b.eta| unicode:: U+1D6C8 .. MATHEMATICAL BOLD SMALL ETA +.. |b.Gamma| unicode:: U+1D6AA .. MATHEMATICAL BOLD CAPITAL GAMMA +.. |b.gamma| unicode:: U+1D6C4 .. MATHEMATICAL BOLD SMALL GAMMA +.. |b.Gammad| unicode:: U+003DC .. GREEK LETTER DIGAMMA +.. |b.gammad| unicode:: U+003DD .. GREEK SMALL LETTER DIGAMMA +.. |b.iota| unicode:: U+1D6CA .. MATHEMATICAL BOLD SMALL IOTA +.. |b.kappa| unicode:: U+1D6CB .. MATHEMATICAL BOLD SMALL KAPPA +.. |b.kappav| unicode:: U+1D6DE .. MATHEMATICAL BOLD KAPPA SYMBOL +.. |b.Lambda| unicode:: U+1D6B2 .. MATHEMATICAL BOLD CAPITAL LAMDA +.. |b.lambda| unicode:: U+1D6CC .. MATHEMATICAL BOLD SMALL LAMDA +.. |b.mu| unicode:: U+1D6CD .. MATHEMATICAL BOLD SMALL MU +.. |b.nu| unicode:: U+1D6CE .. MATHEMATICAL BOLD SMALL NU +.. |b.Omega| unicode:: U+1D6C0 .. MATHEMATICAL BOLD CAPITAL OMEGA +.. |b.omega| unicode:: U+1D6DA .. MATHEMATICAL BOLD SMALL OMEGA +.. |b.Phi| unicode:: U+1D6BD .. MATHEMATICAL BOLD CAPITAL PHI +.. |b.phi| unicode:: U+1D6D7 .. MATHEMATICAL BOLD SMALL PHI +.. |b.phiv| unicode:: U+1D6DF .. MATHEMATICAL BOLD PHI SYMBOL +.. |b.Pi| unicode:: U+1D6B7 .. MATHEMATICAL BOLD CAPITAL PI +.. |b.pi| unicode:: U+1D6D1 .. MATHEMATICAL BOLD SMALL PI +.. |b.piv| unicode:: U+1D6E1 .. MATHEMATICAL BOLD PI SYMBOL +.. |b.Psi| unicode:: U+1D6BF .. MATHEMATICAL BOLD CAPITAL PSI +.. |b.psi| unicode:: U+1D6D9 .. MATHEMATICAL BOLD SMALL PSI +.. |b.rho| unicode:: U+1D6D2 .. MATHEMATICAL BOLD SMALL RHO +.. |b.rhov| unicode:: U+1D6E0 .. MATHEMATICAL BOLD RHO SYMBOL +.. |b.Sigma| unicode:: U+1D6BA .. MATHEMATICAL BOLD CAPITAL SIGMA +.. |b.sigma| unicode:: U+1D6D4 .. MATHEMATICAL BOLD SMALL SIGMA +.. |b.sigmav| unicode:: U+1D6D3 .. MATHEMATICAL BOLD SMALL FINAL SIGMA +.. |b.tau| unicode:: U+1D6D5 .. MATHEMATICAL BOLD SMALL TAU +.. |b.Theta| unicode:: U+1D6AF .. MATHEMATICAL BOLD CAPITAL THETA +.. |b.thetas| unicode:: U+1D6C9 .. MATHEMATICAL BOLD SMALL THETA +.. |b.thetav| unicode:: U+1D6DD .. MATHEMATICAL BOLD THETA SYMBOL +.. |b.Upsi| unicode:: U+1D6BC .. MATHEMATICAL BOLD CAPITAL UPSILON +.. |b.upsi| unicode:: U+1D6D6 .. MATHEMATICAL BOLD SMALL UPSILON +.. |b.Xi| unicode:: U+1D6B5 .. MATHEMATICAL BOLD CAPITAL XI +.. |b.xi| unicode:: U+1D6CF .. MATHEMATICAL BOLD SMALL XI +.. |b.zeta| unicode:: U+1D6C7 .. MATHEMATICAL BOLD SMALL ZETA diff --git a/docutils/parsers/rst/include/isogrk4.txt b/docutils/parsers/rst/include/isogrk4.txt new file mode 100644 index 000000000..5b9f4104f --- /dev/null +++ b/docutils/parsers/rst/include/isogrk4.txt @@ -0,0 +1,8 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |b.Gammad| unicode:: U+003DC .. GREEK LETTER DIGAMMA +.. |b.gammad| unicode:: U+003DD .. GREEK SMALL LETTER DIGAMMA diff --git a/docutils/parsers/rst/include/isolat1.txt b/docutils/parsers/rst/include/isolat1.txt new file mode 100644 index 000000000..3e9ad9df3 --- /dev/null +++ b/docutils/parsers/rst/include/isolat1.txt @@ -0,0 +1,68 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Aacute| unicode:: U+000C1 .. LATIN CAPITAL LETTER A WITH ACUTE +.. |aacute| unicode:: U+000E1 .. LATIN SMALL LETTER A WITH ACUTE +.. |Acirc| unicode:: U+000C2 .. LATIN CAPITAL LETTER A WITH CIRCUMFLEX +.. |acirc| unicode:: U+000E2 .. LATIN SMALL LETTER A WITH CIRCUMFLEX +.. |AElig| unicode:: U+000C6 .. LATIN CAPITAL LETTER AE +.. |aelig| unicode:: U+000E6 .. LATIN SMALL LETTER AE +.. |Agrave| unicode:: U+000C0 .. LATIN CAPITAL LETTER A WITH GRAVE +.. |agrave| unicode:: U+000E0 .. LATIN SMALL LETTER A WITH GRAVE +.. |Aring| unicode:: U+000C5 .. LATIN CAPITAL LETTER A WITH RING ABOVE +.. |aring| unicode:: U+000E5 .. LATIN SMALL LETTER A WITH RING ABOVE +.. |Atilde| unicode:: U+000C3 .. LATIN CAPITAL LETTER A WITH TILDE +.. |atilde| unicode:: U+000E3 .. LATIN SMALL LETTER A WITH TILDE +.. |Auml| unicode:: U+000C4 .. LATIN CAPITAL LETTER A WITH DIAERESIS +.. |auml| unicode:: U+000E4 .. LATIN SMALL LETTER A WITH DIAERESIS +.. |Ccedil| unicode:: U+000C7 .. LATIN CAPITAL LETTER C WITH CEDILLA +.. |ccedil| unicode:: U+000E7 .. LATIN SMALL LETTER C WITH CEDILLA +.. |Eacute| unicode:: U+000C9 .. LATIN CAPITAL LETTER E WITH ACUTE +.. |eacute| unicode:: U+000E9 .. LATIN SMALL LETTER E WITH ACUTE +.. |Ecirc| unicode:: U+000CA .. LATIN CAPITAL LETTER E WITH CIRCUMFLEX +.. |ecirc| unicode:: U+000EA .. LATIN SMALL LETTER E WITH CIRCUMFLEX +.. |Egrave| unicode:: U+000C8 .. LATIN CAPITAL LETTER E WITH GRAVE +.. |egrave| unicode:: U+000E8 .. LATIN SMALL LETTER E WITH GRAVE +.. |ETH| unicode:: U+000D0 .. LATIN CAPITAL LETTER ETH +.. |eth| unicode:: U+000F0 .. LATIN SMALL LETTER ETH +.. |Euml| unicode:: U+000CB .. LATIN CAPITAL LETTER E WITH DIAERESIS +.. |euml| unicode:: U+000EB .. LATIN SMALL LETTER E WITH DIAERESIS +.. |Iacute| unicode:: U+000CD .. LATIN CAPITAL LETTER I WITH ACUTE +.. |iacute| unicode:: U+000ED .. LATIN SMALL LETTER I WITH ACUTE +.. |Icirc| unicode:: U+000CE .. LATIN CAPITAL LETTER I WITH CIRCUMFLEX +.. |icirc| unicode:: U+000EE .. LATIN SMALL LETTER I WITH CIRCUMFLEX +.. |Igrave| unicode:: U+000CC .. LATIN CAPITAL LETTER I WITH GRAVE +.. |igrave| unicode:: U+000EC .. LATIN SMALL LETTER I WITH GRAVE +.. |Iuml| unicode:: U+000CF .. LATIN CAPITAL LETTER I WITH DIAERESIS +.. |iuml| unicode:: U+000EF .. LATIN SMALL LETTER I WITH DIAERESIS +.. |Ntilde| unicode:: U+000D1 .. LATIN CAPITAL LETTER N WITH TILDE +.. |ntilde| unicode:: U+000F1 .. LATIN SMALL LETTER N WITH TILDE +.. |Oacute| unicode:: U+000D3 .. LATIN CAPITAL LETTER O WITH ACUTE +.. |oacute| unicode:: U+000F3 .. LATIN SMALL LETTER O WITH ACUTE +.. |Ocirc| unicode:: U+000D4 .. LATIN CAPITAL LETTER O WITH CIRCUMFLEX +.. |ocirc| unicode:: U+000F4 .. LATIN SMALL LETTER O WITH CIRCUMFLEX +.. |Ograve| unicode:: U+000D2 .. LATIN CAPITAL LETTER O WITH GRAVE +.. |ograve| unicode:: U+000F2 .. LATIN SMALL LETTER O WITH GRAVE +.. |Oslash| unicode:: U+000D8 .. LATIN CAPITAL LETTER O WITH STROKE +.. |oslash| unicode:: U+000F8 .. LATIN SMALL LETTER O WITH STROKE +.. |Otilde| unicode:: U+000D5 .. LATIN CAPITAL LETTER O WITH TILDE +.. |otilde| unicode:: U+000F5 .. LATIN SMALL LETTER O WITH TILDE +.. |Ouml| unicode:: U+000D6 .. LATIN CAPITAL LETTER O WITH DIAERESIS +.. |ouml| unicode:: U+000F6 .. LATIN SMALL LETTER O WITH DIAERESIS +.. |szlig| unicode:: U+000DF .. LATIN SMALL LETTER SHARP S +.. |THORN| unicode:: U+000DE .. LATIN CAPITAL LETTER THORN +.. |thorn| unicode:: U+000FE .. LATIN SMALL LETTER THORN +.. |Uacute| unicode:: U+000DA .. LATIN CAPITAL LETTER U WITH ACUTE +.. |uacute| unicode:: U+000FA .. LATIN SMALL LETTER U WITH ACUTE +.. |Ucirc| unicode:: U+000DB .. LATIN CAPITAL LETTER U WITH CIRCUMFLEX +.. |ucirc| unicode:: U+000FB .. LATIN SMALL LETTER U WITH CIRCUMFLEX +.. |Ugrave| unicode:: U+000D9 .. LATIN CAPITAL LETTER U WITH GRAVE +.. |ugrave| unicode:: U+000F9 .. LATIN SMALL LETTER U WITH GRAVE +.. |Uuml| unicode:: U+000DC .. LATIN CAPITAL LETTER U WITH DIAERESIS +.. |uuml| unicode:: U+000FC .. LATIN SMALL LETTER U WITH DIAERESIS +.. |Yacute| unicode:: U+000DD .. LATIN CAPITAL LETTER Y WITH ACUTE +.. |yacute| unicode:: U+000FD .. LATIN SMALL LETTER Y WITH ACUTE +.. |yuml| unicode:: U+000FF .. LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/docutils/parsers/rst/include/isolat2.txt b/docutils/parsers/rst/include/isolat2.txt new file mode 100644 index 000000000..20de84576 --- /dev/null +++ b/docutils/parsers/rst/include/isolat2.txt @@ -0,0 +1,128 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Abreve| unicode:: U+00102 .. LATIN CAPITAL LETTER A WITH BREVE +.. |abreve| unicode:: U+00103 .. LATIN SMALL LETTER A WITH BREVE +.. |Amacr| unicode:: U+00100 .. LATIN CAPITAL LETTER A WITH MACRON +.. |amacr| unicode:: U+00101 .. LATIN SMALL LETTER A WITH MACRON +.. |Aogon| unicode:: U+00104 .. LATIN CAPITAL LETTER A WITH OGONEK +.. |aogon| unicode:: U+00105 .. LATIN SMALL LETTER A WITH OGONEK +.. |Cacute| unicode:: U+00106 .. LATIN CAPITAL LETTER C WITH ACUTE +.. |cacute| unicode:: U+00107 .. LATIN SMALL LETTER C WITH ACUTE +.. |Ccaron| unicode:: U+0010C .. LATIN CAPITAL LETTER C WITH CARON +.. |ccaron| unicode:: U+0010D .. LATIN SMALL LETTER C WITH CARON +.. |Ccirc| unicode:: U+00108 .. LATIN CAPITAL LETTER C WITH CIRCUMFLEX +.. |ccirc| unicode:: U+00109 .. LATIN SMALL LETTER C WITH CIRCUMFLEX +.. |Cdot| unicode:: U+0010A .. LATIN CAPITAL LETTER C WITH DOT ABOVE +.. |cdot| unicode:: U+0010B .. LATIN SMALL LETTER C WITH DOT ABOVE +.. |Dcaron| unicode:: U+0010E .. LATIN CAPITAL LETTER D WITH CARON +.. |dcaron| unicode:: U+0010F .. LATIN SMALL LETTER D WITH CARON +.. |Dstrok| unicode:: U+00110 .. LATIN CAPITAL LETTER D WITH STROKE +.. |dstrok| unicode:: U+00111 .. LATIN SMALL LETTER D WITH STROKE +.. |Ecaron| unicode:: U+0011A .. LATIN CAPITAL LETTER E WITH CARON +.. |ecaron| unicode:: U+0011B .. LATIN SMALL LETTER E WITH CARON +.. |Edot| unicode:: U+00116 .. LATIN CAPITAL LETTER E WITH DOT ABOVE +.. |edot| unicode:: U+00117 .. LATIN SMALL LETTER E WITH DOT ABOVE +.. |Emacr| unicode:: U+00112 .. LATIN CAPITAL LETTER E WITH MACRON +.. |emacr| unicode:: U+00113 .. LATIN SMALL LETTER E WITH MACRON +.. |ENG| unicode:: U+0014A .. LATIN CAPITAL LETTER ENG +.. |eng| unicode:: U+0014B .. LATIN SMALL LETTER ENG +.. |Eogon| unicode:: U+00118 .. LATIN CAPITAL LETTER E WITH OGONEK +.. |eogon| unicode:: U+00119 .. LATIN SMALL LETTER E WITH OGONEK +.. |gacute| unicode:: U+001F5 .. LATIN SMALL LETTER G WITH ACUTE +.. |Gbreve| unicode:: U+0011E .. LATIN CAPITAL LETTER G WITH BREVE +.. |gbreve| unicode:: U+0011F .. LATIN SMALL LETTER G WITH BREVE +.. |Gcedil| unicode:: U+00122 .. LATIN CAPITAL LETTER G WITH CEDILLA +.. |gcedil| unicode:: U+00123 .. LATIN SMALL LETTER G WITH CEDILLA +.. |Gcirc| unicode:: U+0011C .. LATIN CAPITAL LETTER G WITH CIRCUMFLEX +.. |gcirc| unicode:: U+0011D .. LATIN SMALL LETTER G WITH CIRCUMFLEX +.. |Gdot| unicode:: U+00120 .. LATIN CAPITAL LETTER G WITH DOT ABOVE +.. |gdot| unicode:: U+00121 .. LATIN SMALL LETTER G WITH DOT ABOVE +.. |Hcirc| unicode:: U+00124 .. LATIN CAPITAL LETTER H WITH CIRCUMFLEX +.. |hcirc| unicode:: U+00125 .. LATIN SMALL LETTER H WITH CIRCUMFLEX +.. |Hstrok| unicode:: U+00126 .. LATIN CAPITAL LETTER H WITH STROKE +.. |hstrok| unicode:: U+00127 .. LATIN SMALL LETTER H WITH STROKE +.. |Idot| unicode:: U+00130 .. LATIN CAPITAL LETTER I WITH DOT ABOVE +.. |IJlig| unicode:: U+00132 .. LATIN CAPITAL LIGATURE IJ +.. |ijlig| unicode:: U+00133 .. LATIN SMALL LIGATURE IJ +.. |Imacr| unicode:: U+0012A .. LATIN CAPITAL LETTER I WITH MACRON +.. |imacr| unicode:: U+0012B .. LATIN SMALL LETTER I WITH MACRON +.. |inodot| unicode:: U+00131 .. LATIN SMALL LETTER DOTLESS I +.. |Iogon| unicode:: U+0012E .. LATIN CAPITAL LETTER I WITH OGONEK +.. |iogon| unicode:: U+0012F .. LATIN SMALL LETTER I WITH OGONEK +.. |Itilde| unicode:: U+00128 .. LATIN CAPITAL LETTER I WITH TILDE +.. |itilde| unicode:: U+00129 .. LATIN SMALL LETTER I WITH TILDE +.. |Jcirc| unicode:: U+00134 .. LATIN CAPITAL LETTER J WITH CIRCUMFLEX +.. |jcirc| unicode:: U+00135 .. LATIN SMALL LETTER J WITH CIRCUMFLEX +.. |Kcedil| unicode:: U+00136 .. LATIN CAPITAL LETTER K WITH CEDILLA +.. |kcedil| unicode:: U+00137 .. LATIN SMALL LETTER K WITH CEDILLA +.. |kgreen| unicode:: U+00138 .. LATIN SMALL LETTER KRA +.. |Lacute| unicode:: U+00139 .. LATIN CAPITAL LETTER L WITH ACUTE +.. |lacute| unicode:: U+0013A .. LATIN SMALL LETTER L WITH ACUTE +.. |Lcaron| unicode:: U+0013D .. LATIN CAPITAL LETTER L WITH CARON +.. |lcaron| unicode:: U+0013E .. LATIN SMALL LETTER L WITH CARON +.. |Lcedil| unicode:: U+0013B .. LATIN CAPITAL LETTER L WITH CEDILLA +.. |lcedil| unicode:: U+0013C .. LATIN SMALL LETTER L WITH CEDILLA +.. |Lmidot| unicode:: U+0013F .. LATIN CAPITAL LETTER L WITH MIDDLE DOT +.. |lmidot| unicode:: U+00140 .. LATIN SMALL LETTER L WITH MIDDLE DOT +.. |Lstrok| unicode:: U+00141 .. LATIN CAPITAL LETTER L WITH STROKE +.. |lstrok| unicode:: U+00142 .. LATIN SMALL LETTER L WITH STROKE +.. |Nacute| unicode:: U+00143 .. LATIN CAPITAL LETTER N WITH ACUTE +.. |nacute| unicode:: U+00144 .. LATIN SMALL LETTER N WITH ACUTE +.. |napos| unicode:: U+00149 .. LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +.. |Ncaron| unicode:: U+00147 .. LATIN CAPITAL LETTER N WITH CARON +.. |ncaron| unicode:: U+00148 .. LATIN SMALL LETTER N WITH CARON +.. |Ncedil| unicode:: U+00145 .. LATIN CAPITAL LETTER N WITH CEDILLA +.. |ncedil| unicode:: U+00146 .. LATIN SMALL LETTER N WITH CEDILLA +.. |Odblac| unicode:: U+00150 .. LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +.. |odblac| unicode:: U+00151 .. LATIN SMALL LETTER O WITH DOUBLE ACUTE +.. |OElig| unicode:: U+00152 .. LATIN CAPITAL LIGATURE OE +.. |oelig| unicode:: U+00153 .. LATIN SMALL LIGATURE OE +.. |Omacr| unicode:: U+0014C .. LATIN CAPITAL LETTER O WITH MACRON +.. |omacr| unicode:: U+0014D .. LATIN SMALL LETTER O WITH MACRON +.. |Racute| unicode:: U+00154 .. LATIN CAPITAL LETTER R WITH ACUTE +.. |racute| unicode:: U+00155 .. LATIN SMALL LETTER R WITH ACUTE +.. |Rcaron| unicode:: U+00158 .. LATIN CAPITAL LETTER R WITH CARON +.. |rcaron| unicode:: U+00159 .. LATIN SMALL LETTER R WITH CARON +.. |Rcedil| unicode:: U+00156 .. LATIN CAPITAL LETTER R WITH CEDILLA +.. |rcedil| unicode:: U+00157 .. LATIN SMALL LETTER R WITH CEDILLA +.. |Sacute| unicode:: U+0015A .. LATIN CAPITAL LETTER S WITH ACUTE +.. |sacute| unicode:: U+0015B .. LATIN SMALL LETTER S WITH ACUTE +.. |Scaron| unicode:: U+00160 .. LATIN CAPITAL LETTER S WITH CARON +.. |scaron| unicode:: U+00161 .. LATIN SMALL LETTER S WITH CARON +.. |Scedil| unicode:: U+0015E .. LATIN CAPITAL LETTER S WITH CEDILLA +.. |scedil| unicode:: U+0015F .. LATIN SMALL LETTER S WITH CEDILLA +.. |Scirc| unicode:: U+0015C .. LATIN CAPITAL LETTER S WITH CIRCUMFLEX +.. |scirc| unicode:: U+0015D .. LATIN SMALL LETTER S WITH CIRCUMFLEX +.. |Tcaron| unicode:: U+00164 .. LATIN CAPITAL LETTER T WITH CARON +.. |tcaron| unicode:: U+00165 .. LATIN SMALL LETTER T WITH CARON +.. |Tcedil| unicode:: U+00162 .. LATIN CAPITAL LETTER T WITH CEDILLA +.. |tcedil| unicode:: U+00163 .. LATIN SMALL LETTER T WITH CEDILLA +.. |Tstrok| unicode:: U+00166 .. LATIN CAPITAL LETTER T WITH STROKE +.. |tstrok| unicode:: U+00167 .. LATIN SMALL LETTER T WITH STROKE +.. |Ubreve| unicode:: U+0016C .. LATIN CAPITAL LETTER U WITH BREVE +.. |ubreve| unicode:: U+0016D .. LATIN SMALL LETTER U WITH BREVE +.. |Udblac| unicode:: U+00170 .. LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +.. |udblac| unicode:: U+00171 .. LATIN SMALL LETTER U WITH DOUBLE ACUTE +.. |Umacr| unicode:: U+0016A .. LATIN CAPITAL LETTER U WITH MACRON +.. |umacr| unicode:: U+0016B .. LATIN SMALL LETTER U WITH MACRON +.. |Uogon| unicode:: U+00172 .. LATIN CAPITAL LETTER U WITH OGONEK +.. |uogon| unicode:: U+00173 .. LATIN SMALL LETTER U WITH OGONEK +.. |Uring| unicode:: U+0016E .. LATIN CAPITAL LETTER U WITH RING ABOVE +.. |uring| unicode:: U+0016F .. LATIN SMALL LETTER U WITH RING ABOVE +.. |Utilde| unicode:: U+00168 .. LATIN CAPITAL LETTER U WITH TILDE +.. |utilde| unicode:: U+00169 .. LATIN SMALL LETTER U WITH TILDE +.. |Wcirc| unicode:: U+00174 .. LATIN CAPITAL LETTER W WITH CIRCUMFLEX +.. |wcirc| unicode:: U+00175 .. LATIN SMALL LETTER W WITH CIRCUMFLEX +.. |Ycirc| unicode:: U+00176 .. LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +.. |ycirc| unicode:: U+00177 .. LATIN SMALL LETTER Y WITH CIRCUMFLEX +.. |Yuml| unicode:: U+00178 .. LATIN CAPITAL LETTER Y WITH DIAERESIS +.. |Zacute| unicode:: U+00179 .. LATIN CAPITAL LETTER Z WITH ACUTE +.. |zacute| unicode:: U+0017A .. LATIN SMALL LETTER Z WITH ACUTE +.. |Zcaron| unicode:: U+0017D .. LATIN CAPITAL LETTER Z WITH CARON +.. |zcaron| unicode:: U+0017E .. LATIN SMALL LETTER Z WITH CARON +.. |Zdot| unicode:: U+0017B .. LATIN CAPITAL LETTER Z WITH DOT ABOVE +.. |zdot| unicode:: U+0017C .. LATIN SMALL LETTER Z WITH DOT ABOVE diff --git a/docutils/parsers/rst/include/isomfrk-wide.txt b/docutils/parsers/rst/include/isomfrk-wide.txt new file mode 100644 index 000000000..75bba2575 --- /dev/null +++ b/docutils/parsers/rst/include/isomfrk-wide.txt @@ -0,0 +1,58 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Afr| unicode:: U+1D504 .. MATHEMATICAL FRAKTUR CAPITAL A +.. |afr| unicode:: U+1D51E .. MATHEMATICAL FRAKTUR SMALL A +.. |Bfr| unicode:: U+1D505 .. MATHEMATICAL FRAKTUR CAPITAL B +.. |bfr| unicode:: U+1D51F .. MATHEMATICAL FRAKTUR SMALL B +.. |Cfr| unicode:: U+0212D .. BLACK-LETTER CAPITAL C +.. |cfr| unicode:: U+1D520 .. MATHEMATICAL FRAKTUR SMALL C +.. |Dfr| unicode:: U+1D507 .. MATHEMATICAL FRAKTUR CAPITAL D +.. |dfr| unicode:: U+1D521 .. MATHEMATICAL FRAKTUR SMALL D +.. |Efr| unicode:: U+1D508 .. MATHEMATICAL FRAKTUR CAPITAL E +.. |efr| unicode:: U+1D522 .. MATHEMATICAL FRAKTUR SMALL E +.. |Ffr| unicode:: U+1D509 .. MATHEMATICAL FRAKTUR CAPITAL F +.. |ffr| unicode:: U+1D523 .. MATHEMATICAL FRAKTUR SMALL F +.. |Gfr| unicode:: U+1D50A .. MATHEMATICAL FRAKTUR CAPITAL G +.. |gfr| unicode:: U+1D524 .. MATHEMATICAL FRAKTUR SMALL G +.. |Hfr| unicode:: U+0210C .. BLACK-LETTER CAPITAL H +.. |hfr| unicode:: U+1D525 .. MATHEMATICAL FRAKTUR SMALL H +.. |Ifr| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |ifr| unicode:: U+1D526 .. MATHEMATICAL FRAKTUR SMALL I +.. |Jfr| unicode:: U+1D50D .. MATHEMATICAL FRAKTUR CAPITAL J +.. |jfr| unicode:: U+1D527 .. MATHEMATICAL FRAKTUR SMALL J +.. |Kfr| unicode:: U+1D50E .. MATHEMATICAL FRAKTUR CAPITAL K +.. |kfr| unicode:: U+1D528 .. MATHEMATICAL FRAKTUR SMALL K +.. |Lfr| unicode:: U+1D50F .. MATHEMATICAL FRAKTUR CAPITAL L +.. |lfr| unicode:: U+1D529 .. MATHEMATICAL FRAKTUR SMALL L +.. |Mfr| unicode:: U+1D510 .. MATHEMATICAL FRAKTUR CAPITAL M +.. |mfr| unicode:: U+1D52A .. MATHEMATICAL FRAKTUR SMALL M +.. |Nfr| unicode:: U+1D511 .. MATHEMATICAL FRAKTUR CAPITAL N +.. |nfr| unicode:: U+1D52B .. MATHEMATICAL FRAKTUR SMALL N +.. |Ofr| unicode:: U+1D512 .. MATHEMATICAL FRAKTUR CAPITAL O +.. |ofr| unicode:: U+1D52C .. MATHEMATICAL FRAKTUR SMALL O +.. |Pfr| unicode:: U+1D513 .. MATHEMATICAL FRAKTUR CAPITAL P +.. |pfr| unicode:: U+1D52D .. MATHEMATICAL FRAKTUR SMALL P +.. |Qfr| unicode:: U+1D514 .. MATHEMATICAL FRAKTUR CAPITAL Q +.. |qfr| unicode:: U+1D52E .. MATHEMATICAL FRAKTUR SMALL Q +.. |Rfr| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |rfr| unicode:: U+1D52F .. MATHEMATICAL FRAKTUR SMALL R +.. |Sfr| unicode:: U+1D516 .. MATHEMATICAL FRAKTUR CAPITAL S +.. |sfr| unicode:: U+1D530 .. MATHEMATICAL FRAKTUR SMALL S +.. |Tfr| unicode:: U+1D517 .. MATHEMATICAL FRAKTUR CAPITAL T +.. |tfr| unicode:: U+1D531 .. MATHEMATICAL FRAKTUR SMALL T +.. |Ufr| unicode:: U+1D518 .. MATHEMATICAL FRAKTUR CAPITAL U +.. |ufr| unicode:: U+1D532 .. MATHEMATICAL FRAKTUR SMALL U +.. |Vfr| unicode:: U+1D519 .. MATHEMATICAL FRAKTUR CAPITAL V +.. |vfr| unicode:: U+1D533 .. MATHEMATICAL FRAKTUR SMALL V +.. |Wfr| unicode:: U+1D51A .. MATHEMATICAL FRAKTUR CAPITAL W +.. |wfr| unicode:: U+1D534 .. MATHEMATICAL FRAKTUR SMALL W +.. |Xfr| unicode:: U+1D51B .. MATHEMATICAL FRAKTUR CAPITAL X +.. |xfr| unicode:: U+1D535 .. MATHEMATICAL FRAKTUR SMALL X +.. |Yfr| unicode:: U+1D51C .. MATHEMATICAL FRAKTUR CAPITAL Y +.. |yfr| unicode:: U+1D536 .. MATHEMATICAL FRAKTUR SMALL Y +.. |Zfr| unicode:: U+02128 .. BLACK-LETTER CAPITAL Z +.. |zfr| unicode:: U+1D537 .. MATHEMATICAL FRAKTUR SMALL Z diff --git a/docutils/parsers/rst/include/isomfrk.txt b/docutils/parsers/rst/include/isomfrk.txt new file mode 100644 index 000000000..868b687a5 --- /dev/null +++ b/docutils/parsers/rst/include/isomfrk.txt @@ -0,0 +1,11 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Cfr| unicode:: U+0212D .. BLACK-LETTER CAPITAL C +.. |Hfr| unicode:: U+0210C .. BLACK-LETTER CAPITAL H +.. |Ifr| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |Rfr| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |Zfr| unicode:: U+02128 .. BLACK-LETTER CAPITAL Z diff --git a/docutils/parsers/rst/include/isomopf-wide.txt b/docutils/parsers/rst/include/isomopf-wide.txt new file mode 100644 index 000000000..a91ea43eb --- /dev/null +++ b/docutils/parsers/rst/include/isomopf-wide.txt @@ -0,0 +1,32 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Aopf| unicode:: U+1D538 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL A +.. |Bopf| unicode:: U+1D539 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL B +.. |Copf| unicode:: U+02102 .. DOUBLE-STRUCK CAPITAL C +.. |Dopf| unicode:: U+1D53B .. MATHEMATICAL DOUBLE-STRUCK CAPITAL D +.. |Eopf| unicode:: U+1D53C .. MATHEMATICAL DOUBLE-STRUCK CAPITAL E +.. |Fopf| unicode:: U+1D53D .. MATHEMATICAL DOUBLE-STRUCK CAPITAL F +.. |Gopf| unicode:: U+1D53E .. MATHEMATICAL DOUBLE-STRUCK CAPITAL G +.. |Hopf| unicode:: U+0210D .. DOUBLE-STRUCK CAPITAL H +.. |Iopf| unicode:: U+1D540 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL I +.. |Jopf| unicode:: U+1D541 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL J +.. |Kopf| unicode:: U+1D542 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL K +.. |Lopf| unicode:: U+1D543 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL L +.. |Mopf| unicode:: U+1D544 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL M +.. |Nopf| unicode:: U+02115 .. DOUBLE-STRUCK CAPITAL N +.. |Oopf| unicode:: U+1D546 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL O +.. |Popf| unicode:: U+02119 .. DOUBLE-STRUCK CAPITAL P +.. |Qopf| unicode:: U+0211A .. DOUBLE-STRUCK CAPITAL Q +.. |Ropf| unicode:: U+0211D .. DOUBLE-STRUCK CAPITAL R +.. |Sopf| unicode:: U+1D54A .. MATHEMATICAL DOUBLE-STRUCK CAPITAL S +.. |Topf| unicode:: U+1D54B .. MATHEMATICAL DOUBLE-STRUCK CAPITAL T +.. |Uopf| unicode:: U+1D54C .. MATHEMATICAL DOUBLE-STRUCK CAPITAL U +.. |Vopf| unicode:: U+1D54D .. MATHEMATICAL DOUBLE-STRUCK CAPITAL V +.. |Wopf| unicode:: U+1D54E .. MATHEMATICAL DOUBLE-STRUCK CAPITAL W +.. |Xopf| unicode:: U+1D54F .. MATHEMATICAL DOUBLE-STRUCK CAPITAL X +.. |Yopf| unicode:: U+1D550 .. MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +.. |Zopf| unicode:: U+02124 .. DOUBLE-STRUCK CAPITAL Z diff --git a/docutils/parsers/rst/include/isomopf.txt b/docutils/parsers/rst/include/isomopf.txt new file mode 100644 index 000000000..4350db61b --- /dev/null +++ b/docutils/parsers/rst/include/isomopf.txt @@ -0,0 +1,13 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Copf| unicode:: U+02102 .. DOUBLE-STRUCK CAPITAL C +.. |Hopf| unicode:: U+0210D .. DOUBLE-STRUCK CAPITAL H +.. |Nopf| unicode:: U+02115 .. DOUBLE-STRUCK CAPITAL N +.. |Popf| unicode:: U+02119 .. DOUBLE-STRUCK CAPITAL P +.. |Qopf| unicode:: U+0211A .. DOUBLE-STRUCK CAPITAL Q +.. |Ropf| unicode:: U+0211D .. DOUBLE-STRUCK CAPITAL R +.. |Zopf| unicode:: U+02124 .. DOUBLE-STRUCK CAPITAL Z diff --git a/docutils/parsers/rst/include/isomscr-wide.txt b/docutils/parsers/rst/include/isomscr-wide.txt new file mode 100644 index 000000000..34b278b98 --- /dev/null +++ b/docutils/parsers/rst/include/isomscr-wide.txt @@ -0,0 +1,58 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Ascr| unicode:: U+1D49C .. MATHEMATICAL SCRIPT CAPITAL A +.. |ascr| unicode:: U+1D4B6 .. MATHEMATICAL SCRIPT SMALL A +.. |Bscr| unicode:: U+0212C .. SCRIPT CAPITAL B +.. |bscr| unicode:: U+1D4B7 .. MATHEMATICAL SCRIPT SMALL B +.. |Cscr| unicode:: U+1D49E .. MATHEMATICAL SCRIPT CAPITAL C +.. |cscr| unicode:: U+1D4B8 .. MATHEMATICAL SCRIPT SMALL C +.. |Dscr| unicode:: U+1D49F .. MATHEMATICAL SCRIPT CAPITAL D +.. |dscr| unicode:: U+1D4B9 .. MATHEMATICAL SCRIPT SMALL D +.. |Escr| unicode:: U+02130 .. SCRIPT CAPITAL E +.. |escr| unicode:: U+0212F .. SCRIPT SMALL E +.. |Fscr| unicode:: U+02131 .. SCRIPT CAPITAL F +.. |fscr| unicode:: U+1D4BB .. MATHEMATICAL SCRIPT SMALL F +.. |Gscr| unicode:: U+1D4A2 .. MATHEMATICAL SCRIPT CAPITAL G +.. |gscr| unicode:: U+0210A .. SCRIPT SMALL G +.. |Hscr| unicode:: U+0210B .. SCRIPT CAPITAL H +.. |hscr| unicode:: U+1D4BD .. MATHEMATICAL SCRIPT SMALL H +.. |Iscr| unicode:: U+02110 .. SCRIPT CAPITAL I +.. |iscr| unicode:: U+1D4BE .. MATHEMATICAL SCRIPT SMALL I +.. |Jscr| unicode:: U+1D4A5 .. MATHEMATICAL SCRIPT CAPITAL J +.. |jscr| unicode:: U+1D4BF .. MATHEMATICAL SCRIPT SMALL J +.. |Kscr| unicode:: U+1D4A6 .. MATHEMATICAL SCRIPT CAPITAL K +.. |kscr| unicode:: U+1D4C0 .. MATHEMATICAL SCRIPT SMALL K +.. |Lscr| unicode:: U+02112 .. SCRIPT CAPITAL L +.. |lscr| unicode:: U+1D4C1 .. MATHEMATICAL SCRIPT SMALL L +.. |Mscr| unicode:: U+02133 .. SCRIPT CAPITAL M +.. |mscr| unicode:: U+1D4C2 .. MATHEMATICAL SCRIPT SMALL M +.. |Nscr| unicode:: U+1D4A9 .. MATHEMATICAL SCRIPT CAPITAL N +.. |nscr| unicode:: U+1D4C3 .. MATHEMATICAL SCRIPT SMALL N +.. |Oscr| unicode:: U+1D4AA .. MATHEMATICAL SCRIPT CAPITAL O +.. |oscr| unicode:: U+02134 .. SCRIPT SMALL O +.. |Pscr| unicode:: U+1D4AB .. MATHEMATICAL SCRIPT CAPITAL P +.. |pscr| unicode:: U+1D4C5 .. MATHEMATICAL SCRIPT SMALL P +.. |Qscr| unicode:: U+1D4AC .. MATHEMATICAL SCRIPT CAPITAL Q +.. |qscr| unicode:: U+1D4C6 .. MATHEMATICAL SCRIPT SMALL Q +.. |Rscr| unicode:: U+0211B .. SCRIPT CAPITAL R +.. |rscr| unicode:: U+1D4C7 .. MATHEMATICAL SCRIPT SMALL R +.. |Sscr| unicode:: U+1D4AE .. MATHEMATICAL SCRIPT CAPITAL S +.. |sscr| unicode:: U+1D4C8 .. MATHEMATICAL SCRIPT SMALL S +.. |Tscr| unicode:: U+1D4AF .. MATHEMATICAL SCRIPT CAPITAL T +.. |tscr| unicode:: U+1D4C9 .. MATHEMATICAL SCRIPT SMALL T +.. |Uscr| unicode:: U+1D4B0 .. MATHEMATICAL SCRIPT CAPITAL U +.. |uscr| unicode:: U+1D4CA .. MATHEMATICAL SCRIPT SMALL U +.. |Vscr| unicode:: U+1D4B1 .. MATHEMATICAL SCRIPT CAPITAL V +.. |vscr| unicode:: U+1D4CB .. MATHEMATICAL SCRIPT SMALL V +.. |Wscr| unicode:: U+1D4B2 .. MATHEMATICAL SCRIPT CAPITAL W +.. |wscr| unicode:: U+1D4CC .. MATHEMATICAL SCRIPT SMALL W +.. |Xscr| unicode:: U+1D4B3 .. MATHEMATICAL SCRIPT CAPITAL X +.. |xscr| unicode:: U+1D4CD .. MATHEMATICAL SCRIPT SMALL X +.. |Yscr| unicode:: U+1D4B4 .. MATHEMATICAL SCRIPT CAPITAL Y +.. |yscr| unicode:: U+1D4CE .. MATHEMATICAL SCRIPT SMALL Y +.. |Zscr| unicode:: U+1D4B5 .. MATHEMATICAL SCRIPT CAPITAL Z +.. |zscr| unicode:: U+1D4CF .. MATHEMATICAL SCRIPT SMALL Z diff --git a/docutils/parsers/rst/include/isomscr.txt b/docutils/parsers/rst/include/isomscr.txt new file mode 100644 index 000000000..a77890e97 --- /dev/null +++ b/docutils/parsers/rst/include/isomscr.txt @@ -0,0 +1,17 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Bscr| unicode:: U+0212C .. SCRIPT CAPITAL B +.. |Escr| unicode:: U+02130 .. SCRIPT CAPITAL E +.. |escr| unicode:: U+0212F .. SCRIPT SMALL E +.. |Fscr| unicode:: U+02131 .. SCRIPT CAPITAL F +.. |gscr| unicode:: U+0210A .. SCRIPT SMALL G +.. |Hscr| unicode:: U+0210B .. SCRIPT CAPITAL H +.. |Iscr| unicode:: U+02110 .. SCRIPT CAPITAL I +.. |Lscr| unicode:: U+02112 .. SCRIPT CAPITAL L +.. |Mscr| unicode:: U+02133 .. SCRIPT CAPITAL M +.. |oscr| unicode:: U+02134 .. SCRIPT SMALL O +.. |Rscr| unicode:: U+0211B .. SCRIPT CAPITAL R diff --git a/docutils/parsers/rst/include/isonum.txt b/docutils/parsers/rst/include/isonum.txt new file mode 100644 index 000000000..35793b365 --- /dev/null +++ b/docutils/parsers/rst/include/isonum.txt @@ -0,0 +1,82 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |amp| unicode:: U+00026 .. AMPERSAND +.. |apos| unicode:: U+00027 .. APOSTROPHE +.. |ast| unicode:: U+0002A .. ASTERISK +.. |brvbar| unicode:: U+000A6 .. BROKEN BAR +.. |bsol| unicode:: U+0005C .. REVERSE SOLIDUS +.. |cent| unicode:: U+000A2 .. CENT SIGN +.. |colon| unicode:: U+0003A .. COLON +.. |comma| unicode:: U+0002C .. COMMA +.. |commat| unicode:: U+00040 .. COMMERCIAL AT +.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN +.. |curren| unicode:: U+000A4 .. CURRENCY SIGN +.. |darr| unicode:: U+02193 .. DOWNWARDS ARROW +.. |deg| unicode:: U+000B0 .. DEGREE SIGN +.. |divide| unicode:: U+000F7 .. DIVISION SIGN +.. |dollar| unicode:: U+00024 .. DOLLAR SIGN +.. |equals| unicode:: U+0003D .. EQUALS SIGN +.. |excl| unicode:: U+00021 .. EXCLAMATION MARK +.. |frac12| unicode:: U+000BD .. VULGAR FRACTION ONE HALF +.. |frac14| unicode:: U+000BC .. VULGAR FRACTION ONE QUARTER +.. |frac18| unicode:: U+0215B .. VULGAR FRACTION ONE EIGHTH +.. |frac34| unicode:: U+000BE .. VULGAR FRACTION THREE QUARTERS +.. |frac38| unicode:: U+0215C .. VULGAR FRACTION THREE EIGHTHS +.. |frac58| unicode:: U+0215D .. VULGAR FRACTION FIVE EIGHTHS +.. |frac78| unicode:: U+0215E .. VULGAR FRACTION SEVEN EIGHTHS +.. |gt| unicode:: U+0003E .. GREATER-THAN SIGN +.. |half| unicode:: U+000BD .. VULGAR FRACTION ONE HALF +.. |horbar| unicode:: U+02015 .. HORIZONTAL BAR +.. |hyphen| unicode:: U+02010 .. HYPHEN +.. |iexcl| unicode:: U+000A1 .. INVERTED EXCLAMATION MARK +.. |iquest| unicode:: U+000BF .. INVERTED QUESTION MARK +.. |laquo| unicode:: U+000AB .. LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +.. |larr| unicode:: U+02190 .. LEFTWARDS ARROW +.. |lcub| unicode:: U+0007B .. LEFT CURLY BRACKET +.. |ldquo| unicode:: U+0201C .. LEFT DOUBLE QUOTATION MARK +.. |lowbar| unicode:: U+0005F .. LOW LINE +.. |lpar| unicode:: U+00028 .. LEFT PARENTHESIS +.. |lsqb| unicode:: U+0005B .. LEFT SQUARE BRACKET +.. |lsquo| unicode:: U+02018 .. LEFT SINGLE QUOTATION MARK +.. |lt| unicode:: U+0003C .. LESS-THAN SIGN +.. |micro| unicode:: U+000B5 .. MICRO SIGN +.. |middot| unicode:: U+000B7 .. MIDDLE DOT +.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE +.. |not| unicode:: U+000AC .. NOT SIGN +.. |num| unicode:: U+00023 .. NUMBER SIGN +.. |ohm| unicode:: U+02126 .. OHM SIGN +.. |ordf| unicode:: U+000AA .. FEMININE ORDINAL INDICATOR +.. |ordm| unicode:: U+000BA .. MASCULINE ORDINAL INDICATOR +.. |para| unicode:: U+000B6 .. PILCROW SIGN +.. |percnt| unicode:: U+00025 .. PERCENT SIGN +.. |period| unicode:: U+0002E .. FULL STOP +.. |plus| unicode:: U+0002B .. PLUS SIGN +.. |plusmn| unicode:: U+000B1 .. PLUS-MINUS SIGN +.. |pound| unicode:: U+000A3 .. POUND SIGN +.. |quest| unicode:: U+0003F .. QUESTION MARK +.. |quot| unicode:: U+00022 .. QUOTATION MARK +.. |raquo| unicode:: U+000BB .. RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +.. |rarr| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |rcub| unicode:: U+0007D .. RIGHT CURLY BRACKET +.. |rdquo| unicode:: U+0201D .. RIGHT DOUBLE QUOTATION MARK +.. |reg| unicode:: U+000AE .. REGISTERED SIGN +.. |rpar| unicode:: U+00029 .. RIGHT PARENTHESIS +.. |rsqb| unicode:: U+0005D .. RIGHT SQUARE BRACKET +.. |rsquo| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARK +.. |sect| unicode:: U+000A7 .. SECTION SIGN +.. |semi| unicode:: U+0003B .. SEMICOLON +.. |shy| unicode:: U+000AD .. SOFT HYPHEN +.. |sol| unicode:: U+0002F .. SOLIDUS +.. |sung| unicode:: U+0266A .. EIGHTH NOTE +.. |sup1| unicode:: U+000B9 .. SUPERSCRIPT ONE +.. |sup2| unicode:: U+000B2 .. SUPERSCRIPT TWO +.. |sup3| unicode:: U+000B3 .. SUPERSCRIPT THREE +.. |times| unicode:: U+000D7 .. MULTIPLICATION SIGN +.. |trade| unicode:: U+02122 .. TRADE MARK SIGN +.. |uarr| unicode:: U+02191 .. UPWARDS ARROW +.. |verbar| unicode:: U+0007C .. VERTICAL LINE +.. |yen| unicode:: U+000A5 .. YEN SIGN diff --git a/docutils/parsers/rst/include/isopub.txt b/docutils/parsers/rst/include/isopub.txt new file mode 100644 index 000000000..bc5b6d491 --- /dev/null +++ b/docutils/parsers/rst/include/isopub.txt @@ -0,0 +1,90 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |blank| unicode:: U+02423 .. OPEN BOX +.. |blk12| unicode:: U+02592 .. MEDIUM SHADE +.. |blk14| unicode:: U+02591 .. LIGHT SHADE +.. |blk34| unicode:: U+02593 .. DARK SHADE +.. |block| unicode:: U+02588 .. FULL BLOCK +.. |bull| unicode:: U+02022 .. BULLET +.. |caret| unicode:: U+02041 .. CARET INSERTION POINT +.. |check| unicode:: U+02713 .. CHECK MARK +.. |cir| unicode:: U+025CB .. WHITE CIRCLE +.. |clubs| unicode:: U+02663 .. BLACK CLUB SUIT +.. |copysr| unicode:: U+02117 .. SOUND RECORDING COPYRIGHT +.. |cross| unicode:: U+02717 .. BALLOT X +.. |Dagger| unicode:: U+02021 .. DOUBLE DAGGER +.. |dagger| unicode:: U+02020 .. DAGGER +.. |dash| unicode:: U+02010 .. HYPHEN +.. |diams| unicode:: U+02666 .. BLACK DIAMOND SUIT +.. |dlcrop| unicode:: U+0230D .. BOTTOM LEFT CROP +.. |drcrop| unicode:: U+0230C .. BOTTOM RIGHT CROP +.. |dtri| unicode:: U+025BF .. WHITE DOWN-POINTING SMALL TRIANGLE +.. |dtrif| unicode:: U+025BE .. BLACK DOWN-POINTING SMALL TRIANGLE +.. |emsp| unicode:: U+02003 .. EM SPACE +.. |emsp13| unicode:: U+02004 .. THREE-PER-EM SPACE +.. |emsp14| unicode:: U+02005 .. FOUR-PER-EM SPACE +.. |ensp| unicode:: U+02002 .. EN SPACE +.. |female| unicode:: U+02640 .. FEMALE SIGN +.. |ffilig| unicode:: U+0FB03 .. LATIN SMALL LIGATURE FFI +.. |fflig| unicode:: U+0FB00 .. LATIN SMALL LIGATURE FF +.. |ffllig| unicode:: U+0FB04 .. LATIN SMALL LIGATURE FFL +.. |filig| unicode:: U+0FB01 .. LATIN SMALL LIGATURE FI +.. |flat| unicode:: U+0266D .. MUSIC FLAT SIGN +.. |fllig| unicode:: U+0FB02 .. LATIN SMALL LIGATURE FL +.. |frac13| unicode:: U+02153 .. VULGAR FRACTION ONE THIRD +.. |frac15| unicode:: U+02155 .. VULGAR FRACTION ONE FIFTH +.. |frac16| unicode:: U+02159 .. VULGAR FRACTION ONE SIXTH +.. |frac23| unicode:: U+02154 .. VULGAR FRACTION TWO THIRDS +.. |frac25| unicode:: U+02156 .. VULGAR FRACTION TWO FIFTHS +.. |frac35| unicode:: U+02157 .. VULGAR FRACTION THREE FIFTHS +.. |frac45| unicode:: U+02158 .. VULGAR FRACTION FOUR FIFTHS +.. |frac56| unicode:: U+0215A .. VULGAR FRACTION FIVE SIXTHS +.. |hairsp| unicode:: U+0200A .. HAIR SPACE +.. |hearts| unicode:: U+02665 .. BLACK HEART SUIT +.. |hellip| unicode:: U+02026 .. HORIZONTAL ELLIPSIS +.. |hybull| unicode:: U+02043 .. HYPHEN BULLET +.. |incare| unicode:: U+02105 .. CARE OF +.. |ldquor| unicode:: U+0201E .. DOUBLE LOW-9 QUOTATION MARK +.. |lhblk| unicode:: U+02584 .. LOWER HALF BLOCK +.. |loz| unicode:: U+025CA .. LOZENGE +.. |lozf| unicode:: U+029EB .. BLACK LOZENGE +.. |lsquor| unicode:: U+0201A .. SINGLE LOW-9 QUOTATION MARK +.. |ltri| unicode:: U+025C3 .. WHITE LEFT-POINTING SMALL TRIANGLE +.. |ltrif| unicode:: U+025C2 .. BLACK LEFT-POINTING SMALL TRIANGLE +.. |male| unicode:: U+02642 .. MALE SIGN +.. |malt| unicode:: U+02720 .. MALTESE CROSS +.. |marker| unicode:: U+025AE .. BLACK VERTICAL RECTANGLE +.. |mdash| unicode:: U+02014 .. EM DASH +.. |mldr| unicode:: U+02026 .. HORIZONTAL ELLIPSIS +.. |natur| unicode:: U+0266E .. MUSIC NATURAL SIGN +.. |ndash| unicode:: U+02013 .. EN DASH +.. |nldr| unicode:: U+02025 .. TWO DOT LEADER +.. |numsp| unicode:: U+02007 .. FIGURE SPACE +.. |phone| unicode:: U+0260E .. BLACK TELEPHONE +.. |puncsp| unicode:: U+02008 .. PUNCTUATION SPACE +.. |rdquor| unicode:: U+0201D .. RIGHT DOUBLE QUOTATION MARK +.. |rect| unicode:: U+025AD .. WHITE RECTANGLE +.. |rsquor| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARK +.. |rtri| unicode:: U+025B9 .. WHITE RIGHT-POINTING SMALL TRIANGLE +.. |rtrif| unicode:: U+025B8 .. BLACK RIGHT-POINTING SMALL TRIANGLE +.. |rx| unicode:: U+0211E .. PRESCRIPTION TAKE +.. |sext| unicode:: U+02736 .. SIX POINTED BLACK STAR +.. |sharp| unicode:: U+0266F .. MUSIC SHARP SIGN +.. |spades| unicode:: U+02660 .. BLACK SPADE SUIT +.. |squ| unicode:: U+025A1 .. WHITE SQUARE +.. |squf| unicode:: U+025AA .. BLACK SMALL SQUARE +.. |star| unicode:: U+02606 .. WHITE STAR +.. |starf| unicode:: U+02605 .. BLACK STAR +.. |target| unicode:: U+02316 .. POSITION INDICATOR +.. |telrec| unicode:: U+02315 .. TELEPHONE RECORDER +.. |thinsp| unicode:: U+02009 .. THIN SPACE +.. |uhblk| unicode:: U+02580 .. UPPER HALF BLOCK +.. |ulcrop| unicode:: U+0230F .. TOP LEFT CROP +.. |urcrop| unicode:: U+0230E .. TOP RIGHT CROP +.. |utri| unicode:: U+025B5 .. WHITE UP-POINTING SMALL TRIANGLE +.. |utrif| unicode:: U+025B4 .. BLACK UP-POINTING SMALL TRIANGLE +.. |vellip| unicode:: U+022EE .. VERTICAL ELLIPSIS diff --git a/docutils/parsers/rst/include/isotech.txt b/docutils/parsers/rst/include/isotech.txt new file mode 100644 index 000000000..01f7e346f --- /dev/null +++ b/docutils/parsers/rst/include/isotech.txt @@ -0,0 +1,168 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |acd| unicode:: U+0223F .. SINE WAVE +.. |aleph| unicode:: U+02135 .. ALEF SYMBOL +.. |And| unicode:: U+02A53 .. DOUBLE LOGICAL AND +.. |and| unicode:: U+02227 .. LOGICAL AND +.. |andand| unicode:: U+02A55 .. TWO INTERSECTING LOGICAL AND +.. |andd| unicode:: U+02A5C .. LOGICAL AND WITH HORIZONTAL DASH +.. |andslope| unicode:: U+02A58 .. SLOPING LARGE AND +.. |andv| unicode:: U+02A5A .. LOGICAL AND WITH MIDDLE STEM +.. |ang90| unicode:: U+0221F .. RIGHT ANGLE +.. |angrt| unicode:: U+0221F .. RIGHT ANGLE +.. |angsph| unicode:: U+02222 .. SPHERICAL ANGLE +.. |angst| unicode:: U+0212B .. ANGSTROM SIGN +.. |ap| unicode:: U+02248 .. ALMOST EQUAL TO +.. |apacir| unicode:: U+02A6F .. ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT +.. |awconint| unicode:: U+02233 .. ANTICLOCKWISE CONTOUR INTEGRAL +.. |awint| unicode:: U+02A11 .. ANTICLOCKWISE INTEGRATION +.. |becaus| unicode:: U+02235 .. BECAUSE +.. |bernou| unicode:: U+0212C .. SCRIPT CAPITAL B +.. |bne| unicode:: U+0003D U+020E5 .. EQUALS SIGN with reverse slash +.. |bnequiv| unicode:: U+02261 U+020E5 .. IDENTICAL TO with reverse slash +.. |bNot| unicode:: U+02AED .. REVERSED DOUBLE STROKE NOT SIGN +.. |bnot| unicode:: U+02310 .. REVERSED NOT SIGN +.. |bottom| unicode:: U+022A5 .. UP TACK +.. |cap| unicode:: U+02229 .. INTERSECTION +.. |Cconint| unicode:: U+02230 .. VOLUME INTEGRAL +.. |cirfnint| unicode:: U+02A10 .. CIRCULATION FUNCTION +.. |compfn| unicode:: U+02218 .. RING OPERATOR +.. |cong| unicode:: U+02245 .. APPROXIMATELY EQUAL TO +.. |Conint| unicode:: U+0222F .. SURFACE INTEGRAL +.. |conint| unicode:: U+0222E .. CONTOUR INTEGRAL +.. |ctdot| unicode:: U+022EF .. MIDLINE HORIZONTAL ELLIPSIS +.. |cup| unicode:: U+0222A .. UNION +.. |cwconint| unicode:: U+02232 .. CLOCKWISE CONTOUR INTEGRAL +.. |cwint| unicode:: U+02231 .. CLOCKWISE INTEGRAL +.. |cylcty| unicode:: U+0232D .. CYLINDRICITY +.. |disin| unicode:: U+022F2 .. ELEMENT OF WITH LONG HORIZONTAL STROKE +.. |Dot| unicode:: U+000A8 .. DIAERESIS +.. |DotDot| unicode:: U+020DC .. COMBINING FOUR DOTS ABOVE +.. |dsol| unicode:: U+029F6 .. SOLIDUS WITH OVERBAR +.. |dtdot| unicode:: U+022F1 .. DOWN RIGHT DIAGONAL ELLIPSIS +.. |dwangle| unicode:: U+029A6 .. OBLIQUE ANGLE OPENING UP +.. |elinters| unicode:: U+0FFFD .. REPLACEMENT CHARACTER +.. |epar| unicode:: U+022D5 .. EQUAL AND PARALLEL TO +.. |eparsl| unicode:: U+029E3 .. EQUALS SIGN AND SLANTED PARALLEL +.. |equiv| unicode:: U+02261 .. IDENTICAL TO +.. |eqvparsl| unicode:: U+029E5 .. IDENTICAL TO AND SLANTED PARALLEL +.. |exist| unicode:: U+02203 .. THERE EXISTS +.. |fltns| unicode:: U+025B1 .. WHITE PARALLELOGRAM +.. |fnof| unicode:: U+00192 .. LATIN SMALL LETTER F WITH HOOK +.. |forall| unicode:: U+02200 .. FOR ALL +.. |fpartint| unicode:: U+02A0D .. FINITE PART INTEGRAL +.. |ge| unicode:: U+02265 .. GREATER-THAN OR EQUAL TO +.. |hamilt| unicode:: U+0210B .. SCRIPT CAPITAL H +.. |iff| unicode:: U+021D4 .. LEFT RIGHT DOUBLE ARROW +.. |iinfin| unicode:: U+029DC .. INCOMPLETE INFINITY +.. |imped| unicode:: U+001B5 .. LATIN CAPITAL LETTER Z WITH STROKE +.. |infin| unicode:: U+0221E .. INFINITY +.. |infintie| unicode:: U+029DD .. TIE OVER INFINITY +.. |Int| unicode:: U+0222C .. DOUBLE INTEGRAL +.. |int| unicode:: U+0222B .. INTEGRAL +.. |intlarhk| unicode:: U+02A17 .. INTEGRAL WITH LEFTWARDS ARROW WITH HOOK +.. |isin| unicode:: U+02208 .. ELEMENT OF +.. |isindot| unicode:: U+022F5 .. ELEMENT OF WITH DOT ABOVE +.. |isinE| unicode:: U+022F9 .. ELEMENT OF WITH TWO HORIZONTAL STROKES +.. |isins| unicode:: U+022F4 .. SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +.. |isinsv| unicode:: U+022F3 .. ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +.. |isinv| unicode:: U+02208 .. ELEMENT OF +.. |lagran| unicode:: U+02112 .. SCRIPT CAPITAL L +.. |Lang| unicode:: U+0300A .. LEFT DOUBLE ANGLE BRACKET +.. |lang| unicode:: U+02329 .. LEFT-POINTING ANGLE BRACKET +.. |lArr| unicode:: U+021D0 .. LEFTWARDS DOUBLE ARROW +.. |lbbrk| unicode:: U+03014 .. LEFT TORTOISE SHELL BRACKET +.. |le| unicode:: U+02264 .. LESS-THAN OR EQUAL TO +.. |loang| unicode:: U+03018 .. LEFT WHITE TORTOISE SHELL BRACKET +.. |lobrk| unicode:: U+0301A .. LEFT WHITE SQUARE BRACKET +.. |lopar| unicode:: U+02985 .. LEFT WHITE PARENTHESIS +.. |lowast| unicode:: U+02217 .. ASTERISK OPERATOR +.. |minus| unicode:: U+02212 .. MINUS SIGN +.. |mnplus| unicode:: U+02213 .. MINUS-OR-PLUS SIGN +.. |nabla| unicode:: U+02207 .. NABLA +.. |ne| unicode:: U+02260 .. NOT EQUAL TO +.. |nedot| unicode:: U+02250 U+00338 .. APPROACHES THE LIMIT with slash +.. |nhpar| unicode:: U+02AF2 .. PARALLEL WITH HORIZONTAL STROKE +.. |ni| unicode:: U+0220B .. CONTAINS AS MEMBER +.. |nis| unicode:: U+022FC .. SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +.. |nisd| unicode:: U+022FA .. CONTAINS WITH LONG HORIZONTAL STROKE +.. |niv| unicode:: U+0220B .. CONTAINS AS MEMBER +.. |Not| unicode:: U+02AEC .. DOUBLE STROKE NOT SIGN +.. |notin| unicode:: U+02209 .. NOT AN ELEMENT OF +.. |notindot| unicode:: U+022F5 U+00338 .. ELEMENT OF WITH DOT ABOVE with slash +.. |notinE| unicode:: U+022F9 U+00338 .. ELEMENT OF WITH TWO HORIZONTAL STROKES with slash +.. |notinva| unicode:: U+02209 .. NOT AN ELEMENT OF +.. |notinvb| unicode:: U+022F7 .. SMALL ELEMENT OF WITH OVERBAR +.. |notinvc| unicode:: U+022F6 .. ELEMENT OF WITH OVERBAR +.. |notni| unicode:: U+0220C .. DOES NOT CONTAIN AS MEMBER +.. |notniva| unicode:: U+0220C .. DOES NOT CONTAIN AS MEMBER +.. |notnivb| unicode:: U+022FE .. SMALL CONTAINS WITH OVERBAR +.. |notnivc| unicode:: U+022FD .. CONTAINS WITH OVERBAR +.. |nparsl| unicode:: U+02AFD U+020E5 .. DOUBLE SOLIDUS OPERATOR with reverse slash +.. |npart| unicode:: U+02202 U+00338 .. PARTIAL DIFFERENTIAL with slash +.. |npolint| unicode:: U+02A14 .. LINE INTEGRATION NOT INCLUDING THE POLE +.. |nvinfin| unicode:: U+029DE .. INFINITY NEGATED WITH VERTICAL BAR +.. |olcross| unicode:: U+029BB .. CIRCLE WITH SUPERIMPOSED X +.. |Or| unicode:: U+02A54 .. DOUBLE LOGICAL OR +.. |or| unicode:: U+02228 .. LOGICAL OR +.. |ord| unicode:: U+02A5D .. LOGICAL OR WITH HORIZONTAL DASH +.. |order| unicode:: U+02134 .. SCRIPT SMALL O +.. |oror| unicode:: U+02A56 .. TWO INTERSECTING LOGICAL OR +.. |orslope| unicode:: U+02A57 .. SLOPING LARGE OR +.. |orv| unicode:: U+02A5B .. LOGICAL OR WITH MIDDLE STEM +.. |par| unicode:: U+02225 .. PARALLEL TO +.. |parsl| unicode:: U+02AFD .. DOUBLE SOLIDUS OPERATOR +.. |part| unicode:: U+02202 .. PARTIAL DIFFERENTIAL +.. |permil| unicode:: U+02030 .. PER MILLE SIGN +.. |perp| unicode:: U+022A5 .. UP TACK +.. |pertenk| unicode:: U+02031 .. PER TEN THOUSAND SIGN +.. |phmmat| unicode:: U+02133 .. SCRIPT CAPITAL M +.. |pointint| unicode:: U+02A15 .. INTEGRAL AROUND A POINT OPERATOR +.. |Prime| unicode:: U+02033 .. DOUBLE PRIME +.. |prime| unicode:: U+02032 .. PRIME +.. |profalar| unicode:: U+0232E .. ALL AROUND-PROFILE +.. |profline| unicode:: U+02312 .. ARC +.. |profsurf| unicode:: U+02313 .. SEGMENT +.. |prop| unicode:: U+0221D .. PROPORTIONAL TO +.. |qint| unicode:: U+02A0C .. QUADRUPLE INTEGRAL OPERATOR +.. |qprime| unicode:: U+02057 .. QUADRUPLE PRIME +.. |quatint| unicode:: U+02A16 .. QUATERNION INTEGRAL OPERATOR +.. |radic| unicode:: U+0221A .. SQUARE ROOT +.. |Rang| unicode:: U+0300B .. RIGHT DOUBLE ANGLE BRACKET +.. |rang| unicode:: U+0232A .. RIGHT-POINTING ANGLE BRACKET +.. |rArr| unicode:: U+021D2 .. RIGHTWARDS DOUBLE ARROW +.. |rbbrk| unicode:: U+03015 .. RIGHT TORTOISE SHELL BRACKET +.. |roang| unicode:: U+03019 .. RIGHT WHITE TORTOISE SHELL BRACKET +.. |robrk| unicode:: U+0301B .. RIGHT WHITE SQUARE BRACKET +.. |ropar| unicode:: U+02986 .. RIGHT WHITE PARENTHESIS +.. |rppolint| unicode:: U+02A12 .. LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE +.. |scpolint| unicode:: U+02A13 .. LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE +.. |sim| unicode:: U+0223C .. TILDE OPERATOR +.. |simdot| unicode:: U+02A6A .. TILDE OPERATOR WITH DOT ABOVE +.. |sime| unicode:: U+02243 .. ASYMPTOTICALLY EQUAL TO +.. |smeparsl| unicode:: U+029E4 .. EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE +.. |square| unicode:: U+025A1 .. WHITE SQUARE +.. |squarf| unicode:: U+025AA .. BLACK SMALL SQUARE +.. |strns| unicode:: U+000AF .. MACRON +.. |sub| unicode:: U+02282 .. SUBSET OF +.. |sube| unicode:: U+02286 .. SUBSET OF OR EQUAL TO +.. |sup| unicode:: U+02283 .. SUPERSET OF +.. |supe| unicode:: U+02287 .. SUPERSET OF OR EQUAL TO +.. |tdot| unicode:: U+020DB .. COMBINING THREE DOTS ABOVE +.. |there4| unicode:: U+02234 .. THEREFORE +.. |tint| unicode:: U+0222D .. TRIPLE INTEGRAL +.. |top| unicode:: U+022A4 .. DOWN TACK +.. |topbot| unicode:: U+02336 .. APL FUNCTIONAL SYMBOL I-BEAM +.. |topcir| unicode:: U+02AF1 .. DOWN TACK WITH CIRCLE BELOW +.. |tprime| unicode:: U+02034 .. TRIPLE PRIME +.. |utdot| unicode:: U+022F0 .. UP RIGHT DIAGONAL ELLIPSIS +.. |uwangle| unicode:: U+029A7 .. OBLIQUE ANGLE OPENING DOWN +.. |vangrt| unicode:: U+0299C .. RIGHT ANGLE VARIANT WITH SQUARE +.. |veeeq| unicode:: U+0225A .. EQUIANGULAR TO +.. |Verbar| unicode:: U+02016 .. DOUBLE VERTICAL LINE +.. |wedgeq| unicode:: U+02259 .. ESTIMATES +.. |xnis| unicode:: U+022FB .. CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE diff --git a/docutils/parsers/rst/include/mmlalias.txt b/docutils/parsers/rst/include/mmlalias.txt new file mode 100644 index 000000000..cabc54ac4 --- /dev/null +++ b/docutils/parsers/rst/include/mmlalias.txt @@ -0,0 +1,554 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |angle| unicode:: U+02220 .. ANGLE +.. |ApplyFunction| unicode:: U+02061 .. FUNCTION APPLICATION +.. |approx| unicode:: U+02248 .. ALMOST EQUAL TO +.. |approxeq| unicode:: U+0224A .. ALMOST EQUAL OR EQUAL TO +.. |Assign| unicode:: U+02254 .. COLON EQUALS +.. |backcong| unicode:: U+0224C .. ALL EQUAL TO +.. |backepsilon| unicode:: U+003F6 .. GREEK REVERSED LUNATE EPSILON SYMBOL +.. |backprime| unicode:: U+02035 .. REVERSED PRIME +.. |backsim| unicode:: U+0223D .. REVERSED TILDE +.. |backsimeq| unicode:: U+022CD .. REVERSED TILDE EQUALS +.. |Backslash| unicode:: U+02216 .. SET MINUS +.. |barwedge| unicode:: U+02305 .. PROJECTIVE +.. |Because| unicode:: U+02235 .. BECAUSE +.. |because| unicode:: U+02235 .. BECAUSE +.. |Bernoullis| unicode:: U+0212C .. SCRIPT CAPITAL B +.. |between| unicode:: U+0226C .. BETWEEN +.. |bigcap| unicode:: U+022C2 .. N-ARY INTERSECTION +.. |bigcirc| unicode:: U+025EF .. LARGE CIRCLE +.. |bigcup| unicode:: U+022C3 .. N-ARY UNION +.. |bigodot| unicode:: U+02A00 .. N-ARY CIRCLED DOT OPERATOR +.. |bigoplus| unicode:: U+02A01 .. N-ARY CIRCLED PLUS OPERATOR +.. |bigotimes| unicode:: U+02A02 .. N-ARY CIRCLED TIMES OPERATOR +.. |bigsqcup| unicode:: U+02A06 .. N-ARY SQUARE UNION OPERATOR +.. |bigstar| unicode:: U+02605 .. BLACK STAR +.. |bigtriangledown| unicode:: U+025BD .. WHITE DOWN-POINTING TRIANGLE +.. |bigtriangleup| unicode:: U+025B3 .. WHITE UP-POINTING TRIANGLE +.. |biguplus| unicode:: U+02A04 .. N-ARY UNION OPERATOR WITH PLUS +.. |bigvee| unicode:: U+022C1 .. N-ARY LOGICAL OR +.. |bigwedge| unicode:: U+022C0 .. N-ARY LOGICAL AND +.. |bkarow| unicode:: U+0290D .. RIGHTWARDS DOUBLE DASH ARROW +.. |blacklozenge| unicode:: U+029EB .. BLACK LOZENGE +.. |blacksquare| unicode:: U+025AA .. BLACK SMALL SQUARE +.. |blacktriangle| unicode:: U+025B4 .. BLACK UP-POINTING SMALL TRIANGLE +.. |blacktriangledown| unicode:: U+025BE .. BLACK DOWN-POINTING SMALL TRIANGLE +.. |blacktriangleleft| unicode:: U+025C2 .. BLACK LEFT-POINTING SMALL TRIANGLE +.. |blacktriangleright| unicode:: U+025B8 .. BLACK RIGHT-POINTING SMALL TRIANGLE +.. |bot| unicode:: U+022A5 .. UP TACK +.. |boxminus| unicode:: U+0229F .. SQUARED MINUS +.. |boxplus| unicode:: U+0229E .. SQUARED PLUS +.. |boxtimes| unicode:: U+022A0 .. SQUARED TIMES +.. |Breve| unicode:: U+002D8 .. BREVE +.. |bullet| unicode:: U+02022 .. BULLET +.. |Bumpeq| unicode:: U+0224E .. GEOMETRICALLY EQUIVALENT TO +.. |bumpeq| unicode:: U+0224F .. DIFFERENCE BETWEEN +.. |CapitalDifferentialD| unicode:: U+02145 .. DOUBLE-STRUCK ITALIC CAPITAL D +.. |Cayleys| unicode:: U+0212D .. BLACK-LETTER CAPITAL C +.. |Cedilla| unicode:: U+000B8 .. CEDILLA +.. |CenterDot| unicode:: U+000B7 .. MIDDLE DOT +.. |centerdot| unicode:: U+000B7 .. MIDDLE DOT +.. |checkmark| unicode:: U+02713 .. CHECK MARK +.. |circeq| unicode:: U+02257 .. RING EQUAL TO +.. |circlearrowleft| unicode:: U+021BA .. ANTICLOCKWISE OPEN CIRCLE ARROW +.. |circlearrowright| unicode:: U+021BB .. CLOCKWISE OPEN CIRCLE ARROW +.. |circledast| unicode:: U+0229B .. CIRCLED ASTERISK OPERATOR +.. |circledcirc| unicode:: U+0229A .. CIRCLED RING OPERATOR +.. |circleddash| unicode:: U+0229D .. CIRCLED DASH +.. |CircleDot| unicode:: U+02299 .. CIRCLED DOT OPERATOR +.. |circledR| unicode:: U+000AE .. REGISTERED SIGN +.. |circledS| unicode:: U+024C8 .. CIRCLED LATIN CAPITAL LETTER S +.. |CircleMinus| unicode:: U+02296 .. CIRCLED MINUS +.. |CirclePlus| unicode:: U+02295 .. CIRCLED PLUS +.. |CircleTimes| unicode:: U+02297 .. CIRCLED TIMES +.. |ClockwiseContourIntegral| unicode:: U+02232 .. CLOCKWISE CONTOUR INTEGRAL +.. |CloseCurlyDoubleQuote| unicode:: U+0201D .. RIGHT DOUBLE QUOTATION MARK +.. |CloseCurlyQuote| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARK +.. |clubsuit| unicode:: U+02663 .. BLACK CLUB SUIT +.. |coloneq| unicode:: U+02254 .. COLON EQUALS +.. |complement| unicode:: U+02201 .. COMPLEMENT +.. |complexes| unicode:: U+02102 .. DOUBLE-STRUCK CAPITAL C +.. |Congruent| unicode:: U+02261 .. IDENTICAL TO +.. |ContourIntegral| unicode:: U+0222E .. CONTOUR INTEGRAL +.. |Coproduct| unicode:: U+02210 .. N-ARY COPRODUCT +.. |CounterClockwiseContourIntegral| unicode:: U+02233 .. ANTICLOCKWISE CONTOUR INTEGRAL +.. |CupCap| unicode:: U+0224D .. EQUIVALENT TO +.. |curlyeqprec| unicode:: U+022DE .. EQUAL TO OR PRECEDES +.. |curlyeqsucc| unicode:: U+022DF .. EQUAL TO OR SUCCEEDS +.. |curlyvee| unicode:: U+022CE .. CURLY LOGICAL OR +.. |curlywedge| unicode:: U+022CF .. CURLY LOGICAL AND +.. |curvearrowleft| unicode:: U+021B6 .. ANTICLOCKWISE TOP SEMICIRCLE ARROW +.. |curvearrowright| unicode:: U+021B7 .. CLOCKWISE TOP SEMICIRCLE ARROW +.. |dbkarow| unicode:: U+0290F .. RIGHTWARDS TRIPLE DASH ARROW +.. |ddagger| unicode:: U+02021 .. DOUBLE DAGGER +.. |ddotseq| unicode:: U+02A77 .. EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW +.. |Del| unicode:: U+02207 .. NABLA +.. |DiacriticalAcute| unicode:: U+000B4 .. ACUTE ACCENT +.. |DiacriticalDot| unicode:: U+002D9 .. DOT ABOVE +.. |DiacriticalDoubleAcute| unicode:: U+002DD .. DOUBLE ACUTE ACCENT +.. |DiacriticalGrave| unicode:: U+00060 .. GRAVE ACCENT +.. |DiacriticalTilde| unicode:: U+002DC .. SMALL TILDE +.. |Diamond| unicode:: U+022C4 .. DIAMOND OPERATOR +.. |diamond| unicode:: U+022C4 .. DIAMOND OPERATOR +.. |diamondsuit| unicode:: U+02666 .. BLACK DIAMOND SUIT +.. |DifferentialD| unicode:: U+02146 .. DOUBLE-STRUCK ITALIC SMALL D +.. |digamma| unicode:: U+003DD .. GREEK SMALL LETTER DIGAMMA +.. |div| unicode:: U+000F7 .. DIVISION SIGN +.. |divideontimes| unicode:: U+022C7 .. DIVISION TIMES +.. |doteq| unicode:: U+02250 .. APPROACHES THE LIMIT +.. |doteqdot| unicode:: U+02251 .. GEOMETRICALLY EQUAL TO +.. |DotEqual| unicode:: U+02250 .. APPROACHES THE LIMIT +.. |dotminus| unicode:: U+02238 .. DOT MINUS +.. |dotplus| unicode:: U+02214 .. DOT PLUS +.. |dotsquare| unicode:: U+022A1 .. SQUARED DOT OPERATOR +.. |doublebarwedge| unicode:: U+02306 .. PERSPECTIVE +.. |DoubleContourIntegral| unicode:: U+0222F .. SURFACE INTEGRAL +.. |DoubleDot| unicode:: U+000A8 .. DIAERESIS +.. |DoubleDownArrow| unicode:: U+021D3 .. DOWNWARDS DOUBLE ARROW +.. |DoubleLeftArrow| unicode:: U+021D0 .. LEFTWARDS DOUBLE ARROW +.. |DoubleLeftRightArrow| unicode:: U+021D4 .. LEFT RIGHT DOUBLE ARROW +.. |DoubleLeftTee| unicode:: U+02AE4 .. VERTICAL BAR DOUBLE LEFT TURNSTILE +.. |DoubleLongLeftArrow| unicode:: U+027F8 .. LONG LEFTWARDS DOUBLE ARROW +.. |DoubleLongLeftRightArrow| unicode:: U+027FA .. LONG LEFT RIGHT DOUBLE ARROW +.. |DoubleLongRightArrow| unicode:: U+027F9 .. LONG RIGHTWARDS DOUBLE ARROW +.. |DoubleRightArrow| unicode:: U+021D2 .. RIGHTWARDS DOUBLE ARROW +.. |DoubleRightTee| unicode:: U+022A8 .. TRUE +.. |DoubleUpArrow| unicode:: U+021D1 .. UPWARDS DOUBLE ARROW +.. |DoubleUpDownArrow| unicode:: U+021D5 .. UP DOWN DOUBLE ARROW +.. |DoubleVerticalBar| unicode:: U+02225 .. PARALLEL TO +.. |DownArrow| unicode:: U+02193 .. DOWNWARDS ARROW +.. |Downarrow| unicode:: U+021D3 .. DOWNWARDS DOUBLE ARROW +.. |downarrow| unicode:: U+02193 .. DOWNWARDS ARROW +.. |DownArrowUpArrow| unicode:: U+021F5 .. DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +.. |downdownarrows| unicode:: U+021CA .. DOWNWARDS PAIRED ARROWS +.. |downharpoonleft| unicode:: U+021C3 .. DOWNWARDS HARPOON WITH BARB LEFTWARDS +.. |downharpoonright| unicode:: U+021C2 .. DOWNWARDS HARPOON WITH BARB RIGHTWARDS +.. |DownLeftVector| unicode:: U+021BD .. LEFTWARDS HARPOON WITH BARB DOWNWARDS +.. |DownRightVector| unicode:: U+021C1 .. RIGHTWARDS HARPOON WITH BARB DOWNWARDS +.. |DownTee| unicode:: U+022A4 .. DOWN TACK +.. |DownTeeArrow| unicode:: U+021A7 .. DOWNWARDS ARROW FROM BAR +.. |drbkarow| unicode:: U+02910 .. RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW +.. |Element| unicode:: U+02208 .. ELEMENT OF +.. |emptyset| unicode:: U+02205 .. EMPTY SET +.. |eqcirc| unicode:: U+02256 .. RING IN EQUAL TO +.. |eqcolon| unicode:: U+02255 .. EQUALS COLON +.. |eqsim| unicode:: U+02242 .. MINUS TILDE +.. |eqslantgtr| unicode:: U+02A96 .. SLANTED EQUAL TO OR GREATER-THAN +.. |eqslantless| unicode:: U+02A95 .. SLANTED EQUAL TO OR LESS-THAN +.. |EqualTilde| unicode:: U+02242 .. MINUS TILDE +.. |Equilibrium| unicode:: U+021CC .. RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +.. |Exists| unicode:: U+02203 .. THERE EXISTS +.. |expectation| unicode:: U+02130 .. SCRIPT CAPITAL E +.. |ExponentialE| unicode:: U+02147 .. DOUBLE-STRUCK ITALIC SMALL E +.. |exponentiale| unicode:: U+02147 .. DOUBLE-STRUCK ITALIC SMALL E +.. |fallingdotseq| unicode:: U+02252 .. APPROXIMATELY EQUAL TO OR THE IMAGE OF +.. |ForAll| unicode:: U+02200 .. FOR ALL +.. |Fouriertrf| unicode:: U+02131 .. SCRIPT CAPITAL F +.. |geq| unicode:: U+02265 .. GREATER-THAN OR EQUAL TO +.. |geqq| unicode:: U+02267 .. GREATER-THAN OVER EQUAL TO +.. |geqslant| unicode:: U+02A7E .. GREATER-THAN OR SLANTED EQUAL TO +.. |gg| unicode:: U+0226B .. MUCH GREATER-THAN +.. |ggg| unicode:: U+022D9 .. VERY MUCH GREATER-THAN +.. |gnapprox| unicode:: U+02A8A .. GREATER-THAN AND NOT APPROXIMATE +.. |gneq| unicode:: U+02A88 .. GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +.. |gneqq| unicode:: U+02269 .. GREATER-THAN BUT NOT EQUAL TO +.. |GreaterEqual| unicode:: U+02265 .. GREATER-THAN OR EQUAL TO +.. |GreaterEqualLess| unicode:: U+022DB .. GREATER-THAN EQUAL TO OR LESS-THAN +.. |GreaterFullEqual| unicode:: U+02267 .. GREATER-THAN OVER EQUAL TO +.. |GreaterLess| unicode:: U+02277 .. GREATER-THAN OR LESS-THAN +.. |GreaterSlantEqual| unicode:: U+02A7E .. GREATER-THAN OR SLANTED EQUAL TO +.. |GreaterTilde| unicode:: U+02273 .. GREATER-THAN OR EQUIVALENT TO +.. |gtrapprox| unicode:: U+02A86 .. GREATER-THAN OR APPROXIMATE +.. |gtrdot| unicode:: U+022D7 .. GREATER-THAN WITH DOT +.. |gtreqless| unicode:: U+022DB .. GREATER-THAN EQUAL TO OR LESS-THAN +.. |gtreqqless| unicode:: U+02A8C .. GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +.. |gtrless| unicode:: U+02277 .. GREATER-THAN OR LESS-THAN +.. |gtrsim| unicode:: U+02273 .. GREATER-THAN OR EQUIVALENT TO +.. |gvertneqq| unicode:: U+02269 U+0FE00 .. GREATER-THAN BUT NOT EQUAL TO - with vertical stroke +.. |Hacek| unicode:: U+002C7 .. CARON +.. |hbar| unicode:: U+0210F .. PLANCK CONSTANT OVER TWO PI +.. |heartsuit| unicode:: U+02665 .. BLACK HEART SUIT +.. |HilbertSpace| unicode:: U+0210B .. SCRIPT CAPITAL H +.. |hksearow| unicode:: U+02925 .. SOUTH EAST ARROW WITH HOOK +.. |hkswarow| unicode:: U+02926 .. SOUTH WEST ARROW WITH HOOK +.. |hookleftarrow| unicode:: U+021A9 .. LEFTWARDS ARROW WITH HOOK +.. |hookrightarrow| unicode:: U+021AA .. RIGHTWARDS ARROW WITH HOOK +.. |hslash| unicode:: U+0210F .. PLANCK CONSTANT OVER TWO PI +.. |HumpDownHump| unicode:: U+0224E .. GEOMETRICALLY EQUIVALENT TO +.. |HumpEqual| unicode:: U+0224F .. DIFFERENCE BETWEEN +.. |iiiint| unicode:: U+02A0C .. QUADRUPLE INTEGRAL OPERATOR +.. |iiint| unicode:: U+0222D .. TRIPLE INTEGRAL +.. |Im| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |ImaginaryI| unicode:: U+02148 .. DOUBLE-STRUCK ITALIC SMALL I +.. |imagline| unicode:: U+02110 .. SCRIPT CAPITAL I +.. |imagpart| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |Implies| unicode:: U+021D2 .. RIGHTWARDS DOUBLE ARROW +.. |in| unicode:: U+02208 .. ELEMENT OF +.. |integers| unicode:: U+02124 .. DOUBLE-STRUCK CAPITAL Z +.. |Integral| unicode:: U+0222B .. INTEGRAL +.. |intercal| unicode:: U+022BA .. INTERCALATE +.. |Intersection| unicode:: U+022C2 .. N-ARY INTERSECTION +.. |intprod| unicode:: U+02A3C .. INTERIOR PRODUCT +.. |InvisibleComma| unicode:: U+02063 .. INVISIBLE SEPARATOR +.. |InvisibleTimes| unicode:: U+02062 .. INVISIBLE TIMES +.. |langle| unicode:: U+02329 .. LEFT-POINTING ANGLE BRACKET +.. |Laplacetrf| unicode:: U+02112 .. SCRIPT CAPITAL L +.. |lbrace| unicode:: U+0007B .. LEFT CURLY BRACKET +.. |lbrack| unicode:: U+0005B .. LEFT SQUARE BRACKET +.. |LeftAngleBracket| unicode:: U+02329 .. LEFT-POINTING ANGLE BRACKET +.. |LeftArrow| unicode:: U+02190 .. LEFTWARDS ARROW +.. |Leftarrow| unicode:: U+021D0 .. LEFTWARDS DOUBLE ARROW +.. |leftarrow| unicode:: U+02190 .. LEFTWARDS ARROW +.. |LeftArrowBar| unicode:: U+021E4 .. LEFTWARDS ARROW TO BAR +.. |LeftArrowRightArrow| unicode:: U+021C6 .. LEFTWARDS ARROW OVER RIGHTWARDS ARROW +.. |leftarrowtail| unicode:: U+021A2 .. LEFTWARDS ARROW WITH TAIL +.. |LeftCeiling| unicode:: U+02308 .. LEFT CEILING +.. |LeftDoubleBracket| unicode:: U+0301A .. LEFT WHITE SQUARE BRACKET +.. |LeftDownVector| unicode:: U+021C3 .. DOWNWARDS HARPOON WITH BARB LEFTWARDS +.. |LeftFloor| unicode:: U+0230A .. LEFT FLOOR +.. |leftharpoondown| unicode:: U+021BD .. LEFTWARDS HARPOON WITH BARB DOWNWARDS +.. |leftharpoonup| unicode:: U+021BC .. LEFTWARDS HARPOON WITH BARB UPWARDS +.. |leftleftarrows| unicode:: U+021C7 .. LEFTWARDS PAIRED ARROWS +.. |LeftRightArrow| unicode:: U+02194 .. LEFT RIGHT ARROW +.. |Leftrightarrow| unicode:: U+021D4 .. LEFT RIGHT DOUBLE ARROW +.. |leftrightarrow| unicode:: U+02194 .. LEFT RIGHT ARROW +.. |leftrightarrows| unicode:: U+021C6 .. LEFTWARDS ARROW OVER RIGHTWARDS ARROW +.. |leftrightharpoons| unicode:: U+021CB .. LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +.. |leftrightsquigarrow| unicode:: U+021AD .. LEFT RIGHT WAVE ARROW +.. |LeftTee| unicode:: U+022A3 .. LEFT TACK +.. |LeftTeeArrow| unicode:: U+021A4 .. LEFTWARDS ARROW FROM BAR +.. |leftthreetimes| unicode:: U+022CB .. LEFT SEMIDIRECT PRODUCT +.. |LeftTriangle| unicode:: U+022B2 .. NORMAL SUBGROUP OF +.. |LeftTriangleEqual| unicode:: U+022B4 .. NORMAL SUBGROUP OF OR EQUAL TO +.. |LeftUpVector| unicode:: U+021BF .. UPWARDS HARPOON WITH BARB LEFTWARDS +.. |LeftVector| unicode:: U+021BC .. LEFTWARDS HARPOON WITH BARB UPWARDS +.. |leq| unicode:: U+02264 .. LESS-THAN OR EQUAL TO +.. |leqq| unicode:: U+02266 .. LESS-THAN OVER EQUAL TO +.. |leqslant| unicode:: U+02A7D .. LESS-THAN OR SLANTED EQUAL TO +.. |lessapprox| unicode:: U+02A85 .. LESS-THAN OR APPROXIMATE +.. |lessdot| unicode:: U+022D6 .. LESS-THAN WITH DOT +.. |lesseqgtr| unicode:: U+022DA .. LESS-THAN EQUAL TO OR GREATER-THAN +.. |lesseqqgtr| unicode:: U+02A8B .. LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +.. |LessEqualGreater| unicode:: U+022DA .. LESS-THAN EQUAL TO OR GREATER-THAN +.. |LessFullEqual| unicode:: U+02266 .. LESS-THAN OVER EQUAL TO +.. |LessGreater| unicode:: U+02276 .. LESS-THAN OR GREATER-THAN +.. |lessgtr| unicode:: U+02276 .. LESS-THAN OR GREATER-THAN +.. |lesssim| unicode:: U+02272 .. LESS-THAN OR EQUIVALENT TO +.. |LessSlantEqual| unicode:: U+02A7D .. LESS-THAN OR SLANTED EQUAL TO +.. |LessTilde| unicode:: U+02272 .. LESS-THAN OR EQUIVALENT TO +.. |ll| unicode:: U+0226A .. MUCH LESS-THAN +.. |llcorner| unicode:: U+0231E .. BOTTOM LEFT CORNER +.. |Lleftarrow| unicode:: U+021DA .. LEFTWARDS TRIPLE ARROW +.. |lmoustache| unicode:: U+023B0 .. UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +.. |lnapprox| unicode:: U+02A89 .. LESS-THAN AND NOT APPROXIMATE +.. |lneq| unicode:: U+02A87 .. LESS-THAN AND SINGLE-LINE NOT EQUAL TO +.. |lneqq| unicode:: U+02268 .. LESS-THAN BUT NOT EQUAL TO +.. |LongLeftArrow| unicode:: U+027F5 .. LONG LEFTWARDS ARROW +.. |Longleftarrow| unicode:: U+027F8 .. LONG LEFTWARDS DOUBLE ARROW +.. |longleftarrow| unicode:: U+027F5 .. LONG LEFTWARDS ARROW +.. |LongLeftRightArrow| unicode:: U+027F7 .. LONG LEFT RIGHT ARROW +.. |Longleftrightarrow| unicode:: U+027FA .. LONG LEFT RIGHT DOUBLE ARROW +.. |longleftrightarrow| unicode:: U+027F7 .. LONG LEFT RIGHT ARROW +.. |longmapsto| unicode:: U+027FC .. LONG RIGHTWARDS ARROW FROM BAR +.. |LongRightArrow| unicode:: U+027F6 .. LONG RIGHTWARDS ARROW +.. |Longrightarrow| unicode:: U+027F9 .. LONG RIGHTWARDS DOUBLE ARROW +.. |longrightarrow| unicode:: U+027F6 .. LONG RIGHTWARDS ARROW +.. |looparrowleft| unicode:: U+021AB .. LEFTWARDS ARROW WITH LOOP +.. |looparrowright| unicode:: U+021AC .. RIGHTWARDS ARROW WITH LOOP +.. |LowerLeftArrow| unicode:: U+02199 .. SOUTH WEST ARROW +.. |LowerRightArrow| unicode:: U+02198 .. SOUTH EAST ARROW +.. |lozenge| unicode:: U+025CA .. LOZENGE +.. |lrcorner| unicode:: U+0231F .. BOTTOM RIGHT CORNER +.. |Lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS +.. |lvertneqq| unicode:: U+02268 U+0FE00 .. LESS-THAN BUT NOT EQUAL TO - with vertical stroke +.. |maltese| unicode:: U+02720 .. MALTESE CROSS +.. |mapsto| unicode:: U+021A6 .. RIGHTWARDS ARROW FROM BAR +.. |measuredangle| unicode:: U+02221 .. MEASURED ANGLE +.. |Mellintrf| unicode:: U+02133 .. SCRIPT CAPITAL M +.. |MinusPlus| unicode:: U+02213 .. MINUS-OR-PLUS SIGN +.. |mp| unicode:: U+02213 .. MINUS-OR-PLUS SIGN +.. |multimap| unicode:: U+022B8 .. MULTIMAP +.. |napprox| unicode:: U+02249 .. NOT ALMOST EQUAL TO +.. |natural| unicode:: U+0266E .. MUSIC NATURAL SIGN +.. |naturals| unicode:: U+02115 .. DOUBLE-STRUCK CAPITAL N +.. |nearrow| unicode:: U+02197 .. NORTH EAST ARROW +.. |NegativeMediumSpace| unicode:: U+0200B .. ZERO WIDTH SPACE +.. |NegativeThickSpace| unicode:: U+0200B .. ZERO WIDTH SPACE +.. |NegativeThinSpace| unicode:: U+0200B .. ZERO WIDTH SPACE +.. |NegativeVeryThinSpace| unicode:: U+0200B .. ZERO WIDTH SPACE +.. |NestedGreaterGreater| unicode:: U+0226B .. MUCH GREATER-THAN +.. |NestedLessLess| unicode:: U+0226A .. MUCH LESS-THAN +.. |nexists| unicode:: U+02204 .. THERE DOES NOT EXIST +.. |ngeq| unicode:: U+02271 .. NEITHER GREATER-THAN NOR EQUAL TO +.. |ngeqq| unicode:: U+02267 U+00338 .. GREATER-THAN OVER EQUAL TO with slash +.. |ngeqslant| unicode:: U+02A7E U+00338 .. GREATER-THAN OR SLANTED EQUAL TO with slash +.. |ngtr| unicode:: U+0226F .. NOT GREATER-THAN +.. |nLeftarrow| unicode:: U+021CD .. LEFTWARDS DOUBLE ARROW WITH STROKE +.. |nleftarrow| unicode:: U+0219A .. LEFTWARDS ARROW WITH STROKE +.. |nLeftrightarrow| unicode:: U+021CE .. LEFT RIGHT DOUBLE ARROW WITH STROKE +.. |nleftrightarrow| unicode:: U+021AE .. LEFT RIGHT ARROW WITH STROKE +.. |nleq| unicode:: U+02270 .. NEITHER LESS-THAN NOR EQUAL TO +.. |nleqq| unicode:: U+02266 U+00338 .. LESS-THAN OVER EQUAL TO with slash +.. |nleqslant| unicode:: U+02A7D U+00338 .. LESS-THAN OR SLANTED EQUAL TO with slash +.. |nless| unicode:: U+0226E .. NOT LESS-THAN +.. |NonBreakingSpace| unicode:: U+000A0 .. NO-BREAK SPACE +.. |NotCongruent| unicode:: U+02262 .. NOT IDENTICAL TO +.. |NotDoubleVerticalBar| unicode:: U+02226 .. NOT PARALLEL TO +.. |NotElement| unicode:: U+02209 .. NOT AN ELEMENT OF +.. |NotEqual| unicode:: U+02260 .. NOT EQUAL TO +.. |NotEqualTilde| unicode:: U+02242 U+00338 .. MINUS TILDE with slash +.. |NotExists| unicode:: U+02204 .. THERE DOES NOT EXIST +.. |NotGreater| unicode:: U+0226F .. NOT GREATER-THAN +.. |NotGreaterEqual| unicode:: U+02271 .. NEITHER GREATER-THAN NOR EQUAL TO +.. |NotGreaterFullEqual| unicode:: U+02266 U+00338 .. LESS-THAN OVER EQUAL TO with slash +.. |NotGreaterGreater| unicode:: U+0226B U+00338 .. MUCH GREATER THAN with slash +.. |NotGreaterLess| unicode:: U+02279 .. NEITHER GREATER-THAN NOR LESS-THAN +.. |NotGreaterSlantEqual| unicode:: U+02A7E U+00338 .. GREATER-THAN OR SLANTED EQUAL TO with slash +.. |NotGreaterTilde| unicode:: U+02275 .. NEITHER GREATER-THAN NOR EQUIVALENT TO +.. |NotHumpDownHump| unicode:: U+0224E U+00338 .. GEOMETRICALLY EQUIVALENT TO with slash +.. |NotLeftTriangle| unicode:: U+022EA .. NOT NORMAL SUBGROUP OF +.. |NotLeftTriangleEqual| unicode:: U+022EC .. NOT NORMAL SUBGROUP OF OR EQUAL TO +.. |NotLess| unicode:: U+0226E .. NOT LESS-THAN +.. |NotLessEqual| unicode:: U+02270 .. NEITHER LESS-THAN NOR EQUAL TO +.. |NotLessGreater| unicode:: U+02278 .. NEITHER LESS-THAN NOR GREATER-THAN +.. |NotLessLess| unicode:: U+0226A U+00338 .. MUCH LESS THAN with slash +.. |NotLessSlantEqual| unicode:: U+02A7D U+00338 .. LESS-THAN OR SLANTED EQUAL TO with slash +.. |NotLessTilde| unicode:: U+02274 .. NEITHER LESS-THAN NOR EQUIVALENT TO +.. |NotPrecedes| unicode:: U+02280 .. DOES NOT PRECEDE +.. |NotPrecedesEqual| unicode:: U+02AAF U+00338 .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |NotPrecedesSlantEqual| unicode:: U+022E0 .. DOES NOT PRECEDE OR EQUAL +.. |NotReverseElement| unicode:: U+0220C .. DOES NOT CONTAIN AS MEMBER +.. |NotRightTriangle| unicode:: U+022EB .. DOES NOT CONTAIN AS NORMAL SUBGROUP +.. |NotRightTriangleEqual| unicode:: U+022ED .. DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +.. |NotSquareSubsetEqual| unicode:: U+022E2 .. NOT SQUARE IMAGE OF OR EQUAL TO +.. |NotSquareSupersetEqual| unicode:: U+022E3 .. NOT SQUARE ORIGINAL OF OR EQUAL TO +.. |NotSubset| unicode:: U+02282 U+020D2 .. SUBSET OF with vertical line +.. |NotSubsetEqual| unicode:: U+02288 .. NEITHER A SUBSET OF NOR EQUAL TO +.. |NotSucceeds| unicode:: U+02281 .. DOES NOT SUCCEED +.. |NotSucceedsEqual| unicode:: U+02AB0 U+00338 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |NotSucceedsSlantEqual| unicode:: U+022E1 .. DOES NOT SUCCEED OR EQUAL +.. |NotSuperset| unicode:: U+02283 U+020D2 .. SUPERSET OF with vertical line +.. |NotSupersetEqual| unicode:: U+02289 .. NEITHER A SUPERSET OF NOR EQUAL TO +.. |NotTilde| unicode:: U+02241 .. NOT TILDE +.. |NotTildeEqual| unicode:: U+02244 .. NOT ASYMPTOTICALLY EQUAL TO +.. |NotTildeFullEqual| unicode:: U+02247 .. NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +.. |NotTildeTilde| unicode:: U+02249 .. NOT ALMOST EQUAL TO +.. |NotVerticalBar| unicode:: U+02224 .. DOES NOT DIVIDE +.. |nparallel| unicode:: U+02226 .. NOT PARALLEL TO +.. |nprec| unicode:: U+02280 .. DOES NOT PRECEDE +.. |npreceq| unicode:: U+02AAF U+00338 .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |nRightarrow| unicode:: U+021CF .. RIGHTWARDS DOUBLE ARROW WITH STROKE +.. |nrightarrow| unicode:: U+0219B .. RIGHTWARDS ARROW WITH STROKE +.. |nshortmid| unicode:: U+02224 .. DOES NOT DIVIDE +.. |nshortparallel| unicode:: U+02226 .. NOT PARALLEL TO +.. |nsimeq| unicode:: U+02244 .. NOT ASYMPTOTICALLY EQUAL TO +.. |nsubset| unicode:: U+02282 U+020D2 .. SUBSET OF with vertical line +.. |nsubseteq| unicode:: U+02288 .. NEITHER A SUBSET OF NOR EQUAL TO +.. |nsubseteqq| unicode:: U+02AC5 U+00338 .. SUBSET OF ABOVE EQUALS SIGN with slash +.. |nsucc| unicode:: U+02281 .. DOES NOT SUCCEED +.. |nsucceq| unicode:: U+02AB0 U+00338 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +.. |nsupset| unicode:: U+02283 U+020D2 .. SUPERSET OF with vertical line +.. |nsupseteq| unicode:: U+02289 .. NEITHER A SUPERSET OF NOR EQUAL TO +.. |nsupseteqq| unicode:: U+02AC6 U+00338 .. SUPERSET OF ABOVE EQUALS SIGN with slash +.. |ntriangleleft| unicode:: U+022EA .. NOT NORMAL SUBGROUP OF +.. |ntrianglelefteq| unicode:: U+022EC .. NOT NORMAL SUBGROUP OF OR EQUAL TO +.. |ntriangleright| unicode:: U+022EB .. DOES NOT CONTAIN AS NORMAL SUBGROUP +.. |ntrianglerighteq| unicode:: U+022ED .. DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +.. |nwarrow| unicode:: U+02196 .. NORTH WEST ARROW +.. |oint| unicode:: U+0222E .. CONTOUR INTEGRAL +.. |OpenCurlyDoubleQuote| unicode:: U+0201C .. LEFT DOUBLE QUOTATION MARK +.. |OpenCurlyQuote| unicode:: U+02018 .. LEFT SINGLE QUOTATION MARK +.. |orderof| unicode:: U+02134 .. SCRIPT SMALL O +.. |parallel| unicode:: U+02225 .. PARALLEL TO +.. |PartialD| unicode:: U+02202 .. PARTIAL DIFFERENTIAL +.. |pitchfork| unicode:: U+022D4 .. PITCHFORK +.. |PlusMinus| unicode:: U+000B1 .. PLUS-MINUS SIGN +.. |pm| unicode:: U+000B1 .. PLUS-MINUS SIGN +.. |Poincareplane| unicode:: U+0210C .. BLACK-LETTER CAPITAL H +.. |prec| unicode:: U+0227A .. PRECEDES +.. |precapprox| unicode:: U+02AB7 .. PRECEDES ABOVE ALMOST EQUAL TO +.. |preccurlyeq| unicode:: U+0227C .. PRECEDES OR EQUAL TO +.. |Precedes| unicode:: U+0227A .. PRECEDES +.. |PrecedesEqual| unicode:: U+02AAF .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +.. |PrecedesSlantEqual| unicode:: U+0227C .. PRECEDES OR EQUAL TO +.. |PrecedesTilde| unicode:: U+0227E .. PRECEDES OR EQUIVALENT TO +.. |preceq| unicode:: U+02AAF .. PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +.. |precnapprox| unicode:: U+02AB9 .. PRECEDES ABOVE NOT ALMOST EQUAL TO +.. |precneqq| unicode:: U+02AB5 .. PRECEDES ABOVE NOT EQUAL TO +.. |precnsim| unicode:: U+022E8 .. PRECEDES BUT NOT EQUIVALENT TO +.. |precsim| unicode:: U+0227E .. PRECEDES OR EQUIVALENT TO +.. |primes| unicode:: U+02119 .. DOUBLE-STRUCK CAPITAL P +.. |Proportion| unicode:: U+02237 .. PROPORTION +.. |Proportional| unicode:: U+0221D .. PROPORTIONAL TO +.. |propto| unicode:: U+0221D .. PROPORTIONAL TO +.. |quaternions| unicode:: U+0210D .. DOUBLE-STRUCK CAPITAL H +.. |questeq| unicode:: U+0225F .. QUESTIONED EQUAL TO +.. |rangle| unicode:: U+0232A .. RIGHT-POINTING ANGLE BRACKET +.. |rationals| unicode:: U+0211A .. DOUBLE-STRUCK CAPITAL Q +.. |rbrace| unicode:: U+0007D .. RIGHT CURLY BRACKET +.. |rbrack| unicode:: U+0005D .. RIGHT SQUARE BRACKET +.. |Re| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |realine| unicode:: U+0211B .. SCRIPT CAPITAL R +.. |realpart| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |reals| unicode:: U+0211D .. DOUBLE-STRUCK CAPITAL R +.. |ReverseElement| unicode:: U+0220B .. CONTAINS AS MEMBER +.. |ReverseEquilibrium| unicode:: U+021CB .. LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +.. |ReverseUpEquilibrium| unicode:: U+0296F .. DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +.. |RightAngleBracket| unicode:: U+0232A .. RIGHT-POINTING ANGLE BRACKET +.. |RightArrow| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |Rightarrow| unicode:: U+021D2 .. RIGHTWARDS DOUBLE ARROW +.. |rightarrow| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |RightArrowBar| unicode:: U+021E5 .. RIGHTWARDS ARROW TO BAR +.. |RightArrowLeftArrow| unicode:: U+021C4 .. RIGHTWARDS ARROW OVER LEFTWARDS ARROW +.. |rightarrowtail| unicode:: U+021A3 .. RIGHTWARDS ARROW WITH TAIL +.. |RightCeiling| unicode:: U+02309 .. RIGHT CEILING +.. |RightDoubleBracket| unicode:: U+0301B .. RIGHT WHITE SQUARE BRACKET +.. |RightDownVector| unicode:: U+021C2 .. DOWNWARDS HARPOON WITH BARB RIGHTWARDS +.. |RightFloor| unicode:: U+0230B .. RIGHT FLOOR +.. |rightharpoondown| unicode:: U+021C1 .. RIGHTWARDS HARPOON WITH BARB DOWNWARDS +.. |rightharpoonup| unicode:: U+021C0 .. RIGHTWARDS HARPOON WITH BARB UPWARDS +.. |rightleftarrows| unicode:: U+021C4 .. RIGHTWARDS ARROW OVER LEFTWARDS ARROW +.. |rightleftharpoons| unicode:: U+021CC .. RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +.. |rightrightarrows| unicode:: U+021C9 .. RIGHTWARDS PAIRED ARROWS +.. |rightsquigarrow| unicode:: U+0219D .. RIGHTWARDS WAVE ARROW +.. |RightTee| unicode:: U+022A2 .. RIGHT TACK +.. |RightTeeArrow| unicode:: U+021A6 .. RIGHTWARDS ARROW FROM BAR +.. |rightthreetimes| unicode:: U+022CC .. RIGHT SEMIDIRECT PRODUCT +.. |RightTriangle| unicode:: U+022B3 .. CONTAINS AS NORMAL SUBGROUP +.. |RightTriangleEqual| unicode:: U+022B5 .. CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +.. |RightUpVector| unicode:: U+021BE .. UPWARDS HARPOON WITH BARB RIGHTWARDS +.. |RightVector| unicode:: U+021C0 .. RIGHTWARDS HARPOON WITH BARB UPWARDS +.. |risingdotseq| unicode:: U+02253 .. IMAGE OF OR APPROXIMATELY EQUAL TO +.. |rmoustache| unicode:: U+023B1 .. UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +.. |Rrightarrow| unicode:: U+021DB .. RIGHTWARDS TRIPLE ARROW +.. |Rsh| unicode:: U+021B1 .. UPWARDS ARROW WITH TIP RIGHTWARDS +.. |searrow| unicode:: U+02198 .. SOUTH EAST ARROW +.. |setminus| unicode:: U+02216 .. SET MINUS +.. |ShortDownArrow| unicode:: U+02193 .. DOWNWARDS ARROW +.. |ShortLeftArrow| unicode:: U+02190 .. LEFTWARDS ARROW +.. |shortmid| unicode:: U+02223 .. DIVIDES +.. |shortparallel| unicode:: U+02225 .. PARALLEL TO +.. |ShortRightArrow| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |ShortUpArrow| unicode:: U+02191 .. UPWARDS ARROW +.. |simeq| unicode:: U+02243 .. ASYMPTOTICALLY EQUAL TO +.. |SmallCircle| unicode:: U+02218 .. RING OPERATOR +.. |smallsetminus| unicode:: U+02216 .. SET MINUS +.. |spadesuit| unicode:: U+02660 .. BLACK SPADE SUIT +.. |Sqrt| unicode:: U+0221A .. SQUARE ROOT +.. |sqsubset| unicode:: U+0228F .. SQUARE IMAGE OF +.. |sqsubseteq| unicode:: U+02291 .. SQUARE IMAGE OF OR EQUAL TO +.. |sqsupset| unicode:: U+02290 .. SQUARE ORIGINAL OF +.. |sqsupseteq| unicode:: U+02292 .. SQUARE ORIGINAL OF OR EQUAL TO +.. |Square| unicode:: U+025A1 .. WHITE SQUARE +.. |SquareIntersection| unicode:: U+02293 .. SQUARE CAP +.. |SquareSubset| unicode:: U+0228F .. SQUARE IMAGE OF +.. |SquareSubsetEqual| unicode:: U+02291 .. SQUARE IMAGE OF OR EQUAL TO +.. |SquareSuperset| unicode:: U+02290 .. SQUARE ORIGINAL OF +.. |SquareSupersetEqual| unicode:: U+02292 .. SQUARE ORIGINAL OF OR EQUAL TO +.. |SquareUnion| unicode:: U+02294 .. SQUARE CUP +.. |Star| unicode:: U+022C6 .. STAR OPERATOR +.. |straightepsilon| unicode:: U+003F5 .. GREEK LUNATE EPSILON SYMBOL +.. |straightphi| unicode:: U+003D5 .. GREEK PHI SYMBOL +.. |Subset| unicode:: U+022D0 .. DOUBLE SUBSET +.. |subset| unicode:: U+02282 .. SUBSET OF +.. |subseteq| unicode:: U+02286 .. SUBSET OF OR EQUAL TO +.. |subseteqq| unicode:: U+02AC5 .. SUBSET OF ABOVE EQUALS SIGN +.. |SubsetEqual| unicode:: U+02286 .. SUBSET OF OR EQUAL TO +.. |subsetneq| unicode:: U+0228A .. SUBSET OF WITH NOT EQUAL TO +.. |subsetneqq| unicode:: U+02ACB .. SUBSET OF ABOVE NOT EQUAL TO +.. |succ| unicode:: U+0227B .. SUCCEEDS +.. |succapprox| unicode:: U+02AB8 .. SUCCEEDS ABOVE ALMOST EQUAL TO +.. |succcurlyeq| unicode:: U+0227D .. SUCCEEDS OR EQUAL TO +.. |Succeeds| unicode:: U+0227B .. SUCCEEDS +.. |SucceedsEqual| unicode:: U+02AB0 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +.. |SucceedsSlantEqual| unicode:: U+0227D .. SUCCEEDS OR EQUAL TO +.. |SucceedsTilde| unicode:: U+0227F .. SUCCEEDS OR EQUIVALENT TO +.. |succeq| unicode:: U+02AB0 .. SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +.. |succnapprox| unicode:: U+02ABA .. SUCCEEDS ABOVE NOT ALMOST EQUAL TO +.. |succneqq| unicode:: U+02AB6 .. SUCCEEDS ABOVE NOT EQUAL TO +.. |succnsim| unicode:: U+022E9 .. SUCCEEDS BUT NOT EQUIVALENT TO +.. |succsim| unicode:: U+0227F .. SUCCEEDS OR EQUIVALENT TO +.. |SuchThat| unicode:: U+0220B .. CONTAINS AS MEMBER +.. |Sum| unicode:: U+02211 .. N-ARY SUMMATION +.. |Superset| unicode:: U+02283 .. SUPERSET OF +.. |SupersetEqual| unicode:: U+02287 .. SUPERSET OF OR EQUAL TO +.. |Supset| unicode:: U+022D1 .. DOUBLE SUPERSET +.. |supset| unicode:: U+02283 .. SUPERSET OF +.. |supseteq| unicode:: U+02287 .. SUPERSET OF OR EQUAL TO +.. |supseteqq| unicode:: U+02AC6 .. SUPERSET OF ABOVE EQUALS SIGN +.. |supsetneq| unicode:: U+0228B .. SUPERSET OF WITH NOT EQUAL TO +.. |supsetneqq| unicode:: U+02ACC .. SUPERSET OF ABOVE NOT EQUAL TO +.. |swarrow| unicode:: U+02199 .. SOUTH WEST ARROW +.. |Therefore| unicode:: U+02234 .. THEREFORE +.. |therefore| unicode:: U+02234 .. THEREFORE +.. |thickapprox| unicode:: U+02248 .. ALMOST EQUAL TO +.. |thicksim| unicode:: U+0223C .. TILDE OPERATOR +.. |ThinSpace| unicode:: U+02009 .. THIN SPACE +.. |Tilde| unicode:: U+0223C .. TILDE OPERATOR +.. |TildeEqual| unicode:: U+02243 .. ASYMPTOTICALLY EQUAL TO +.. |TildeFullEqual| unicode:: U+02245 .. APPROXIMATELY EQUAL TO +.. |TildeTilde| unicode:: U+02248 .. ALMOST EQUAL TO +.. |toea| unicode:: U+02928 .. NORTH EAST ARROW AND SOUTH EAST ARROW +.. |tosa| unicode:: U+02929 .. SOUTH EAST ARROW AND SOUTH WEST ARROW +.. |triangle| unicode:: U+025B5 .. WHITE UP-POINTING SMALL TRIANGLE +.. |triangledown| unicode:: U+025BF .. WHITE DOWN-POINTING SMALL TRIANGLE +.. |triangleleft| unicode:: U+025C3 .. WHITE LEFT-POINTING SMALL TRIANGLE +.. |trianglelefteq| unicode:: U+022B4 .. NORMAL SUBGROUP OF OR EQUAL TO +.. |triangleq| unicode:: U+0225C .. DELTA EQUAL TO +.. |triangleright| unicode:: U+025B9 .. WHITE RIGHT-POINTING SMALL TRIANGLE +.. |trianglerighteq| unicode:: U+022B5 .. CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +.. |TripleDot| unicode:: U+020DB .. COMBINING THREE DOTS ABOVE +.. |twoheadleftarrow| unicode:: U+0219E .. LEFTWARDS TWO HEADED ARROW +.. |twoheadrightarrow| unicode:: U+021A0 .. RIGHTWARDS TWO HEADED ARROW +.. |ulcorner| unicode:: U+0231C .. TOP LEFT CORNER +.. |Union| unicode:: U+022C3 .. N-ARY UNION +.. |UnionPlus| unicode:: U+0228E .. MULTISET UNION +.. |UpArrow| unicode:: U+02191 .. UPWARDS ARROW +.. |Uparrow| unicode:: U+021D1 .. UPWARDS DOUBLE ARROW +.. |uparrow| unicode:: U+02191 .. UPWARDS ARROW +.. |UpArrowDownArrow| unicode:: U+021C5 .. UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +.. |UpDownArrow| unicode:: U+02195 .. UP DOWN ARROW +.. |Updownarrow| unicode:: U+021D5 .. UP DOWN DOUBLE ARROW +.. |updownarrow| unicode:: U+02195 .. UP DOWN ARROW +.. |UpEquilibrium| unicode:: U+0296E .. UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +.. |upharpoonleft| unicode:: U+021BF .. UPWARDS HARPOON WITH BARB LEFTWARDS +.. |upharpoonright| unicode:: U+021BE .. UPWARDS HARPOON WITH BARB RIGHTWARDS +.. |UpperLeftArrow| unicode:: U+02196 .. NORTH WEST ARROW +.. |UpperRightArrow| unicode:: U+02197 .. NORTH EAST ARROW +.. |upsilon| unicode:: U+003C5 .. GREEK SMALL LETTER UPSILON +.. |UpTee| unicode:: U+022A5 .. UP TACK +.. |UpTeeArrow| unicode:: U+021A5 .. UPWARDS ARROW FROM BAR +.. |upuparrows| unicode:: U+021C8 .. UPWARDS PAIRED ARROWS +.. |urcorner| unicode:: U+0231D .. TOP RIGHT CORNER +.. |varepsilon| unicode:: U+003B5 .. GREEK SMALL LETTER EPSILON +.. |varkappa| unicode:: U+003F0 .. GREEK KAPPA SYMBOL +.. |varnothing| unicode:: U+02205 .. EMPTY SET +.. |varphi| unicode:: U+003C6 .. GREEK SMALL LETTER PHI +.. |varpi| unicode:: U+003D6 .. GREEK PI SYMBOL +.. |varpropto| unicode:: U+0221D .. PROPORTIONAL TO +.. |varrho| unicode:: U+003F1 .. GREEK RHO SYMBOL +.. |varsigma| unicode:: U+003C2 .. GREEK SMALL LETTER FINAL SIGMA +.. |varsubsetneq| unicode:: U+0228A U+0FE00 .. SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +.. |varsubsetneqq| unicode:: U+02ACB U+0FE00 .. SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +.. |varsupsetneq| unicode:: U+0228B U+0FE00 .. SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +.. |varsupsetneqq| unicode:: U+02ACC U+0FE00 .. SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +.. |vartheta| unicode:: U+003D1 .. GREEK THETA SYMBOL +.. |vartriangleleft| unicode:: U+022B2 .. NORMAL SUBGROUP OF +.. |vartriangleright| unicode:: U+022B3 .. CONTAINS AS NORMAL SUBGROUP +.. |Vee| unicode:: U+022C1 .. N-ARY LOGICAL OR +.. |vee| unicode:: U+02228 .. LOGICAL OR +.. |Vert| unicode:: U+02016 .. DOUBLE VERTICAL LINE +.. |vert| unicode:: U+0007C .. VERTICAL LINE +.. |VerticalBar| unicode:: U+02223 .. DIVIDES +.. |VerticalTilde| unicode:: U+02240 .. WREATH PRODUCT +.. |VeryThinSpace| unicode:: U+0200A .. HAIR SPACE +.. |Wedge| unicode:: U+022C0 .. N-ARY LOGICAL AND +.. |wedge| unicode:: U+02227 .. LOGICAL AND +.. |wp| unicode:: U+02118 .. SCRIPT CAPITAL P +.. |wr| unicode:: U+02240 .. WREATH PRODUCT +.. |zeetrf| unicode:: U+02128 .. BLACK-LETTER CAPITAL Z diff --git a/docutils/parsers/rst/include/mmlextra-wide.txt b/docutils/parsers/rst/include/mmlextra-wide.txt new file mode 100644 index 000000000..0177ccc09 --- /dev/null +++ b/docutils/parsers/rst/include/mmlextra-wide.txt @@ -0,0 +1,113 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |af| unicode:: U+02061 .. FUNCTION APPLICATION +.. |aopf| unicode:: U+1D552 .. MATHEMATICAL DOUBLE-STRUCK SMALL A +.. |asympeq| unicode:: U+0224D .. EQUIVALENT TO +.. |bopf| unicode:: U+1D553 .. MATHEMATICAL DOUBLE-STRUCK SMALL B +.. |copf| unicode:: U+1D554 .. MATHEMATICAL DOUBLE-STRUCK SMALL C +.. |Cross| unicode:: U+02A2F .. VECTOR OR CROSS PRODUCT +.. |DD| unicode:: U+02145 .. DOUBLE-STRUCK ITALIC CAPITAL D +.. |dd| unicode:: U+02146 .. DOUBLE-STRUCK ITALIC SMALL D +.. |dopf| unicode:: U+1D555 .. MATHEMATICAL DOUBLE-STRUCK SMALL D +.. |DownArrowBar| unicode:: U+02913 .. DOWNWARDS ARROW TO BAR +.. |DownBreve| unicode:: U+00311 .. COMBINING INVERTED BREVE +.. |DownLeftRightVector| unicode:: U+02950 .. LEFT BARB DOWN RIGHT BARB DOWN HARPOON +.. |DownLeftTeeVector| unicode:: U+0295E .. LEFTWARDS HARPOON WITH BARB DOWN FROM BAR +.. |DownLeftVectorBar| unicode:: U+02956 .. LEFTWARDS HARPOON WITH BARB DOWN TO BAR +.. |DownRightTeeVector| unicode:: U+0295F .. RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR +.. |DownRightVectorBar| unicode:: U+02957 .. RIGHTWARDS HARPOON WITH BARB DOWN TO BAR +.. |ee| unicode:: U+02147 .. DOUBLE-STRUCK ITALIC SMALL E +.. |EmptySmallSquare| unicode:: U+025FB .. WHITE MEDIUM SQUARE +.. |EmptyVerySmallSquare| unicode:: U+025AB .. WHITE SMALL SQUARE +.. |eopf| unicode:: U+1D556 .. MATHEMATICAL DOUBLE-STRUCK SMALL E +.. |Equal| unicode:: U+02A75 .. TWO CONSECUTIVE EQUALS SIGNS +.. |FilledSmallSquare| unicode:: U+025FC .. BLACK MEDIUM SQUARE +.. |FilledVerySmallSquare| unicode:: U+025AA .. BLACK SMALL SQUARE +.. |fopf| unicode:: U+1D557 .. MATHEMATICAL DOUBLE-STRUCK SMALL F +.. |gopf| unicode:: U+1D558 .. MATHEMATICAL DOUBLE-STRUCK SMALL G +.. |GreaterGreater| unicode:: U+02AA2 .. DOUBLE NESTED GREATER-THAN +.. |Hat| unicode:: U+0005E .. CIRCUMFLEX ACCENT +.. |hopf| unicode:: U+1D559 .. MATHEMATICAL DOUBLE-STRUCK SMALL H +.. |HorizontalLine| unicode:: U+02500 .. BOX DRAWINGS LIGHT HORIZONTAL +.. |ic| unicode:: U+02063 .. INVISIBLE SEPARATOR +.. |ii| unicode:: U+02148 .. DOUBLE-STRUCK ITALIC SMALL I +.. |iopf| unicode:: U+1D55A .. MATHEMATICAL DOUBLE-STRUCK SMALL I +.. |it| unicode:: U+02062 .. INVISIBLE TIMES +.. |jopf| unicode:: U+1D55B .. MATHEMATICAL DOUBLE-STRUCK SMALL J +.. |kopf| unicode:: U+1D55C .. MATHEMATICAL DOUBLE-STRUCK SMALL K +.. |larrb| unicode:: U+021E4 .. LEFTWARDS ARROW TO BAR +.. |LeftDownTeeVector| unicode:: U+02961 .. DOWNWARDS HARPOON WITH BARB LEFT FROM BAR +.. |LeftDownVectorBar| unicode:: U+02959 .. DOWNWARDS HARPOON WITH BARB LEFT TO BAR +.. |LeftRightVector| unicode:: U+0294E .. LEFT BARB UP RIGHT BARB UP HARPOON +.. |LeftTeeVector| unicode:: U+0295A .. LEFTWARDS HARPOON WITH BARB UP FROM BAR +.. |LeftTriangleBar| unicode:: U+029CF .. LEFT TRIANGLE BESIDE VERTICAL BAR +.. |LeftUpDownVector| unicode:: U+02951 .. UP BARB LEFT DOWN BARB LEFT HARPOON +.. |LeftUpTeeVector| unicode:: U+02960 .. UPWARDS HARPOON WITH BARB LEFT FROM BAR +.. |LeftUpVectorBar| unicode:: U+02958 .. UPWARDS HARPOON WITH BARB LEFT TO BAR +.. |LeftVectorBar| unicode:: U+02952 .. LEFTWARDS HARPOON WITH BARB UP TO BAR +.. |LessLess| unicode:: U+02AA1 .. DOUBLE NESTED LESS-THAN +.. |lopf| unicode:: U+1D55D .. MATHEMATICAL DOUBLE-STRUCK SMALL L +.. |mapstodown| unicode:: U+021A7 .. DOWNWARDS ARROW FROM BAR +.. |mapstoleft| unicode:: U+021A4 .. LEFTWARDS ARROW FROM BAR +.. |mapstoup| unicode:: U+021A5 .. UPWARDS ARROW FROM BAR +.. |MediumSpace| unicode:: U+0205F .. MEDIUM MATHEMATICAL SPACE +.. |mopf| unicode:: U+1D55E .. MATHEMATICAL DOUBLE-STRUCK SMALL M +.. |nbump| unicode:: U+0224E U+00338 .. GEOMETRICALLY EQUIVALENT TO with slash +.. |nbumpe| unicode:: U+0224F U+00338 .. DIFFERENCE BETWEEN with slash +.. |nesim| unicode:: U+02242 U+00338 .. MINUS TILDE with slash +.. |NewLine| unicode:: U+0000A .. LINE FEED (LF) +.. |NoBreak| unicode:: U+02060 .. WORD JOINER +.. |nopf| unicode:: U+1D55F .. MATHEMATICAL DOUBLE-STRUCK SMALL N +.. |NotCupCap| unicode:: U+0226D .. NOT EQUIVALENT TO +.. |NotHumpEqual| unicode:: U+0224F U+00338 .. DIFFERENCE BETWEEN with slash +.. |NotLeftTriangleBar| unicode:: U+029CF U+00338 .. LEFT TRIANGLE BESIDE VERTICAL BAR with slash +.. |NotNestedGreaterGreater| unicode:: U+02AA2 U+00338 .. DOUBLE NESTED GREATER-THAN with slash +.. |NotNestedLessLess| unicode:: U+02AA1 U+00338 .. DOUBLE NESTED LESS-THAN with slash +.. |NotRightTriangleBar| unicode:: U+029D0 U+00338 .. VERTICAL BAR BESIDE RIGHT TRIANGLE with slash +.. |NotSquareSubset| unicode:: U+0228F U+00338 .. SQUARE IMAGE OF with slash +.. |NotSquareSuperset| unicode:: U+02290 U+00338 .. SQUARE ORIGINAL OF with slash +.. |NotSucceedsTilde| unicode:: U+0227F U+00338 .. SUCCEEDS OR EQUIVALENT TO with slash +.. |oopf| unicode:: U+1D560 .. MATHEMATICAL DOUBLE-STRUCK SMALL O +.. |OverBar| unicode:: U+000AF .. MACRON +.. |OverBrace| unicode:: U+0FE37 .. PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET +.. |OverBracket| unicode:: U+023B4 .. TOP SQUARE BRACKET +.. |OverParenthesis| unicode:: U+0FE35 .. PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS +.. |planckh| unicode:: U+0210E .. PLANCK CONSTANT +.. |popf| unicode:: U+1D561 .. MATHEMATICAL DOUBLE-STRUCK SMALL P +.. |Product| unicode:: U+0220F .. N-ARY PRODUCT +.. |qopf| unicode:: U+1D562 .. MATHEMATICAL DOUBLE-STRUCK SMALL Q +.. |rarrb| unicode:: U+021E5 .. RIGHTWARDS ARROW TO BAR +.. |RightDownTeeVector| unicode:: U+0295D .. DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR +.. |RightDownVectorBar| unicode:: U+02955 .. DOWNWARDS HARPOON WITH BARB RIGHT TO BAR +.. |RightTeeVector| unicode:: U+0295B .. RIGHTWARDS HARPOON WITH BARB UP FROM BAR +.. |RightTriangleBar| unicode:: U+029D0 .. VERTICAL BAR BESIDE RIGHT TRIANGLE +.. |RightUpDownVector| unicode:: U+0294F .. UP BARB RIGHT DOWN BARB RIGHT HARPOON +.. |RightUpTeeVector| unicode:: U+0295C .. UPWARDS HARPOON WITH BARB RIGHT FROM BAR +.. |RightUpVectorBar| unicode:: U+02954 .. UPWARDS HARPOON WITH BARB RIGHT TO BAR +.. |RightVectorBar| unicode:: U+02953 .. RIGHTWARDS HARPOON WITH BARB UP TO BAR +.. |ropf| unicode:: U+1D563 .. MATHEMATICAL DOUBLE-STRUCK SMALL R +.. |RoundImplies| unicode:: U+02970 .. RIGHT DOUBLE ARROW WITH ROUNDED HEAD +.. |RuleDelayed| unicode:: U+029F4 .. RULE-DELAYED +.. |sopf| unicode:: U+1D564 .. MATHEMATICAL DOUBLE-STRUCK SMALL S +.. |Tab| unicode:: U+00009 .. CHARACTER TABULATION +.. |ThickSpace| unicode:: U+02009 U+0200A U+0200A .. space of width 5/18 em +.. |topf| unicode:: U+1D565 .. MATHEMATICAL DOUBLE-STRUCK SMALL T +.. |UnderBar| unicode:: U+00332 .. COMBINING LOW LINE +.. |UnderBrace| unicode:: U+0FE38 .. PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET +.. |UnderBracket| unicode:: U+023B5 .. BOTTOM SQUARE BRACKET +.. |UnderParenthesis| unicode:: U+0FE36 .. PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS +.. |uopf| unicode:: U+1D566 .. MATHEMATICAL DOUBLE-STRUCK SMALL U +.. |UpArrowBar| unicode:: U+02912 .. UPWARDS ARROW TO BAR +.. |Upsilon| unicode:: U+003A5 .. GREEK CAPITAL LETTER UPSILON +.. |VerticalLine| unicode:: U+0007C .. VERTICAL LINE +.. |VerticalSeparator| unicode:: U+02758 .. LIGHT VERTICAL BAR +.. |vopf| unicode:: U+1D567 .. MATHEMATICAL DOUBLE-STRUCK SMALL V +.. |wopf| unicode:: U+1D568 .. MATHEMATICAL DOUBLE-STRUCK SMALL W +.. |xopf| unicode:: U+1D569 .. MATHEMATICAL DOUBLE-STRUCK SMALL X +.. |yopf| unicode:: U+1D56A .. MATHEMATICAL DOUBLE-STRUCK SMALL Y +.. |ZeroWidthSpace| unicode:: U+0200B .. ZERO WIDTH SPACE +.. |zopf| unicode:: U+1D56B .. MATHEMATICAL DOUBLE-STRUCK SMALL Z diff --git a/docutils/parsers/rst/include/mmlextra.txt b/docutils/parsers/rst/include/mmlextra.txt new file mode 100644 index 000000000..790a9775a --- /dev/null +++ b/docutils/parsers/rst/include/mmlextra.txt @@ -0,0 +1,87 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |af| unicode:: U+02061 .. FUNCTION APPLICATION +.. |asympeq| unicode:: U+0224D .. EQUIVALENT TO +.. |Cross| unicode:: U+02A2F .. VECTOR OR CROSS PRODUCT +.. |DD| unicode:: U+02145 .. DOUBLE-STRUCK ITALIC CAPITAL D +.. |dd| unicode:: U+02146 .. DOUBLE-STRUCK ITALIC SMALL D +.. |DownArrowBar| unicode:: U+02913 .. DOWNWARDS ARROW TO BAR +.. |DownBreve| unicode:: U+00311 .. COMBINING INVERTED BREVE +.. |DownLeftRightVector| unicode:: U+02950 .. LEFT BARB DOWN RIGHT BARB DOWN HARPOON +.. |DownLeftTeeVector| unicode:: U+0295E .. LEFTWARDS HARPOON WITH BARB DOWN FROM BAR +.. |DownLeftVectorBar| unicode:: U+02956 .. LEFTWARDS HARPOON WITH BARB DOWN TO BAR +.. |DownRightTeeVector| unicode:: U+0295F .. RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR +.. |DownRightVectorBar| unicode:: U+02957 .. RIGHTWARDS HARPOON WITH BARB DOWN TO BAR +.. |ee| unicode:: U+02147 .. DOUBLE-STRUCK ITALIC SMALL E +.. |EmptySmallSquare| unicode:: U+025FB .. WHITE MEDIUM SQUARE +.. |EmptyVerySmallSquare| unicode:: U+025AB .. WHITE SMALL SQUARE +.. |Equal| unicode:: U+02A75 .. TWO CONSECUTIVE EQUALS SIGNS +.. |FilledSmallSquare| unicode:: U+025FC .. BLACK MEDIUM SQUARE +.. |FilledVerySmallSquare| unicode:: U+025AA .. BLACK SMALL SQUARE +.. |GreaterGreater| unicode:: U+02AA2 .. DOUBLE NESTED GREATER-THAN +.. |Hat| unicode:: U+0005E .. CIRCUMFLEX ACCENT +.. |HorizontalLine| unicode:: U+02500 .. BOX DRAWINGS LIGHT HORIZONTAL +.. |ic| unicode:: U+02063 .. INVISIBLE SEPARATOR +.. |ii| unicode:: U+02148 .. DOUBLE-STRUCK ITALIC SMALL I +.. |it| unicode:: U+02062 .. INVISIBLE TIMES +.. |larrb| unicode:: U+021E4 .. LEFTWARDS ARROW TO BAR +.. |LeftDownTeeVector| unicode:: U+02961 .. DOWNWARDS HARPOON WITH BARB LEFT FROM BAR +.. |LeftDownVectorBar| unicode:: U+02959 .. DOWNWARDS HARPOON WITH BARB LEFT TO BAR +.. |LeftRightVector| unicode:: U+0294E .. LEFT BARB UP RIGHT BARB UP HARPOON +.. |LeftTeeVector| unicode:: U+0295A .. LEFTWARDS HARPOON WITH BARB UP FROM BAR +.. |LeftTriangleBar| unicode:: U+029CF .. LEFT TRIANGLE BESIDE VERTICAL BAR +.. |LeftUpDownVector| unicode:: U+02951 .. UP BARB LEFT DOWN BARB LEFT HARPOON +.. |LeftUpTeeVector| unicode:: U+02960 .. UPWARDS HARPOON WITH BARB LEFT FROM BAR +.. |LeftUpVectorBar| unicode:: U+02958 .. UPWARDS HARPOON WITH BARB LEFT TO BAR +.. |LeftVectorBar| unicode:: U+02952 .. LEFTWARDS HARPOON WITH BARB UP TO BAR +.. |LessLess| unicode:: U+02AA1 .. DOUBLE NESTED LESS-THAN +.. |mapstodown| unicode:: U+021A7 .. DOWNWARDS ARROW FROM BAR +.. |mapstoleft| unicode:: U+021A4 .. LEFTWARDS ARROW FROM BAR +.. |mapstoup| unicode:: U+021A5 .. UPWARDS ARROW FROM BAR +.. |MediumSpace| unicode:: U+0205F .. MEDIUM MATHEMATICAL SPACE +.. |nbump| unicode:: U+0224E U+00338 .. GEOMETRICALLY EQUIVALENT TO with slash +.. |nbumpe| unicode:: U+0224F U+00338 .. DIFFERENCE BETWEEN with slash +.. |nesim| unicode:: U+02242 U+00338 .. MINUS TILDE with slash +.. |NewLine| unicode:: U+0000A .. LINE FEED (LF) +.. |NoBreak| unicode:: U+02060 .. WORD JOINER +.. |NotCupCap| unicode:: U+0226D .. NOT EQUIVALENT TO +.. |NotHumpEqual| unicode:: U+0224F U+00338 .. DIFFERENCE BETWEEN with slash +.. |NotLeftTriangleBar| unicode:: U+029CF U+00338 .. LEFT TRIANGLE BESIDE VERTICAL BAR with slash +.. |NotNestedGreaterGreater| unicode:: U+02AA2 U+00338 .. DOUBLE NESTED GREATER-THAN with slash +.. |NotNestedLessLess| unicode:: U+02AA1 U+00338 .. DOUBLE NESTED LESS-THAN with slash +.. |NotRightTriangleBar| unicode:: U+029D0 U+00338 .. VERTICAL BAR BESIDE RIGHT TRIANGLE with slash +.. |NotSquareSubset| unicode:: U+0228F U+00338 .. SQUARE IMAGE OF with slash +.. |NotSquareSuperset| unicode:: U+02290 U+00338 .. SQUARE ORIGINAL OF with slash +.. |NotSucceedsTilde| unicode:: U+0227F U+00338 .. SUCCEEDS OR EQUIVALENT TO with slash +.. |OverBar| unicode:: U+000AF .. MACRON +.. |OverBrace| unicode:: U+0FE37 .. PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET +.. |OverBracket| unicode:: U+023B4 .. TOP SQUARE BRACKET +.. |OverParenthesis| unicode:: U+0FE35 .. PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS +.. |planckh| unicode:: U+0210E .. PLANCK CONSTANT +.. |Product| unicode:: U+0220F .. N-ARY PRODUCT +.. |rarrb| unicode:: U+021E5 .. RIGHTWARDS ARROW TO BAR +.. |RightDownTeeVector| unicode:: U+0295D .. DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR +.. |RightDownVectorBar| unicode:: U+02955 .. DOWNWARDS HARPOON WITH BARB RIGHT TO BAR +.. |RightTeeVector| unicode:: U+0295B .. RIGHTWARDS HARPOON WITH BARB UP FROM BAR +.. |RightTriangleBar| unicode:: U+029D0 .. VERTICAL BAR BESIDE RIGHT TRIANGLE +.. |RightUpDownVector| unicode:: U+0294F .. UP BARB RIGHT DOWN BARB RIGHT HARPOON +.. |RightUpTeeVector| unicode:: U+0295C .. UPWARDS HARPOON WITH BARB RIGHT FROM BAR +.. |RightUpVectorBar| unicode:: U+02954 .. UPWARDS HARPOON WITH BARB RIGHT TO BAR +.. |RightVectorBar| unicode:: U+02953 .. RIGHTWARDS HARPOON WITH BARB UP TO BAR +.. |RoundImplies| unicode:: U+02970 .. RIGHT DOUBLE ARROW WITH ROUNDED HEAD +.. |RuleDelayed| unicode:: U+029F4 .. RULE-DELAYED +.. |Tab| unicode:: U+00009 .. CHARACTER TABULATION +.. |ThickSpace| unicode:: U+02009 U+0200A U+0200A .. space of width 5/18 em +.. |UnderBar| unicode:: U+00332 .. COMBINING LOW LINE +.. |UnderBrace| unicode:: U+0FE38 .. PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET +.. |UnderBracket| unicode:: U+023B5 .. BOTTOM SQUARE BRACKET +.. |UnderParenthesis| unicode:: U+0FE36 .. PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS +.. |UpArrowBar| unicode:: U+02912 .. UPWARDS ARROW TO BAR +.. |Upsilon| unicode:: U+003A5 .. GREEK CAPITAL LETTER UPSILON +.. |VerticalLine| unicode:: U+0007C .. VERTICAL LINE +.. |VerticalSeparator| unicode:: U+02758 .. LIGHT VERTICAL BAR +.. |ZeroWidthSpace| unicode:: U+0200B .. ZERO WIDTH SPACE diff --git a/docutils/parsers/rst/include/xhtml1-lat1.txt b/docutils/parsers/rst/include/xhtml1-lat1.txt new file mode 100644 index 000000000..824dc61c0 --- /dev/null +++ b/docutils/parsers/rst/include/xhtml1-lat1.txt @@ -0,0 +1,102 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |Aacute| unicode:: U+000C1 .. LATIN CAPITAL LETTER A WITH ACUTE +.. |aacute| unicode:: U+000E1 .. LATIN SMALL LETTER A WITH ACUTE +.. |Acirc| unicode:: U+000C2 .. LATIN CAPITAL LETTER A WITH CIRCUMFLEX +.. |acirc| unicode:: U+000E2 .. LATIN SMALL LETTER A WITH CIRCUMFLEX +.. |acute| unicode:: U+000B4 .. ACUTE ACCENT +.. |AElig| unicode:: U+000C6 .. LATIN CAPITAL LETTER AE +.. |aelig| unicode:: U+000E6 .. LATIN SMALL LETTER AE +.. |Agrave| unicode:: U+000C0 .. LATIN CAPITAL LETTER A WITH GRAVE +.. |agrave| unicode:: U+000E0 .. LATIN SMALL LETTER A WITH GRAVE +.. |Aring| unicode:: U+000C5 .. LATIN CAPITAL LETTER A WITH RING ABOVE +.. |aring| unicode:: U+000E5 .. LATIN SMALL LETTER A WITH RING ABOVE +.. |Atilde| unicode:: U+000C3 .. LATIN CAPITAL LETTER A WITH TILDE +.. |atilde| unicode:: U+000E3 .. LATIN SMALL LETTER A WITH TILDE +.. |Auml| unicode:: U+000C4 .. LATIN CAPITAL LETTER A WITH DIAERESIS +.. |auml| unicode:: U+000E4 .. LATIN SMALL LETTER A WITH DIAERESIS +.. |brvbar| unicode:: U+000A6 .. BROKEN BAR +.. |Ccedil| unicode:: U+000C7 .. LATIN CAPITAL LETTER C WITH CEDILLA +.. |ccedil| unicode:: U+000E7 .. LATIN SMALL LETTER C WITH CEDILLA +.. |cedil| unicode:: U+000B8 .. CEDILLA +.. |cent| unicode:: U+000A2 .. CENT SIGN +.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN +.. |curren| unicode:: U+000A4 .. CURRENCY SIGN +.. |deg| unicode:: U+000B0 .. DEGREE SIGN +.. |divide| unicode:: U+000F7 .. DIVISION SIGN +.. |Eacute| unicode:: U+000C9 .. LATIN CAPITAL LETTER E WITH ACUTE +.. |eacute| unicode:: U+000E9 .. LATIN SMALL LETTER E WITH ACUTE +.. |Ecirc| unicode:: U+000CA .. LATIN CAPITAL LETTER E WITH CIRCUMFLEX +.. |ecirc| unicode:: U+000EA .. LATIN SMALL LETTER E WITH CIRCUMFLEX +.. |Egrave| unicode:: U+000C8 .. LATIN CAPITAL LETTER E WITH GRAVE +.. |egrave| unicode:: U+000E8 .. LATIN SMALL LETTER E WITH GRAVE +.. |ETH| unicode:: U+000D0 .. LATIN CAPITAL LETTER ETH +.. |eth| unicode:: U+000F0 .. LATIN SMALL LETTER ETH +.. |Euml| unicode:: U+000CB .. LATIN CAPITAL LETTER E WITH DIAERESIS +.. |euml| unicode:: U+000EB .. LATIN SMALL LETTER E WITH DIAERESIS +.. |frac12| unicode:: U+000BD .. VULGAR FRACTION ONE HALF +.. |frac14| unicode:: U+000BC .. VULGAR FRACTION ONE QUARTER +.. |frac34| unicode:: U+000BE .. VULGAR FRACTION THREE QUARTERS +.. |Iacute| unicode:: U+000CD .. LATIN CAPITAL LETTER I WITH ACUTE +.. |iacute| unicode:: U+000ED .. LATIN SMALL LETTER I WITH ACUTE +.. |Icirc| unicode:: U+000CE .. LATIN CAPITAL LETTER I WITH CIRCUMFLEX +.. |icirc| unicode:: U+000EE .. LATIN SMALL LETTER I WITH CIRCUMFLEX +.. |iexcl| unicode:: U+000A1 .. INVERTED EXCLAMATION MARK +.. |Igrave| unicode:: U+000CC .. LATIN CAPITAL LETTER I WITH GRAVE +.. |igrave| unicode:: U+000EC .. LATIN SMALL LETTER I WITH GRAVE +.. |iquest| unicode:: U+000BF .. INVERTED QUESTION MARK +.. |Iuml| unicode:: U+000CF .. LATIN CAPITAL LETTER I WITH DIAERESIS +.. |iuml| unicode:: U+000EF .. LATIN SMALL LETTER I WITH DIAERESIS +.. |laquo| unicode:: U+000AB .. LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +.. |macr| unicode:: U+000AF .. MACRON +.. |micro| unicode:: U+000B5 .. MICRO SIGN +.. |middot| unicode:: U+000B7 .. MIDDLE DOT +.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE +.. |not| unicode:: U+000AC .. NOT SIGN +.. |Ntilde| unicode:: U+000D1 .. LATIN CAPITAL LETTER N WITH TILDE +.. |ntilde| unicode:: U+000F1 .. LATIN SMALL LETTER N WITH TILDE +.. |Oacute| unicode:: U+000D3 .. LATIN CAPITAL LETTER O WITH ACUTE +.. |oacute| unicode:: U+000F3 .. LATIN SMALL LETTER O WITH ACUTE +.. |Ocirc| unicode:: U+000D4 .. LATIN CAPITAL LETTER O WITH CIRCUMFLEX +.. |ocirc| unicode:: U+000F4 .. LATIN SMALL LETTER O WITH CIRCUMFLEX +.. |Ograve| unicode:: U+000D2 .. LATIN CAPITAL LETTER O WITH GRAVE +.. |ograve| unicode:: U+000F2 .. LATIN SMALL LETTER O WITH GRAVE +.. |ordf| unicode:: U+000AA .. FEMININE ORDINAL INDICATOR +.. |ordm| unicode:: U+000BA .. MASCULINE ORDINAL INDICATOR +.. |Oslash| unicode:: U+000D8 .. LATIN CAPITAL LETTER O WITH STROKE +.. |oslash| unicode:: U+000F8 .. LATIN SMALL LETTER O WITH STROKE +.. |Otilde| unicode:: U+000D5 .. LATIN CAPITAL LETTER O WITH TILDE +.. |otilde| unicode:: U+000F5 .. LATIN SMALL LETTER O WITH TILDE +.. |Ouml| unicode:: U+000D6 .. LATIN CAPITAL LETTER O WITH DIAERESIS +.. |ouml| unicode:: U+000F6 .. LATIN SMALL LETTER O WITH DIAERESIS +.. |para| unicode:: U+000B6 .. PILCROW SIGN +.. |plusmn| unicode:: U+000B1 .. PLUS-MINUS SIGN +.. |pound| unicode:: U+000A3 .. POUND SIGN +.. |raquo| unicode:: U+000BB .. RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +.. |reg| unicode:: U+000AE .. REGISTERED SIGN +.. |sect| unicode:: U+000A7 .. SECTION SIGN +.. |shy| unicode:: U+000AD .. SOFT HYPHEN +.. |sup1| unicode:: U+000B9 .. SUPERSCRIPT ONE +.. |sup2| unicode:: U+000B2 .. SUPERSCRIPT TWO +.. |sup3| unicode:: U+000B3 .. SUPERSCRIPT THREE +.. |szlig| unicode:: U+000DF .. LATIN SMALL LETTER SHARP S +.. |THORN| unicode:: U+000DE .. LATIN CAPITAL LETTER THORN +.. |thorn| unicode:: U+000FE .. LATIN SMALL LETTER THORN +.. |times| unicode:: U+000D7 .. MULTIPLICATION SIGN +.. |Uacute| unicode:: U+000DA .. LATIN CAPITAL LETTER U WITH ACUTE +.. |uacute| unicode:: U+000FA .. LATIN SMALL LETTER U WITH ACUTE +.. |Ucirc| unicode:: U+000DB .. LATIN CAPITAL LETTER U WITH CIRCUMFLEX +.. |ucirc| unicode:: U+000FB .. LATIN SMALL LETTER U WITH CIRCUMFLEX +.. |Ugrave| unicode:: U+000D9 .. LATIN CAPITAL LETTER U WITH GRAVE +.. |ugrave| unicode:: U+000F9 .. LATIN SMALL LETTER U WITH GRAVE +.. |uml| unicode:: U+000A8 .. DIAERESIS +.. |Uuml| unicode:: U+000DC .. LATIN CAPITAL LETTER U WITH DIAERESIS +.. |uuml| unicode:: U+000FC .. LATIN SMALL LETTER U WITH DIAERESIS +.. |Yacute| unicode:: U+000DD .. LATIN CAPITAL LETTER Y WITH ACUTE +.. |yacute| unicode:: U+000FD .. LATIN SMALL LETTER Y WITH ACUTE +.. |yen| unicode:: U+000A5 .. YEN SIGN +.. |yuml| unicode:: U+000FF .. LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/docutils/parsers/rst/include/xhtml1-special.txt b/docutils/parsers/rst/include/xhtml1-special.txt new file mode 100644 index 000000000..dc6f5753c --- /dev/null +++ b/docutils/parsers/rst/include/xhtml1-special.txt @@ -0,0 +1,37 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |bdquo| unicode:: U+0201E .. DOUBLE LOW-9 QUOTATION MARK +.. |circ| unicode:: U+002C6 .. MODIFIER LETTER CIRCUMFLEX ACCENT +.. |Dagger| unicode:: U+02021 .. DOUBLE DAGGER +.. |dagger| unicode:: U+02020 .. DAGGER +.. |emsp| unicode:: U+02003 .. EM SPACE +.. |ensp| unicode:: U+02002 .. EN SPACE +.. |euro| unicode:: U+020AC .. EURO SIGN +.. |gt| unicode:: U+0003E .. GREATER-THAN SIGN +.. |ldquo| unicode:: U+0201C .. LEFT DOUBLE QUOTATION MARK +.. |lrm| unicode:: U+0200E .. LEFT-TO-RIGHT MARK +.. |lsaquo| unicode:: U+02039 .. SINGLE LEFT-POINTING ANGLE QUOTATION MARK +.. |lsquo| unicode:: U+02018 .. LEFT SINGLE QUOTATION MARK +.. |lt| unicode:: U+0003C .. LESS-THAN SIGN +.. |mdash| unicode:: U+02014 .. EM DASH +.. |ndash| unicode:: U+02013 .. EN DASH +.. |OElig| unicode:: U+00152 .. LATIN CAPITAL LIGATURE OE +.. |oelig| unicode:: U+00153 .. LATIN SMALL LIGATURE OE +.. |permil| unicode:: U+02030 .. PER MILLE SIGN +.. |quot| unicode:: U+00022 .. QUOTATION MARK +.. |rdquo| unicode:: U+0201D .. RIGHT DOUBLE QUOTATION MARK +.. |rlm| unicode:: U+0200F .. RIGHT-TO-LEFT MARK +.. |rsaquo| unicode:: U+0203A .. SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +.. |rsquo| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARK +.. |sbquo| unicode:: U+0201A .. SINGLE LOW-9 QUOTATION MARK +.. |Scaron| unicode:: U+00160 .. LATIN CAPITAL LETTER S WITH CARON +.. |scaron| unicode:: U+00161 .. LATIN SMALL LETTER S WITH CARON +.. |thinsp| unicode:: U+02009 .. THIN SPACE +.. |tilde| unicode:: U+002DC .. SMALL TILDE +.. |Yuml| unicode:: U+00178 .. LATIN CAPITAL LETTER Y WITH DIAERESIS +.. |zwj| unicode:: U+0200D .. ZERO WIDTH JOINER +.. |zwnj| unicode:: U+0200C .. ZERO WIDTH NON-JOINER diff --git a/docutils/parsers/rst/include/xhtml1-symbol.txt b/docutils/parsers/rst/include/xhtml1-symbol.txt new file mode 100644 index 000000000..8fe97f808 --- /dev/null +++ b/docutils/parsers/rst/include/xhtml1-symbol.txt @@ -0,0 +1,130 @@ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + +.. |alefsym| unicode:: U+02135 .. ALEF SYMBOL +.. |Alpha| unicode:: U+00391 .. GREEK CAPITAL LETTER ALPHA +.. |alpha| unicode:: U+003B1 .. GREEK SMALL LETTER ALPHA +.. |and| unicode:: U+02227 .. LOGICAL AND +.. |ang| unicode:: U+02220 .. ANGLE +.. |asymp| unicode:: U+02248 .. ALMOST EQUAL TO +.. |Beta| unicode:: U+00392 .. GREEK CAPITAL LETTER BETA +.. |beta| unicode:: U+003B2 .. GREEK SMALL LETTER BETA +.. |bull| unicode:: U+02022 .. BULLET +.. |cap| unicode:: U+02229 .. INTERSECTION +.. |Chi| unicode:: U+003A7 .. GREEK CAPITAL LETTER CHI +.. |chi| unicode:: U+003C7 .. GREEK SMALL LETTER CHI +.. |clubs| unicode:: U+02663 .. BLACK CLUB SUIT +.. |cong| unicode:: U+02245 .. APPROXIMATELY EQUAL TO +.. |crarr| unicode:: U+021B5 .. DOWNWARDS ARROW WITH CORNER LEFTWARDS +.. |cup| unicode:: U+0222A .. UNION +.. |dArr| unicode:: U+021D3 .. DOWNWARDS DOUBLE ARROW +.. |darr| unicode:: U+02193 .. DOWNWARDS ARROW +.. |Delta| unicode:: U+00394 .. GREEK CAPITAL LETTER DELTA +.. |delta| unicode:: U+003B4 .. GREEK SMALL LETTER DELTA +.. |diams| unicode:: U+02666 .. BLACK DIAMOND SUIT +.. |empty| unicode:: U+02205 .. EMPTY SET +.. |Epsilon| unicode:: U+00395 .. GREEK CAPITAL LETTER EPSILON +.. |epsilon| unicode:: U+003B5 .. GREEK SMALL LETTER EPSILON +.. |equiv| unicode:: U+02261 .. IDENTICAL TO +.. |Eta| unicode:: U+00397 .. GREEK CAPITAL LETTER ETA +.. |eta| unicode:: U+003B7 .. GREEK SMALL LETTER ETA +.. |exist| unicode:: U+02203 .. THERE EXISTS +.. |fnof| unicode:: U+00192 .. LATIN SMALL LETTER F WITH HOOK +.. |forall| unicode:: U+02200 .. FOR ALL +.. |frasl| unicode:: U+02044 .. FRACTION SLASH +.. |Gamma| unicode:: U+00393 .. GREEK CAPITAL LETTER GAMMA +.. |gamma| unicode:: U+003B3 .. GREEK SMALL LETTER GAMMA +.. |ge| unicode:: U+02265 .. GREATER-THAN OR EQUAL TO +.. |hArr| unicode:: U+021D4 .. LEFT RIGHT DOUBLE ARROW +.. |harr| unicode:: U+02194 .. LEFT RIGHT ARROW +.. |hearts| unicode:: U+02665 .. BLACK HEART SUIT +.. |hellip| unicode:: U+02026 .. HORIZONTAL ELLIPSIS +.. |image| unicode:: U+02111 .. BLACK-LETTER CAPITAL I +.. |infin| unicode:: U+0221E .. INFINITY +.. |int| unicode:: U+0222B .. INTEGRAL +.. |Iota| unicode:: U+00399 .. GREEK CAPITAL LETTER IOTA +.. |iota| unicode:: U+003B9 .. GREEK SMALL LETTER IOTA +.. |isin| unicode:: U+02208 .. ELEMENT OF +.. |Kappa| unicode:: U+0039A .. GREEK CAPITAL LETTER KAPPA +.. |kappa| unicode:: U+003BA .. GREEK SMALL LETTER KAPPA +.. |Lambda| unicode:: U+0039B .. GREEK CAPITAL LETTER LAMDA +.. |lambda| unicode:: U+003BB .. GREEK SMALL LETTER LAMDA +.. |lang| unicode:: U+02329 .. LEFT-POINTING ANGLE BRACKET +.. |lArr| unicode:: U+021D0 .. LEFTWARDS DOUBLE ARROW +.. |larr| unicode:: U+02190 .. LEFTWARDS ARROW +.. |lceil| unicode:: U+02308 .. LEFT CEILING +.. |le| unicode:: U+02264 .. LESS-THAN OR EQUAL TO +.. |lfloor| unicode:: U+0230A .. LEFT FLOOR +.. |lowast| unicode:: U+02217 .. ASTERISK OPERATOR +.. |loz| unicode:: U+025CA .. LOZENGE +.. |minus| unicode:: U+02212 .. MINUS SIGN +.. |Mu| unicode:: U+0039C .. GREEK CAPITAL LETTER MU +.. |mu| unicode:: U+003BC .. GREEK SMALL LETTER MU +.. |nabla| unicode:: U+02207 .. NABLA +.. |ne| unicode:: U+02260 .. NOT EQUAL TO +.. |ni| unicode:: U+0220B .. CONTAINS AS MEMBER +.. |notin| unicode:: U+02209 .. NOT AN ELEMENT OF +.. |nsub| unicode:: U+02284 .. NOT A SUBSET OF +.. |Nu| unicode:: U+0039D .. GREEK CAPITAL LETTER NU +.. |nu| unicode:: U+003BD .. GREEK SMALL LETTER NU +.. |oline| unicode:: U+0203E .. OVERLINE +.. |Omega| unicode:: U+003A9 .. GREEK CAPITAL LETTER OMEGA +.. |omega| unicode:: U+003C9 .. GREEK SMALL LETTER OMEGA +.. |Omicron| unicode:: U+0039F .. GREEK CAPITAL LETTER OMICRON +.. |omicron| unicode:: U+003BF .. GREEK SMALL LETTER OMICRON +.. |oplus| unicode:: U+02295 .. CIRCLED PLUS +.. |or| unicode:: U+02228 .. LOGICAL OR +.. |otimes| unicode:: U+02297 .. CIRCLED TIMES +.. |part| unicode:: U+02202 .. PARTIAL DIFFERENTIAL +.. |perp| unicode:: U+022A5 .. UP TACK +.. |Phi| unicode:: U+003A6 .. GREEK CAPITAL LETTER PHI +.. |phi| unicode:: U+003D5 .. GREEK PHI SYMBOL +.. |Pi| unicode:: U+003A0 .. GREEK CAPITAL LETTER PI +.. |pi| unicode:: U+003C0 .. GREEK SMALL LETTER PI +.. |piv| unicode:: U+003D6 .. GREEK PI SYMBOL +.. |Prime| unicode:: U+02033 .. DOUBLE PRIME +.. |prime| unicode:: U+02032 .. PRIME +.. |prod| unicode:: U+0220F .. N-ARY PRODUCT +.. |prop| unicode:: U+0221D .. PROPORTIONAL TO +.. |Psi| unicode:: U+003A8 .. GREEK CAPITAL LETTER PSI +.. |psi| unicode:: U+003C8 .. GREEK SMALL LETTER PSI +.. |radic| unicode:: U+0221A .. SQUARE ROOT +.. |rang| unicode:: U+0232A .. RIGHT-POINTING ANGLE BRACKET +.. |rArr| unicode:: U+021D2 .. RIGHTWARDS DOUBLE ARROW +.. |rarr| unicode:: U+02192 .. RIGHTWARDS ARROW +.. |rceil| unicode:: U+02309 .. RIGHT CEILING +.. |real| unicode:: U+0211C .. BLACK-LETTER CAPITAL R +.. |rfloor| unicode:: U+0230B .. RIGHT FLOOR +.. |Rho| unicode:: U+003A1 .. GREEK CAPITAL LETTER RHO +.. |rho| unicode:: U+003C1 .. GREEK SMALL LETTER RHO +.. |sdot| unicode:: U+022C5 .. DOT OPERATOR +.. |Sigma| unicode:: U+003A3 .. GREEK CAPITAL LETTER SIGMA +.. |sigma| unicode:: U+003C3 .. GREEK SMALL LETTER SIGMA +.. |sigmaf| unicode:: U+003C2 .. GREEK SMALL LETTER FINAL SIGMA +.. |sim| unicode:: U+0223C .. TILDE OPERATOR +.. |spades| unicode:: U+02660 .. BLACK SPADE SUIT +.. |sub| unicode:: U+02282 .. SUBSET OF +.. |sube| unicode:: U+02286 .. SUBSET OF OR EQUAL TO +.. |sum| unicode:: U+02211 .. N-ARY SUMMATION +.. |sup| unicode:: U+02283 .. SUPERSET OF +.. |supe| unicode:: U+02287 .. SUPERSET OF OR EQUAL TO +.. |Tau| unicode:: U+003A4 .. GREEK CAPITAL LETTER TAU +.. |tau| unicode:: U+003C4 .. GREEK SMALL LETTER TAU +.. |there4| unicode:: U+02234 .. THEREFORE +.. |Theta| unicode:: U+00398 .. GREEK CAPITAL LETTER THETA +.. |theta| unicode:: U+003B8 .. GREEK SMALL LETTER THETA +.. |thetasym| unicode:: U+003D1 .. GREEK THETA SYMBOL +.. |trade| unicode:: U+02122 .. TRADE MARK SIGN +.. |uArr| unicode:: U+021D1 .. UPWARDS DOUBLE ARROW +.. |uarr| unicode:: U+02191 .. UPWARDS ARROW +.. |upsih| unicode:: U+003D2 .. GREEK UPSILON WITH HOOK SYMBOL +.. |Upsilon| unicode:: U+003A5 .. GREEK CAPITAL LETTER UPSILON +.. |upsilon| unicode:: U+003C5 .. GREEK SMALL LETTER UPSILON +.. |weierp| unicode:: U+02118 .. SCRIPT CAPITAL P +.. |Xi| unicode:: U+0039E .. GREEK CAPITAL LETTER XI +.. |xi| unicode:: U+003BE .. GREEK SMALL LETTER XI +.. |Zeta| unicode:: U+00396 .. GREEK CAPITAL LETTER ZETA +.. |zeta| unicode:: U+003B6 .. GREEK SMALL LETTER ZETA diff --git a/setup.py b/setup.py index cb737ef7d..6666de678 100755 --- a/setup.py +++ b/setup.py @@ -4,8 +4,22 @@ import sys import os +import glob from distutils.core import setup from distutils.command.build_py import build_py +from distutils.command.install_data import install_data + + +class smart_install_data(install_data): + + # From <http://wiki.python.org/moin/DistutilsInstallDataScattered>, + # by Pete Shinners. + + def run(self): + #need to change self.install_dir to the library dir + install_cmd = self.get_finalized_command('install') + self.install_dir = getattr(install_cmd, 'install_lib') + return install_data.run(self) def do_setup(): @@ -34,6 +48,7 @@ what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'author_email': 'goodger@users.sourceforge.net', 'license': 'public domain, Python, BSD, GPL (see COPYING.txt)', 'platforms': 'OS-independent', + 'cmdclass': {'install_data': smart_install_data}, 'package_dir': {'docutils': 'docutils', '': 'extras'}, 'packages': ['docutils', 'docutils.languages', 'docutils.parsers', 'docutils.parsers.rst', @@ -42,6 +57,8 @@ what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'docutils.readers', 'docutils.readers.python', 'docutils.transforms', 'docutils.writers',], + 'data_files': [('docutils/parsers/rst/data', + glob.glob('docutils/parsers/rst/data/*.txt'))], 'scripts' : ['tools/rst2html.py','tools/rst2latex.py'],} """Distutils setup parameters.""" diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index 3987e04e0..9199c1402 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -32,7 +32,8 @@ include11 = os.path.join(mydir, 'include 11.txt') include11rel = DocutilsTestSupport.utils.relative_path(None, include11) utf_16_file = os.path.join(mydir, 'utf-16.csv') utf_16_file_rel = DocutilsTestSupport.utils.relative_path(None, utf_16_file) - +nonexistant_rel = DocutilsTestSupport.utils.relative_path( + None, '../docutils/parsers/rst/data/nonexistant') totest = {} @@ -351,6 +352,43 @@ Include file with whitespace in the path: <paragraph> some text """], +["""\ +Standard include data file: + +.. include:: <isogrk4.txt> +""", +"""\ +<document source="test data"> + <paragraph> + Standard include data file: + <comment xml:space="preserve"> + This data file has been placed in the public domain. + <comment xml:space="preserve"> + Derived from the Unicode character mappings available from + <http://www.w3.org/2003/entities/xml/>. + Processed by unicode2rstsubs.py, part of Docutils: + <http://docutils.sourceforge.net>. + <substitution_definition names="b.Gammad"> + \\u03dc + <substitution_definition names="b.gammad"> + \\u03dd +"""], +["""\ +Nonexistant standard include data file: + +.. include:: <nonexistant> +""", +"""\ +<document source="test data"> + <paragraph> + Nonexistant standard include data file: + <system_message level="4" line="3" source="test data" type="SEVERE"> + <paragraph> + Problems with "include" directive path: + IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/data/nonexistant'. + <literal_block xml:space="preserve"> + .. include:: <nonexistant> +"""], ] -- cgit v1.2.1 From 530bfbe824e80b0996edf5961ccf63d93f542afd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 16:44:50 +0000 Subject: correction git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3473 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/substitutions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/rst/substitutions.txt b/docs/ref/rst/substitutions.txt index 3ddb71123..d4ff17a42 100644 --- a/docs/ref/rst/substitutions.txt +++ b/docs/ref/rst/substitutions.txt @@ -80,7 +80,7 @@ Recommentation XML source. __ http://www.w3.org/2003/entities/xml/ ================== ================================================== -Entity Set File Description +Entity Set File Description ================== ================================================== isoamsa.txt Added Mathematical Symbols: Arrows isoamsb.txt Added Mathematical Symbols: Binary Operators -- cgit v1.2.1 From cbc0c71cce99abae907d275148e80e1e8a201881 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 16:59:38 +0000 Subject: corrected path to data files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3474 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 3 ++- test/test_parsers/test_rst/test_directives/test_include.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index af206751f..de50d3c6b 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -21,7 +21,8 @@ except ImportError: urllib2 = None -standard_include_path = os.path.join(os.path.dirname(states.__file__), 'data') +standard_include_path = os.path.join(os.path.dirname(states.__file__), + 'include') def include(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index 9199c1402..805a08e0c 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -33,7 +33,7 @@ include11rel = DocutilsTestSupport.utils.relative_path(None, include11) utf_16_file = os.path.join(mydir, 'utf-16.csv') utf_16_file_rel = DocutilsTestSupport.utils.relative_path(None, utf_16_file) nonexistant_rel = DocutilsTestSupport.utils.relative_path( - None, '../docutils/parsers/rst/data/nonexistant') + None, '../docutils/parsers/rst/include/nonexistant') totest = {} @@ -385,7 +385,7 @@ Nonexistant standard include data file: <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/data/nonexistant'. + IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/include/nonexistant'. <literal_block xml:space="preserve"> .. include:: <nonexistant> """], -- cgit v1.2.1 From ed1b6c92164e41d468f87eae3cb4b0965431db77 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 12 Jun 2005 20:34:06 +0000 Subject: removed unnecessary text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3475 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/include/README.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docutils/parsers/rst/include/README.txt b/docutils/parsers/rst/include/README.txt index af29691be..cd03135f9 100644 --- a/docutils/parsers/rst/include/README.txt +++ b/docutils/parsers/rst/include/README.txt @@ -2,10 +2,6 @@ ``docutils/parsers/rst/include`` Directory ============================================ -The individual data files are stored with the Docutils source code in -the "docutils" package, in the ``docutils/parsers/rst/include`` -directory. - This directory contains standard data files intended for inclusion in reStructuredText documents. To access these files, use the "include" directive with the special syntax for standard "include" data files, -- cgit v1.2.1 From 03b1c8e2a42aa2987828cccef1a99d6c9ebafdec Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 13 Jun 2005 03:22:17 +0000 Subject: removed implemented item git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3476 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 016388305..1b201598a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -33,10 +33,6 @@ Priorities __ ../../BUGS.html -* Include substitution files for character entities, produced by the - tools/unicode2rstsubs.py. As static data, these files could go - inside the docutils package somewhere. - * A Python Source Reader component (Python auto-documentation) will be added. See the document `"Plan for Enthought API Documentation Tool"`__ for details. If you'd like to help, let me know! -- cgit v1.2.1 From d55d631ab124aa07e18845a72b45d413acf3852f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 13 Jun 2005 18:58:56 +0000 Subject: spelling git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3477 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_directives/test_include.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index 805a08e0c..330dfd8c8 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -32,8 +32,8 @@ include11 = os.path.join(mydir, 'include 11.txt') include11rel = DocutilsTestSupport.utils.relative_path(None, include11) utf_16_file = os.path.join(mydir, 'utf-16.csv') utf_16_file_rel = DocutilsTestSupport.utils.relative_path(None, utf_16_file) -nonexistant_rel = DocutilsTestSupport.utils.relative_path( - None, '../docutils/parsers/rst/include/nonexistant') +nonexistent_rel = DocutilsTestSupport.utils.relative_path( + None, '../docutils/parsers/rst/include/nonexistent') totest = {} @@ -374,20 +374,20 @@ Standard include data file: \\u03dd """], ["""\ -Nonexistant standard include data file: +Nonexistent standard include data file: -.. include:: <nonexistant> +.. include:: <nonexistent> """, """\ <document source="test data"> <paragraph> - Nonexistant standard include data file: + Nonexistent standard include data file: <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/include/nonexistant'. + IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/include/nonexistent'. <literal_block xml:space="preserve"> - .. include:: <nonexistant> + .. include:: <nonexistent> """], ] -- cgit v1.2.1 From eea838e5d1dc2071e2c50315d740c6ff495ebdf5 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 22:28:26 +0000 Subject: added link targets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3479 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/index.txt b/docs/index.txt index c8a933ac7..08fbddcf0 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -71,6 +71,8 @@ top level of the Docutils project directory. .. _THANKS.txt: ../THANKS.html +.. _user: + ``user/``: Introductory & Tutorial Material for End-Users ========================================================= @@ -93,6 +95,8 @@ Docutils-general: look at the `text source <user/rst/demo.txt>`__) +.. _ref: + ``ref/``: Reference Material for All Groups =========================================== @@ -128,6 +132,8 @@ Prehistoric: <http://docutils.sourceforge.net/mirror/setext.html>`__ +.. _peps: + ``peps/``: Python Enhancement Proposals ======================================= @@ -156,6 +162,8 @@ __ http://www.python.org/peps/pep-0287.html .. _master repository: http://www.python.org/peps/ +.. _api: + ``api/``: API Reference Material for Client-Developers ====================================================== @@ -167,6 +175,8 @@ __ http://www.python.org/peps/pep-0287.html `PEP 258`_ is an overview of the architecture of Docutils. +.. _howto: + ``howto/``: Instructions for Developers ======================================= @@ -176,6 +186,8 @@ __ http://www.python.org/peps/pep-0287.html <howto/rst-roles.html>`__ +.. _dev: + ``dev/``: Development Notes and Plans for Core-Developers ========================================================= -- cgit v1.2.1 From 3f6ae9297e9fc97dca334d88e3efef68cc1b5a80 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:27:09 +0000 Subject: added proper euro symbol; added temporary figure support git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3484 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 54 +++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 973414291..88b6a8499 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -17,6 +17,14 @@ } +\providecommand{\DSsymbols}{% + % The Euro symbol in Computer Modern looks, um, funny. Let's get a + % proper Euro symbol. + \usepackage{eurosym}% + \renewcommand{\texteuro}{\euro}% +} + + % Taken from % <http://groups.google.de/groups?selm=1i0n5tgtplti420e1omp4pctlv19jpuhbb%404ax.com> % and modified. Used with permission. @@ -897,15 +905,14 @@ % class=border (see \DNimageCborder). \sbox{\Dalignedimagebox}{#2}% \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}% - % Now we do something *really* ugly. \parpic[#1]{% \begin{minipage}[b]{\Dalignedimagewidth}% - % Compensate for previously added space, but not entirely. - \vspace*{2.0pt}% - \vspace*{\Dfloatimagetopmargin}% - \usebox{\Dalignedimagebox}% - \vspace*{1.5pt}% - \vspace*{\Dfloatimagebottommargin}% + % Compensate for previously added space, but not entirely. + \vspace*{2.0pt}% + \vspace*{\Dfloatimagetopmargin}% + \usebox{\Dalignedimagebox}% + \vspace*{1.5pt}% + \vspace*{\Dfloatimagebottommargin}% \end{minipage}% }% \renewcommand{\Dinsidehalign}{false}% @@ -926,9 +933,9 @@ \Dhalign{r}{#5}% }{% \ifthenelse{\equal{#3}{center}}{% - % Text floating around centered figures is brain damage. - % Thus we use a center environment. Note that no extra space - % is added by the writer, so the space added by the center + % Text floating around centered figures is a bad idea. Thus + % we use a center environment. Note that no extra space is + % added by the writer, so the space added by the center % environment is fine. \begin{center}#5\end{center}% }{% @@ -959,12 +966,10 @@ % 1. Image width. % 2. Image path. % Need to make bottom-alignment dependent on align attribute (add - % functional test first). - \begin{minipage}[b]{#1}% - \includegraphics[width=\linewidth,height=\textheight,keepaspectratio]{#2}% - \ifthenelse{\equal{\Dinsidehalign}{true}}{% - }{}% - \end{minipage}% + % functional test first). Need to observe height attribute. + %\begin{minipage}[b]{#1}% + \includegraphics[width=#1,height=\textheight,keepaspectratio]{#2}% + %\end{minipage}% } \providecommand{\Dcurrentimagemaxwidth}{} \providecommand{\Dsimpleimage}[1]{% @@ -992,6 +997,19 @@ \Dwidthimage{#1\Dlinewidthpercent}{#2}% } +% Figures. +\providecommand{\DNfigureAalign}[5]{% + % Hack to make it work Right Now. + %\def\DcurrentNimageAwidth{\DcurrentNfigureAwidth}% + % + %\def\DcurrentNimageAwidth{\linewidth}% + \DNimageAalign{#1}{#2}{#3}{#4}{% + \begin{minipage}[b]{0.4\linewidth}#5\end{minipage}}% + %\let\DcurrentNimageAwidth=\relax% + % + %\let\DcurrentNimageAwidth=\relax% +} +\providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}} \providecommand{\DCborder}[1]{\fbox{#1}} % No padding between image and border. @@ -1048,6 +1066,9 @@ \addtocounter{Dtoclevel}{-1}% } + + + %\usepackage{fixmath} %\usepackage{amsmath} @@ -1059,6 +1080,7 @@ \DSauxiliaryspace \DSparagraphs \DSlinks +\DSsymbols \DSlate \makeatother -- cgit v1.2.1 From 151676b3efb075a4f7524d2e5681e0ccefee8e2b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:30:17 +0000 Subject: added attribute propagation order; that might be over-engineering at the moment, but I think we will need it sooner or later because things work only coincidentally now, relying on alphabetic (= arbitrary) attribute ordering; do not add space around caption git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3485 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index dc89e18d6..49f00e0a5 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -605,12 +605,35 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def node_name(self, node): return node.__class__.__name__.replace('_', '') + # Attribute propagation order. + attribute_order = ['align', 'classes', 'ids'] + + def attribute_cmp(self, a1, a2): + """ + Compare attribute names `a1` and `a2`. Used in + propagate_attributes to determine propagation order. + + See built-in function `cmp` for return value. + """ + if a1 in self.attribute_order and a2 in self.attribute_order: + return cmp(self.attribute_order.index(a1), + self.attribute_order.index(a2)) + if (a1 in self.attribute_order) != (a2 in self.attribute_order): + # Attributes not in self.attribute_order come last. + return a1 in self.attribute_order and -1 or 1 + else: + return cmp(a1, a2) + def propagate_attributes(self, node): # Propagate attributes using \Dattr macros. node_name = self.node_name(node) attlist = [] if isinstance(node, nodes.Element): attlist = node.attlist() + attlist.sort(lambda pair1, pair2: self.attribute_cmp(pair1[0], + pair2[0])) + # `numatts` may be greater than len(attlist) due to list + # attributes. numatts = 0 pass_contents = self.pass_contents(node) for key, value in attlist: @@ -742,7 +765,6 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): isinstance(node, nodes.topic) or #isinstance(node, nodes.rubric) or isinstance(node, nodes.transition) or - isinstance(node, nodes.caption) or isinstance(node, nodes.legend)) and not (self.is_invisible(node) or isinstance(node.parent, nodes.TextElement))) -- cgit v1.2.1 From 9425c5e74a7324d830f0484ccf1d9eedb76c4aa6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:33:44 +0000 Subject: moved links from sandbox/README.txt to links.txt git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3486 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 466f8a8ee..ea9460168 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -2,6 +2,8 @@ Docutils_ Links ================= +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de :Revision: $Revision$ :Date: $Date$ :Copyright: This document has been placed in the public domain. @@ -11,8 +13,76 @@ The most current version of this document can always be found at http://docutils.sourceforge.net/docs/user/links.html. -* rest2web__ is a tool for creating web sites with reStructuredText. - __ http://article.gmane.org/gmane.text.docutils.user/2006 +Related Projects +================ -* to be continued... +These are projects users of Docutils and reStructuredText may find +useful. Many of them projects are hosted in the `Docutils Sandbox`_. +All projects are usable by end users in some way, however do not +expect all of them to run out of the box. + +* rest2web_, by Michael Foord, is a tool for creating web sites with + reStructuredText. + +* ZReST_, by Richard Jones, is a "ReStructuredText Document for Zope" + application that is complete and ready to install. + +* PySource_, by Tony Ibbs, is an experimental Python source Reader. + In some form, it will soon become part of core Docutils. There is + some related code in David Goodger's sandbox (pysource_reader_) and + a `Python Source Reader`_ document. + + .. Is this usable for end users? Maybe move to a "Developers" + section? + +* The Docutils interface to PythonPoint_, also by Richard Jones, + produces PDF presentations using ReportLabs. + +* Engelbert Gruber has begun a `ManPage Writer`_. + +* Sidnei da Silva has taken over `ReportLabs/PDF Writer`_ components. + + .. Can anyone confirm that this works and maybe provide installation + instructions? (Emailed Sidnei about that.) + +* Oliver Rutherfurd has begun a `DocBook Writer`_ component and + `HT2HTML integration`_ component. + +* Gunnar Schwant's DocFactory_ is a wxPython GUI application for + Docutils. + +* Aahz has begun an `OpenOffice.org Writer`_. + + .. Can anyone confirm that this works and maybe provide installation + instructions? (Emailed Aahz about that.) + +* For Wikis, please see the `FAQ entry about Wikis`_. + +* Bill Bumgarner has written a `simple HTML writer`_ that doesn't rely + on CSS (stylesheets). + +* Beni Cherniavsky has written a generic `preprocessing module`_ for + roles and/or directives and built preprocessors for TeX math for + both LaTeX and HTML output on top of it. + +* Beni Cherniavsky maintains a Makefile_ for driving Docutils, hoping + to handle everything one might do with docutils. + +.. _rest2web: http://www.voidspace.org.uk/python/rest2web/ +.. _Docutils Sandbox: http://docutils.sf.net/sandbox/README.html +.. _ZReST: http://docutils.sf.net/sandbox/richard/ZReST/ +.. _PySource: http://docutils.sf.net/sandbox/tibs/pysource/ +.. _pysource_reader: http://docutils.sf.net/sandbox/davidg/pysource_reader/ +.. _Python Source Reader: http://docutils.sf.net/docs/dev/pysource.html +.. _PythonPoint: http://docutils.sf.net/sandbox/richard/pythonpoint/ +.. _Manpage Writer: http://docutils.sf.net/sandbox/grubert/man/ +.. _ReportLabs/PDF Writer: http://docutils.sf.net/sandbox/dreamcatcher/rlpdf/ +.. _DocBook Writer: http://docutils.sf.net/sandbox/oliverr/docbook/ +.. _HT2HTML integration: http://docutils.sf.net/sandbox/oliverr/ht/ +.. _DocFactory: http://docutils.sf.net/sandbox/gschwant/docfactory/doc/ +.. _OpenOffice.org Writer: http://docutils.sf.net/sandbox/aahz/OO/ +.. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax +.. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ +.. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ +.. _Makefile: http://docutils.sf.net/sandbox/cben/make/ -- cgit v1.2.1 From 51dc4c46044bf4bbc46465cbd8536521cb9128ac Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:54:52 +0000 Subject: moved profiledocutils and testcoverage into main tree git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3488 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/testcoverage.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/dev/README.txt | 1 + tools/dev/profile.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100755 test/testcoverage.sh create mode 100644 tools/dev/README.txt create mode 100755 tools/dev/profile.sh diff --git a/test/testcoverage.sh b/test/testcoverage.sh new file mode 100755 index 000000000..e2005448d --- /dev/null +++ b/test/testcoverage.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This script has been placed in the public domain. + +set -e +proj="${PWD##*/}" +if test "$proj" == test; then + cd .. + proj="${PWD##*/}" +fi +if test "$1"; then + proj="$1" +fi +echo Performing code coverage test for project \""$proj"\"... +echo +cd test +rm -rf cover +mkdir -p cover +python -u -m trace --count --coverdir=cover --missing alltests.py +cd .. +echo +echo +echo Uncovered lines +echo =============== +echo +( + find "$proj" -name \*.py | while read i; do + i="${i%.py}" + test -f test/cover/"${i//\//.}".cover -o "${i##*/}" == Template || echo "${i//\//.}" "`cat "$i.py" | wc -l`" + done + cd test/cover + find . \( -name . -o ! -name "$proj".\* -exec rm {} \; \) + for i in *.cover; do + sed 's/^>>>>>> \(.*"""\)/ \1/' < "$i" > "${i%.cover}" + rm "$i" + done + for i in *; do echo -n "$i "; grep -c '^>>>>>> ' "$i" || true; done +) | grep -v ' 0$' | sort -nk 2 diff --git a/tools/dev/README.txt b/tools/dev/README.txt new file mode 100644 index 000000000..ca9e99ee8 --- /dev/null +++ b/tools/dev/README.txt @@ -0,0 +1 @@ +Tools for developers. diff --git a/tools/dev/profile.sh b/tools/dev/profile.sh new file mode 100755 index 000000000..1f79c655e --- /dev/null +++ b/tools/dev/profile.sh @@ -0,0 +1,41 @@ +#!/usr/bin/python -i + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This script has been placed in the public domain. + +import os.path +import docutils.core +import hotshot.stats + +print 'Profiler started.' + +os.chdir(os.path.join(os.path.dirname(docutils.__file__), '..')) + +print 'Profiling...' + +prof = hotshot.Profile('docutils.prof') +prof.runcall(docutils.core.publish_file, source_path='HISTORY.txt', + destination_path='prof.HISTORY.html', writer_name='html') +prof.close() + +print 'Loading statistics...' + +print """ +stats = hotshot.stats.load('docutils.prof') +stats.strip_dirs() +stats.sort_stats('time') # 'cumulative'; 'calls' +stats.print_stats(40) +""" + +stats = hotshot.stats.load('docutils.prof') +stats.strip_dirs() +stats.sort_stats('time') +stats.print_stats(40) + +try: + execfile(os.environ['PYTHONSTARTUP']) +except: + pass -- cgit v1.2.1 From 8f85d3e3390fb81fedfc42b709266a823cdba373 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:56:28 +0000 Subject: renamed testcoverage.sh to coverage.sh git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3489 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/coverage.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ test/testcoverage.sh | 42 ------------------------------------------ 2 files changed, 42 insertions(+), 42 deletions(-) create mode 100755 test/coverage.sh delete mode 100755 test/testcoverage.sh diff --git a/test/coverage.sh b/test/coverage.sh new file mode 100755 index 000000000..e2005448d --- /dev/null +++ b/test/coverage.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This script has been placed in the public domain. + +set -e +proj="${PWD##*/}" +if test "$proj" == test; then + cd .. + proj="${PWD##*/}" +fi +if test "$1"; then + proj="$1" +fi +echo Performing code coverage test for project \""$proj"\"... +echo +cd test +rm -rf cover +mkdir -p cover +python -u -m trace --count --coverdir=cover --missing alltests.py +cd .. +echo +echo +echo Uncovered lines +echo =============== +echo +( + find "$proj" -name \*.py | while read i; do + i="${i%.py}" + test -f test/cover/"${i//\//.}".cover -o "${i##*/}" == Template || echo "${i//\//.}" "`cat "$i.py" | wc -l`" + done + cd test/cover + find . \( -name . -o ! -name "$proj".\* -exec rm {} \; \) + for i in *.cover; do + sed 's/^>>>>>> \(.*"""\)/ \1/' < "$i" > "${i%.cover}" + rm "$i" + done + for i in *; do echo -n "$i "; grep -c '^>>>>>> ' "$i" || true; done +) | grep -v ' 0$' | sort -nk 2 diff --git a/test/testcoverage.sh b/test/testcoverage.sh deleted file mode 100755 index e2005448d..000000000 --- a/test/testcoverage.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This script has been placed in the public domain. - -set -e -proj="${PWD##*/}" -if test "$proj" == test; then - cd .. - proj="${PWD##*/}" -fi -if test "$1"; then - proj="$1" -fi -echo Performing code coverage test for project \""$proj"\"... -echo -cd test -rm -rf cover -mkdir -p cover -python -u -m trace --count --coverdir=cover --missing alltests.py -cd .. -echo -echo -echo Uncovered lines -echo =============== -echo -( - find "$proj" -name \*.py | while read i; do - i="${i%.py}" - test -f test/cover/"${i//\//.}".cover -o "${i##*/}" == Template || echo "${i//\//.}" "`cat "$i.py" | wc -l`" - done - cd test/cover - find . \( -name . -o ! -name "$proj".\* -exec rm {} \; \) - for i in *.cover; do - sed 's/^>>>>>> \(.*"""\)/ \1/' < "$i" > "${i%.cover}" - rm "$i" - done - for i in *; do echo -n "$i "; grep -c '^>>>>>> ' "$i" || true; done -) | grep -v ' 0$' | sort -nk 2 -- cgit v1.2.1 From 5cb3b0ed53caac06299dae0f567cec2aef86717a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 15 Jun 2005 23:59:49 +0000 Subject: fixed name *sigh* git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3490 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/dev/profile.sh | 41 ----------------------------------------- tools/dev/profile_docutils.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 41 deletions(-) delete mode 100755 tools/dev/profile.sh create mode 100755 tools/dev/profile_docutils.py diff --git a/tools/dev/profile.sh b/tools/dev/profile.sh deleted file mode 100755 index 1f79c655e..000000000 --- a/tools/dev/profile.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/python -i - -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This script has been placed in the public domain. - -import os.path -import docutils.core -import hotshot.stats - -print 'Profiler started.' - -os.chdir(os.path.join(os.path.dirname(docutils.__file__), '..')) - -print 'Profiling...' - -prof = hotshot.Profile('docutils.prof') -prof.runcall(docutils.core.publish_file, source_path='HISTORY.txt', - destination_path='prof.HISTORY.html', writer_name='html') -prof.close() - -print 'Loading statistics...' - -print """ -stats = hotshot.stats.load('docutils.prof') -stats.strip_dirs() -stats.sort_stats('time') # 'cumulative'; 'calls' -stats.print_stats(40) -""" - -stats = hotshot.stats.load('docutils.prof') -stats.strip_dirs() -stats.sort_stats('time') -stats.print_stats(40) - -try: - execfile(os.environ['PYTHONSTARTUP']) -except: - pass diff --git a/tools/dev/profile_docutils.py b/tools/dev/profile_docutils.py new file mode 100755 index 000000000..1f79c655e --- /dev/null +++ b/tools/dev/profile_docutils.py @@ -0,0 +1,41 @@ +#!/usr/bin/python -i + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This script has been placed in the public domain. + +import os.path +import docutils.core +import hotshot.stats + +print 'Profiler started.' + +os.chdir(os.path.join(os.path.dirname(docutils.__file__), '..')) + +print 'Profiling...' + +prof = hotshot.Profile('docutils.prof') +prof.runcall(docutils.core.publish_file, source_path='HISTORY.txt', + destination_path='prof.HISTORY.html', writer_name='html') +prof.close() + +print 'Loading statistics...' + +print """ +stats = hotshot.stats.load('docutils.prof') +stats.strip_dirs() +stats.sort_stats('time') # 'cumulative'; 'calls' +stats.print_stats(40) +""" + +stats = hotshot.stats.load('docutils.prof') +stats.strip_dirs() +stats.sort_stats('time') +stats.print_stats(40) + +try: + execfile(os.environ['PYTHONSTARTUP']) +except: + pass -- cgit v1.2.1 From c9bdf0b05fc639f4112d0dfd7538ff63a02c79b5 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 00:27:26 +0000 Subject: fixed bug with escaped colons introducing literal block git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3491 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- test/test_parsers/test_rst/test_literal_blocks.py | 40 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b7a359159..9f12bd560 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -386,7 +386,7 @@ class RSTState(StateWS): Return a list (paragraph & messages) & a boolean: literal_block next? """ data = '\n'.join(lines).rstrip() - if data[-2:] == '::': + if re.search(r'(?<!\\)(\\\\)*::$', data): if len(data) == 2: return [], 1 elif data[-3] in ' \n': diff --git a/test/test_parsers/test_rst/test_literal_blocks.py b/test/test_parsers/test_rst/test_literal_blocks.py index 517edd557..332e0eb27 100755 --- a/test/test_parsers/test_rst/test_literal_blocks.py +++ b/test/test_parsers/test_rst/test_literal_blocks.py @@ -125,6 +125,46 @@ no blank line <paragraph> no blank line """], +[r""" +A paragraph\\:: + + A literal block. + +A paragraph\:: + + Not a literal block. +""", +r"""<document source="test data"> + <paragraph> + A paragraph\: + <literal_block xml:space="preserve"> + A literal block. + <paragraph> + A paragraph:: + <block_quote> + <paragraph> + Not a literal block. +"""], +[r""" +\\:: + + A literal block. + +\:: + + Not a literal block. +""", +r"""<document source="test data"> + <paragraph> + \: + <literal_block xml:space="preserve"> + A literal block. + <paragraph> + :: + <block_quote> + <paragraph> + Not a literal block. +"""], ["""\ A paragraph: :: -- cgit v1.2.1 From 394d49d987b18f5ad502706f603eac2d6ea473e2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 00:31:57 +0000 Subject: added history entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3492 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index da7835b6d..b8c01db2a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -27,18 +27,28 @@ Changes Since 0.3.9 - Added validator to tab_width setting, with test. Closes SF bug #1212515, report from Wu Wei. -* docutils/parsers/rst/include/: Directory added to project; contains - standard data files for the "include" directive. Initial contents: - character entity substitution definition sets. +* docutils/parsers/rst/states.py: + + - Fixed bug with escaped colons indicating a literal block. * docutils/parsers/rst/directives/misc.py: - Added the "default-role" and "title" directives. - Added standard data file syntax to the "include" directive. +* docutils/parsers/rst/include/: Directory added to project; contains + standard data files for the "include" directive. Initial contents: + character entity substitution definition sets. + +* docs/user/links.txt: Added to project; link list. + * docs/ref/rst/substitutions.txt: "reStructuredText Standard Substitution Definition Sets", added to project. +* test/coverage.sh: Added to project; test coverage script. + +* tools/dev/profile_docutils.py: Added to project; profiler script. + Release 0.3.9 (2005-05-26) ========================== -- cgit v1.2.1 From 09e012ec57acc45f8d56ee2f176c03f1ffab1862 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 00:37:34 +0000 Subject: added link target; removed reference to fixed bug; removed other idea -- looks bad git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3493 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 1b201598a..3509a87c5 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -949,7 +949,7 @@ __ rst/alternatives.html#or-not-to-do commonly used for line endings. * Allow a "::"-only paragraph (first line, actually) to introduce a - literal block without a blank line? (Idea from Paul Moore.) :: + _`literal block without a blank line`? (Idea from Paul Moore.) :: :: This is a literal block @@ -958,25 +958,16 @@ __ rst/alternatives.html#or-not-to-do which contains just a ``::`` and the literal text unambiguous? There's one problem with this concession. What if one wants a definition list item which defines the term "::"? We'd have to - escape it. Currenty, ``\::`` doesn't work (although it should; - **bug**), and ``:\:`` is misinterpreted as a field name (name ``\``; - also a **bug**). Assuming these bugs are squashed, I suppose it's a - useful special case. It would only be reasonable to apply it to - "::"-only paragraphs though. I think the blank line is visually + escape it. Currenty, ``:\:`` is misinterpreted as a field name + (name ``\``; **bug**). Assuming this bug is squashed, I suppose + it's a useful special case. It would only be reasonable to apply it + to "::"-only paragraphs though. I think the blank line is visually necessary if there's text before the "::":: The text in this paragraph needs separation from the literal block following:: This doesn't look right. - Another idea. Would it be worthwhile to allow literal blocks to - begin without a newline after the "::"? Example:: - - :: while True: - print 'hello world' - - Perhaps. Perhaps not. - * Add new syntax for _`nested inline markup`? Or extend the parser to parse nested inline markup somehow? See the `collected notes <rst/alternatives.html#nested-inline-markup>`__. -- cgit v1.2.1 From 6e7fbd8d90a9a62a8f5219080e2c4660d0f7732f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 00:58:44 +0000 Subject: applied patch to fix problems when wide characters appear in section title; thanks to "gentoo" user; closing https://sourceforge.net/tracker/?func=detail&atid=422032&aid=1220126&group_id=38414 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3494 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index fe39265b2..3c670a224 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -397,7 +397,12 @@ This is useful for filling list item paragraphs." (current-column))) ;; ending column - (endcol (- (line-end-position) (line-beginning-position))) + (endcol (- (save-excursion + (end-of-line) + (current-column)) + (save-excursion + (back-to-indentation) + (current-column)))) ) ;; if there is no current style found... -- cgit v1.2.1 From bea16992178d8ce87ce5e315d459beb7905cd14e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 01:08:33 +0000 Subject: removed link to PDF writer; Sidnei says it's probably not functional; he hasn't used it for ages git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3495 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index ea9460168..1e463e0a2 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -41,11 +41,6 @@ expect all of them to run out of the box. * Engelbert Gruber has begun a `ManPage Writer`_. -* Sidnei da Silva has taken over `ReportLabs/PDF Writer`_ components. - - .. Can anyone confirm that this works and maybe provide installation - instructions? (Emailed Sidnei about that.) - * Oliver Rutherfurd has begun a `DocBook Writer`_ component and `HT2HTML integration`_ component. -- cgit v1.2.1 From 04f2424447e9de96e74c65e24d68fab32bfa33e3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 22:03:08 +0000 Subject: added support for units in image widths and heights; I called a number combined with a unit (e.g. 5em) a "measure"; I am not entirely sure if that's the right term, though git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3497 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 +++++ docs/ref/docutils.dtd | 7 ++-- docs/ref/rst/directives.txt | 8 +++++ docs/ref/rst/restructuredtext.txt | 40 ++++++++++++++++++++++ docutils/parsers/rst/directives/__init__.py | 26 ++++++++++++++ docutils/parsers/rst/directives/images.py | 4 +-- docutils/writers/html4css1.py | 10 ++++++ .../expected/standalone_rst_html4css1.html | 15 ++++++-- test/functional/expected/standalone_rst_latex.tex | 18 ++++++++++ .../expected/standalone_rst_pseudoxml.txt | 14 ++++++++ test/functional/input/data/standard.txt | 24 +++++++++++++ .../test_rst/test_directives/test_images.py | 36 +++++++++++++++++++ 12 files changed, 203 insertions(+), 7 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index b8c01db2a..5cb822a0f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -36,10 +36,18 @@ Changes Since 0.3.9 - Added the "default-role" and "title" directives. - Added standard data file syntax to the "include" directive. +* docutils/parsers/rst/directives/images.py: + + - Added support for image width and height units. + * docutils/parsers/rst/include/: Directory added to project; contains standard data files for the "include" directive. Initial contents: character entity substitution definition sets. +* docutils/writers/html4css1.py: + + - Added support for image width and height units. + * docs/user/links.txt: Added to project; link list. * docs/ref/rst/substitutions.txt: "reStructuredText Standard diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index f3a7d37ca..fd47b6c91 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -39,6 +39,9 @@ by wrapper DTDs. <!-- Emphasize that the attribute value must be a number. --> <!ENTITY % number "NMTOKEN"> +<!-- A number which may be immediately followed by a unit. --> +<!ENTITY % measure "NMTOKEN"> + <!ENTITY % additional.basic.atts ""> <!-- Attributes shared by all elements in this DTD: @@ -481,8 +484,8 @@ or " ") or the text between option arguments (typically either "," or %align-hv.att; uri CDATA #REQUIRED alt CDATA #IMPLIED - height %number; #IMPLIED - width %number; #IMPLIED + height %measure; #IMPLIED + width %measure; #IMPLIED scale %number; #IMPLIED> <!ELEMENT caption %text.model;> diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index cf5c20361..2235c428f 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -202,11 +202,19 @@ The following options are recognized: specified, they are combined. For example, a height of 200 and a scale of 50 is equivalent to a height of 100 with no scale. + It is also possible to specify a `length value`_. + ``width`` : integer The width of the image in pixels, used to reserve space or scale the image horizontally. As with "height" above, when the "scale" option is also specified, they are combined. + It is also possible to specify a length_ or `percentage value`_. + + .. _length: + .. _length value: restructuredtext.html#length-units + .. _percentage value: restructuredtext.html#percentage-units + ``scale`` : integer The uniform scaling factor of the image, a percentage (but no "%" symbol is required or allowed). "100" means full-size, and is diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 6d21934b4..0823cc8eb 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2781,6 +2781,46 @@ characters (see `Escaping Mechanism`_ above). RFC2396_ and RFC2732_. +Units +===== + +All measures consist of a positive floating point number in standard +(non-scientific) notation and a unit, possibly separated by one or +more spaces. + +Units are only supported where explicitly mentioned in the reference +manuals. + + +Length Units +------------ + +The following length units are supported by the reStructuredText +parser: + +* em (ems, the height of the element's font) +* ex (x-height, the height of the letter "x") +* px (pixels, relative to the canvas resolution) +* in (inches; 1in=2.54cm) +* cm (centimeters; 1cm=10mm) +* mm (millimeters) +* pt (points; 1pt=1/72in) +* pc (picas; 1pc=12pt) + +(List and explanations taken from +http://www.htmlhelp.com/reference/css/units.html#length.) + +The following are all valid length values: "1.5em", "20 mm", ".5in". + + +Percentage Units +---------------- + +Percentage values have a percent sign ("%") as unit. Percentage +values are relative to other values, depending on the context in which +they occur. + + ---------------- Error Handling ---------------- diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index d78a3b9c1..dadd08e65 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -286,6 +286,32 @@ def nonnegative_int(argument): raise ValueError('negative value; must be positive or zero') return value +length_units = ['em', 'ex', 'px', 'in', 'cm', 'mm', 'pt', 'pc'] + +def get_measure(argument, units): + """ + Check for a positive argument of one of the units and return a + normalized string of the form "<value><unit>" (without space in + between). + + To be called from directive option conversion functions. + """ + match = re.match(r'^([0-9.]+) *(%s)$' % '|'.join(units), argument) + try: + assert match is not None + float(match.group(1)) + except (AssertionError, ValueError): + raise ValueError( + 'not a positive measure of one of the following units:\n%s' + % ' '.join(['"%s"' % i for i in units])) + return match.group(1) + match.group(2) + +def length_or_unitless(argument): + return get_measure(argument, length_units + ['']) + +def length_or_percentage_or_unitless(argument): + return get_measure(argument, length_units + ['%', '']) + def class_option(argument): """ Convert the argument into a list of ID-compatible strings and return it. diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 670f969a0..ef77c2bef 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -76,8 +76,8 @@ def image(name, arguments, options, content, lineno, image.arguments = (1, 0, 1) image.options = {'alt': directives.unchanged, - 'height': directives.nonnegative_int, - 'width': directives.nonnegative_int, + 'height': directives.length_or_unitless, + 'width': directives.length_or_percentage_or_unitless, 'scale': directives.nonnegative_int, 'align': align, 'target': directives.unchanged_required, diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e2f36721f..1dae18b5c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -890,6 +890,16 @@ class HTMLTranslator(nodes.NodeVisitor): if atts.has_key('height'): atts['height'] = int(round(node['height'] * (float(node['scale']) / 100))) + style = [] + for att_name in 'width', 'height': + if atts.has_key(att_name): + if re.match(r'^[0-9.]+$', atts[att_name]): + # Interpret unitless values as pixels. + atts[att_name] += 'px' + style.append('%s: %s;' % (att_name, atts[att_name])) + del atts[att_name] + if style: + atts['style'] = ' '.join(style) atts['alt'] = node.get('alt', atts['src']) if node.has_key('align'): atts['align'] = self.attval(node['align']) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index ba5d7784d..e624dacb0 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -550,7 +550,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <span id="image-target-2"></span><span id="image-target-1"></span><img alt="../../../docs/user/rst/images/title.png" id="image-target-3" name="image-target-3" src="../../../docs/user/rst/images/title.png" /> <p>A figure directive:</p> <div align="right" class="figclass1 figclass2 figure"> -<img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" width="50" /> +<img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" style="width: 50px;" /> <p class="caption">A figure is an image with a caption and/or a legend:</p> <div class="legend"> <table border="1" class="docutils"> @@ -576,7 +576,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph might flow around the figure...</p> <p>A centered figure:</p> <div align="center" class="figure"> -<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="width: 50px;" /> <p class="caption">This is the caption.</p> <div class="legend"> <p>This is the legend.</p> @@ -586,7 +586,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph might flow around the figure...</p> <p>A left-aligned figure:</p> <div align="left" class="figure"> -<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" width="50" /> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="width: 50px;" /> <p class="caption">This is the caption.</p> <div class="legend"> <p>This is the legend.</p> @@ -594,6 +594,15 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o </div> </div> <p>This paragraph might flow around the figure...</p> +<p>Now widths:</p> +<p>An image 2 em wide:</p> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="width: 2em;" /> +<p>An image 2 em wide and 30 pixel high:</p> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="width: 2em; height: 30px;" /> +<p>An image occupying 70% of the line width:</p> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="width: 70%;" /> +<p>An image 3 cm high:</p> +<img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="height: 3cm;" /> </div> <div class="section" id="admonitions"> <h3><a class="toc-backref" href="#id64" name="admonitions">2.14.3   Admonitions</a></h3> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 3abaf8a9e..06e00ab67 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -925,6 +925,24 @@ The legend may consist of several paragraphs. This paragraph might flow around the figure... +Now widths: + +An image 2 em wide: + +\includegraphics{../../../docs/user/rst/images/biohazard.png} + +An image 2 em wide and 30 pixel high: + +\includegraphics{../../../docs/user/rst/images/biohazard.png} + +An image occupying 70{\%} of the line width: + +\includegraphics{../../../docs/user/rst/images/biohazard.png} + +An image 3 cm high: + +\includegraphics{../../../docs/user/rst/images/biohazard.png} + %___________________________________________________________________________ diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 62f923a03..d7f4d0103 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1191,6 +1191,20 @@ The legend may consist of several paragraphs. <paragraph> This paragraph might flow around the figure... + <paragraph> + Now widths: + <paragraph> + An image 2 em wide: + <image uri="../../../docs/user/rst/images/biohazard.png" width="2em"> + <paragraph> + An image 2 em wide and 30 pixel high: + <image height="30px" uri="../../../docs/user/rst/images/biohazard.png" width="2em"> + <paragraph> + An image occupying 70% of the line width: + <image uri="../../../docs/user/rst/images/biohazard.png" width="70%"> + <paragraph> + An image 3 cm high: + <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> <title auto="1" refid="id64"> <generated classes="sectnum"> diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index cfcc6e7f7..140be35c7 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -485,6 +485,30 @@ A left-aligned figure: This paragraph might flow around the figure... +Now widths: + +An image 2 em wide: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :width: 2 em + +An image 2 em wide and 30 pixel high: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :width: 2em + :height: 30 px + +An image occupying 70% of the line width: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :width: 70% + +An image 3 cm high: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :height: 3 cm + + Admonitions ``````````` diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index 3e0c89344..4e4c429f6 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -97,6 +97,42 @@ totest['images'] = [ <image height="100" scale="50" uri="a/very/long/path/to/picture.png" width="200"> """], ["""\ +.. image:: picture.png + :width: 200px + :height: 100 em +""", +"""\ +<document source="test data"> + <image height="100em" uri="picture.png" width="200px"> +"""], +["""\ +.. image:: picture.png + :width: 50% + :height: 10mm +""", +"""\ +<document source="test data"> + <image height="10mm" uri="picture.png" width="50%"> +"""], +["""\ +.. image:: picture.png + :width: 50% + :height: 40% +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Error in "image" directive: + invalid option value: (option: "height"; value: \'40%\') + not a positive measure of one of the following units: + "em" "ex" "px" "in" "cm" "mm" "pt" "pc" "". + <literal_block xml:space="preserve"> + .. image:: picture.png + :width: 50% + :height: 40% +"""], +["""\ .. image:: picture.png :height: 100 :width: 200 -- cgit v1.2.1 From 5b01b700102eafc5edc5284f17b9055dc7d24e20 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 22:04:32 +0000 Subject: removed to do list entries: image.border: bad idea; units of measure: implemented git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3498 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 3509a87c5..481a99142 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1106,13 +1106,6 @@ when used in a document. .. _unicode: http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes - - _`images.image`: "border"? No, bad idea; use CSS instead. - - _`Units of measure`? (See `docutils-users, 2003-03-02 - <http://article.gmane.org/gmane.text.docutils.user/154>`__, and - `docutils-develop, 2004-04-29 - <http://article.gmane.org/gmane.text.docutils.devel/1439>`_.) - - _`images.figure`: "title" and "number", to indicate a formal figure? -- cgit v1.2.1 From 1ff93dd94d3e3b0d398f88a6cfa3ece4558ef8ad Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 22:07:31 +0000 Subject: documented what image widths as percentage are relative to git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3499 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 2235c428f..73614b043 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -209,7 +209,8 @@ The following options are recognized: the image horizontally. As with "height" above, when the "scale" option is also specified, they are combined. - It is also possible to specify a length_ or `percentage value`_. + It is also possible to specify a length_ or `percentage value`_ + (which is relative to the current line width). .. _length: .. _length value: restructuredtext.html#length-units -- cgit v1.2.1 From 31021ff8ab8370d847c7f408bd89e5edff925959 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 23:07:19 +0000 Subject: made unicode_latex.py look nicer and changed license to Public Domain git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3500 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/unicode_latex.py | 2376 ++++++++++++++++++++++++++++++++++++- 1 file changed, 2360 insertions(+), 16 deletions(-) diff --git a/docutils/writers/unicode_latex.py b/docutils/writers/unicode_latex.py index b311574d2..22830abbf 100644 --- a/docutils/writers/unicode_latex.py +++ b/docutils/writers/unicode_latex.py @@ -1,25 +1,2369 @@ +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de # Revision: $Revision$ # Date: $Date$ +# Copyright: This file has been placed in the public domain. # # This is a mapping of Unicode characters to LaTeX # equivalents. The information has been extracted from # <http://www.w3.org/2003/entities/xml/unicode.xml>. # The extraction has been done by the "create_unimap.py" # script written by Felix Wiemann. -# -# This file may be used and distributed under the terms -# set forth in the original copyright notice of -# unicode.xml. -# -# Original copyright notice of unicode.xml follows: -# -# -# $Id: unicode.xml,v 1.5 2003/12/08 15:02:15 davidc Exp $ -# -# Copyright David Carlisle, Sebastian Rahtz 1998-2003 -# -# Use and distribution of this file are permitted under the terms of the <a -# href="http://www.w3.org/Consortium/Legal/copyright-software-19980720" -# >W3C Software Notice and License</a>. -unicode_map = {u'\u0302': '{\\^}', u'\u2785': '{\\ding{197}}', u'\u2a87': '$\\lneq$', u'\U0001d68f': '$\\mathtt{f}$', u'\U0001d50e': '$\\mathfrak{K}$', u'\u2297': '$\\otimes$', u'\u0116': '{\\.{E}}', u'\u0418': '{\\cyrchar\\CYRI}', u'\u271a': '{\\ding{58}}', u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', u'\U0001d624': '$\\mathsfsl{c}$', u'\xab': '{\\guillemotleft}', u'\u03ad': '$\\acute{\\epsilon}$', u'\u222c': '$\\int\\!\\int$', u'\U0001d5b9': '$\\mathsf{Z}$', u'\U0001d438': '$\\mathsl{E}$', u'\U0001d73a': '$\\mathbit{\\Epsilon}$', u'\u21c1': '$\\rightharpoondown$', u'\u04c3': '{\\cyrchar\\CYRKHK}', u'\u2644': '{\\saturn}', u'\u2788': '{\\ding{200}}', u'\U0001d6cf': '$\\mathbf{\\Xi}$', u'\U0001d54e': '$\\mathbb{W}$', u'\u22d7': '$\\gtrdot$', u'\u2156': '$\\textfrac{2}{5}$', u'\u0458': '{\\cyrchar\\cyrje}', u'\u275a': '{\\ding{122}}', u'\U0001d4e3': '$\\mathmit{T}$', u'\U0001d7e5': '$\\mathsf{3}$', u'\U0001d664': '$\\mathsfbfsl{o}$', u'\xeb': '{\\"{e}}', u'\u026c': '$\\Elzbtdl$', u'\U0001d5f9': '$\\mathsfbf{l}$', u'\U0001d478': '$\\mathbit{Q}$', u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', u'\u0101': '{\\={a}}', u'\u0403': "{\\cyrchar{\\'\\CYRG}}", u'\u2a07': '$\\ElzInf$', u'\u2986': '$\\Elroang$', u'\u300b': '$\\ElsevierGlyph{300B}$', u'\u2116': '{\\cyrchar\\textnumero}', u'\U0001d60f': '$\\mathsfsl{H}$', u'\U0001d58e': '$\\mathslbb{i}$', u'\u2217': '${_\\ast}$', u'\u2196': '$\\nwarrow$', u'\u2519': '$\\Elzsqfnw$', u'\u0498': '{\\cyrchar\\CYRZDSC}', u'\u279a': '{\\ding{218}}', u'\U0001d423': '$\\mathbf{j}$', u'\U0001d725': '$\\mathbit{\\Kappa}$', u'\u22ac': '$\\nvdash$', u'\U0001d539': '$\\mathbb{B}$', u'\U0001d4b8': '$\\mathscr{c}$', u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', u'\u0141': '{\\L}', u'\xc0': '{\\`{A}}', u'\u0443': '{\\cyrchar\\cyru}', u'\u03c2': '$\\varsigma$', u'\u2745': '{\\ding{101}}', u'\U0001d64f': '$\\mathsfbfsl{T}$', u'\U0001d5ce': '$\\mathsf{u}$', u'\u0322': '{\\Elzrh}', u'\u2257': '$\\circeq$', u'\u04d8': '{\\cyrchar\\CYRSCHWA}', u'\u2254': '{:=}', u'\U0001d463': '$\\mathsl{v}$', u'\u027a': '$\\Elztrnrl$', u'\U0001d765': '$\\mathsfbf{\\Pi}$', u'\U0001d6e4': '$\\mathsl{\\Gamma}$', u'\u02d0': '$\\Elzlmrk$', u'\u22ec': '$\\ntrianglelefteq$', u'\u266f': '$\\sharp$', u'\U0001d579': '$\\mathslbb{N}$', u'\U0001d4f8': '$\\mathmit{o}$', u'\U0001d7fa': '$\\mathtt{4}$', u'\u0100': '{\\={A}}', u'\u2202': '$\\partial$', u'\u2704': '{\\ding{36}}', u'\U0001d78f': '{\\mathsfbf{\\varpi}}', u'\U0001d40e': '$\\mathbf{O}$', u'\u0397': '$\\Eta$', u'\u2016': '$\\Vert$', u'\u0499': '{\\cyrchar\\cyrzdsc}', u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', u'\u025b': '$\\varepsilon$', u'\U0001d5a3': '$\\mathsf{D}$', u'\U0001d724': '$\\mathbit{\\Iota}$', u'\u015d': '{\\^{s}}', u'\u21ab': '$\\looparrowleft$', u'\u22ad': '$\\nvDash$', u'\u27af': '{\\ding{239}}', u'\u042e': '{\\cyrchar\\CYRYU}', u'\U0001d4b9': '$\\mathscr{d}$', u'\U0001d538': '$\\mathbb{A}$', u'\U0001d63a': '$\\mathsfsl{y}$', u'\xc1': "{\\'{A}}", u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', u'\u25c3': '$\\triangleleft$', u'\u2242': '$\\ElsevierGlyph{2242}$', u'\u2744': '{\\ding{100}}', u'\u0136': '{\\c{K}}', u'\U0001d7cf': '$\\mathbf{1}$', u'\U0001d44e': '$\\mathsl{a}$', u'\u030f': '{\\cyrchar\\C}', u'\u04d9': '{\\cyrchar\\cyrschwa}', u'\U0001d5e3': '$\\mathsfbf{P}$', u'\U0001d6e5': '$\\mathsl{\\Delta}$', u'\U0001d764': '$O$', u'\u22ed': '$\\ntrianglerighteq$', u'\u046e': '{\\cyrchar\\CYRKSI}', u'\u2970': '$\\RoundImplies$', u'\U0001d4f9': '$\\mathmit{p}$', u'\U0001d578': '$\\mathslbb{M}$', u'\U0001d67a': '$\\mathtt{K}$', u'\u2282': '$\\subset$', u'\u2605': '{\\ding{72}}', u'\u2784': '{\\ding{196}}', u'\U0001d70f': '$\\mathsl{\\Tau}$', u'\U0001d48e': '$\\mathbit{m}$', u'\u0419': '{\\cyrchar\\CYRISHRT}', u'\U0001d523': '$\\mathfrak{f}$', u'\U0001d625': '$\\mathsfsl{d}$', u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', u'\u012b': '{\\={\\i}}', u'\u222d': '$\\int\\!\\int\\!\\int$', u'\u03ac': "{\\'{$\\alpha$}}", u'\u272f': '{\\ding{79}}', u'\u04ae': '{\\cyrchar\\CYRY}', u'\U0001d439': '$\\mathsl{F}$', u'\U0001d5b8': '$\\mathsf{Y}$', u'\U0001d6ba': '$\\mathbf{\\Sigma}$', u'\u21c0': '$\\rightharpoonup$', u'\u22c2': '$\\bigcap$', u'\u2645': '{\\uranus}', u'\U0001d74f': '$\\partial$', u'\U0001d4ce': '$\\mathscr{y}$', u'\xd6': '{\\"{O}}', u'\u0459': '{\\cyrchar\\cyrlje}', u'\u25d8': '$\\Elzrvbull$', u'\u295b': '$\\RightTeeVector$', u'\u227b': '$\\succ$', u'\U0001d563': '$\\mathbb{r}$', u'\U0001d665': '$\\mathsfbfsl{p}$', u'\U0001d7e4': '$\\mathsf{2}$', u'\u016b': '{\\={u}}', u'\u026d': '$\\Elzrtll$', u'\U0001d479': '$\\mathbit{R}$', u'\U0001d5f8': '$\\mathsfbf{k}$', u'\U0001d6fa': '$\\mathsl{\\Omega}$', u'\u2200': '$\\forall$', u'\u2102': '$\\mathbb{C}$', u'\u0404': '{\\cyrchar\\CYRIE}', u'\u0156': '{\\c{R}}', u'\U0001d48f': '$\\mathbit{n}$', u'\U0001d70e': '$\\mathsl{\\Sigma}$', u'\u2316': '$\\mathchar"2208$', u'\u2799': '{\\ding{217}}', u'\U0001d6a3': '$\\mathtt{z}$', u'\U0001d5a5': '$\\mathsf{F}$', u'\U0001d424': '$\\mathbf{k}$', u'\u22ab': '$\\VDash$', u'\u21ad': '$\\leftrightsquigarrow$', u'\u04af': '{\\cyrchar\\cyry}', u'\u272e': '{\\ding{78}}', u'\u02e9': '{\\tone{11}}', u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', u'\U0001d638': '$\\mathsfsl{w}$', u'\u03c1': '$\\rho$', u'\u2240': '$\\wr$', u'\u0142': '{\\l}', u'\u0444': '{\\cyrchar\\cyrf}', u'\U0001d4cf': '$\\mathscr{z}$', u'\U0001d74e': '$\\mathbit{\\Omega}$', u'\xd7': '{\\texttimes}', u'\U0001d6e3': '$\\mathsl{\\Beta}$', u'\U0001d5e5': '$\\mathsfbf{R}$', u'\U0001d464': '$\\mathsl{w}$', u'\u22eb': '$\\ntriangleright$', u'\U0001d7f9': '$\\mathtt{3}$', u'\U0001d678': '$\\mathtt{I}$', u'\U0001d57a': '$\\mathslbb{O}$', u'\u02c8': '$\\Elzverts$', u'\u0301': "{\\'}", u'\u2280': '$\\not\\prec$', u'\U0001d40f': '$\\mathbf{P}$', u'\u226c': '$\\between$', u'\u0396': '$\\Zeta$', u'\u2719': '{\\ding{57}}', u'\u03c4': '$\\tau$', u'\U0001d623': '$\\mathsfsl{b}$', u'\U0001d525': '$\\mathfrak{h}$', u'\u222b': '$\\int$', u'\u212d': '$\\mathfrak{C}$', u'\xac': '$\\lnot$', u'\u042f': '{\\cyrchar\\CYRYA}', u'\u27ae': '{\\ding{238}}', u'\u2ab0': '$\\succeq$', u'\U0001d739': '$\\mathbit{\\Delta}$', u'\U0001d6b8': '$\\mathbf{\\Rho}$', u'\U0001d5ba': '$\\mathsf{a}$', u'\u22c0': '$\\ElsevierGlyph{22C0}$', u'\u2643': '{\\jupiter}', u'\u21c2': '$\\downharpoonright$', u'\u04c4': '{\\cyrchar\\cyrkhk}', u'\U0001d44f': '$\\mathsl{b}$', u'\U0001d7ce': '$\\mathbf{0}$', u'\u2057': "$''''$", u'\u03d6': '$\\varpi$', u'\u2759': '{\\ding{121}}', u'\u295d': '$\\RightDownTeeVector$', u'\U0001d663': '$\\mathsfbfsl{n}$', u'\U0001d565': '$\\mathbb{t}$', u'\U0001d4e4': '$\\mathmit{U}$', u'\u226b': '$\\gg$', u'\u016d': '{\\u{u}}', u'\xec': '{\\`{\\i}}', u'\u046f': '{\\cyrchar\\cyrksi}', u'\U0001d779': '$\\mathsfbf{\\Kappa}$', u'\U0001d6f8': '$\\mathsl{\\Chi}$', u'\U0001d5fa': '$\\mathsfbf{m}$', u'\u2281': '$\\not\\succ$', u'\u0300': '{\\`}', u'\u2783': '{\\ding{195}}', u'\u2002': '{\\hspace{0.6em}}', u'\u2a06': '$\\Elxsqcup$', u'\U0001d58f': '$\\mathslbb{j}$', u'\U0001d60e': '$\\mathsfsl{G}$', u'\u2197': '$\\nearrow$', u'\u2216': '$\\setminus$', u'\u2718': '{\\ding{56}}', u'\u041a': '{\\cyrchar\\CYRK}', u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', u'\u02da': '{\\r{}}', u'\U0001d4a5': '$\\mathscr{J}$', u'\U0001d524': '$\\mathfrak{g}$', u'\u03ab': '$\\mathrm{\\ddot{Y}}$', u'\xad': '$\\-$', u'\u212c': '$\\mathscr{B}$', u'\u25af': '$\\Elzvrecto$', u'\U0001d6b9': '{\\mathbf{\\vartheta}}', u'\U0001d738': '$\\mathbit{\\Gamma}$', u'\U0001d43a': '$\\mathsl{G}$', u'\u22c1': '$\\ElsevierGlyph{22C1}$', u'\u0461': '{\\cyrchar\\cyromega}', u'\U0001d5cf': '$\\mathsf{v}$', u'\U0001d64e': '$\\mathsfbfsl{S}$', u'\u2256': '$\\eqcirc$', u'\u2265': '$\\geq$', u'\u045a': '{\\cyrchar\\cyrnje}', u'\u295c': '$\\RightUpTeeVector$', u'\U0001d7e3': '$\\mathsf{1}$', u'\U0001d4e5': '$\\mathmit{V}$', u'\U0001d564': '$\\mathbb{s}$', u'\xed': "{\\'{\\i}}", u'\u016c': '{\\u{U}}', u'\u25ef': '$\\bigcirc$', u'\u266e': '$\\natural$', u'\U0001d6f9': '$\\mathsl{\\Psi}$', u'\U0001d778': '$\\mathsfbf{\\Iota}$', u'\U0001d47a': '$\\mathbit{S}$', u'\u2201': '$\\complement$', u'\u2703': '{\\ding{35}}', u'\u0405': '{\\cyrchar\\CYRDZE}', u'\u2a86': '$\\gtrapprox$', u'\U0001d50f': '$\\mathfrak{L}$', u'\U0001d68e': '$\\mathtt{e}$', u'\u0117': '{\\.{e}}', u'\u0296': '$\\Elzinglst$', u'\u2798': '{\\ding{216}}', u'\u049a': '{\\cyrchar\\CYRKDSC}', u'\u299c': '$\\Angle$', u'\U0001d723': '$\\mathbit{\\Theta}$', u'\U0001d425': '$\\mathbf{l}$', u'\U0001d5a4': '$\\mathsf{E}$', u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', u'\u21ac': '$\\looparrowright$', u'\U0001d639': '$\\mathsfsl{x}$', u'\U0001d7b8': '$O$', u'\u2241': '$\\not\\sim$', u'\u03c0': '$\\pi$', u'\u2743': '{\\ding{99}}', u'\xc2': '{\\^{A}}', u'\u0445': '{\\cyrchar\\cyrh}', u'\u2947': '$\\Elzrarrx$', u'\u2ac6': '$\\supseteqq$', u'\u2423': '{\\textvisiblespace}', u'\U0001d54f': '$\\mathbb{X}$', u'\U0001d6ce': '$N$', u'\u2157': '$\\textfrac{3}{5}$', u'\u22d6': '$\\lessdot$', u'\u29dc': '$\\ElsevierGlyph{E372}$', u'\u22d1': '$\\Supset$', u'\U0001d763': '$\\mathsfbf{\\Xi}$', u'\U0001d465': '$\\mathsl{x}$', u'\U0001d5e4': '$\\mathsfbf{Q}$', u'\U0001d679': '$\\mathtt{J}$', u'\U0001d7f8': '$\\mathtt{2}$', u'\U0001d4fa': '$\\mathmit{q}$', u'\u2702': '{\\ding{34}}', u'\u2204': '$\\nexists$', u'\U0001d48b': '$\\mathbit{j}$', u'\U0001d78d': '{\\mathsfbf{\\phi}}', u'\U0001d60c': '$\\mathsfsl{E}$', u'\u2199': '$\\swarrow$', u'\u2018': '{`}', u'\U0001d5a1': '$\\mathsf{B}$', u'\U0001d420': '$\\mathbf{g}$', u'\U0001d722': '$\\mathbit{\\Eta}$', u'\u04ab': '{\\cyrchar\\cyrsdsc}', u'\u27ad': '{\\ding{237}}', u'\u22af': '$\\nVDash$', u'\u015c': '{\\^{S}}', u'\u2a34': '$\\ElsevierGlyph{E25E}$', u'\U0001d6b7': '$\\mathbf{\\Pi}$', u'\U0001d536': '$\\mathfrak{y}$', u'\u0440': '{\\cyrchar\\cyrr}', u'\xc3': '{\\~{A}}', u'\u2742': '{\\ding{98}}', u'\u03c5': '$\\upsilon$', u'\u2244': '$\\not\\simeq$', u'\U0001d4cb': '$\\mathscr{v}$', u'\U0001d64c': '$\\mathsfbfsl{Q}$', u'\u0462': '{\\cyrchar\\CYRYAT}', u'\u295e': '$\\DownLeftTeeVector$', u'\U0001d5e1': '$\\mathsfbf{N}$', u'\U0001d460': '$\\mathsl{s}$', u'\U0001d762': '$N$', u'\u22ef': '$\\cdots$', u'\u016e': '{\\r{U}}', u'\U0001d6f7': '$\\mathsl{\\Phi}$', u'\U0001d576': '$\\mathslbb{K}$', u'\u0480': '{\\cyrchar\\CYRKOPPA}', u'\u2003': '{\\hspace{1em}}', u'\u2782': '{\\ding{194}}', u'\u2305': '{\\barwedge}', u'\u2284': '$\\not\\subset$', u'\U0001d40b': '$\\mathbf{L}$', u'\U0001d70d': '$\\mathsl{\\varsigma}$', u'\U0001d68c': '$\\mathtt{c}$', u'\u2119': '$\\mathbb{P}$', u'\u039a': '$\\Kappa$', u'\U0001d521': '$\\mathfrak{d}$', u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', u'\u042b': '{\\cyrchar\\CYRERY}', u'\u272d': '{\\ding{77}}', u'\u222f': '$\\surfintegral$', u'\u21ae': '$\\nleftrightarrow$', u'\U0001d637': '$\\mathsfsl{v}$', u'\U0001d5b6': '$\\mathsf{W}$', u'\u04c0': '{\\cyrchar\\CYRpalochka}', u'\u22c4': '$\\diamond$', u'\U0001d44b': '$\\mathsl{X}$', u'\U0001d74d': '$\\mathbit{\\Psi}$', u'\U0001d6cc': '$\\mathbf{\\Lambda}$', u'\u22cc': '$\\rightthreetimes$', u'\u2159': '$\\textfrac{1}{6}$', u'\xd8': '{\\O}', u'\u03da': '$\\Stigma$', u'\u2a5f': '$\\Elzminhat$', u'\U0001d561': '$\\mathbb{p}$', u'\U0001d4e0': '$\\mathmit{Q}$', u'\U0001d7e2': '$\\mathsf{0}$', u'\u226f': '$\\not>$', u'\U0001d677': '$\\mathtt{H}$', u'\U0001d5f6': '$\\mathsfbf{i}$', u'\u0481': '{\\cyrchar\\cyrkoppa}', u'\u2285': '$\\not\\supset$', u'\u0304': '{\\=}', u'\U0001d58b': '$\\mathslbb{f}$', u'\U0001d68d': '$\\mathtt{d}$', u'\U0001d70c': '$\\mathsl{\\Rho}$', u'\u0416': '{\\cyrchar\\CYRZH}', u'\u2118': '$\\wp$', u'\u221a': '$\\surd$', u'\U0001d520': '$\\mathfrak{c}$', u'\U0001d622': '$\\mathsfsl{a}$', u'\u272c': '{\\ding{76}}', u'\u03af': '$\\acute{\\iota}$', u'\u2ab5': '$\\precneqq$', u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', u'\U0001d436': '$\\mathsl{C}$', u'\u21c3': '$\\downharpoonleft$', u'\u2642': '{\\male}', u'\u22c5': '$\\cdot$', u'\U0001d5cb': '$\\mathsf{r}$', u'\U0001d6cd': '$M$', u'\U0001d74c': '$\\mathbit{\\Chi}$', u'\u0456': '{\\cyrchar\\cyrii}', u'\xd9': '{\\`{U}}', u'\u2158': '$\\textfrac{4}{5}$', u'\u225a': '$\\ElsevierGlyph{225A}$', u'\U0001d4e1': '$\\mathmit{R}$', u'\U0001d560': '$\\mathbb{o}$', u'\U0001d662': '$\\mathsfbfsl{m}$', u'\U0001d7f7': '$\\mathtt{1}$', u'\U0001d476': '$\\mathbit{O}$', u'\u0401': '{\\cyrchar\\CYRYO}', u'\u0103': '{\\u{a}}', u'\u2205': '$\\varnothing$', u'\u2a8a': '$\\gnapprox$', u'\U0001d60d': '$\\mathsfsl{F}$', u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', u'\u2717': '{\\ding{55}}', u'\u0496': '{\\cyrchar\\CYRZHDSC}', u'\u2019': "{'}", u'\u2198': '$\\searrow$', u'\u229a': '$\\circledcirc$', u'\U0001d421': '$\\mathbf{h}$', u'\U0001d5a0': '$\\mathsf{A}$', u'\U0001d6a2': '$\\mathtt{y}$', u'\u27ac': '{\\ding{236}}', u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', u'\xae': '{\\textregistered}', u'\u2933': '$\\ElsevierGlyph{E21C}$', u'\u2a35': '$\\ElsevierGlyph{E25E}$', u'\U0001d737': '$\\mathbit{\\Beta}$', u'\U0001d4b6': '$\\mathscr{a}$', u'\u0441': '{\\cyrchar\\cyrs}', u'\u0143': "{\\'{N}}", u'\u2245': '$\\cong$', u'\u2277': '$\\gtrless$', u'\U0001d54b': '$\\mathbb{T}$', u'\U0001d64d': '$\\mathsfbfsl{R}$', u'\u22da': '$\\lesseqgtr$', u'\U0001d461': '$\\mathsl{t}$', u'\U0001d5e0': '$\\mathsfbf{M}$', u'\U0001d6e2': '$\\mathsl{\\Alpha}$', u'\u2127': '$\\mho$', u'\u266d': '$\\flat$', u'\xee': '{\\^{\\i}}', u'\u2a75': '$\\Equal$', u'\U0001d777': '$\\mathsfbf{\\Theta}$', u'\U0001d4f6': '$\\mathmit{m}$', u'\u2781': '{\\ding{193}}', u'\u2283': '$\\supset$', u'\u2004': '{\\hspace{0.33em}}', u'\u2a08': '$\\ElzSup$', u'\U0001d68b': '$\\mathtt{b}$', u'\U0001d58d': '$\\mathslbb{h}$', u'\U0001d40c': '$\\mathbf{M}$', u'\u01f5': "{\\'{g}}", u'\u0497': '{\\cyrchar\\cyrzhdsc}', u'\u2716': '{\\ding{54}}', u'\u0399': '$\\Iota$', u'\u2218': '$\\circ$', u'\u211a': '$\\mathbb{Q}$', u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', u'\U0001d620': '$\\mathsfsl{Y}$', u'\U0001d522': '$\\mathfrak{e}$', u'\u23b0': '$\\lmoustache$', u'\u25ad': '$\\fbox{~~}$', u'\u042c': '{\\cyrchar\\CYRSFTSN}', u'\xaf': '{\\textasciimacron}', u'\u29b5': '$\\ElsevierGlyph{E260}$', u'\U0001d4b7': '$\\mathscr{b}$', u'\U0001d736': '$\\mathbit{\\Alpha}$', u'\u2640': '{\\venus}', u'\u22c3': '$\\bigcup$', u'\u21c5': '$\\dblarrowupdown$', u'\U0001d6cb': '$\\mathbf{\\Kappa}$', u'\U0001d5cd': '$\\mathsf{t}$', u'\U0001d44c': '$\\mathsl{Y}$', u'\u2756': '{\\ding{118}}', u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', u'\u215a': '$\\textfrac{5}{6}$', u'\U0001d7e1': '$\\mathbb{9}$', u'\U0001d660': '$\\mathsfbfsl{k}$', u'\U0001d562': '$\\mathbb{q}$', u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', u'\xef': '{\\"{\\i}}', u'\U0001d4f7': '$\\mathmit{n}$', u'\U0001d776': '$\\mathsfbf{\\Eta}$', u'\u2701': '{\\ding{33}}', u'\u2203': '$\\exists$', u'\u0105': '{\\k{a}}', u'\u2a88': '$\\gneq$', u'\U0001d60b': '$\\mathsfsl{D}$', u'\U0001d50d': '$\\mathfrak{J}$', u'\U0001d48c': '$\\mathbit{k}$', u'\u0417': '{\\cyrchar\\CYRZ}', u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', u'\u2298': '$\\oslash$', u'\u219a': '$\\nleftarrow$', u'\U0001d721': '$\\mathbit{\\Zeta}$', u'\U0001d6a0': '$\\mathtt{w}$', u'\U0001d5a2': '$\\mathsf{C}$', u'\u04ac': '{\\cyrchar\\CYRTDSC}', u'\u03ae': '$\\acute{\\eta}$', u'\U0001d437': '$\\mathsl{D}$', u'\U0001d7b6': '$N$', u'\u2741': '{\\ding{97}}', u'\u2243': '$\\simeq$', u'\u25c2': '$\\blacktriangleleft$', u'\u0145': '{\\c{N}}', u'\xc4': '{\\"{A}}', u'\U0001d64b': '$\\mathsfbfsl{P}$', u'\u29ca': '$\\ElzLap$', u'\U0001d54d': '$\\mathbb{V}$', u'\U0001d4cc': '$\\mathscr{w}$', u'\u0457': '{\\cyrchar\\cyryi}', u'\u0278': '{\\textphi}', u'\u22d8': '$\\verymuchless$', u'\u21da': '$\\Lleftarrow$', u'\U0001d761': '$M$', u'\U0001d6e0': '{\\mathbf{\\varrho}}', u'\U0001d5e2': '$\\mathsfbf{O}$', u'\U0001d477': '$\\mathbit{P}$', u'\U0001d7f6': '$\\mathtt{0}$', u'\u0402': '{\\cyrchar\\CYRDJE}', u'\u0104': '{\\k{A}}', u'\u2a89': '$\\lnapprox$', u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', u'\U0001d48d': '$\\mathbit{l}$', u'\u2299': '$\\odot$', u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', u'\u201a': '{,}', u'\U0001d6a1': '$\\mathtt{x}$', u'\U0001d720': '$\\mathbit{\\Epsilon}$', u'\U0001d422': '$\\mathbf{i}$', u'\u0306': '{\\u}', u'\u27ab': '{\\ding{235}}', u'\u04ad': '{\\cyrchar\\cyrtdsc}', u'\u222e': '$\\oint$', u'\U0001d5b7': '$\\mathsf{X}$', u'\U0001d636': '$\\mathsfsl{u}$', u'\U0001d6de': '{\\mathbf{\\varkappa}}', u'\u2740': '{\\ding{96}}', u'\u03c3': '$\\sigma$', u'\u0442': '{\\cyrchar\\cyrt}', u'\xc5': '{\\AA}', u'\u0144': "{\\'{n}}", u'\U0001d4cd': '$\\mathscr{x}$', u'\U0001d54c': '$\\mathbb{U}$', u'\u25d7': '{\\ding{119}}', u'\u22d9': '$\\verymuchgreater$', u'\u2a5e': '$\\perspcorrespond$', u'\U0001d6e1': '{\\mathbf{\\varpi}}', u'\U0001d760': '$\\mathsfbf{\\Lambda}$', u'\U0001d462': '$\\mathsl{u}$', u'\u2122': '{\\texttrademark}', u'\u02e6': '{\\tone{44}}', u'\u226e': '$\\not<$', u'\U0001d5f7': '$\\mathsfbf{j}$', u'\U0001d676': '$\\mathtt{G}$', u'\u2780': '{\\ding{192}}', u'\u0303': '{\\~}', u'\u0482': '{\\cyrchar\\cyrthousands}', u'\u2005': '{\\hspace{0.25em}}', u'\U0001d70b': '$\\mathsl{\\Pi}$', u'\U0001d40d': '$\\mathbf{N}$', u'\U0001d58c': '$\\mathslbb{g}$', u'\u2219': '$\\bullet$', u'\u0398': '$\\Theta$', u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', u'\U0001d621': '$\\mathsfsl{Z}$', u'\u2271': '$\\not\\geq$', u'\U0001d4a2': '$\\mathscr{G}$', u'\u272b': '{\\ding{75}}', u'\u042d': '{\\cyrchar\\CYREREV}', u'\u212f': '$\\mathscr{e}$', u'\u22ae': '$\\nVdash$', u'\U0001d537': '$\\mathfrak{z}$', u'\U0001d6b6': '$O$', u'\u21c4': '$\\rightleftarrows$', u'\U0001d74b': '$\\mathbit{\\Phi}$', u'\U0001d44d': '$\\mathsl{Z}$', u'\U0001d5cc': '$\\mathsf{s}$', u'\u0259': '$\\Elzschwa$', u'\xda': "{\\'{U}}", u'\u295f': '$\\DownRightTeeVector$', u'\U0001d661': '$\\mathsfbfsl{l}$', u'\U0001d7e0': '$\\mathbb{8}$', u'\U0001d4e2': '$\\mathmit{S}$', u'\u046d': '{\\cyrchar\\cyriotbyus}', u'\u016f': '{\\r{u}}', u'\u22ee': '$\\vdots$', u'\u29f4': '$\\RuleDelayed$', u'\U0001d577': '$\\mathslbb{L}$', u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', u'\u0287': '$\\Elztrnt$', u'\u0106': "{\\'{C}}", u'\u0408': '{\\cyrchar\\CYRJE}', u'\U0001d493': '$\\mathbit{r}$', u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', u'\U0001d614': '$\\mathsfsl{M}$', u'\u039d': '$N$', u'\U0001d5a9': '$\\mathsf{J}$', u'\U0001d428': '$\\mathbf{o}$', u'\U0001d72a': '$O$', u'\u21b1': '$\\Rsh$', u'\u2030': '{\\textperthousand}', u'\u04b3': '{\\cyrchar\\cyrhdsc}', u'\u27b5': '{\\ding{245}}', u'\U0001d6bf': '$\\mathbf{\\Psi}$', u'\U0001d53e': '$\\mathbb{G}$', u'\u030a': '{\\r}', u'\u22c7': '$\\divideontimes$', u'\u0146': '{\\c{n}}', u'\u0448': '{\\cyrchar\\cyrsh}', u'\u274a': '{\\ding{106}}', u'\U0001d4d3': '$\\mathmit{D}$', u'\U0001d7d5': '$\\mathbf{7}$', u'\U0001d654': '$\\mathsfbfsl{Y}$', u'\u2956': '$\\DownLeftVectorBar$', u'\u20db': '$\\dddot$', u'\u03dd': '$\\digamma$', u'\u225c': '$\\triangleq$', u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', u'\U0001d5e9': '$\\mathsfbf{V}$', u'\U0001d468': '$\\mathbit{A}$', u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', u'\u27f5': '$\\longleftarrow$', u'\U0001d6ff': '$\\mathsl{\\Delta}$', u'\U0001d57e': '$\\mathslbb{S}$', u'\u2207': '$\\nabla$', u'\u0488': '{\\cyrchar\\cyrhundredthousands}', u'\u278a': '{\\ding{202}}', u'\U0001d413': '$\\mathbf{T}$', u'\U0001d715': '$\\partial$', u'\U0001d694': '$\\mathtt{k}$', u'\u201b': '$\\Elzreapos$', u'\u231d': '$\\urcorner$', u'\u0158': '{\\v{R}}', u'\U0001d529': '$\\mathfrak{l}$', u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', u'\u2131': '$\\mathscr{F}$', u'\xb0': '{\\textdegree}', u'\u0433': '{\\cyrchar\\cyrg}', u'\u03b2': '$\\beta$', u'\u2735': '{\\ding{85}}', u'\u011e': '{\\u{G}}', u'\U0001d63f': '$\\mathsfbfsl{D}$', u'\U0001d5be': '$\\mathsf{e}$', u'\u2941': '$\\Elorarr$', u'\u2247': '$\\not\\cong$', u'\u21c6': '$\\leftrightarrows$', u'\u24c8': '$\\circledS$', u'\U0001d453': '$\\mathsl{f}$', u'\U0001d755': '{\\mathbit{\\varpi}}', u'\U0001d6d4': '$\\mathbf{\\Sigma}$', u'\u02dc': '{\\texttildelow}', u'\U0001d569': '$\\mathbb{x}$', u'\U0001d4e8': '$\\mathmit{Y}$', u'\U0001d7ea': '$\\mathsf{8}$', u'\u0171': '{\\H{u}}', u'\xf0': '{\\dh}', u'\U0001d67f': '$\\mathtt{P}$', u'\U0001d5fe': '$\\mathsfbf{q}$', u'\u232a': '$\\rangle$', u'\u2006': '{\\hspace{0.166em}}', u'\u0489': '{\\cyrchar\\cyrmillions}', u'\U0001d593': '$\\mathslbb{n}$', u'\u0282': '$\\Elzrtls$', u'\U0001d695': '$\\mathtt{l}$', u'\U0001d714': '$\\mathsl{\\Omega}$', u'\u02d8': '{\\textasciibreve}', u'\u219b': '$\\nrightarrow$', u'\u229d': '$\\circleddash$', u'\u231c': '$\\ulcorner$', u'\u279f': '{\\ding{223}}', u'\u041e': '{\\cyrchar\\CYRO}', u'\U0001d4a9': '$\\mathscr{N}$', u'\U0001d528': '$\\mathfrak{k}$', u'\U0001d62a': '$\\mathsfsl{i}$', u'\xb1': '$\\pm$', u'\u2130': '$\\mathscr{E}$', u'\u25b3': '$\\bigtriangleup$', u'\u2232': '$\\ElsevierGlyph{2232}$', u'\u2734': '{\\ding{84}}', u'\u010b': '{\\.{c}}', u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', u'\U0001d43e': '$\\mathsl{K}$', u'\u2940': '$\\Elolarr$', u'\u03c7': '$\\chi$', u'\u264a': '{\\gemini}', u'\U0001d5d3': '$\\mathsf{z}$', u'\U0001d6d5': '$\\mathbf{\\Tau}$', u'\U0001d754': '{\\mathbit{\\varrho}}', u'\u21db': '$\\Rrightarrow$', u'\u02dd': '{\\H{}}', u'\u045e': '{\\cyrchar\\cyrushrt}', u'\U0001d4e9': '$\\mathmit{Z}$', u'\U0001d568': '$\\mathbb{w}$', u'\u29eb': '$\\blacklozenge$', u'\U0001d66a': '$\\mathsfbfsl{u}$', u'\U0001d63c': '$\\mathsfbfsl{A}$', u'\xf1': '{\\~{n}}', u'\u0170': '{\\H{U}}', u'\u2272': '$\\lessequivlnt$', u'\U0001d7ff': '$\\mathtt{9}$', u'\U0001d47e': '$\\mathbit{W}$', u'\u2980': '$\\Elztfnc$', u'\u0307': '{\\.}', u'\u0409': '{\\cyrchar\\CYRLJE}', u'\U0001d513': '$\\mathfrak{P}$', u'\U0001d615': '$\\mathsfsl{N}$', u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', u'\u211b': '$\\mathscr{R}$', u'\u221d': '$\\propto$', u'\u039c': '$M$', u'\u271f': '{\\ding{63}}', u'\u049e': '{\\cyrchar\\CYRKHCRS}', u'\U0001d429': '$\\mathbf{p}$', u'\U0001d5a8': '$\\mathsf{I}$', u'\U0001d6aa': '$\\mathbf{\\Gamma}$', u'\u2a2d': '$\\ElsevierGlyph{E25C}$', u'\u2031': '{\\textpertenthousand}', u'\u21b0': '$\\Lsh$', u'\u22b2': '$\\vartriangleleft$', u'\u27b4': '{\\ding{244}}', u'\U0001d73f': '$\\mathbit{\\Kappa}$', u'\U0001d4be': '$\\mathscr{i}$', u'\xc6': '{\\AE}', u'\u0449': '{\\cyrchar\\cyrshch}', u'\U0001d553': '$\\mathbb{b}$', u'\U0001d655': '$\\mathsfbfsl{Z}$', u'\U0001d7d4': '$\\mathbf{6}$', u'\u215b': '$\\textfrac{1}{8}$', u'\u03dc': '$\\Digamma$', u'\u27a4': '{\\ding{228}}', u'\U0001d469': '$\\mathbit{B}$', u'\U0001d5e8': '$\\mathsfbf{U}$', u'\U0001d6ea': '$\\mathsl{\\Iota}$', u'\u212b': '{\\AA}', u'\U0001d77f': '$\\mathsfbf{\\Pi}$', u'\U0001d4fe': '$\\mathmit{u}$', u'\u2306': '$\\perspcorrespond$', u'\u2789': '{\\ding{201}}', u'\U0001d693': '$\\mathtt{j}$', u'\U0001d595': '$\\mathslbb{p}$', u'\U0001d414': '$\\mathbf{U}$', u'\u229b': '$\\circledast$', u'\u219d': '$\\arrowwaveright$', u'\u201c': '{\\textquotedblleft}', u'\u049f': '{\\cyrchar\\cyrkhcrs}', u'\u271e': '{\\ding{62}}', u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', u'\U0001d628': '$\\mathsfsl{g}$', u'\U0001d52a': '$\\mathfrak{m}$', u'\u03b1': '$\\alpha$', u'\u2230': '$\\volintegral$', u'\u0132': '{IJ}', u'\u25b5': '$\\vartriangle$', u'\u0434': '{\\cyrchar\\cyrd}', u'\u015e': '{\\c{S}}', u'\U0001d4bf': '$\\mathscr{j}$', u'\U0001d73e': '$\\mathbit{\\Iota}$', u'\u2942': '$\\ElzRlarr$', u'\xc7': '{\\c{C}}', u'\u2648': '{\\aries}', u'\U0001d6d3': '$\\mathbf{\\varsigma}$', u'\U0001d5d5': '$\\mathsfbf{B}$', u'\U0001d454': '$\\mathsl{g}$', u'\u22db': '$\\gtreqless$', u'\u21dd': '$\\rightsquigarrow$', u'\u275e': '{\\ding{126}}', u'\U0001d7e9': '$\\mathsf{7}$', u'\U0001d668': '$\\mathsfbfsl{s}$', u'\u2aeb': '$\\ElsevierGlyph{E30D}$', u'\U0001d56a': '$\\mathbb{y}$', u'\u03f1': '$\\varrho$', u'\u0270': '$\\Elztrnmlr$', u'\u0172': '{\\k{U}}', u'\u0474': '{\\cyrchar\\CYRIZH}', u'\U0001d4ff': '$\\mathmit{v}$', u'\U0001d77e': '$O$', u'\u2007': '{\\hphantom{0}}', u'\u0386': "{\\'{A}}", u'\u2709': '{\\ding{41}}', u'\U0001d613': '$\\mathsfsl{L}$', u'\U0001d494': '$\\mathbit{s}$', u'\u211d': '$\\mathbb{R}$', u'\u041f': '{\\cyrchar\\CYRP}', u'\u279e': '{\\ding{222}}', u'\U0001d729': '$\\mathbit{\\Xi}$', u'\U0001d6a8': '$\\mathbf{\\Alpha}$', u'\U0001d5aa': '$\\mathsf{K}$', u'\u04b4': '{\\cyrchar\\CYRTETSE}', u'\U0001d43f': '$\\mathsl{L}$', u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', u'\u03c6': '$\\varphi$', u'\u2749': '{\\ding{105}}', u'\u25ca': '$\\lozenge$', u'\u03a3': '$\\Sigma$', u'\U0001d653': '$\\mathsfbfsl{X}$', u'\U0001d555': '$\\mathbb{d}$', u'\U0001d4d4': '$\\mathmit{E}$', u'\u225b': '$\\starequal$', u'\u215d': '$\\textfrac{5}{8}$', u'\u20dc': '$\\ddddot$', u'\u045f': '{\\cyrchar\\cyrdzhe}', u'\u0124': '{\\^{H}}', u'\U0001d769': '$\\mathsfbf{\\Tau}$', u'\U0001d6e8': '$\\mathsl{\\Eta}$', u'\U0001d5ea': '$\\mathsfbf{W}$', u'\u22f0': '$\\upslopeellipsis$', u'\U0001d47f': '$\\mathbit{X}$', u'\U0001d7fe': '$\\mathtt{8}$', u'\u2708': '{\\ding{40}}', u'\u040a': '{\\cyrchar\\CYRNJE}', u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', u'\U0001d495': '$\\mathbit{t}$', u'\U0001d514': '$\\mathfrak{Q}$', u'\u2a16': '$\\sqrint$', u'\u039b': '$\\Lambda$', u'\u211c': '$\\mathfrak{R}$', u'\u261e': '{\\ding{43}}', u'\U0001d6a9': '$\\mathbf{\\Beta}$', u'\U0001d728': '$N$', u'\U0001d42a': '$\\mathbf{q}$', u'\u27b3': '{\\ding{243}}', u'\u2032': "${'}$", u'\u04b5': '{\\cyrchar\\cyrtetse}', u'\U0001d5bf': '$\\mathsf{f}$', u'\U0001d63e': '$\\mathsfbfsl{C}$', u'\u21c7': '$\\leftleftarrows$', u'\u2246': '$\\approxnotequal$', u'\u2748': '{\\ding{104}}', u'\u044a': '{\\cyrchar\\cyrhrdsn}', u'\U0001d7d3': '$\\mathbf{5}$', u'\U0001d4d5': '$\\mathmit{F}$', u'\U0001d554': '$\\mathbb{c}$', u'\u2a56': '$\\ElOr$', u'\xdd': "{\\'{Y}}", u'\u215c': '$\\textfrac{3}{8}$', u'\U0001d6e9': '$\\mathsl{\\Theta}$', u'\U0001d768': '$\\mathsfbf{\\Sigma}$', u'\U0001d46a': '$\\mathbit{C}$', u'\u22f1': '$\\downslopeellipsis$', u'\U0001d5ff': '$\\mathsfbf{r}$', u'\U0001d67e': '$\\mathtt{O}$', u'\u0107': "{\\'{c}}", u'\u2286': '$\\subseteq$', u'\u226d': '$\\not\\kern-0.3em\\times$', u'\U0001d713': '$\\mathsl{\\Psi}$', u'\U0001d415': '$\\mathbf{V}$', u'\U0001d594': '$\\mathslbb{o}$', u'\u2a96': '$\\eqslantgtr$', u'\u201d': '{\\textquotedblright}', u'\u219c': '$\\arrowwaveright$', u'\U0001d7ee': '$\\mathsfbf{2}$', u'\U0001d629': '$\\mathsfsl{h}$', u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', u'\U0001d4aa': '$\\mathscr{O}$', u'\u2231': '$\\clwintegral$', u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', u'\u2733': '{\\ding{83}}', u'\xb2': '${^2}$', u'\u0435': '{\\cyrchar\\cyre}', u'\u25b4': '$\\blacktriangle$', u'\u019e': '{\\textnrleg}', u'\u011d': '{\\^{g}}', u'\U0001d6be': '$\\mathbf{\\Chi}$', u'\u010a': '{\\.{C}}', u'\u0147': '{\\v{N}}', u'\u22c6': '$\\star$', u'\u2649': '{\\taurus}', u'\U0001d753': '{\\mathbit{\\phi}}', u'\U0001d5d4': '$\\mathsfbf{A}$', u'\u2957': '$\\DownRightVectorBar$', u'\u02db': '{\\k{}}', u'\U0001d669': '$\\mathsfbfsl{t}$', u'\U0001d7e8': '$\\mathsf{6}$', u'\U0001d4ea': '$\\mathmit{a}$', u'\u0271': '$\\Elzltlmr$', u'\u03f0': '$\\varkappa$', u'\xf2': '{\\`{o}}', u'\U0001d57f': '$\\mathslbb{T}$', u'\U0001d6fe': '$\\mathsl{\\Gamma}$', u'\u2a04': '$\\Elxuplus$', u'\u2506': '$\\Elzdshfnc$', u'\u2008': '{\\hphantom{,}}', u'\u230a': '$\\lfloor$', u'\U0001d591': '$\\mathslbb{l}$', u'\U0001d410': '$\\mathbf{Q}$', u'\U0001d712': '$\\mathsl{\\Chi}$', u'\u2999': '$\\Elzddfnc$', u'\u049b': '{\\cyrchar\\cyrkdsc}', u'\u279d': '{\\ding{221}}', u'\u229f': '$\\boxminus$', u'\u211e': '$\\Elzxrat$', u'\U0001d526': '$\\mathfrak{i}$', u'\u2aaf': '$\\preceq$', u'\u25b1': '$\\ElsevierGlyph{E381}$', u'\u0430': '{\\cyrchar\\cyra}', u'\xb3': '${^3}$', u'\u2732': '{\\ding{82}}', u'\u03b5': '$\\epsilon$', u'\u2234': '$\\therefore$', u'\U0001d4bb': '$\\mathscr{f}$', u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', u'\u228b': '$\\supsetneq$', u'\xdc': '{\\"{U}}', u'\u21c9': '$\\rightrightarrows$', u'\U0001d5d1': '$\\mathsf{x}$', u'\U0001d450': '$\\mathsl{c}$', u'\U0001d752': '{\\mathbit{\\varkappa}}', u'\u22df': '$\\curlyeqsucc$', u'\u215e': '$\\textfrac{7}{8}$', u'\u0294': '$\\Elzglst$', u'\U0001d6e7': '$\\mathsl{\\Zeta}$', u'\U0001d566': '$\\mathbb{u}$', u'\u296e': '$\\UpEquilibrium$', u'\u0470': '{\\cyrchar\\CYRPSI}', u'\xf3': "{\\'{o}}", u'\u2274': '$\\ElsevierGlyph{2274}$', u'\U0001d4fb': '$\\mathmit{r}$', u'\U0001d7fd': '$\\mathtt{7}$', u'\U0001d67c': '$\\mathtt{M}$', u'\u0109': '{\\^{c}}', u'\u038a': "{\\'{}{I}}", u'\U0001d511': '$\\mathfrak{N}$', u'\U0001d490': '$\\mathbit{o}$', u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', u'\u041b': '{\\cyrchar\\CYRL}', u'\u271d': '{\\ding{61}}', u'\u0134': '{\\^{J}}', u'\u221f': '$\\rightangle$', u'\u219e': '$\\twoheadleftarrow$', u'\U0001d627': '$\\mathsfsl{f}$', u'\U0001d5a6': '$\\mathsf{G}$', u'\u2a2f': '$\\ElzTimes$', u'\u04b0': '{\\cyrchar\\CYRYHCRS}', u'\u2033': "${''}$", u'\u27b2': '{\\ding{242}}', u'\u0335': '{\\Elzxl}', u'\u22b4': '$\\trianglelefteq$', u'\U0001d43b': '$\\mathsl{H}$', u'\U0001d73d': '$\\mathbit{\\Theta}$', u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', u'\u2647': '{\\pluto}', u'\u25c6': '{\\ding{117}}', u'\u0149': "{'n}", u'\xc8': '{\\`{E}}', u'\u03ca': '$\\ddot{\\iota}$', u'\U0001d4d0': '$\\mathmit{A}$', u'\U0001d7d2': '$\\mathbf{4}$', u'\u2959': '$\\LeftDownVectorBar$', u'\u045b': '{\\cyrchar\\cyrtshe}', u'\u275d': '{\\ding{125}}', u'\u225f': '$\\ElsevierGlyph{225F}$', u'\U0001d667': '$\\mathsfbfsl{r}$', u'\U0001d5e6': '$\\mathsfbf{S}$', u'\u2571': '$\\diagup$', u'\U0001d47b': '$\\mathbit{T}$', u'\U0001d77d': '$\\mathsfbf{\\Xi}$', u'\U0001d6fc': '$\\mathsl{\\Alpha}$', u'\u22d4': '$\\pitchfork$', u'\u2a85': '$\\lessapprox$', u'\u2787': '{\\ding{199}}', u'\u0406': '{\\cyrchar\\CYRII}', u'\u0108': '{\\^{C}}', u'\U0001d491': '$\\mathbit{p}$', u'\U0001d510': '$\\mathfrak{M}$', u'\U0001d612': '$\\mathsfsl{K}$', u'\u271c': '{\\ding{60}}', u'\u039f': '$O$', u'\u201e': '{,,}', u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', u'\U0001d426': '$\\mathbf{m}$', u'\u04b1': '{\\cyrchar\\cyryhcrs}', u'\u21b3': '$\\ElsevierGlyph{21B3}$', u'\u22b5': '$\\trianglerighteq$', u'\U0001d5bb': '$\\mathsf{b}$', u'\U0001d6bd': '$\\mathbf{\\Phi}$', u'\U0001d73c': '$\\mathbit{\\Eta}$', u'\u2ac5': '$\\subseteqq$', u'\u0446': '{\\cyrchar\\cyrc}', u'\xc9': "{\\'{E}}", u'\u0148': '{\\v{n}}', u'\u224a': '$\\approxeq$', u'\U0001d4d1': '$\\mathmit{B}$', u'\U0001d550': '$\\mathbb{Y}$', u'\U0001d652': '$\\mathsfbfsl{W}$', u'\u010f': '{\\v{d}}', u'\u2958': '$\\LeftUpVectorBar$', u'\u028e': '$\\Elztrny$', u'\u275c': '{\\ding{124}}', u'\U0001d7e7': '$\\mathsf{5}$', u'\U0001d466': '$\\mathsl{y}$', u'\u0283': '$\\Elzesh$', u'\U0001d5fb': '$\\mathsfbf{n}$', u'\U0001d6fd': '$\\mathsl{\\Beta}$', u'\U0001d77c': '$N$', u'\u2a05': '$\\ElzThr$', u'\u2707': '{\\ding{39}}', u'\u2009': '{\\hspace{0.167em}}', u'\u028a': '$\\Elzpupsil$', u'\U0001d411': '$\\mathbf{R}$', u'\U0001d590': '$\\mathslbb{k}$', u'\U0001d692': '$\\mathtt{i}$', u'\u279c': '{\\ding{220}}', u'\u231f': '$\\lrcorner$', u'\U0001d727': '$M$', u'\U0001d4a6': '$\\mathscr{K}$', u'\u0431': '{\\cyrchar\\cyrb}', u'\u2133': '$\\mathscr{M}$', u'\u2235': '$\\because$', u'\u03b4': '$\\delta$', u'\U0001d53b': '$\\mathbb{D}$', u'\U0001d63d': '$\\mathsfbfsl{B}$', u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', u'\u2747': '{\\ding{103}}', u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', u'\u21c8': '$\\upuparrows$', u'\u22ca': '$\\rtimes$', u'\U0001d451': '$\\mathsl{d}$', u'\U0001d5d0': '$\\mathsf{w}$', u'\U0001d6d2': '$\\mathbf{\\Rho}$', u'\xde': '{\\TH}', u'\U0001d767': '{\\mathsfbf{\\vartheta}}', u'\U0001d4e6': '$\\mathmit{W}$', u'\u0471': '{\\cyrchar\\cyrpsi}', u'\u0173': '{\\k{u}}', u'\u2275': '$\\ElsevierGlyph{2275}$', u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', u'\U0001d57b': '$\\mathslbb{P}$', u'\U0001d67d': '$\\mathtt{N}$', u'\U0001d7fc': '$\\mathtt{6}$', u'\u2985': '$\\ElsevierGlyph{3018}$', u'\u2706': '{\\ding{38}}', u'\u0389': "{\\'{H}}", u'\u2208': '$\\in$', u'\u210a': '{\\mathscr{g}}', u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', u'\U0001d610': '$\\mathsfsl{I}$', u'\U0001d512': '$\\mathfrak{O}$', u'\u012f': '{\\k{i}}', u'\u041c': '{\\cyrchar\\CYRM}', u'\u231e': '$\\llcorner$', u'\U0001d726': '$\\mathbit{\\Lambda}$', u'\u27b1': '{\\ding{241}}', u'\u22b3': '$\\vartriangleright$', u'\u2034': "${'''}$", u'\U0001d6bb': '$\\mathbf{\\Tau}$', u'\U0001d5bd': '$\\mathsf{d}$', u'\U0001d43c': '$\\mathsl{I}$', u'\u04c7': '{\\cyrchar\\CYRNHK}', u'\u2746': '{\\ding{102}}', u'\u03c9': '$\\omega$', u'\u2248': '$\\approx$', u'\u014a': '{\\NG}', u'\U0001d7d1': '$\\mathbf{3}$', u'\U0001d650': '$\\mathsfbfsl{U}$', u'\U0001d552': '$\\mathbb{a}$', u'\u295a': '$\\LeftTeeVector$', u'\u045c': "{\\cyrchar{\\'\\cyrk}}", u'\xdf': '{\\ss}', u'\u0464': '{\\cyrchar\\CYRIOTE}', u'\u011a': '{\\v{E}}', u'\u0491': '{\\cyrchar\\cyrgup}', u'\U0001d4e7': '$\\mathmit{X}$', u'\U0001d766': '$\\mathsfbf{\\Rho}$', u'\u21f5': '$\\DownArrowUpArrow$', u'\u2295': '$\\oplus$', u'\U0001d6fb': '$\\mathsl{\\nabla}$', u'\U0001d5fd': '$\\mathsfbf{p}$', u'\U0001d47c': '$\\mathbit{U}$', u'\u2905': '$\\ElsevierGlyph{E212}$', u'\u0407': '{\\cyrchar\\CYRYI}', u'\u2786': '{\\ding{198}}', u'\u2309': '$\\rceil$', u'\u0288': '$\\Elzrtlt$', u'\U0001d711': '$\\mathsl{\\Phi}$', u'\U0001d690': '$\\mathtt{g}$', u'\U0001d592': '$\\mathslbb{m}$', u'\u261b': '{\\ding{42}}', u'\u049c': '{\\cyrchar\\CYRKVCRS}', u'\u039e': '$\\Xi$', u'\U0001d427': '$\\mathbf{n}$', u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', u'\u2731': '{\\ding{81}}', u'\u2233': '$\\ElsevierGlyph{2233}$', u'\u25b2': '{\\ding{115}}', u'\u2135': '$\\aleph$', u'\xb4': '{\\textasciiacute}', u'\U0001d63b': '$\\mathsfsl{z}$', u'\U0001d53d': '$\\mathbb{F}$', u'\u0447': '{\\cyrchar\\cyrch}', u'\u22c8': '$\\bowtie$', u'\u21ca': '$\\downdownarrows$', u'\U0001d751': '{\\mathbit{\\vartheta}}', u'\U0001d6d0': '$O$', u'\U0001d5d2': '$\\mathsf{y}$', u'\u205f': '{\\mkern4mu}', u'\u03de': '$\\Koppa$', u'\U0001d467': '$\\mathsl{z}$', u'\U0001d7e6': '$\\mathsf{4}$', u'\u2273': '$\\greaterequivlnt$', u'\u0175': '{\\^{w}}', u'\xf4': '{\\^{o}}', u'\u0128': '{\\~{I}}', u'\U0001d67b': '$\\mathtt{L}$', u'\U0001d57d': '$\\mathslbb{R}$', u'\U0001d4fc': '$\\mathmit{s}$', u'\u2606': '{\\ding{73}}', u'\u2289': '$\\not\\supseteq$', u'\u2308': '$\\lceil$', u'\u200a': '$\\mkern1mu$', u'\U0001d691': '$\\mathtt{h}$', u'\u2259': '$\\estimates$', u'\U0001d412': '$\\mathbf{S}$', u'\u279b': '{\\ding{219}}', u'\u049d': '{\\cyrchar\\cyrkvcrs}', u'\u221e': '$\\infty$', u'\U0001d5a7': '$\\mathsf{H}$', u'\U0001d626': '$\\mathsfsl{e}$', u'\u2a2e': '$\\ElsevierGlyph{E25D}$', u'\u2730': '{\\ding{80}}', u'\u03b3': '$\\gamma$', u'\u0432': '{\\cyrchar\\cyrv}', u'\xb5': '$\\mathrm{\\mu}$', u'\u2134': '$\\mathscr{o}$', u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', u'\U0001d4bd': '$\\mathscr{h}$', u'\U0001d53c': '$\\mathbb{E}$', u'\u2944': '$\\ElzrLarr$', u'\u2646': '{\\neptune}', u'\u22c9': '$\\ltimes$', u'\u010d': '{\\v{c}}', u'\U0001d6d1': '$\\mathbf{\\Pi}$', u'\U0001d750': '$\\in$', u'\U0001d452': '$\\mathsl{e}$', u'\U0001d78e': '{\\mathsfbf{\\varrho}}', u'\U0001d5e7': '$\\mathsfbf{T}$', u'\U0001d666': '$\\mathsfbfsl{q}$', u'\u2a6e': '$\\stackrel{*}{=}$', u'\u0472': '{\\cyrchar\\CYRFITA}', u'\xf5': '{\\~{o}}', u'\u0174': '{\\^{W}}', u'\U0001d7fb': '$\\mathtt{5}$', u'\U0001d4fd': '$\\mathmit{t}$', u'\U0001d57c': '$\\mathslbb{Q}$', u'\u2209': '$\\not\\in$', u'\u0388': "{\\'{E}}", u'\U0001d611': '$\\mathsfsl{J}$', u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', u'\U0001d492': '$\\mathbit{q}$', u'\u271b': '{\\ding{59}}', u'\u041d': '{\\cyrchar\\CYRN}', u'\u011f': '{\\u{g}}', u'\u229e': '$\\boxplus$', u'\U0001d527': '$\\mathfrak{j}$', u'\u04b2': '{\\cyrchar\\CYRHDSC}', u'\u2035': '$\\backprime$', u'\U0001d73b': '$\\mathbit{\\Zeta}$', u'\U0001d43d': '$\\mathsl{J}$', u'\U0001d5bc': '$\\mathsf{c}$', u'\u2249': '$\\not\\approx$', u'\u03c8': '$\\psi$', u'\xca': '{\\^{E}}', u'\U0001d651': '$\\mathsfbfsl{V}$', u'\u0279': '$\\Elztrnr$', u'\U0001d4d2': '$\\mathmit{C}$', u'\u275b': '{\\ding{123}}', u'\u015f': '{\\c{s}}', u'\u22de': '$\\curlyeqprec$', u'\U0001d567': '$\\mathbb{v}$', u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', u'\u296f': '$\\ReverseUpEquilibrium$', u'\U0001d77b': '$M$', u'\U0001d47d': '$\\mathbit{V}$', u'\U0001d5fc': '$\\mathsfbf{o}$', u'\U0001d483': '$\\mathbit{b}$', u'\U0001d785': '$\\mathsfbf{\\Phi}$', u'\U0001d604': '$\\mathsfbf{w}$', u'\u012d': '{\\u{\\i}}', u'\u220c': '$\\not\\ni$', u'\u20ac': '{\\mbox{\\texteuro}}', u'\ufb02': '{fl}', u'\U0001d599': '$\\mathslbb{t}$', u'\U0001d418': '$\\mathbf{Y}$', u'\U0001d71a': '{\\mathsl{\\varrho}}', u'\u2020': '{\\textdagger}', u'\u04a3': '{\\cyrchar\\cyrndsc}', u'\u2322': '$\\frown$', u'\u27a5': '{\\ding{229}}', u'\u2287': '$\\supseteq$', u'\u2926': '$\\ElsevierGlyph{E20A}$', u'\U0001d6af': '$\\mathbf{\\Theta}$', u'\U0001d52e': '$\\mathfrak{q}$', u'\u22b7': '$\\image$', u'\u2136': '$\\beth$', u'\u25b9': '$\\triangleright$', u'\u0438': '{\\cyrchar\\cyri}', u'\u273a': '{\\ding{90}}', u'\u2a3c': '$\\ElsevierGlyph{E259}$', u'\U0001d4c3': '$\\mathscr{n}$', u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', u'\U0001d644': '$\\mathsfbfsl{I}$', u'\xcb': '{\\"{E}}', u'\u03cd': '$\\acute{\\upsilon}$', u'\u224c': '$\\allequal$', u'\U0001d5d9': '$\\mathsfbf{F}$', u'\U0001d458': '$\\mathsl{k}$', u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', u'\u2060': '{\\nolinebreak}', u'\u0466': '{\\cyrchar\\CYRLYUS}', u'\U0001d6ef': '$\\mathsl{\\Xi}$', u'\U0001d56e': '$\\mathslbb{C}$', u'\u0176': '{\\^{Y}}', u'\u0478': '{\\cyrchar\\CYRUK}', u'\u277a': '{\\ding{186}}', u'\U0001d403': '$\\mathbf{D}$', u'\U0001d705': '$\\mathsl{\\Kappa}$', u'\U0001d684': '$\\mathtt{U}$', u'\u028c': '$\\Elzinvv$', u'\u01c2': '{\\textdoublepipe}', u'\U0001d519': '$\\mathfrak{V}$', u'\U0001d498': '$\\mathbit{w}$', u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', u'\u0121': '{\\.{g}}', u'\xa0': '$~$', u'\u0423': '{\\cyrchar\\CYRU}', u'\u2725': '{\\ding{69}}', u'\U0001d62f': '$\\mathsfsl{n}$', u'\U0001d5ae': '$\\mathsf{O}$', u'\u2237': '$\\Colon$', u'\u21b6': '$\\curvearrowleft$', u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', u'\u27ba': '{\\ding{250}}', u'\U0001d443': '$\\mathsl{P}$', u'\U0001d745': '$\\mathbit{\\Pi}$', u'\U0001d6c4': '$\\mathbf{\\Gamma}$', u'\u02cc': '$\\Elzverti$', u'\u264f': '{\\scorpio}', u'\u2951': '$\\LeftUpDownVector$', u'\U0001d559': '$\\mathbb{h}$', u'\U0001d4d8': '$\\mathmit{I}$', u'\U0001d7da': '$\\mathbb{2}$', u'\u0161': '{\\v{s}}', u'\xe0': '{\\`{a}}', u'\u2463': '{\\ding{175}}', u'\u2765': '{\\ding{165}}', u'\u22a7': '$\\truestate$', u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', u'\U0001d66f': '$\\mathsfbfsl{z}$', u'\U0001d5ee': '$\\mathsfbf{a}$', u'\u0277': '$\\Elzclomeg$', u'\u2464': '{\\ding{176}}', u'\u27fa': '$\\Longleftrightarrow$', u'\U0001d583': '$\\mathslbb{X}$', u'\U0001d685': '$\\mathtt{V}$', u'\U0001d704': '$\\mathsl{\\Iota}$', u'\u028d': '$\\Elzinvw$', u'\u030c': '{\\v}', u'\u278f': '{\\ding{207}}', u'\u040e': '{\\cyrchar\\CYRUSHRT}', u'\U0001d499': '$\\mathbit{x}$', u'\U0001d518': '$\\mathfrak{U}$', u'\U0001d61a': '$\\mathsfsl{S}$', u'\xa1': '{\\textexclamdown}', u'\u0120': '{\\.{G}}', u'\u2222': '$\\sphericalangle$', u'\u2724': '{\\ding{68}}', u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', u'\U0001d42e': '$\\mathbf{u}$', u'\u03b7': '$\\eta$', u'\u04b9': '{\\cyrchar\\cyrchvcrs}', u'\U0001d5c3': '$\\mathsf{j}$', u'\u228a': '$\\subsetneq$', u'\U0001d6c5': '$\\mathbf{\\Delta}$', u'\U0001d744': '$O$', u'\u21cb': '$\\leftrightharpoons$', u'\u22cd': '$\\backsimeq$', u'\u044e': '{\\cyrchar\\cyryu}', u'\u2950': '$\\DownLeftRightVector$', u'\U0001d4d9': '$\\mathmit{J}$', u'\U0001d558': '$\\mathbb{g}$', u'\U0001d65a': '$\\mathsfbfsl{e}$', u'\xe1': "{\\'{a}}", u'\u0160': '{\\v{S}}', u'\u2262': '$\\not\\equiv$', u'\u2764': '{\\ding{164}}', u'\u02e5': '{\\tone{55}}', u'\u0113': '{\\={e}}', u'\U0001d7ef': '$\\mathsfbf{3}$', u'\U0001d46e': '$\\mathbit{G}$', u'\u2afd': '${{/}\\!\\!{/}}$', u'\u0394': '$\\Delta$', u'\U0001d503': '$\\mathmit{z}$', u'\U0001d605': '$\\mathsfbf{x}$', u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', u'\u210b': '$\\mathscr{H}$', u'\u038c': "{\\'{}O}", u'\u270f': '{\\ding{47}}', u'\u048e': '{\\cyrchar\\CYRRTICK}', u'\U0001d419': '$\\mathbf{Z}$', u'\U0001d598': '$\\mathslbb{s}$', u'\U0001d69a': '$\\mathtt{q}$', u'\u2021': '{\\textdaggerdbl}', u'\u21a0': '$\\twoheadrightarrow$', u'\u22a2': '$\\vdash$', u'\u02c7': '{\\textasciicaron}', u'\U0001d72f': '$\\mathbit{\\Tau}$', u'\U0001d4ae': '$\\mathscr{S}$', u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', u'\xb6': '{\\textparagraph}', u'\u0439': '{\\cyrchar\\cyrishrt}', u'\u25b8': '$\\blacktriangleright$', u'\U0001d543': '$\\mathbb{L}$', u'\U0001d645': '$\\mathsfbfsl{J}$', u'\U0001d7c4': '$\\in$', u'\u014b': '{\\ng}', u'\u224d': '$\\asymp$', u'\u03cc': "{\\'{o}}", u'\u274f': '{\\ding{111}}', u'\u29d0': '$\\RightTriangleBar$', u'\U0001d459': '$\\mathsl{l}$', u'\U0001d5d8': '$\\mathsfbf{E}$', u'\U0001d6da': '$\\mathbf{\\Omega}$', u'\u22e2': '$\\not\\sqsubseteq$', u'\u2665': '{\\ding{170}}', u'\U0001d76f': '$\\mathsfbf{\\nabla}$', u'\U0001d4ee': '$\\mathmit{e}$', u'\xf6': '{\\"{o}}', u'\u0479': '{\\cyrchar\\cyruk}', u'\u2a7d': '$\\leqslant$', u'\U0001d683': '$\\mathtt{T}$', u'\U0001d585': '$\\mathslbb{Z}$', u'\U0001d404': '$\\mathbf{E}$', u'\u028b': '$\\Elzpscrv$', u'\u048f': '{\\cyrchar\\cyrrtick}', u'\u270e': '{\\ding{46}}', u'\u2a10': '$\\ElsevierGlyph{E395}$', u'\u2912': '$\\UpArrowBar$', u'\u0192': '$f$', u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', u'\U0001d618': '$\\mathsfsl{Q}$', u'\U0001d51a': '$\\mathfrak{W}$', u'\xdb': '{\\^{U}}', u'\u03a1': '$\\Rho$', u'\u2220': '$\\angle$', u'\u0122': '{\\c{G}}', u'\u0424': '{\\cyrchar\\CYRF}', u'\u0133': '{ij}', u'\U0001d4af': '$\\mathscr{T}$', u'\U0001d72e': '$\\mathbit{\\Sigma}$', u'\xb7': '$\\cdot$', u'\u0336': '{\\Elzbar}', u'\u27b9': '{\\ding{249}}', u'\U0001d6c3': '$\\mathbf{\\Beta}$', u'\U0001d5c5': '$\\mathsf{l}$', u'\U0001d444': '$\\mathsl{Q}$', u'\u22cb': '$\\leftthreetimes$', u'\u21cd': '$\\nLeftarrow$', u'\u010c': '{\\v{C}}', u'\u2952': '$\\LeftVectorBar$', u'\U0001d7d9': '$\\mathbb{1}$', u'\U0001d658': '$\\mathsfbfsl{c}$', u'\U0001d55a': '$\\mathbb{i}$', u'\u2260': '$\\not =$', u'\u0162': '{\\c{T}}', u'\u02e7': '{\\tone{33}}', u'\U0001d4ef': '$\\mathmit{f}$', u'\U0001d76e': '$\\mathsfbf{\\Omega}$', u'\xf7': '$\\div$', u'\u2468': '{\\ding{180}}', u'\u27f9': '$\\Longrightarrow$', u'\U0001d603': '$\\mathsfbf{v}$', u'\U0001d505': '$\\mathfrak{B}$', u'\U0001d484': '$\\mathbit{c}$', u'\u220b': '$\\ni$', u'\u210d': '$\\mathbb{H}$', u'\u040f': '{\\cyrchar\\CYRDZHE}', u'\u278e': '{\\ding{206}}', u'\U0001d719': '{\\mathsl{\\phi}}', u'\U0001d698': '$\\mathtt{o}$', u'\U0001d59a': '$\\mathslbb{u}$', u'\u0321': '$\\Elzpalh$', u'\u22a0': '$\\boxtimes$', u'\u21a2': '$\\leftarrowtail$', u'\u04a4': '{\\cyrchar\\CYRNG}', u'\U0001d42f': '$\\mathbf{v}$', u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', u'\u03b6': '$\\zeta$', u'\u2739': '{\\ding{89}}', u'\U0001d643': '$\\mathsfbfsl{H}$', u'\u224b': '$\\tildetrpl$', u'\u014d': '{\\={o}}', u'\xcc': '{\\`{I}}', u'\u044f': '{\\cyrchar\\cyrya}', u'\U0001d759': '$\\mathsfbf{\\Delta}$', u'\U0001d6d8': '$\\mathbf{\\Chi}$', u'\U0001d5da': '$\\mathsfbf{G}$', u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', u'\u2663': '{\\ding{168}}', u'\u0153': '{\\oe}', u'\U0001d46f': '$\\mathbit{H}$', u'\u227c': '$\\preccurlyeq$', u'\u0467': '{\\cyrchar\\cyrlyus}', u'\u03f6': '$\\backepsilon$', u'\u2779': '{\\ding{185}}', u'\u297d': '$\\ElsevierGlyph{E215}$', u'\U0001d783': '$\\mathsfbf{\\Tau}$', u'\U0001d485': '$\\mathbit{d}$', u'\U0001d504': '$\\mathfrak{A}$', u'\u210c': '$\\mathfrak{H}$', u'\u260e': '{\\ding{37}}', u'\U0001d699': '$\\mathtt{p}$', u'\U0001d718': '{\\mathsl{\\varkappa}}', u'\U0001d41a': '$\\mathbf{a}$', u'\u22a1': '$\\boxdot$', u'\u27a3': '{\\ding{227}}', u'\u2022': '{\\textbullet}', u'\u04a5': '{\\cyrchar\\cyrng}', u'\U0001d5af': '$\\mathsf{P}$', u'\U0001d62e': '$\\mathsfsl{m}$', u'\u21b7': '$\\curvearrowright$', u'\u2738': '{\\ding{88}}', u'\u043a': '{\\cyrchar\\cyrk}', u'\U0001d7c3': '$\\partial$', u'\U0001d4c5': '$\\mathscr{p}$', u'\U0001d544': '$\\mathbb{M}$', u'\u03cb': '$\\ddot{\\upsilon}$', u'\xcd': "{\\'{I}}", u'\u014c': '{\\={O}}', u'\u25cf': '{\\ding{108}}', u'\u264e': '{\\libra}', u'\U0001d6d9': '$\\mathbf{\\Psi}$', u'\U0001d758': '$\\mathsfbf{\\Gamma}$', u'\U0001d45a': '$\\mathsl{m}$', u'\u0111': '{\\dj}', u'\U0001d5ef': '$\\mathsfbf{b}$', u'\U0001d66e': '$\\mathsfbfsl{y}$', u'\u2276': '$\\lessgtr$', u'\u2778': '{\\ding{184}}', u'\u047a': '{\\cyrchar\\CYROMEGARND}', u'\u297c': '$\\ElsevierGlyph{E214}$', u'\U0001d703': '$\\mathsl{\\Theta}$', u'\U0001d405': '$\\mathbf{F}$', u'\U0001d584': '$\\mathslbb{Y}$', u'\u230b': '$\\rfloor$', u'\U0001d619': '$\\mathsfsl{R}$', u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', u'\U0001d49a': '$\\mathbit{y}$', u'\u2221': '$\\measuredangle$', u'\u03a0': '$\\Pi$', u'\u2723': '{\\ding{67}}', u'\xa2': '{\\textcent}', u'\u0425': '{\\cyrchar\\CYRH}', u'\u2927': '$\\ElsevierGlyph{E211}$', u'\U0001d52f': '$\\mathfrak{r}$', u'\U0001d6ae': '$\\mathbf{\\Eta}$', u'\u2137': '$\\gimel$', u'\u22b6': '$\\original$', u'\u27b8': '{\\ding{248}}', u'\u04ba': '{\\cyrchar\\CYRSHHA}', u'\u03f4': '{\\textTheta}', u'\U0001d743': '$\\mathbit{\\Xi}$', u'\U0001d445': '$\\mathsl{R}$', u'\U0001d5c4': '$\\mathsf{k}$', u'\u21cc': '$\\rightleftharpoons$', u'\U0001d659': '$\\mathsfbfsl{d}$', u'\U0001d7d8': '$\\mathbb{0}$', u'\U0001d4da': '$\\mathmit{K}$', u'\u2261': '$\\equiv$', u'\u03e0': '$\\Sampi$', u'\u2763': '{\\ding{163}}', u'\xe2': '{\\^{a}}', u'\u0465': '{\\cyrchar\\cyriote}', u'\U0001d56f': '$\\mathslbb{D}$', u'\U0001d6ee': '$N$', u'\u0177': '{\\^{y}}', u'\u27f8': '$\\Longleftarrow$', u'\U0001d581': '$\\mathslbb{V}$', u'\U0001d400': '$\\mathbf{A}$', u'\U0001d702': '$\\mathsl{\\Eta}$', u'\u0256': '$\\Elzrtld$', u'\u278d': '{\\ding{205}}', u'\u228f': '$\\sqsubset$', u'\u010e': '{\\v{D}}', u'\U0001d697': '$\\mathtt{n}$', u'\U0001d516': '$\\mathfrak{S}$', u'\u3018': '$\\ElsevierGlyph{3018}$', u'\u25a1': '$\\square$', u'\u0131': '{\\i}', u'\xa3': '{\\textsterling}', u'\u2722': '{\\ding{66}}', u'\u03a5': '$\\Upsilon$', u'\u2224': '$\\nmid$', u'\U0001d4ab': '$\\mathscr{P}$', u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', u'\U0001d62c': '$\\mathsfsl{k}$', u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', u'\U0001d5c1': '$\\mathsf{h}$', u'\U0001d440': '$\\mathsl{M}$', u'\U0001d742': '$N$', u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', u'\u264c': '{\\leo}', u'\u22cf': '$\\curlywedge$', u'\u014e': '{\\u{O}}', u'\u2a54': '$\\ElzOr$', u'\U0001d6d7': '$\\mathbf{\\Phi}$', u'\U0001d556': '$\\mathbb{e}$', u'\u2460': '{\\ding{172}}', u'\xe3': '{\\~{a}}', u'\u2762': '{\\ding{162}}', u'\u2264': '$\\leq$', u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', u'\U0001d4eb': '$\\mathmit{b}$', u'\U0001d7ed': '$\\mathsfbf{1}$', u'\U0001d66c': '$\\mathsfbfsl{w}$', u'\u0195': '{\\texthvlig}', u'\U0001d501': '$\\mathmit{x}$', u'\U0001d480': '$\\mathbit{Y}$', u'\U0001d782': '$\\mathsfbf{\\Sigma}$', u'\u040b': '{\\cyrchar\\CYRTSHE}', u'\u270d': '{\\ding{45}}', u'\u220f': '$\\prod$', u'\U0001d617': '$\\mathsfsl{P}$', u'\U0001d596': '$\\mathslbb{q}$', u'\u04a0': '{\\cyrchar\\CYRKBEAK}', u'\u27a2': '{\\ding{226}}', u'\u22a4': '$\\top$', u'\u2929': '$\\ElsevierGlyph{E20F}$', u'\U0001d42b': '$\\mathbf{r}$', u'\U0001d72d': '{\\mathbit{O}}', u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', u'\u04c8': '{\\cyrchar\\cyrnhk}', u'\u0139': "{\\'{L}}", u'\xb8': '{\\c{}}', u'\u03ba': '$\\kappa$', u'\u2a3f': '$\\amalg$', u'\U0001d541': '$\\mathbb{J}$', u'\U0001d4c0': '$\\mathscr{k}$', u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', u'\u044b': '{\\cyrchar\\cyrery}', u'\u274d': '{\\ding{109}}', u'\u224f': '$\\bumpeq$', u'\u21ce': '$\\nLeftrightarrow$', u'\U0001d657': '$\\mathsfbfsl{b}$', u'\U0001d5d6': '$\\mathsfbf{C}$', u'\u04e0': '{\\cyrchar\\CYRABHDZE}', u'\U0001d46b': '$\\mathbit{D}$', u'\U0001d76d': '$\\mathsfbf{\\Psi}$', u'\U0001d6ec': '$\\mathsl{\\Lambda}$', u'\u0179': "{\\'{Z}}", u'\xf8': '{\\o}', u'\U0001d481': '$\\mathbit{Z}$', u'\U0001d500': '$\\mathmit{w}$', u'\U0001d602': '$\\mathsfbf{u}$', u'\u270c': '{\\ding{44}}', u'\u038f': "$\\mathrm{'\\Omega}$", u'\u2993': '$<\\kern-0.58em($', u'\u2a95': '$\\eqslantless$', u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', u'\U0001d416': '$\\mathbf{W}$', u'\u04a1': '{\\cyrchar\\cyrkbeak}', u'\u21a3': '$\\rightarrowtail$', u'\u22a5': '$\\perp$', u'\u2928': '$\\ElsevierGlyph{E20E}$', u'\U0001d5ab': '$\\mathsf{L}$', u'\u2a2a': '$\\ElsevierGlyph{E25B}$', u'\U0001d6ad': '$\\mathbf{\\Zeta}$', u'\U0001d72c': '$\\mathbit{\\Rho}$', u'\u27b7': '{\\ding{247}}', u'\u0436': '{\\cyrchar\\cyrzh}', u'\xb9': '${^1}$', u'\u2138': '$\\daleth$', u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', u'\u030b': '{\\H}', u'\U0001d4c1': '$\\mathscr{l}$', u'\U0001d540': '$\\mathbb{I}$', u'\U0001d642': '$\\mathsfbfsl{G}$', u'\u25cb': '$\\bigcirc$', u'\U0001d7d7': '$\\mathbf{9}$', u'\U0001d456': '$\\mathsl{i}$', u'\u04e1': '{\\cyrchar\\cyrabhdze}', u'\u2662': '$\\diamond$', u'\u22e5': '$\\Elzsqspne$', u'\U0001d5eb': '$\\mathsfbf{X}$', u'\U0001d6ed': '$M$', u'\U0001d76c': '$\\mathsfbf{\\Chi}$', u'\u27f7': '$\\longleftrightarrow$', u'\xf9': '{\\`{u}}', u'\u0178': '{\\"{Y}}', u'\u227a': '$\\prec$', u'\U0001d401': '$\\mathbf{B}$', u'\U0001d580': '$\\mathslbb{U}$', u'\U0001d682': '$\\mathtt{S}$', u'\u2296': '$\\ominus$', u'\u278c': '{\\ding{204}}', u'\u2758': '{\\ding{120}}', u'\u2913': '$\\DownArrowBar$', u'\U0001d717': '{\\mathsl{\\vartheta}}', u'\U0001d496': '$\\mathbit{u}$', u'\u3019': '$\\ElsevierGlyph{3019}$', u'\u0421': '{\\cyrchar\\CYRS}', u'\u25a0': '{\\ding{110}}', u'\u0123': '{\\c{g}}', u'\u2225': '$\\parallel$', u'\u03a4': '$\\Tau$', u'\U0001d52b': '$\\mathfrak{n}$', u'\U0001d62d': '$\\mathsfsl{l}$', u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', u'\u2737': '{\\ding{87}}', u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', u'\u2039': '{\\guilsinglleft}', u'\u22ba': '$\\intercal$', u'\U0001d441': '$\\mathsl{N}$', u'\U0001d5c0': '$\\mathsf{g}$', u'\U0001d6c2': '$\\mathbf{\\Alpha}$', u'\u264d': '{\\virgo}', u'\xce': '{\\^{I}}', u'\u2953': '$\\RightVectorBar$', u'\u2a55': '$\\ElsevierGlyph{E36E}$', u'\U0001d757': '$\\mathsfbf{\\Beta}$', u'\U0001d4d6': '$\\mathmit{G}$', u'\u2461': '{\\ding{173}}', u'\u0163': '{\\c{t}}', u'\u0265': '$\\Elztrnh$', u'\U0001d56b': '$\\mathbb{z}$', u'\U0001d66d': '$\\mathsfbfsl{x}$', u'\u02d3': '$\\Elzsblhr$', u'\u2777': '{\\ding{183}}', u'\U0001d781': '$\\mathsfbf{\\varsigma}$', u'\U0001d600': '$\\mathsfbf{s}$', u'\U0001d502': '$\\mathmit{y}$', u'\u040c': "{\\cyrchar{\\'\\CYRK}}", u'\U0001d497': '$\\mathbit{v}$', u'\U0001d716': '$\\in$', u'\u27a1': '{\\ding{225}}', u'\u22a3': '$\\dashv$', u'\u2024': '{.}', u'\U0001d6ab': '$\\mathbf{\\Delta}$', u'\u292a': '$\\ElsevierGlyph{E210}$', u'\U0001d5ad': '$\\mathsf{N}$', u'\U0001d42c': '$\\mathbf{s}$', u'\u04b7': '{\\cyrchar\\cyrchrdsc}', u'\u2736': '{\\ding{86}}', u'\u03b9': '$\\iota$', u'\u2238': '$\\ElsevierGlyph{2238}$', u'\u013a': "{\\'{l}}", u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', u'\U0001d640': '$\\mathsfbfsl{E}$', u'\U0001d542': '$\\mathbb{K}$', u'\u0137': '{\\c{k}}', u'\u044c': '{\\cyrchar\\cyrsftsn}', u'\xcf': '{\\"{I}}', u'\U0001d4d7': '$\\mathmit{H}$', u'\U0001d756': '$\\mathsfbf{\\Alpha}$', u'\u2660': '{\\ding{171}}', u'\u22e3': '$\\not\\sqsupseteq$', u'\u0110': '{\\DJ}', u'\U0001d6eb': '$\\mathsl{\\Kappa}$', u'\U0001d5ed': '$\\mathsfbf{Z}$', u'\U0001d46c': '$\\mathbit{E}$', u'\u2776': '{\\ding{182}}', u'\u2278': '$\\notlessgreater$', u'\u017a': "{\\'{z}}", u'\U0001d701': '$\\mathsl{\\Zeta}$', u'\U0001d680': '$\\mathtt{Q}$', u'\U0001d582': '$\\mathslbb{W}$', u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', u'\u038e': "$\\mathrm{'Y}$", u'\U0001d417': '$\\mathbf{X}$', u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', u'\u2721': '{\\ding{65}}', u'\u2223': '$\\mid$', u'\u0125': '{\\^{h}}', u'\xa4': '{\\textcurrency}', u'\U0001d62b': '$\\mathsfsl{j}$', u'\U0001d52d': '$\\mathfrak{p}$', u'\U0001d4ac': '$\\mathscr{Q}$', u'\u0437': '{\\cyrchar\\cyrz}', u'\u27b6': '{\\ding{246}}', u'\u22b8': '$\\multimap$', u'\u21ba': '$\\circlearrowleft$', u'\U0001d741': '$M$', u'\U0001d6c0': '$\\mathbf{\\Omega}$', u'\U0001d5c2': '$\\mathsf{i}$', u'\u011c': '{\\^{G}}', u'\u264b': '{\\cancer}', u'\u04cc': '{\\cyrchar\\cyrchldsc}', u'\u03ce': '$\\acute{\\omega}$', u'\u2a53': '$\\ElzAnd$', u'\u2955': '$\\RightDownVectorBar$', u'\U0001d457': '$\\mathsl{j}$', u'\U0001d7d6': '$\\mathbf{8}$', u'\u2761': '{\\ding{161}}', u'\u0263': '$\\Elzpgamma$', u'\u0165': '{\\v{t}}', u'\xe4': '{\\"{a}}', u'\U0001d66b': '$\\mathsfbfsl{v}$', u'\U0001d56d': '$\\mathslbb{B}$', u'\U0001d4ec': '$\\mathmit{c}$', u'\u27f6': '$\\longrightarrow$', u'\U0001d681': '$\\mathtt{R}$', u'\U0001d700': '$\\mathsl{\\Epsilon}$', u'\U0001d402': '$\\mathbf{C}$', u'\u0157': '{\\c{r}}', u'\u278b': '{\\ding{203}}', u'\u048d': '{\\cyrchar\\cyrsemisftsn}', u'\U0001d597': '$\\mathslbb{r}$', u'\U0001d616': '$\\mathsfsl{O}$', u'\u301a': '$\\openbracketleft$', u'\u2720': '{\\ding{64}}', u'\u23a3': '$\\Elzdlcorn$', u'\u0422': '{\\cyrchar\\CYRT}', u'\xa5': '{\\textyen}', u'\u2124': '$\\mathbb{Z}$', u'\u0130': '{\\.{I}}', u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', u'\U0001d52c': '$\\mathfrak{o}$', u'\u2288': '$\\not\\subseteq$', u'\u22b9': '$\\hermitconjmatrix$', u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', u'\u203a': '{\\guilsinglright}', u'\U0001d6c1': '$\\mathbf{\\nabla}$', u'\U0001d740': '$\\mathbit{\\Lambda}$', u'\U0001d442': '$\\mathsl{O}$', u'\u21cf': '$\\nRightarrow$', u'\u224e': '$\\Bumpeq$', u'\u2954': '$\\RightUpVectorBar$', u'\U0001d5d7': '$\\mathsfbf{D}$', u'\U0001d656': '$\\mathsfbfsl{a}$', u'\u2465': '{\\ding{177}}', u'\u2462': '{\\ding{174}}', u'\xe5': '{\\aa}', u'\u0164': '{\\v{T}}', u'\U0001d7eb': '$\\mathsf{9}$', u'\U0001d4ed': '$\\mathmit{d}$', u'\U0001d56c': '$\\mathslbb{A}$', u'\u0115': '{\\u{e}}', u'\U0001d7ec': '$\\mathsfbf{0}$', u'\u2a7e': '$\\geqslant$', u'\U0001d601': '$\\mathsfbf{t}$', u'\U0001d780': '$\\mathsfbf{\\Rho}$', u'\U0001d482': '$\\mathbit{a}$', u'\u210f': '$\\hslash$', u'\u228e': '$\\uplus$', u'\u2994': '$\\ElsevierGlyph{E291}$', u'\U0001d517': '$\\mathfrak{T}$', u'\U0001d696': '$\\mathtt{m}$', u'\u27a0': '{\\ding{224}}', u'\u2323': '$\\smile$', u'\u04a2': '{\\cyrchar\\CYRNDSC}', u'\u2025': '{..}', u'\U0001d72b': '$\\mathbit{\\Pi}$', u'\U0001d42d': '$\\mathbf{t}$', u'\U0001d5ac': '$\\mathsf{M}$', u'\u03b8': '{\\texttheta}', u'\xba': '{\\textordmasculine}', u'\U0001d641': '$\\mathsfbfsl{F}$', u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', u'\U0001d4c2': '$\\mathscr{m}$', u'\u274b': '{\\ding{107}}', u'\u044d': '{\\cyrchar\\cyrerev}', u'\u014f': '{\\u{o}}', u'\u22ce': '$\\curlyvee$', u'\U0001d557': '$\\mathbb{f}$', u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', u'\U0001d76b': '$\\mathsfbf{\\Phi}$', u'\u27a6': '{\\ding{230}}', u'\U0001d46d': '$\\mathbit{F}$', u'\U0001d5ec': '$\\mathsfbf{Y}$', u'\u2252': '$\\fallingdotseq$', u'\u2279': '$\\notgreaterless$', u'\u0119': '{\\k{e}}', u'\xfa': "{\\'{u}}", u'\u01aa': '$\\eth$', u'\U0001d589': '$\\mathslbb{d}$', u'\U0001d408': '$\\mathbf{I}$', u'\U0001d70a': '$O$', u'\u2191': '$\\uparrow$', u'\u2010': '{-}', u'\u0493': '{\\cyrchar\\cyrghcrs}', u'\U0001d69f': '$\\mathtt{v}$', u'\U0001d51e': '$\\mathfrak{a}$', u'\u029e': '{\\textturnk}', u'\u02a7': '$\\Elztesh$', u'\u2126': '$\\Omega$', u'\u0428': '{\\cyrchar\\CYRSH}', u'\u272a': '{\\ding{74}}', u'\U0001d4b3': '$\\mathscr{X}$', u'\U0001d7b5': '$M$', u'\U0001d634': '$\\mathsfsl{s}$', u'\u2ab7': '$\\precapprox$', u'\u2936': '$\\ElsevierGlyph{E21A}$', u'\u0135': '{\\^{\\j}}', u'\xbb': '{\\guillemotright}', u'\u03bd': '$\\nu$', u'\u223c': '$\\sim$', u'\U0001d5c9': '$\\mathsf{p}$', u'\U0001d448': '$\\mathsl{U}$', u'\U0001d74a': '$\\mathbit{\\Upsilon}$', u'\u21d1': '$\\Uparrow$', u'\U0001d6df': '{\\mathbf{\\phi}}', u'\U0001d55e': '$\\mathbb{m}$', u'\u22e7': '$\\gnsim$', u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', u'\U0001d4f3': '$\\mathmit{j}$', u'\U0001d7f5': '$\\mathsfbf{9}$', u'\U0001d674': '$\\mathtt{E}$', u'\xfb': '{\\^{u}}', u'\u027c': '$\\Elzrl$', u'\U0001d509': '$\\mathfrak{F}$', u'\U0001d488': '$\\mathbit{g}$', u'\U0001d78a': '$\\in$', u'\u2a8c': '$\\gtreqqless$', u'\u2111': '$\\mathfrak{I}$', u'\u0413': '{\\cyrchar\\CYRG}', u'\u0392': '$\\Beta$', u'\u2715': '{\\ding{53}}', u'\u301b': '$\\openbracketright$', u'\U0001d61f': '$\\mathsfsl{X}$', u'\U0001d59e': '$\\mathslbb{y}$', u'\u2227': '$\\wedge$', u'\u21a6': '$\\mapsto$', u'\u04a8': '{\\cyrchar\\CYRABHHA}', u'\u27aa': '{\\ding{234}}', u'\U0001d433': '$\\mathbf{z}$', u'\u0272': '{\\Elzltln}', u'\U0001d735': '$\\mathbit{\\nabla}$', u'\U0001d6b4': '$N$', u'\u29b6': '$\\ElsevierGlyph{E61B}$', u'\u233d': '$\\ElsevierGlyph{E838}$', u'\u02bc': "{'}", u'\u263f': '{\\mercury}', u'\u25be': '$\\blacktriangledown$', u'\u0420': '{\\cyrchar\\CYRR}', u'\U0001d4c8': '$\\mathscr{s}$', u'\u2acc': '$\\supsetneqq$', u'\u0151': '{\\H{o}}', u'\xd0': '{\\DH}', u'\u0453': "{\\cyrchar{\\'\\cyrg}}", u'\u03d2': '$\\Upsilon$', u'\U0001d65f': '$\\mathsfbfsl{j}$', u'\U0001d5de': '$\\mathsfbf{K}$', u'\u2961': '$\\LeftDownTeeVector$', u'\u015a': "{\\'{S}}", u'\u2267': '$\\geqq$', u'\u04e8': '{\\cyrchar\\CYROTLD}', u'\U0001d473': '$\\mathbit{L}$', u'\U0001d775': '$\\mathsfbf{\\Zeta}$', u'\U0001d6f4': '$\\mathsl{\\Sigma}$', u'\u0155': "{\\'{r}}", u'\U0001d489': '$\\mathbit{h}$', u'\U0001d508': '$\\mathfrak{E}$', u'\U0001d60a': '$\\mathsfsl{C}$', u'\u2110': '$\\mathscr{I}$', u'\u2212': '{-}', u'\u2714': '{\\ding{52}}', u'\u012e': '{\\k{I}}', u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', u'\U0001d41e': '$\\mathbf{e}$', u'\u03a7': '$\\Chi$', u'\u2026': '{\\ldots}', u'\u04a9': '{\\cyrchar\\cyrabhha}', u'\U0001d5b3': '$\\mathsf{T}$', u'\U0001d6b5': '$\\mathbf{\\Xi}$', u'\U0001d734': '$\\mathbit{\\Omega}$', u'\u21bb': '$\\circlearrowright$', u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', u'\u043e': '{\\cyrchar\\cyro}', u'\U0001d4c9': '$\\mathscr{t}$', u'\u29cb': '$\\Elzdefas$', u'\U0001d64a': '$\\mathsfbfsl{O}$', u'\xd1': '{\\~{N}}', u'\u0150': '{\\H{O}}', u'\u0252': '$\\Elztrnsa$', u'\U0001d7df': '$\\mathbb{7}$', u'\U0001d45e': '$\\mathsl{q}$', u'\u2960': '$\\LeftUpTeeVector$', u'\u012c': '{\\u{I}}', u'\u04e9': '{\\cyrchar\\cyrotld}', u'\u266a': '{\\eighthnote}', u'\U0001d5f3': '$\\mathsfbf{f}$', u'\u2292': '$\\sqsupseteq$', u'\U0001d6f5': '$\\mathsl{\\Tau}$', u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', u'\u02e8': '{\\tone{22}}', u'\u27ff': '$\\sim\\joinrel\\leadsto$', u'\u047e': '{\\cyrchar\\CYROT}', u'\U0001d409': '$\\mathbf{J}$', u'\U0001d588': '$\\mathslbb{c}$', u'\U0001d68a': '$\\mathtt{a}$', u'\u2a0d': '$\\ElzCint$', u'\u2190': '$\\leftarrow$', u'\u0292': '$\\Elzyogh$', u'\u2794': '{\\ding{212}}', u'\u011b': '{\\v{e}}', u'\U0001d71f': '$\\mathbit{\\Delta}$', u'\U0001d49e': '$\\mathscr{C}$', u'\u29a0': '$\\Elzlpargt$', u'\u2aa2': '$\\NestedGreaterGreater$', u'\u0327': '{\\c}', u'\xa6': '{\\textbrokenbar}', u'\u0429': '{\\cyrchar\\CYRSHCH}', u'\u0273': '$\\Elzrtln$', u'\U0001d533': '$\\mathfrak{v}$', u'\U0001d635': '$\\mathsfsl{t}$', u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', u'\u013b': '{\\c{L}}', u'\u223d': '$\\backsim$', u'\u03bc': '$\\mu$', u'\u273f': '{\\ding{95}}', u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', u'\U0001d449': '$\\mathsl{V}$', u'\U0001d5c8': '$\\mathsf{o}$', u'\U0001d6ca': '$\\mathbf{\\Iota}$', u'\u21d0': '$\\Leftarrow$', u'\u02d2': '$\\Elzsbrhr$', u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', u'\U0001d4de': '$\\mathmit{O}$', u'\u0261': '{g}', u'\xe6': '{\\ae}', u'\u0469': '{\\cyrchar\\cyriotlyus}', u'\u25e8': '$\\Elzsqfr$', u'\U0001d573': '$\\mathslbb{H}$', u'\U0001d675': '$\\mathtt{F}$', u'\U0001d7f4': '$\\mathsfbf{8}$', u'\u017b': '{\\.{Z}}', u'\u027d': '$\\Elzrtlr$', u'\u277f': '{\\ding{191}}', u'\U0001d789': '$\\partial$', u'\U0001d608': '$\\mathsfsl{A}$', u'\u2a8b': '$\\lesseqqgtr$', u'\U0001d50a': '$\\mathfrak{G}$', u'\u0391': '$\\Alpha$', u'\u2210': '$\\coprod$', u'\u2112': '$\\mathscr{L}$', u'\u0414': '{\\cyrchar\\CYRD}', u'\U0001d49f': '$\\mathscr{D}$', u'\U0001d71e': '$\\mathbit{\\Gamma}$', u'\xa7': '{\\textsection}', u'\u27a9': '{\\ding{233}}', u'\U0001d6b3': '$M$', u'\U0001d5b5': '$\\mathsf{V}$', u'\U0001d434': '$\\mathsl{A}$', u'\u0308': '{\\"}', u'\u22bb': '$\\veebar$', u'\u21bd': '$\\leftharpoondown$', u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', u'\u273e': '{\\ding{94}}', u'\u0460': '{\\cyrchar\\CYROMEGA}', u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', u'\U0001d648': '$\\mathsfbfsl{M}$', u'\u2acb': '$\\subsetneqq$', u'\U0001d54a': '$\\mathbb{S}$', u'\u03d1': '{\\textvartheta}', u'\u0250': '$\\Elztrna$', u'\u0152': '{\\OE}', u'\u0454': '{\\cyrchar\\cyrie}', u'\U0001d4df': '$\\mathmit{P}$', u'\u0264': '$\\Elzpbgam$', u'\xe7': '{\\c{c}}', u'\U0001d710': '$\\mathsl{\\Upsilon}$', u'\u0102': '{\\u{A}}', u'\U0001d6f3': '{\\mathsl{\\vartheta}}', u'\U0001d5f5': '$\\mathsfbf{h}$', u'\U0001d474': '$\\mathbit{M}$', u'\u277e': '{\\ding{190}}', u'\ufb01': '{fi}', u'\U0001d709': '$\\mathsl{\\Xi}$', u'\U0001d688': '$\\mathtt{Y}$', u'\U0001d58a': '$\\mathslbb{e}$', u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', u'\u0290': '$\\Elzrtlz$', u'\u2192': '$\\rightarrow$', u'\u0494': '{\\cyrchar\\CYRGHK}', u'\u0129': '{\\~{\\i}}', u'\U0001d41f': '$\\mathbf{f}$', u'\U0001d79e': '$O$', u'\u03a6': '$\\Phi$', u'\u2729': '{\\ding{73}}', u'\u25aa': '$\\blacksquare$', u'\U0001d633': '$\\mathsfsl{r}$', u'\U0001d535': '$\\mathfrak{x}$', u'\U0001d4b4': '$\\mathscr{Y}$', u'\u223b': '$\\homothetic$', u'\u013d': '{\\v{L}}', u'\xbc': '{\\textonequarter}', u'\u043f': '{\\cyrchar\\cyrp}', u'\u27be': '{\\ding{254}}', u'\U0001d749': '$\\mathbit{\\Tau}$', u'\U0001d6c8': '$\\mathbf{\\Eta}$', u'\U0001d5ca': '$\\mathsf{q}$', u'\u22d0': '$\\Subset$', u'\u2653': '{\\pisces}', u'\u21d2': '$\\Rightarrow$', u'\u04d4': '{\\cyrchar\\CYRAE}', u'\U0001d45f': '$\\mathsl{r}$', u'\U0001d7de': '$\\mathbb{6}$', u'\u25ea': '$\\Elzsqfse$', u'\U0001d673': '$\\mathtt{D}$', u'\u22d2': '$\\Cap$', u'\U0001d575': '$\\mathslbb{J}$', u'\U0001d4f4': '$\\mathmit{k}$', u'\u027b': '$\\Elzrttrnr$', u'\u017d': '{\\v{Z}}', u'\xfc': '{\\"{u}}', u'\u047f': '{\\cyrchar\\cyrot}', u'\ufb00': '{ff}', u'\U0001d689': '$\\mathtt{Z}$', u'\U0001d708': '$N$', u'\U0001d40a': '$\\mathbf{K}$', u'\u2291': '$\\sqsubseteq$', u'\u2793': '{\\ding{211}}', u'\u0495': '{\\cyrchar\\cyrghk}', u'\u015b': "{\\'{s}}", u'\U0001d59f': '$\\mathslbb{z}$', u'\U0001d61e': '$\\mathsfsl{W}$', u'\u2aa1': '$\\NestedLessLess$', u'\u2226': '$\\nparallel$', u'\u042a': '{\\cyrchar\\CYRHRDSN}', u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', u'\U0001d4b5': '$\\mathscr{Z}$', u'\U0001d534': '$\\mathfrak{w}$', u'\u03bb': '$\\lambda$', u'\xbd': '{\\textonehalf}', u'\u013c': '{\\c{l}}', u'\u25bf': '$\\triangledown$', u'\u263e': '{\\rightmoon}', u'\U0001d6c9': '$\\mathbf{\\theta}$', u'\U0001d748': '$\\mathbit{\\Sigma}$', u'\U0001d44a': '$\\mathsl{W}$', u'\u02d1': '$\\Elzhlmrk$', u'\u04d5': '{\\cyrchar\\cyrae}', u'\U0001d5df': '$\\mathsfbf{L}$', u'\U0001d65e': '$\\mathsfbfsl{i}$', u'\u2266': '$\\leqq$', u'\u046a': '{\\cyrchar\\CYRBYUS}', u'\u2469': '{\\ding{181}}', u'\U0001d7f3': '$\\mathsfbf{7}$', u'\U0001d4f5': '$\\mathmit{l}$', u'\U0001d574': '$\\mathslbb{I}$', u'\xfd': "{\\'{y}}", u'\u017c': '{\\.{z}}', u'\U0001d609': '$\\mathsfsl{B}$', u'\U0001d788': '$\\mathsfbf{\\Omega}$', u'\U0001d48a': '$\\mathbit{i}$', u'\u2211': '$\\sum$', u'\u0390': '$\\acute{\\ddot{\\iota}}$', u'\u2713': '{\\ding{51}}', u'\u0415': '{\\cyrchar\\CYRE}', u'\U0001d51f': '$\\mathfrak{b}$', u'\U0001d69e': '$\\mathtt{u}$', u'\u0127': '$\\Elzxh$', u'\u27a8': '{\\ding{232}}', u'\u04aa': '{\\cyrchar\\CYRSDSC}', u'\U0001d733': '$\\mathbit{\\Psi}$', u'\U0001d435': '$\\mathsl{B}$', u'\U0001d5b4': '$\\mathsf{U}$', u'\u2937': '$\\ElsevierGlyph{E219}$', u'\u2ab6': '$\\succneqq$', u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', u'\u21bc': '$\\leftharpoonup$', u'\U0001d649': '$\\mathsfbfsl{N}$', u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', u'\U0001d4ca': '$\\mathscr{u}$', u'\u2251': '$\\doteqdot$', u'\u03d0': '{\\Pisymbol{ppi022}{87}}', u'\xd2': '{\\`{O}}', u'\u0455': '{\\cyrchar\\cyrdze}', u'\U0001d55f': '$\\mathbb{n}$', u'\u02a4': '$\\Elzdyogh$', u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', u'\u22e6': '$\\lnsim$', u'\u2669': '{\\quarternote}', u'\u227d': '$\\succcurlyeq$', u'\U0001d773': '$\\mathsfbf{\\Delta}$', u'\U0001d475': '$\\mathbit{N}$', u'\U0001d5f4': '$\\mathsfbf{g}$', u'\u2af6': '$\\Elztdcol$', u'\u0154': "{\\'{R}}", u'\U0001d687': '$\\mathtt{X}$', u'\u0410': '{\\cyrchar\\CYRA}', u'\u2712': '{\\ding{50}}', u'\u0395': '$\\Epsilon$', u'\u2214': '$\\dotplus$', u'\U0001d49b': '$\\mathbit{z}$', u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', u'\U0001d61c': '$\\mathsfsl{U}$', u'\u21a9': '$\\hookleftarrow$', u'\u032a': '$\\Elzsbbrg$', u'\U0001d5b1': '$\\mathsf{R}$', u'\U0001d430': '$\\mathbf{w}$', u'\U0001d732': '$\\mathbit{\\Chi}$', u'\u04bb': '{\\cyrchar\\cyrshha}', u'\u27bd': '{\\ding{253}}', u'\u013e': '{\\v{l}}', u'\U0001d6c7': '$\\mathbf{\\Zeta}$', u'\U0001d546': '$\\mathbb{O}$', u'\u294e': '$\\LeftRightVector$', u'\u25d1': '$\\Elzcirfr$', u'\xd3': "{\\'{O}}", u'\u2752': '{\\ding{114}}', u'\u03d5': '$\\phi$', u'\u0254': '$\\Elzopeno$', u'\U0001d4db': '$\\mathmit{L}$', u'\U0001d7dd': '$\\mathbb{5}$', u'\U0001d65c': '$\\mathsfbfsl{g}$', u'\u2666': '{\\ding{169}}', u'\U0001d5f1': '$\\mathsfbf{d}$', u'\U0001d470': '$\\mathbit{I}$', u'\U0001d772': '$\\mathsfbf{\\Gamma}$', u'\u017e': '{\\v{z}}', u'\U0001d607': '$\\mathsfbf{z}$', u'\U0001d586': '$\\mathslbb{a}$', u'\u2a0f': '$\\clockoint$', u'\u0490': '{\\cyrchar\\CYRGUP}', u'\u2013': '{\\textendash}', u'\u2792': '{\\ding{210}}', u'\u2315': '$\\recorder$', u'\u2294': '$\\sqcup$', u'\U0001d41b': '$\\mathbf{b}$', u'\U0001d71d': '$\\mathbit{\\Beta}$', u'\U0001d69c': '$\\mathtt{s}$', u'\u2129': '$\\ElsevierGlyph{2129}$', u'\xa8': '{\\textasciidieresis}', u'\u03aa': '$\\mathrm{\\ddot{I}}$', u'\U0001d531': '$\\mathfrak{t}$', u'\U0001d4b0': '$\\mathscr{U}$', u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', u'\u043b': '{\\cyrchar\\cyrl}', u'\u273d': '{\\ding{93}}', u'\u21be': '$\\upharpoonright$', u'\U0001d647': '$\\mathsfbfsl{L}$', u'\U0001d5c6': '$\\mathsf{m}$', u'\u02d4': '$\\Elzrais$', u'\U0001d45b': '$\\mathsl{n}$', u'\U0001d75d': '$\\mathsfbf{\\Theta}$', u'\U0001d6dc': '$\\in$', u'\u20a7': '{\\ensuremath{\\Elzpes}}', u'\u0169': '{\\~{u}}', u'\xe8': '{\\`{e}}', u'\U0001d571': '$\\mathslbb{F}$', u'\U0001d4f0': '$\\mathmit{g}$', u'\U0001d7f2': '$\\mathsfbf{6}$', u'\u047b': '{\\cyrchar\\cyromegarnd}', u'\u027e': '$\\Elzfhr$', u'\u277d': '{\\ding{189}}', u'\u227f': '$\\succapprox$', u'\ufb04': '{ffl}', u'\U0001d787': '$\\mathsfbf{\\Psi}$', u'\U0001d406': '$\\mathbf{G}$', u'\u0112': '{\\={E}}', u'\u0159': '{\\v{r}}', u'\u2193': '$\\downarrow$', u'\u0295': '$\\Elzreglst$', u'\U0001d59b': '$\\mathslbb{v}$', u'\U0001d69d': '$\\mathtt{t}$', u'\U0001d71c': '$\\mathbit{\\Alpha}$', u'\u23b1': '$\\rmoustache$', u'\u27a7': '{\\ding{231}}', u'\u0426': '{\\cyrchar\\CYRC}', u'\xa9': '{\\textcopyright}', u'\u2128': '$\\mathfrak{Z}$', u'\u222a': '$\\cup$', u'\U0001d4b1': '$\\mathscr{V}$', u'\U0001d530': '$\\mathfrak{s}$', u'\U0001d632': '$\\mathsfsl{q}$', u'\u273c': '{\\ding{92}}', u'\u03bf': '$o$', u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', u'\U0001d446': '$\\mathsl{S}$', u'\u21d3': '$\\Downarrow$', u'\u2652': '{\\aquarius}', u'\u02d5': '$\\Elzlow$', u'\U0001d5db': '$\\mathsfbf{H}$', u'\U0001d6dd': '{\\mathbf{\\vartheta}}', u'\U0001d75c': '$\\mathsfbf{\\Eta}$', u'\u2466': '{\\ding{178}}', u'\xe9': "{\\'{e}}", u'\u0168': '{\\~{U}}', u'\u226a': '$\\ll$', u'\U0001d4f1': '$\\mathmit{h}$', u'\U0001d570': '$\\mathslbb{E}$', u'\U0001d672': '$\\mathtt{C}$', u'\u277c': '{\\ding{188}}', u'\U0001d707': '$M$', u'\U0001d486': '$\\mathbit{e}$', u'\u0411': '{\\cyrchar\\CYRB}', u'\u2113': '$\\mathscr{l}$', u'\u026f': '$\\Elztrnm$', u'\U0001d51b': '$\\mathfrak{X}$', u'\U0001d61d': '$\\mathsfsl{V}$', u'\U0001d79c': '$N$', u'\u2923': '$\\ElsevierGlyph{E20C}$', u'\u2a25': '$\\ElsevierGlyph{E25A}$', u'\u2727': '{\\ding{71}}', u'\u04a6': '{\\cyrchar\\CYRPHK}', u'\u22aa': '$\\Vvdash$', u'\U0001d431': '$\\mathbf{x}$', u'\U0001d5b0': '$\\mathsf{Q}$', u'\U0001d6b2': '$\\mathbf{\\Lambda}$', u'\u2aba': '$\\succnapprox$', u'\u27bc': '{\\ding{252}}', u'\xbe': '{\\textthreequarters}', u'\U0001d747': '$\\mathbit{\\varsigma}$', u'\U0001d4c6': '$\\mathscr{q}$', u'\u0451': '{\\cyrchar\\cyryo}', u'\u25d0': '$\\Elzcirfl$', u'\u2153': '$\\textfrac{1}{3}$', u'\u2255': '$=:$', u'\U0001d55b': '$\\mathbb{j}$', u'\U0001d65d': '$\\mathsfbfsl{h}$', u'\U0001d7dc': '$\\mathbb{4}$', u'\u2767': '{\\ding{167}}', u'\u2250': '$\\doteq$', u'\u22ea': '$\\ntriangleleft$', u'\U0001d471': '$\\mathbit{J}$', u'\U0001d5f0': '$\\mathsfbf{c}$', u'\U0001d6f2': '$\\mathsl{\\Rho}$', u'\u27fc': '$\\longmapsto$', u'\xfe': '{\\th}', u'\U0001d487': '$\\mathbit{f}$', u'\U0001d706': '$\\mathsl{\\Lambda}$', u'\u2791': '{\\ding{209}}', u'\u2293': '$\\sqcap$', u'\u2195': '$\\updownarrow$', u'\u2014': '{\\textemdash}', u'\U0001d69b': '$\\mathtt{r}$', u'\U0001d59d': '$\\mathslbb{x}$', u'\U0001d41c': '$\\mathbf{c}$', u'\u04a7': '{\\cyrchar\\cyrphk}', u'\u2726': '{\\ding{70}}', u'\u03a9': '$\\Omega$', u'\u2228': '$\\vee$', u'\u012a': '{\\={I}}', u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', u'\U0001d630': '$\\mathsfsl{o}$', u'\U0001d532': '$\\mathfrak{u}$', u'\U0001d75e': '$\\mathsfbf{\\Iota}$', u'\u25bd': '$\\bigtriangledown$', u'\u043c': '{\\cyrchar\\cyrm}', u'\xbf': '{\\textquestiondown}', u'\U0001d4c7': '$\\mathscr{r}$', u'\U0001d746': '$\\mathbit{\\Rho}$', u'\u2650': '{\\sagittarius}', u'\u22d3': '$\\Cup$', u'\u21d5': '$\\Updownarrow$', u'\U0001d6db': '$\\partial$', u'\U0001d5dd': '$\\mathsfbf{J}$', u'\U0001d45c': '$\\mathsl{o}$', u'\u2766': '{\\ding{166}}', u'\u2268': '$\\lneqq$', u'\u016a': '{\\={U}}', u'\U0001d7f1': '$\\mathsfbf{5}$', u'\U0001d670': '$\\mathtt{A}$', u'\U0001d572': '$\\mathslbb{G}$', u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', u'\xff': '{\\"{y}}', u'\U0001d407': '$\\mathbf{H}$', u'\U0001d786': '$\\mathsfbf{\\Chi}$', u'\u2711': '{\\ding{49}}', u'\u2213': '$\\mp$', u'\u2115': '$\\mathbb{N}$', u'\u0118': '{\\k{E}}', u'\U0001d61b': '$\\mathsfsl{T}$', u'\U0001d49c': '$\\mathscr{A}$', u'\u2925': '$\\ElsevierGlyph{E20B}$', u'\u0427': '{\\cyrchar\\CYRCH}', u'\u2270': '$\\not\\leq$', u'\u2329': '$\\langle$', u'\u22a8': '$\\forcesextra$', u'\u21aa': '$\\hookrightarrow$', u'\U0001d731': '$\\mathbit{\\Phi}$', u'\U0001d6b0': '$\\mathbf{\\Iota}$', u'\U0001d5b2': '$\\mathsf{S}$', u'\u2ab8': '$\\succapprox$', u'\u04bc': '{\\cyrchar\\CYRABHCH}', u'\u03be': '$\\xi$', u'\U0001d447': '$\\mathsl{T}$', u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', u'\u2751': '{\\ding{113}}', u'\u2253': '$\\risingdotseq$', u'\u25d2': '$\\Elzcirfb$', u'\u2155': '$\\textfrac{1}{5}$', u'\xd4': '{\\^{O}}', u'\U0001d65b': '$\\mathsfbfsl{f}$', u'\U0001d55d': '$\\mathbb{l}$', u'\U0001d4dc': '$\\mathmit{M}$', u'\u2a63': '$\\ElsevierGlyph{225A}$', u'\u2467': '{\\ding{179}}', u'\U0001d7d0': '$\\mathbf{2}$', u'\u22e8': '$\\precedesnotsimilar$', u'\U0001d771': '$\\mathsfbf{\\Beta}$', u'\U0001d6f0': '$O$', u'\U0001d5f2': '$\\mathsfbf{e}$', u'\U0001d587': '$\\mathslbb{b}$', u'\U0001d606': '$\\mathsfbf{y}$', u'\u300a': '$\\ElsevierGlyph{300A}$', u'\u2710': '{\\ding{48}}', u'\u0393': '$\\Gamma$', u'\u0412': '{\\cyrchar\\CYRV}', u'\u0114': '{\\u{E}}', u'\U0001d79b': '$M$', u'\U0001d51c': '$\\mathfrak{Y}$', u'\u2924': '$\\ElsevierGlyph{E20D}$', u'\u22a9': '$\\Vdash$', u'\u0328': '{\\k}', u'\U0001d6b1': '$\\mathbf{\\Kappa}$', u'\U0001d730': '$\\mathbit{\\Upsilon}$', u'\U0001d432': '$\\mathbf{y}$', u'\u2ab9': '$\\precnapprox$', u'\u27bb': '{\\ding{251}}', u'\u04bd': '{\\cyrchar\\cyrabhch}', u'\u21bf': '$\\upharpoonleft$', u'\u223e': '$\\lazysinv$', u'\U0001d5c7': '$\\mathsf{n}$', u'\U0001d646': '$\\mathsfbfsl{K}$', u'\u29cf': '$\\LeftTriangleBar$', u'\u2750': '{\\ding{112}}', u'\u0452': '{\\cyrchar\\cyrdje}', u'\xd5': '{\\~{O}}', u'\u2154': '$\\textfrac{2}{3}$', u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', u'\U0001d7db': '$\\mathbb{3}$', u'\U0001d4dd': '$\\mathmit{N}$', u'\U0001d55c': '$\\mathbb{k}$', u'\u25e7': '$\\Elzsqfl$', u'\u2290': '$\\sqsupset$', u'\u22e9': '$\\succnsim$', u'\U0001d6f1': '$\\mathsl{\\Pi}$', u'\U0001d770': '$\\mathsfbf{\\Alpha}$', u'\U0001d472': '$\\mathbit{K}$', u'\u227e': '$\\precapprox$', u'\ufb03': '{ffi}', u'\U0001d507': '$\\mathfrak{D}$', u'\U0001d686': '$\\mathtt{W}$', u'\u02d9': '{\\textperiodcentered}', u'\u2790': '{\\ding{208}}', u'\u0492': '{\\cyrchar\\CYRGHCRS}', u'\u2015': '{\\rule{1em}{1pt}}', u'\u2194': '$\\leftrightarrow$', u'\U0001d71b': '{\\mathsl{\\varpi}}', u'\U0001d41d': '$\\mathbf{d}$', u'\U0001d59c': '$\\mathslbb{w}$', u'\u2229': '$\\cap$', u'\u03a8': '$\\Psi$', u'\xaa': '{\\textordfeminine}', u'\U0001d631': '$\\mathsfsl{p}$', u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', u'\U0001d4b2': '$\\mathscr{W}$', u'\u273b': '{\\ding{91}}', u'\u043d': '{\\cyrchar\\cyrn}', u'\u25bc': '{\\ding{116}}', u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', u'\u22be': '$\\rightanglearc$', u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', u'\u294f': '$\\RightUpDownVector$', u'\u2651': '{\\capricornus}', u'\u21d4': '$\\Leftrightarrow$', u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', u'\U0001d45d': '$\\mathsl{p}$', u'\U0001d5dc': '$\\mathsfbf{I}$', u'\u2269': '$\\gneqq$', u'\xea': '{\\^{e}}', u'\U0001d671': '$\\mathtt{B}$', u'\U0001d7f0': '$\\mathsfbf{4}$', u'\U0001d4f2': '$\\mathmit{i}$', u'\u277b': '{\\ding{187}}', u'\u047d': '{\\cyrchar\\cyromegatitlo}'} +unicode_map = {u'\xa0': '$~$', +u'\xa1': '{\\textexclamdown}', +u'\xa2': '{\\textcent}', +u'\xa3': '{\\textsterling}', +u'\xa4': '{\\textcurrency}', +u'\xa5': '{\\textyen}', +u'\xa6': '{\\textbrokenbar}', +u'\xa7': '{\\textsection}', +u'\xa8': '{\\textasciidieresis}', +u'\xa9': '{\\textcopyright}', +u'\xaa': '{\\textordfeminine}', +u'\xab': '{\\guillemotleft}', +u'\xac': '$\\lnot$', +u'\xad': '$\\-$', +u'\xae': '{\\textregistered}', +u'\xaf': '{\\textasciimacron}', +u'\xb0': '{\\textdegree}', +u'\xb1': '$\\pm$', +u'\xb2': '${^2}$', +u'\xb3': '${^3}$', +u'\xb4': '{\\textasciiacute}', +u'\xb5': '$\\mathrm{\\mu}$', +u'\xb6': '{\\textparagraph}', +u'\xb7': '$\\cdot$', +u'\xb8': '{\\c{}}', +u'\xb9': '${^1}$', +u'\xba': '{\\textordmasculine}', +u'\xbb': '{\\guillemotright}', +u'\xbc': '{\\textonequarter}', +u'\xbd': '{\\textonehalf}', +u'\xbe': '{\\textthreequarters}', +u'\xbf': '{\\textquestiondown}', +u'\xc0': '{\\`{A}}', +u'\xc1': "{\\'{A}}", +u'\xc2': '{\\^{A}}', +u'\xc3': '{\\~{A}}', +u'\xc4': '{\\"{A}}', +u'\xc5': '{\\AA}', +u'\xc6': '{\\AE}', +u'\xc7': '{\\c{C}}', +u'\xc8': '{\\`{E}}', +u'\xc9': "{\\'{E}}", +u'\xca': '{\\^{E}}', +u'\xcb': '{\\"{E}}', +u'\xcc': '{\\`{I}}', +u'\xcd': "{\\'{I}}", +u'\xce': '{\\^{I}}', +u'\xcf': '{\\"{I}}', +u'\xd0': '{\\DH}', +u'\xd1': '{\\~{N}}', +u'\xd2': '{\\`{O}}', +u'\xd3': "{\\'{O}}", +u'\xd4': '{\\^{O}}', +u'\xd5': '{\\~{O}}', +u'\xd6': '{\\"{O}}', +u'\xd7': '{\\texttimes}', +u'\xd8': '{\\O}', +u'\xd9': '{\\`{U}}', +u'\xda': "{\\'{U}}", +u'\xdb': '{\\^{U}}', +u'\xdc': '{\\"{U}}', +u'\xdd': "{\\'{Y}}", +u'\xde': '{\\TH}', +u'\xdf': '{\\ss}', +u'\xe0': '{\\`{a}}', +u'\xe1': "{\\'{a}}", +u'\xe2': '{\\^{a}}', +u'\xe3': '{\\~{a}}', +u'\xe4': '{\\"{a}}', +u'\xe5': '{\\aa}', +u'\xe6': '{\\ae}', +u'\xe7': '{\\c{c}}', +u'\xe8': '{\\`{e}}', +u'\xe9': "{\\'{e}}", +u'\xea': '{\\^{e}}', +u'\xeb': '{\\"{e}}', +u'\xec': '{\\`{\\i}}', +u'\xed': "{\\'{\\i}}", +u'\xee': '{\\^{\\i}}', +u'\xef': '{\\"{\\i}}', +u'\xf0': '{\\dh}', +u'\xf1': '{\\~{n}}', +u'\xf2': '{\\`{o}}', +u'\xf3': "{\\'{o}}", +u'\xf4': '{\\^{o}}', +u'\xf5': '{\\~{o}}', +u'\xf6': '{\\"{o}}', +u'\xf7': '$\\div$', +u'\xf8': '{\\o}', +u'\xf9': '{\\`{u}}', +u'\xfa': "{\\'{u}}", +u'\xfb': '{\\^{u}}', +u'\xfc': '{\\"{u}}', +u'\xfd': "{\\'{y}}", +u'\xfe': '{\\th}', +u'\xff': '{\\"{y}}', +u'\u0100': '{\\={A}}', +u'\u0101': '{\\={a}}', +u'\u0102': '{\\u{A}}', +u'\u0103': '{\\u{a}}', +u'\u0104': '{\\k{A}}', +u'\u0105': '{\\k{a}}', +u'\u0106': "{\\'{C}}", +u'\u0107': "{\\'{c}}", +u'\u0108': '{\\^{C}}', +u'\u0109': '{\\^{c}}', +u'\u010a': '{\\.{C}}', +u'\u010b': '{\\.{c}}', +u'\u010c': '{\\v{C}}', +u'\u010d': '{\\v{c}}', +u'\u010e': '{\\v{D}}', +u'\u010f': '{\\v{d}}', +u'\u0110': '{\\DJ}', +u'\u0111': '{\\dj}', +u'\u0112': '{\\={E}}', +u'\u0113': '{\\={e}}', +u'\u0114': '{\\u{E}}', +u'\u0115': '{\\u{e}}', +u'\u0116': '{\\.{E}}', +u'\u0117': '{\\.{e}}', +u'\u0118': '{\\k{E}}', +u'\u0119': '{\\k{e}}', +u'\u011a': '{\\v{E}}', +u'\u011b': '{\\v{e}}', +u'\u011c': '{\\^{G}}', +u'\u011d': '{\\^{g}}', +u'\u011e': '{\\u{G}}', +u'\u011f': '{\\u{g}}', +u'\u0120': '{\\.{G}}', +u'\u0121': '{\\.{g}}', +u'\u0122': '{\\c{G}}', +u'\u0123': '{\\c{g}}', +u'\u0124': '{\\^{H}}', +u'\u0125': '{\\^{h}}', +u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', +u'\u0127': '$\\Elzxh$', +u'\u0128': '{\\~{I}}', +u'\u0129': '{\\~{\\i}}', +u'\u012a': '{\\={I}}', +u'\u012b': '{\\={\\i}}', +u'\u012c': '{\\u{I}}', +u'\u012d': '{\\u{\\i}}', +u'\u012e': '{\\k{I}}', +u'\u012f': '{\\k{i}}', +u'\u0130': '{\\.{I}}', +u'\u0131': '{\\i}', +u'\u0132': '{IJ}', +u'\u0133': '{ij}', +u'\u0134': '{\\^{J}}', +u'\u0135': '{\\^{\\j}}', +u'\u0136': '{\\c{K}}', +u'\u0137': '{\\c{k}}', +u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', +u'\u0139': "{\\'{L}}", +u'\u013a': "{\\'{l}}", +u'\u013b': '{\\c{L}}', +u'\u013c': '{\\c{l}}', +u'\u013d': '{\\v{L}}', +u'\u013e': '{\\v{l}}', +u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', +u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', +u'\u0141': '{\\L}', +u'\u0142': '{\\l}', +u'\u0143': "{\\'{N}}", +u'\u0144': "{\\'{n}}", +u'\u0145': '{\\c{N}}', +u'\u0146': '{\\c{n}}', +u'\u0147': '{\\v{N}}', +u'\u0148': '{\\v{n}}', +u'\u0149': "{'n}", +u'\u014a': '{\\NG}', +u'\u014b': '{\\ng}', +u'\u014c': '{\\={O}}', +u'\u014d': '{\\={o}}', +u'\u014e': '{\\u{O}}', +u'\u014f': '{\\u{o}}', +u'\u0150': '{\\H{O}}', +u'\u0151': '{\\H{o}}', +u'\u0152': '{\\OE}', +u'\u0153': '{\\oe}', +u'\u0154': "{\\'{R}}", +u'\u0155': "{\\'{r}}", +u'\u0156': '{\\c{R}}', +u'\u0157': '{\\c{r}}', +u'\u0158': '{\\v{R}}', +u'\u0159': '{\\v{r}}', +u'\u015a': "{\\'{S}}", +u'\u015b': "{\\'{s}}", +u'\u015c': '{\\^{S}}', +u'\u015d': '{\\^{s}}', +u'\u015e': '{\\c{S}}', +u'\u015f': '{\\c{s}}', +u'\u0160': '{\\v{S}}', +u'\u0161': '{\\v{s}}', +u'\u0162': '{\\c{T}}', +u'\u0163': '{\\c{t}}', +u'\u0164': '{\\v{T}}', +u'\u0165': '{\\v{t}}', +u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', +u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', +u'\u0168': '{\\~{U}}', +u'\u0169': '{\\~{u}}', +u'\u016a': '{\\={U}}', +u'\u016b': '{\\={u}}', +u'\u016c': '{\\u{U}}', +u'\u016d': '{\\u{u}}', +u'\u016e': '{\\r{U}}', +u'\u016f': '{\\r{u}}', +u'\u0170': '{\\H{U}}', +u'\u0171': '{\\H{u}}', +u'\u0172': '{\\k{U}}', +u'\u0173': '{\\k{u}}', +u'\u0174': '{\\^{W}}', +u'\u0175': '{\\^{w}}', +u'\u0176': '{\\^{Y}}', +u'\u0177': '{\\^{y}}', +u'\u0178': '{\\"{Y}}', +u'\u0179': "{\\'{Z}}", +u'\u017a': "{\\'{z}}", +u'\u017b': '{\\.{Z}}', +u'\u017c': '{\\.{z}}', +u'\u017d': '{\\v{Z}}', +u'\u017e': '{\\v{z}}', +u'\u0192': '$f$', +u'\u0195': '{\\texthvlig}', +u'\u019e': '{\\textnrleg}', +u'\u01aa': '$\\eth$', +u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', +u'\u01c2': '{\\textdoublepipe}', +u'\u01f5': "{\\'{g}}", +u'\u0250': '$\\Elztrna$', +u'\u0252': '$\\Elztrnsa$', +u'\u0254': '$\\Elzopeno$', +u'\u0256': '$\\Elzrtld$', +u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', +u'\u0259': '$\\Elzschwa$', +u'\u025b': '$\\varepsilon$', +u'\u0261': '{g}', +u'\u0263': '$\\Elzpgamma$', +u'\u0264': '$\\Elzpbgam$', +u'\u0265': '$\\Elztrnh$', +u'\u026c': '$\\Elzbtdl$', +u'\u026d': '$\\Elzrtll$', +u'\u026f': '$\\Elztrnm$', +u'\u0270': '$\\Elztrnmlr$', +u'\u0271': '$\\Elzltlmr$', +u'\u0272': '{\\Elzltln}', +u'\u0273': '$\\Elzrtln$', +u'\u0277': '$\\Elzclomeg$', +u'\u0278': '{\\textphi}', +u'\u0279': '$\\Elztrnr$', +u'\u027a': '$\\Elztrnrl$', +u'\u027b': '$\\Elzrttrnr$', +u'\u027c': '$\\Elzrl$', +u'\u027d': '$\\Elzrtlr$', +u'\u027e': '$\\Elzfhr$', +u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', +u'\u0282': '$\\Elzrtls$', +u'\u0283': '$\\Elzesh$', +u'\u0287': '$\\Elztrnt$', +u'\u0288': '$\\Elzrtlt$', +u'\u028a': '$\\Elzpupsil$', +u'\u028b': '$\\Elzpscrv$', +u'\u028c': '$\\Elzinvv$', +u'\u028d': '$\\Elzinvw$', +u'\u028e': '$\\Elztrny$', +u'\u0290': '$\\Elzrtlz$', +u'\u0292': '$\\Elzyogh$', +u'\u0294': '$\\Elzglst$', +u'\u0295': '$\\Elzreglst$', +u'\u0296': '$\\Elzinglst$', +u'\u029e': '{\\textturnk}', +u'\u02a4': '$\\Elzdyogh$', +u'\u02a7': '$\\Elztesh$', +u'\u02bc': "{'}", +u'\u02c7': '{\\textasciicaron}', +u'\u02c8': '$\\Elzverts$', +u'\u02cc': '$\\Elzverti$', +u'\u02d0': '$\\Elzlmrk$', +u'\u02d1': '$\\Elzhlmrk$', +u'\u02d2': '$\\Elzsbrhr$', +u'\u02d3': '$\\Elzsblhr$', +u'\u02d4': '$\\Elzrais$', +u'\u02d5': '$\\Elzlow$', +u'\u02d8': '{\\textasciibreve}', +u'\u02d9': '{\\textperiodcentered}', +u'\u02da': '{\\r{}}', +u'\u02db': '{\\k{}}', +u'\u02dc': '{\\texttildelow}', +u'\u02dd': '{\\H{}}', +u'\u02e5': '{\\tone{55}}', +u'\u02e6': '{\\tone{44}}', +u'\u02e7': '{\\tone{33}}', +u'\u02e8': '{\\tone{22}}', +u'\u02e9': '{\\tone{11}}', +u'\u0300': '{\\`}', +u'\u0301': "{\\'}", +u'\u0302': '{\\^}', +u'\u0303': '{\\~}', +u'\u0304': '{\\=}', +u'\u0306': '{\\u}', +u'\u0307': '{\\.}', +u'\u0308': '{\\"}', +u'\u030a': '{\\r}', +u'\u030b': '{\\H}', +u'\u030c': '{\\v}', +u'\u030f': '{\\cyrchar\\C}', +u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', +u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', +u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', +u'\u0321': '$\\Elzpalh$', +u'\u0322': '{\\Elzrh}', +u'\u0327': '{\\c}', +u'\u0328': '{\\k}', +u'\u032a': '$\\Elzsbbrg$', +u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', +u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', +u'\u0335': '{\\Elzxl}', +u'\u0336': '{\\Elzbar}', +u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', +u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', +u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', +u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', +u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', +u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', +u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', +u'\u0386': "{\\'{A}}", +u'\u0388': "{\\'{E}}", +u'\u0389': "{\\'{H}}", +u'\u038a': "{\\'{}{I}}", +u'\u038c': "{\\'{}O}", +u'\u038e': "$\\mathrm{'Y}$", +u'\u038f': "$\\mathrm{'\\Omega}$", +u'\u0390': '$\\acute{\\ddot{\\iota}}$', +u'\u0391': '$\\Alpha$', +u'\u0392': '$\\Beta$', +u'\u0393': '$\\Gamma$', +u'\u0394': '$\\Delta$', +u'\u0395': '$\\Epsilon$', +u'\u0396': '$\\Zeta$', +u'\u0397': '$\\Eta$', +u'\u0398': '$\\Theta$', +u'\u0399': '$\\Iota$', +u'\u039a': '$\\Kappa$', +u'\u039b': '$\\Lambda$', +u'\u039c': '$M$', +u'\u039d': '$N$', +u'\u039e': '$\\Xi$', +u'\u039f': '$O$', +u'\u03a0': '$\\Pi$', +u'\u03a1': '$\\Rho$', +u'\u03a3': '$\\Sigma$', +u'\u03a4': '$\\Tau$', +u'\u03a5': '$\\Upsilon$', +u'\u03a6': '$\\Phi$', +u'\u03a7': '$\\Chi$', +u'\u03a8': '$\\Psi$', +u'\u03a9': '$\\Omega$', +u'\u03aa': '$\\mathrm{\\ddot{I}}$', +u'\u03ab': '$\\mathrm{\\ddot{Y}}$', +u'\u03ac': "{\\'{$\\alpha$}}", +u'\u03ad': '$\\acute{\\epsilon}$', +u'\u03ae': '$\\acute{\\eta}$', +u'\u03af': '$\\acute{\\iota}$', +u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', +u'\u03b1': '$\\alpha$', +u'\u03b2': '$\\beta$', +u'\u03b3': '$\\gamma$', +u'\u03b4': '$\\delta$', +u'\u03b5': '$\\epsilon$', +u'\u03b6': '$\\zeta$', +u'\u03b7': '$\\eta$', +u'\u03b8': '{\\texttheta}', +u'\u03b9': '$\\iota$', +u'\u03ba': '$\\kappa$', +u'\u03bb': '$\\lambda$', +u'\u03bc': '$\\mu$', +u'\u03bd': '$\\nu$', +u'\u03be': '$\\xi$', +u'\u03bf': '$o$', +u'\u03c0': '$\\pi$', +u'\u03c1': '$\\rho$', +u'\u03c2': '$\\varsigma$', +u'\u03c3': '$\\sigma$', +u'\u03c4': '$\\tau$', +u'\u03c5': '$\\upsilon$', +u'\u03c6': '$\\varphi$', +u'\u03c7': '$\\chi$', +u'\u03c8': '$\\psi$', +u'\u03c9': '$\\omega$', +u'\u03ca': '$\\ddot{\\iota}$', +u'\u03cb': '$\\ddot{\\upsilon}$', +u'\u03cc': "{\\'{o}}", +u'\u03cd': '$\\acute{\\upsilon}$', +u'\u03ce': '$\\acute{\\omega}$', +u'\u03d0': '{\\Pisymbol{ppi022}{87}}', +u'\u03d1': '{\\textvartheta}', +u'\u03d2': '$\\Upsilon$', +u'\u03d5': '$\\phi$', +u'\u03d6': '$\\varpi$', +u'\u03da': '$\\Stigma$', +u'\u03dc': '$\\Digamma$', +u'\u03dd': '$\\digamma$', +u'\u03de': '$\\Koppa$', +u'\u03e0': '$\\Sampi$', +u'\u03f0': '$\\varkappa$', +u'\u03f1': '$\\varrho$', +u'\u03f4': '{\\textTheta}', +u'\u03f6': '$\\backepsilon$', +u'\u0401': '{\\cyrchar\\CYRYO}', +u'\u0402': '{\\cyrchar\\CYRDJE}', +u'\u0403': "{\\cyrchar{\\'\\CYRG}}", +u'\u0404': '{\\cyrchar\\CYRIE}', +u'\u0405': '{\\cyrchar\\CYRDZE}', +u'\u0406': '{\\cyrchar\\CYRII}', +u'\u0407': '{\\cyrchar\\CYRYI}', +u'\u0408': '{\\cyrchar\\CYRJE}', +u'\u0409': '{\\cyrchar\\CYRLJE}', +u'\u040a': '{\\cyrchar\\CYRNJE}', +u'\u040b': '{\\cyrchar\\CYRTSHE}', +u'\u040c': "{\\cyrchar{\\'\\CYRK}}", +u'\u040e': '{\\cyrchar\\CYRUSHRT}', +u'\u040f': '{\\cyrchar\\CYRDZHE}', +u'\u0410': '{\\cyrchar\\CYRA}', +u'\u0411': '{\\cyrchar\\CYRB}', +u'\u0412': '{\\cyrchar\\CYRV}', +u'\u0413': '{\\cyrchar\\CYRG}', +u'\u0414': '{\\cyrchar\\CYRD}', +u'\u0415': '{\\cyrchar\\CYRE}', +u'\u0416': '{\\cyrchar\\CYRZH}', +u'\u0417': '{\\cyrchar\\CYRZ}', +u'\u0418': '{\\cyrchar\\CYRI}', +u'\u0419': '{\\cyrchar\\CYRISHRT}', +u'\u041a': '{\\cyrchar\\CYRK}', +u'\u041b': '{\\cyrchar\\CYRL}', +u'\u041c': '{\\cyrchar\\CYRM}', +u'\u041d': '{\\cyrchar\\CYRN}', +u'\u041e': '{\\cyrchar\\CYRO}', +u'\u041f': '{\\cyrchar\\CYRP}', +u'\u0420': '{\\cyrchar\\CYRR}', +u'\u0421': '{\\cyrchar\\CYRS}', +u'\u0422': '{\\cyrchar\\CYRT}', +u'\u0423': '{\\cyrchar\\CYRU}', +u'\u0424': '{\\cyrchar\\CYRF}', +u'\u0425': '{\\cyrchar\\CYRH}', +u'\u0426': '{\\cyrchar\\CYRC}', +u'\u0427': '{\\cyrchar\\CYRCH}', +u'\u0428': '{\\cyrchar\\CYRSH}', +u'\u0429': '{\\cyrchar\\CYRSHCH}', +u'\u042a': '{\\cyrchar\\CYRHRDSN}', +u'\u042b': '{\\cyrchar\\CYRERY}', +u'\u042c': '{\\cyrchar\\CYRSFTSN}', +u'\u042d': '{\\cyrchar\\CYREREV}', +u'\u042e': '{\\cyrchar\\CYRYU}', +u'\u042f': '{\\cyrchar\\CYRYA}', +u'\u0430': '{\\cyrchar\\cyra}', +u'\u0431': '{\\cyrchar\\cyrb}', +u'\u0432': '{\\cyrchar\\cyrv}', +u'\u0433': '{\\cyrchar\\cyrg}', +u'\u0434': '{\\cyrchar\\cyrd}', +u'\u0435': '{\\cyrchar\\cyre}', +u'\u0436': '{\\cyrchar\\cyrzh}', +u'\u0437': '{\\cyrchar\\cyrz}', +u'\u0438': '{\\cyrchar\\cyri}', +u'\u0439': '{\\cyrchar\\cyrishrt}', +u'\u043a': '{\\cyrchar\\cyrk}', +u'\u043b': '{\\cyrchar\\cyrl}', +u'\u043c': '{\\cyrchar\\cyrm}', +u'\u043d': '{\\cyrchar\\cyrn}', +u'\u043e': '{\\cyrchar\\cyro}', +u'\u043f': '{\\cyrchar\\cyrp}', +u'\u0440': '{\\cyrchar\\cyrr}', +u'\u0441': '{\\cyrchar\\cyrs}', +u'\u0442': '{\\cyrchar\\cyrt}', +u'\u0443': '{\\cyrchar\\cyru}', +u'\u0444': '{\\cyrchar\\cyrf}', +u'\u0445': '{\\cyrchar\\cyrh}', +u'\u0446': '{\\cyrchar\\cyrc}', +u'\u0447': '{\\cyrchar\\cyrch}', +u'\u0448': '{\\cyrchar\\cyrsh}', +u'\u0449': '{\\cyrchar\\cyrshch}', +u'\u044a': '{\\cyrchar\\cyrhrdsn}', +u'\u044b': '{\\cyrchar\\cyrery}', +u'\u044c': '{\\cyrchar\\cyrsftsn}', +u'\u044d': '{\\cyrchar\\cyrerev}', +u'\u044e': '{\\cyrchar\\cyryu}', +u'\u044f': '{\\cyrchar\\cyrya}', +u'\u0451': '{\\cyrchar\\cyryo}', +u'\u0452': '{\\cyrchar\\cyrdje}', +u'\u0453': "{\\cyrchar{\\'\\cyrg}}", +u'\u0454': '{\\cyrchar\\cyrie}', +u'\u0455': '{\\cyrchar\\cyrdze}', +u'\u0456': '{\\cyrchar\\cyrii}', +u'\u0457': '{\\cyrchar\\cyryi}', +u'\u0458': '{\\cyrchar\\cyrje}', +u'\u0459': '{\\cyrchar\\cyrlje}', +u'\u045a': '{\\cyrchar\\cyrnje}', +u'\u045b': '{\\cyrchar\\cyrtshe}', +u'\u045c': "{\\cyrchar{\\'\\cyrk}}", +u'\u045e': '{\\cyrchar\\cyrushrt}', +u'\u045f': '{\\cyrchar\\cyrdzhe}', +u'\u0460': '{\\cyrchar\\CYROMEGA}', +u'\u0461': '{\\cyrchar\\cyromega}', +u'\u0462': '{\\cyrchar\\CYRYAT}', +u'\u0464': '{\\cyrchar\\CYRIOTE}', +u'\u0465': '{\\cyrchar\\cyriote}', +u'\u0466': '{\\cyrchar\\CYRLYUS}', +u'\u0467': '{\\cyrchar\\cyrlyus}', +u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', +u'\u0469': '{\\cyrchar\\cyriotlyus}', +u'\u046a': '{\\cyrchar\\CYRBYUS}', +u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', +u'\u046d': '{\\cyrchar\\cyriotbyus}', +u'\u046e': '{\\cyrchar\\CYRKSI}', +u'\u046f': '{\\cyrchar\\cyrksi}', +u'\u0470': '{\\cyrchar\\CYRPSI}', +u'\u0471': '{\\cyrchar\\cyrpsi}', +u'\u0472': '{\\cyrchar\\CYRFITA}', +u'\u0474': '{\\cyrchar\\CYRIZH}', +u'\u0478': '{\\cyrchar\\CYRUK}', +u'\u0479': '{\\cyrchar\\cyruk}', +u'\u047a': '{\\cyrchar\\CYROMEGARND}', +u'\u047b': '{\\cyrchar\\cyromegarnd}', +u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', +u'\u047d': '{\\cyrchar\\cyromegatitlo}', +u'\u047e': '{\\cyrchar\\CYROT}', +u'\u047f': '{\\cyrchar\\cyrot}', +u'\u0480': '{\\cyrchar\\CYRKOPPA}', +u'\u0481': '{\\cyrchar\\cyrkoppa}', +u'\u0482': '{\\cyrchar\\cyrthousands}', +u'\u0488': '{\\cyrchar\\cyrhundredthousands}', +u'\u0489': '{\\cyrchar\\cyrmillions}', +u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', +u'\u048d': '{\\cyrchar\\cyrsemisftsn}', +u'\u048e': '{\\cyrchar\\CYRRTICK}', +u'\u048f': '{\\cyrchar\\cyrrtick}', +u'\u0490': '{\\cyrchar\\CYRGUP}', +u'\u0491': '{\\cyrchar\\cyrgup}', +u'\u0492': '{\\cyrchar\\CYRGHCRS}', +u'\u0493': '{\\cyrchar\\cyrghcrs}', +u'\u0494': '{\\cyrchar\\CYRGHK}', +u'\u0495': '{\\cyrchar\\cyrghk}', +u'\u0496': '{\\cyrchar\\CYRZHDSC}', +u'\u0497': '{\\cyrchar\\cyrzhdsc}', +u'\u0498': '{\\cyrchar\\CYRZDSC}', +u'\u0499': '{\\cyrchar\\cyrzdsc}', +u'\u049a': '{\\cyrchar\\CYRKDSC}', +u'\u049b': '{\\cyrchar\\cyrkdsc}', +u'\u049c': '{\\cyrchar\\CYRKVCRS}', +u'\u049d': '{\\cyrchar\\cyrkvcrs}', +u'\u049e': '{\\cyrchar\\CYRKHCRS}', +u'\u049f': '{\\cyrchar\\cyrkhcrs}', +u'\u04a0': '{\\cyrchar\\CYRKBEAK}', +u'\u04a1': '{\\cyrchar\\cyrkbeak}', +u'\u04a2': '{\\cyrchar\\CYRNDSC}', +u'\u04a3': '{\\cyrchar\\cyrndsc}', +u'\u04a4': '{\\cyrchar\\CYRNG}', +u'\u04a5': '{\\cyrchar\\cyrng}', +u'\u04a6': '{\\cyrchar\\CYRPHK}', +u'\u04a7': '{\\cyrchar\\cyrphk}', +u'\u04a8': '{\\cyrchar\\CYRABHHA}', +u'\u04a9': '{\\cyrchar\\cyrabhha}', +u'\u04aa': '{\\cyrchar\\CYRSDSC}', +u'\u04ab': '{\\cyrchar\\cyrsdsc}', +u'\u04ac': '{\\cyrchar\\CYRTDSC}', +u'\u04ad': '{\\cyrchar\\cyrtdsc}', +u'\u04ae': '{\\cyrchar\\CYRY}', +u'\u04af': '{\\cyrchar\\cyry}', +u'\u04b0': '{\\cyrchar\\CYRYHCRS}', +u'\u04b1': '{\\cyrchar\\cyryhcrs}', +u'\u04b2': '{\\cyrchar\\CYRHDSC}', +u'\u04b3': '{\\cyrchar\\cyrhdsc}', +u'\u04b4': '{\\cyrchar\\CYRTETSE}', +u'\u04b5': '{\\cyrchar\\cyrtetse}', +u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', +u'\u04b7': '{\\cyrchar\\cyrchrdsc}', +u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', +u'\u04b9': '{\\cyrchar\\cyrchvcrs}', +u'\u04ba': '{\\cyrchar\\CYRSHHA}', +u'\u04bb': '{\\cyrchar\\cyrshha}', +u'\u04bc': '{\\cyrchar\\CYRABHCH}', +u'\u04bd': '{\\cyrchar\\cyrabhch}', +u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', +u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', +u'\u04c0': '{\\cyrchar\\CYRpalochka}', +u'\u04c3': '{\\cyrchar\\CYRKHK}', +u'\u04c4': '{\\cyrchar\\cyrkhk}', +u'\u04c7': '{\\cyrchar\\CYRNHK}', +u'\u04c8': '{\\cyrchar\\cyrnhk}', +u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', +u'\u04cc': '{\\cyrchar\\cyrchldsc}', +u'\u04d4': '{\\cyrchar\\CYRAE}', +u'\u04d5': '{\\cyrchar\\cyrae}', +u'\u04d8': '{\\cyrchar\\CYRSCHWA}', +u'\u04d9': '{\\cyrchar\\cyrschwa}', +u'\u04e0': '{\\cyrchar\\CYRABHDZE}', +u'\u04e1': '{\\cyrchar\\cyrabhdze}', +u'\u04e8': '{\\cyrchar\\CYROTLD}', +u'\u04e9': '{\\cyrchar\\cyrotld}', +u'\u2002': '{\\hspace{0.6em}}', +u'\u2003': '{\\hspace{1em}}', +u'\u2004': '{\\hspace{0.33em}}', +u'\u2005': '{\\hspace{0.25em}}', +u'\u2006': '{\\hspace{0.166em}}', +u'\u2007': '{\\hphantom{0}}', +u'\u2008': '{\\hphantom{,}}', +u'\u2009': '{\\hspace{0.167em}}', +u'\u200a': '$\\mkern1mu$', +u'\u2010': '{-}', +u'\u2013': '{\\textendash}', +u'\u2014': '{\\textemdash}', +u'\u2015': '{\\rule{1em}{1pt}}', +u'\u2016': '$\\Vert$', +u'\u2018': '{`}', +u'\u2019': "{'}", +u'\u201a': '{,}', +u'\u201b': '$\\Elzreapos$', +u'\u201c': '{\\textquotedblleft}', +u'\u201d': '{\\textquotedblright}', +u'\u201e': '{,,}', +u'\u2020': '{\\textdagger}', +u'\u2021': '{\\textdaggerdbl}', +u'\u2022': '{\\textbullet}', +u'\u2024': '{.}', +u'\u2025': '{..}', +u'\u2026': '{\\ldots}', +u'\u2030': '{\\textperthousand}', +u'\u2031': '{\\textpertenthousand}', +u'\u2032': "${'}$", +u'\u2033': "${''}$", +u'\u2034': "${'''}$", +u'\u2035': '$\\backprime$', +u'\u2039': '{\\guilsinglleft}', +u'\u203a': '{\\guilsinglright}', +u'\u2057': "$''''$", +u'\u205f': '{\\mkern4mu}', +u'\u2060': '{\\nolinebreak}', +u'\u20a7': '{\\ensuremath{\\Elzpes}}', +u'\u20ac': '{\\mbox{\\texteuro}}', +u'\u20db': '$\\dddot$', +u'\u20dc': '$\\ddddot$', +u'\u2102': '$\\mathbb{C}$', +u'\u210a': '{\\mathscr{g}}', +u'\u210b': '$\\mathscr{H}$', +u'\u210c': '$\\mathfrak{H}$', +u'\u210d': '$\\mathbb{H}$', +u'\u210f': '$\\hslash$', +u'\u2110': '$\\mathscr{I}$', +u'\u2111': '$\\mathfrak{I}$', +u'\u2112': '$\\mathscr{L}$', +u'\u2113': '$\\mathscr{l}$', +u'\u2115': '$\\mathbb{N}$', +u'\u2116': '{\\cyrchar\\textnumero}', +u'\u2118': '$\\wp$', +u'\u2119': '$\\mathbb{P}$', +u'\u211a': '$\\mathbb{Q}$', +u'\u211b': '$\\mathscr{R}$', +u'\u211c': '$\\mathfrak{R}$', +u'\u211d': '$\\mathbb{R}$', +u'\u211e': '$\\Elzxrat$', +u'\u2122': '{\\texttrademark}', +u'\u2124': '$\\mathbb{Z}$', +u'\u2126': '$\\Omega$', +u'\u2127': '$\\mho$', +u'\u2128': '$\\mathfrak{Z}$', +u'\u2129': '$\\ElsevierGlyph{2129}$', +u'\u212b': '{\\AA}', +u'\u212c': '$\\mathscr{B}$', +u'\u212d': '$\\mathfrak{C}$', +u'\u212f': '$\\mathscr{e}$', +u'\u2130': '$\\mathscr{E}$', +u'\u2131': '$\\mathscr{F}$', +u'\u2133': '$\\mathscr{M}$', +u'\u2134': '$\\mathscr{o}$', +u'\u2135': '$\\aleph$', +u'\u2136': '$\\beth$', +u'\u2137': '$\\gimel$', +u'\u2138': '$\\daleth$', +u'\u2153': '$\\textfrac{1}{3}$', +u'\u2154': '$\\textfrac{2}{3}$', +u'\u2155': '$\\textfrac{1}{5}$', +u'\u2156': '$\\textfrac{2}{5}$', +u'\u2157': '$\\textfrac{3}{5}$', +u'\u2158': '$\\textfrac{4}{5}$', +u'\u2159': '$\\textfrac{1}{6}$', +u'\u215a': '$\\textfrac{5}{6}$', +u'\u215b': '$\\textfrac{1}{8}$', +u'\u215c': '$\\textfrac{3}{8}$', +u'\u215d': '$\\textfrac{5}{8}$', +u'\u215e': '$\\textfrac{7}{8}$', +u'\u2190': '$\\leftarrow$', +u'\u2191': '$\\uparrow$', +u'\u2192': '$\\rightarrow$', +u'\u2193': '$\\downarrow$', +u'\u2194': '$\\leftrightarrow$', +u'\u2195': '$\\updownarrow$', +u'\u2196': '$\\nwarrow$', +u'\u2197': '$\\nearrow$', +u'\u2198': '$\\searrow$', +u'\u2199': '$\\swarrow$', +u'\u219a': '$\\nleftarrow$', +u'\u219b': '$\\nrightarrow$', +u'\u219c': '$\\arrowwaveright$', +u'\u219d': '$\\arrowwaveright$', +u'\u219e': '$\\twoheadleftarrow$', +u'\u21a0': '$\\twoheadrightarrow$', +u'\u21a2': '$\\leftarrowtail$', +u'\u21a3': '$\\rightarrowtail$', +u'\u21a6': '$\\mapsto$', +u'\u21a9': '$\\hookleftarrow$', +u'\u21aa': '$\\hookrightarrow$', +u'\u21ab': '$\\looparrowleft$', +u'\u21ac': '$\\looparrowright$', +u'\u21ad': '$\\leftrightsquigarrow$', +u'\u21ae': '$\\nleftrightarrow$', +u'\u21b0': '$\\Lsh$', +u'\u21b1': '$\\Rsh$', +u'\u21b3': '$\\ElsevierGlyph{21B3}$', +u'\u21b6': '$\\curvearrowleft$', +u'\u21b7': '$\\curvearrowright$', +u'\u21ba': '$\\circlearrowleft$', +u'\u21bb': '$\\circlearrowright$', +u'\u21bc': '$\\leftharpoonup$', +u'\u21bd': '$\\leftharpoondown$', +u'\u21be': '$\\upharpoonright$', +u'\u21bf': '$\\upharpoonleft$', +u'\u21c0': '$\\rightharpoonup$', +u'\u21c1': '$\\rightharpoondown$', +u'\u21c2': '$\\downharpoonright$', +u'\u21c3': '$\\downharpoonleft$', +u'\u21c4': '$\\rightleftarrows$', +u'\u21c5': '$\\dblarrowupdown$', +u'\u21c6': '$\\leftrightarrows$', +u'\u21c7': '$\\leftleftarrows$', +u'\u21c8': '$\\upuparrows$', +u'\u21c9': '$\\rightrightarrows$', +u'\u21ca': '$\\downdownarrows$', +u'\u21cb': '$\\leftrightharpoons$', +u'\u21cc': '$\\rightleftharpoons$', +u'\u21cd': '$\\nLeftarrow$', +u'\u21ce': '$\\nLeftrightarrow$', +u'\u21cf': '$\\nRightarrow$', +u'\u21d0': '$\\Leftarrow$', +u'\u21d1': '$\\Uparrow$', +u'\u21d2': '$\\Rightarrow$', +u'\u21d3': '$\\Downarrow$', +u'\u21d4': '$\\Leftrightarrow$', +u'\u21d5': '$\\Updownarrow$', +u'\u21da': '$\\Lleftarrow$', +u'\u21db': '$\\Rrightarrow$', +u'\u21dd': '$\\rightsquigarrow$', +u'\u21f5': '$\\DownArrowUpArrow$', +u'\u2200': '$\\forall$', +u'\u2201': '$\\complement$', +u'\u2202': '$\\partial$', +u'\u2203': '$\\exists$', +u'\u2204': '$\\nexists$', +u'\u2205': '$\\varnothing$', +u'\u2207': '$\\nabla$', +u'\u2208': '$\\in$', +u'\u2209': '$\\not\\in$', +u'\u220b': '$\\ni$', +u'\u220c': '$\\not\\ni$', +u'\u220f': '$\\prod$', +u'\u2210': '$\\coprod$', +u'\u2211': '$\\sum$', +u'\u2212': '{-}', +u'\u2213': '$\\mp$', +u'\u2214': '$\\dotplus$', +u'\u2216': '$\\setminus$', +u'\u2217': '${_\\ast}$', +u'\u2218': '$\\circ$', +u'\u2219': '$\\bullet$', +u'\u221a': '$\\surd$', +u'\u221d': '$\\propto$', +u'\u221e': '$\\infty$', +u'\u221f': '$\\rightangle$', +u'\u2220': '$\\angle$', +u'\u2221': '$\\measuredangle$', +u'\u2222': '$\\sphericalangle$', +u'\u2223': '$\\mid$', +u'\u2224': '$\\nmid$', +u'\u2225': '$\\parallel$', +u'\u2226': '$\\nparallel$', +u'\u2227': '$\\wedge$', +u'\u2228': '$\\vee$', +u'\u2229': '$\\cap$', +u'\u222a': '$\\cup$', +u'\u222b': '$\\int$', +u'\u222c': '$\\int\\!\\int$', +u'\u222d': '$\\int\\!\\int\\!\\int$', +u'\u222e': '$\\oint$', +u'\u222f': '$\\surfintegral$', +u'\u2230': '$\\volintegral$', +u'\u2231': '$\\clwintegral$', +u'\u2232': '$\\ElsevierGlyph{2232}$', +u'\u2233': '$\\ElsevierGlyph{2233}$', +u'\u2234': '$\\therefore$', +u'\u2235': '$\\because$', +u'\u2237': '$\\Colon$', +u'\u2238': '$\\ElsevierGlyph{2238}$', +u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', +u'\u223b': '$\\homothetic$', +u'\u223c': '$\\sim$', +u'\u223d': '$\\backsim$', +u'\u223e': '$\\lazysinv$', +u'\u2240': '$\\wr$', +u'\u2241': '$\\not\\sim$', +u'\u2242': '$\\ElsevierGlyph{2242}$', +u'\u2243': '$\\simeq$', +u'\u2244': '$\\not\\simeq$', +u'\u2245': '$\\cong$', +u'\u2246': '$\\approxnotequal$', +u'\u2247': '$\\not\\cong$', +u'\u2248': '$\\approx$', +u'\u2249': '$\\not\\approx$', +u'\u224a': '$\\approxeq$', +u'\u224b': '$\\tildetrpl$', +u'\u224c': '$\\allequal$', +u'\u224d': '$\\asymp$', +u'\u224e': '$\\Bumpeq$', +u'\u224f': '$\\bumpeq$', +u'\u2250': '$\\doteq$', +u'\u2251': '$\\doteqdot$', +u'\u2252': '$\\fallingdotseq$', +u'\u2253': '$\\risingdotseq$', +u'\u2254': '{:=}', +u'\u2255': '$=:$', +u'\u2256': '$\\eqcirc$', +u'\u2257': '$\\circeq$', +u'\u2259': '$\\estimates$', +u'\u225a': '$\\ElsevierGlyph{225A}$', +u'\u225b': '$\\starequal$', +u'\u225c': '$\\triangleq$', +u'\u225f': '$\\ElsevierGlyph{225F}$', +u'\u2260': '$\\not =$', +u'\u2261': '$\\equiv$', +u'\u2262': '$\\not\\equiv$', +u'\u2264': '$\\leq$', +u'\u2265': '$\\geq$', +u'\u2266': '$\\leqq$', +u'\u2267': '$\\geqq$', +u'\u2268': '$\\lneqq$', +u'\u2269': '$\\gneqq$', +u'\u226a': '$\\ll$', +u'\u226b': '$\\gg$', +u'\u226c': '$\\between$', +u'\u226d': '$\\not\\kern-0.3em\\times$', +u'\u226e': '$\\not<$', +u'\u226f': '$\\not>$', +u'\u2270': '$\\not\\leq$', +u'\u2271': '$\\not\\geq$', +u'\u2272': '$\\lessequivlnt$', +u'\u2273': '$\\greaterequivlnt$', +u'\u2274': '$\\ElsevierGlyph{2274}$', +u'\u2275': '$\\ElsevierGlyph{2275}$', +u'\u2276': '$\\lessgtr$', +u'\u2277': '$\\gtrless$', +u'\u2278': '$\\notlessgreater$', +u'\u2279': '$\\notgreaterless$', +u'\u227a': '$\\prec$', +u'\u227b': '$\\succ$', +u'\u227c': '$\\preccurlyeq$', +u'\u227d': '$\\succcurlyeq$', +u'\u227e': '$\\precapprox$', +u'\u227f': '$\\succapprox$', +u'\u2280': '$\\not\\prec$', +u'\u2281': '$\\not\\succ$', +u'\u2282': '$\\subset$', +u'\u2283': '$\\supset$', +u'\u2284': '$\\not\\subset$', +u'\u2285': '$\\not\\supset$', +u'\u2286': '$\\subseteq$', +u'\u2287': '$\\supseteq$', +u'\u2288': '$\\not\\subseteq$', +u'\u2289': '$\\not\\supseteq$', +u'\u228a': '$\\subsetneq$', +u'\u228b': '$\\supsetneq$', +u'\u228e': '$\\uplus$', +u'\u228f': '$\\sqsubset$', +u'\u2290': '$\\sqsupset$', +u'\u2291': '$\\sqsubseteq$', +u'\u2292': '$\\sqsupseteq$', +u'\u2293': '$\\sqcap$', +u'\u2294': '$\\sqcup$', +u'\u2295': '$\\oplus$', +u'\u2296': '$\\ominus$', +u'\u2297': '$\\otimes$', +u'\u2298': '$\\oslash$', +u'\u2299': '$\\odot$', +u'\u229a': '$\\circledcirc$', +u'\u229b': '$\\circledast$', +u'\u229d': '$\\circleddash$', +u'\u229e': '$\\boxplus$', +u'\u229f': '$\\boxminus$', +u'\u22a0': '$\\boxtimes$', +u'\u22a1': '$\\boxdot$', +u'\u22a2': '$\\vdash$', +u'\u22a3': '$\\dashv$', +u'\u22a4': '$\\top$', +u'\u22a5': '$\\perp$', +u'\u22a7': '$\\truestate$', +u'\u22a8': '$\\forcesextra$', +u'\u22a9': '$\\Vdash$', +u'\u22aa': '$\\Vvdash$', +u'\u22ab': '$\\VDash$', +u'\u22ac': '$\\nvdash$', +u'\u22ad': '$\\nvDash$', +u'\u22ae': '$\\nVdash$', +u'\u22af': '$\\nVDash$', +u'\u22b2': '$\\vartriangleleft$', +u'\u22b3': '$\\vartriangleright$', +u'\u22b4': '$\\trianglelefteq$', +u'\u22b5': '$\\trianglerighteq$', +u'\u22b6': '$\\original$', +u'\u22b7': '$\\image$', +u'\u22b8': '$\\multimap$', +u'\u22b9': '$\\hermitconjmatrix$', +u'\u22ba': '$\\intercal$', +u'\u22bb': '$\\veebar$', +u'\u22be': '$\\rightanglearc$', +u'\u22c0': '$\\ElsevierGlyph{22C0}$', +u'\u22c1': '$\\ElsevierGlyph{22C1}$', +u'\u22c2': '$\\bigcap$', +u'\u22c3': '$\\bigcup$', +u'\u22c4': '$\\diamond$', +u'\u22c5': '$\\cdot$', +u'\u22c6': '$\\star$', +u'\u22c7': '$\\divideontimes$', +u'\u22c8': '$\\bowtie$', +u'\u22c9': '$\\ltimes$', +u'\u22ca': '$\\rtimes$', +u'\u22cb': '$\\leftthreetimes$', +u'\u22cc': '$\\rightthreetimes$', +u'\u22cd': '$\\backsimeq$', +u'\u22ce': '$\\curlyvee$', +u'\u22cf': '$\\curlywedge$', +u'\u22d0': '$\\Subset$', +u'\u22d1': '$\\Supset$', +u'\u22d2': '$\\Cap$', +u'\u22d3': '$\\Cup$', +u'\u22d4': '$\\pitchfork$', +u'\u22d6': '$\\lessdot$', +u'\u22d7': '$\\gtrdot$', +u'\u22d8': '$\\verymuchless$', +u'\u22d9': '$\\verymuchgreater$', +u'\u22da': '$\\lesseqgtr$', +u'\u22db': '$\\gtreqless$', +u'\u22de': '$\\curlyeqprec$', +u'\u22df': '$\\curlyeqsucc$', +u'\u22e2': '$\\not\\sqsubseteq$', +u'\u22e3': '$\\not\\sqsupseteq$', +u'\u22e5': '$\\Elzsqspne$', +u'\u22e6': '$\\lnsim$', +u'\u22e7': '$\\gnsim$', +u'\u22e8': '$\\precedesnotsimilar$', +u'\u22e9': '$\\succnsim$', +u'\u22ea': '$\\ntriangleleft$', +u'\u22eb': '$\\ntriangleright$', +u'\u22ec': '$\\ntrianglelefteq$', +u'\u22ed': '$\\ntrianglerighteq$', +u'\u22ee': '$\\vdots$', +u'\u22ef': '$\\cdots$', +u'\u22f0': '$\\upslopeellipsis$', +u'\u22f1': '$\\downslopeellipsis$', +u'\u2305': '{\\barwedge}', +u'\u2306': '$\\perspcorrespond$', +u'\u2308': '$\\lceil$', +u'\u2309': '$\\rceil$', +u'\u230a': '$\\lfloor$', +u'\u230b': '$\\rfloor$', +u'\u2315': '$\\recorder$', +u'\u2316': '$\\mathchar"2208$', +u'\u231c': '$\\ulcorner$', +u'\u231d': '$\\urcorner$', +u'\u231e': '$\\llcorner$', +u'\u231f': '$\\lrcorner$', +u'\u2322': '$\\frown$', +u'\u2323': '$\\smile$', +u'\u2329': '$\\langle$', +u'\u232a': '$\\rangle$', +u'\u233d': '$\\ElsevierGlyph{E838}$', +u'\u23a3': '$\\Elzdlcorn$', +u'\u23b0': '$\\lmoustache$', +u'\u23b1': '$\\rmoustache$', +u'\u2423': '{\\textvisiblespace}', +u'\u2460': '{\\ding{172}}', +u'\u2461': '{\\ding{173}}', +u'\u2462': '{\\ding{174}}', +u'\u2463': '{\\ding{175}}', +u'\u2464': '{\\ding{176}}', +u'\u2465': '{\\ding{177}}', +u'\u2466': '{\\ding{178}}', +u'\u2467': '{\\ding{179}}', +u'\u2468': '{\\ding{180}}', +u'\u2469': '{\\ding{181}}', +u'\u24c8': '$\\circledS$', +u'\u2506': '$\\Elzdshfnc$', +u'\u2519': '$\\Elzsqfnw$', +u'\u2571': '$\\diagup$', +u'\u25a0': '{\\ding{110}}', +u'\u25a1': '$\\square$', +u'\u25aa': '$\\blacksquare$', +u'\u25ad': '$\\fbox{~~}$', +u'\u25af': '$\\Elzvrecto$', +u'\u25b1': '$\\ElsevierGlyph{E381}$', +u'\u25b2': '{\\ding{115}}', +u'\u25b3': '$\\bigtriangleup$', +u'\u25b4': '$\\blacktriangle$', +u'\u25b5': '$\\vartriangle$', +u'\u25b8': '$\\blacktriangleright$', +u'\u25b9': '$\\triangleright$', +u'\u25bc': '{\\ding{116}}', +u'\u25bd': '$\\bigtriangledown$', +u'\u25be': '$\\blacktriangledown$', +u'\u25bf': '$\\triangledown$', +u'\u25c2': '$\\blacktriangleleft$', +u'\u25c3': '$\\triangleleft$', +u'\u25c6': '{\\ding{117}}', +u'\u25ca': '$\\lozenge$', +u'\u25cb': '$\\bigcirc$', +u'\u25cf': '{\\ding{108}}', +u'\u25d0': '$\\Elzcirfl$', +u'\u25d1': '$\\Elzcirfr$', +u'\u25d2': '$\\Elzcirfb$', +u'\u25d7': '{\\ding{119}}', +u'\u25d8': '$\\Elzrvbull$', +u'\u25e7': '$\\Elzsqfl$', +u'\u25e8': '$\\Elzsqfr$', +u'\u25ea': '$\\Elzsqfse$', +u'\u25ef': '$\\bigcirc$', +u'\u2605': '{\\ding{72}}', +u'\u2606': '{\\ding{73}}', +u'\u260e': '{\\ding{37}}', +u'\u261b': '{\\ding{42}}', +u'\u261e': '{\\ding{43}}', +u'\u263e': '{\\rightmoon}', +u'\u263f': '{\\mercury}', +u'\u2640': '{\\venus}', +u'\u2642': '{\\male}', +u'\u2643': '{\\jupiter}', +u'\u2644': '{\\saturn}', +u'\u2645': '{\\uranus}', +u'\u2646': '{\\neptune}', +u'\u2647': '{\\pluto}', +u'\u2648': '{\\aries}', +u'\u2649': '{\\taurus}', +u'\u264a': '{\\gemini}', +u'\u264b': '{\\cancer}', +u'\u264c': '{\\leo}', +u'\u264d': '{\\virgo}', +u'\u264e': '{\\libra}', +u'\u264f': '{\\scorpio}', +u'\u2650': '{\\sagittarius}', +u'\u2651': '{\\capricornus}', +u'\u2652': '{\\aquarius}', +u'\u2653': '{\\pisces}', +u'\u2660': '{\\ding{171}}', +u'\u2662': '$\\diamond$', +u'\u2663': '{\\ding{168}}', +u'\u2665': '{\\ding{170}}', +u'\u2666': '{\\ding{169}}', +u'\u2669': '{\\quarternote}', +u'\u266a': '{\\eighthnote}', +u'\u266d': '$\\flat$', +u'\u266e': '$\\natural$', +u'\u266f': '$\\sharp$', +u'\u2701': '{\\ding{33}}', +u'\u2702': '{\\ding{34}}', +u'\u2703': '{\\ding{35}}', +u'\u2704': '{\\ding{36}}', +u'\u2706': '{\\ding{38}}', +u'\u2707': '{\\ding{39}}', +u'\u2708': '{\\ding{40}}', +u'\u2709': '{\\ding{41}}', +u'\u270c': '{\\ding{44}}', +u'\u270d': '{\\ding{45}}', +u'\u270e': '{\\ding{46}}', +u'\u270f': '{\\ding{47}}', +u'\u2710': '{\\ding{48}}', +u'\u2711': '{\\ding{49}}', +u'\u2712': '{\\ding{50}}', +u'\u2713': '{\\ding{51}}', +u'\u2714': '{\\ding{52}}', +u'\u2715': '{\\ding{53}}', +u'\u2716': '{\\ding{54}}', +u'\u2717': '{\\ding{55}}', +u'\u2718': '{\\ding{56}}', +u'\u2719': '{\\ding{57}}', +u'\u271a': '{\\ding{58}}', +u'\u271b': '{\\ding{59}}', +u'\u271c': '{\\ding{60}}', +u'\u271d': '{\\ding{61}}', +u'\u271e': '{\\ding{62}}', +u'\u271f': '{\\ding{63}}', +u'\u2720': '{\\ding{64}}', +u'\u2721': '{\\ding{65}}', +u'\u2722': '{\\ding{66}}', +u'\u2723': '{\\ding{67}}', +u'\u2724': '{\\ding{68}}', +u'\u2725': '{\\ding{69}}', +u'\u2726': '{\\ding{70}}', +u'\u2727': '{\\ding{71}}', +u'\u2729': '{\\ding{73}}', +u'\u272a': '{\\ding{74}}', +u'\u272b': '{\\ding{75}}', +u'\u272c': '{\\ding{76}}', +u'\u272d': '{\\ding{77}}', +u'\u272e': '{\\ding{78}}', +u'\u272f': '{\\ding{79}}', +u'\u2730': '{\\ding{80}}', +u'\u2731': '{\\ding{81}}', +u'\u2732': '{\\ding{82}}', +u'\u2733': '{\\ding{83}}', +u'\u2734': '{\\ding{84}}', +u'\u2735': '{\\ding{85}}', +u'\u2736': '{\\ding{86}}', +u'\u2737': '{\\ding{87}}', +u'\u2738': '{\\ding{88}}', +u'\u2739': '{\\ding{89}}', +u'\u273a': '{\\ding{90}}', +u'\u273b': '{\\ding{91}}', +u'\u273c': '{\\ding{92}}', +u'\u273d': '{\\ding{93}}', +u'\u273e': '{\\ding{94}}', +u'\u273f': '{\\ding{95}}', +u'\u2740': '{\\ding{96}}', +u'\u2741': '{\\ding{97}}', +u'\u2742': '{\\ding{98}}', +u'\u2743': '{\\ding{99}}', +u'\u2744': '{\\ding{100}}', +u'\u2745': '{\\ding{101}}', +u'\u2746': '{\\ding{102}}', +u'\u2747': '{\\ding{103}}', +u'\u2748': '{\\ding{104}}', +u'\u2749': '{\\ding{105}}', +u'\u274a': '{\\ding{106}}', +u'\u274b': '{\\ding{107}}', +u'\u274d': '{\\ding{109}}', +u'\u274f': '{\\ding{111}}', +u'\u2750': '{\\ding{112}}', +u'\u2751': '{\\ding{113}}', +u'\u2752': '{\\ding{114}}', +u'\u2756': '{\\ding{118}}', +u'\u2758': '{\\ding{120}}', +u'\u2759': '{\\ding{121}}', +u'\u275a': '{\\ding{122}}', +u'\u275b': '{\\ding{123}}', +u'\u275c': '{\\ding{124}}', +u'\u275d': '{\\ding{125}}', +u'\u275e': '{\\ding{126}}', +u'\u2761': '{\\ding{161}}', +u'\u2762': '{\\ding{162}}', +u'\u2763': '{\\ding{163}}', +u'\u2764': '{\\ding{164}}', +u'\u2765': '{\\ding{165}}', +u'\u2766': '{\\ding{166}}', +u'\u2767': '{\\ding{167}}', +u'\u2776': '{\\ding{182}}', +u'\u2777': '{\\ding{183}}', +u'\u2778': '{\\ding{184}}', +u'\u2779': '{\\ding{185}}', +u'\u277a': '{\\ding{186}}', +u'\u277b': '{\\ding{187}}', +u'\u277c': '{\\ding{188}}', +u'\u277d': '{\\ding{189}}', +u'\u277e': '{\\ding{190}}', +u'\u277f': '{\\ding{191}}', +u'\u2780': '{\\ding{192}}', +u'\u2781': '{\\ding{193}}', +u'\u2782': '{\\ding{194}}', +u'\u2783': '{\\ding{195}}', +u'\u2784': '{\\ding{196}}', +u'\u2785': '{\\ding{197}}', +u'\u2786': '{\\ding{198}}', +u'\u2787': '{\\ding{199}}', +u'\u2788': '{\\ding{200}}', +u'\u2789': '{\\ding{201}}', +u'\u278a': '{\\ding{202}}', +u'\u278b': '{\\ding{203}}', +u'\u278c': '{\\ding{204}}', +u'\u278d': '{\\ding{205}}', +u'\u278e': '{\\ding{206}}', +u'\u278f': '{\\ding{207}}', +u'\u2790': '{\\ding{208}}', +u'\u2791': '{\\ding{209}}', +u'\u2792': '{\\ding{210}}', +u'\u2793': '{\\ding{211}}', +u'\u2794': '{\\ding{212}}', +u'\u2798': '{\\ding{216}}', +u'\u2799': '{\\ding{217}}', +u'\u279a': '{\\ding{218}}', +u'\u279b': '{\\ding{219}}', +u'\u279c': '{\\ding{220}}', +u'\u279d': '{\\ding{221}}', +u'\u279e': '{\\ding{222}}', +u'\u279f': '{\\ding{223}}', +u'\u27a0': '{\\ding{224}}', +u'\u27a1': '{\\ding{225}}', +u'\u27a2': '{\\ding{226}}', +u'\u27a3': '{\\ding{227}}', +u'\u27a4': '{\\ding{228}}', +u'\u27a5': '{\\ding{229}}', +u'\u27a6': '{\\ding{230}}', +u'\u27a7': '{\\ding{231}}', +u'\u27a8': '{\\ding{232}}', +u'\u27a9': '{\\ding{233}}', +u'\u27aa': '{\\ding{234}}', +u'\u27ab': '{\\ding{235}}', +u'\u27ac': '{\\ding{236}}', +u'\u27ad': '{\\ding{237}}', +u'\u27ae': '{\\ding{238}}', +u'\u27af': '{\\ding{239}}', +u'\u27b1': '{\\ding{241}}', +u'\u27b2': '{\\ding{242}}', +u'\u27b3': '{\\ding{243}}', +u'\u27b4': '{\\ding{244}}', +u'\u27b5': '{\\ding{245}}', +u'\u27b6': '{\\ding{246}}', +u'\u27b7': '{\\ding{247}}', +u'\u27b8': '{\\ding{248}}', +u'\u27b9': '{\\ding{249}}', +u'\u27ba': '{\\ding{250}}', +u'\u27bb': '{\\ding{251}}', +u'\u27bc': '{\\ding{252}}', +u'\u27bd': '{\\ding{253}}', +u'\u27be': '{\\ding{254}}', +u'\u27f5': '$\\longleftarrow$', +u'\u27f6': '$\\longrightarrow$', +u'\u27f7': '$\\longleftrightarrow$', +u'\u27f8': '$\\Longleftarrow$', +u'\u27f9': '$\\Longrightarrow$', +u'\u27fa': '$\\Longleftrightarrow$', +u'\u27fc': '$\\longmapsto$', +u'\u27ff': '$\\sim\\joinrel\\leadsto$', +u'\u2905': '$\\ElsevierGlyph{E212}$', +u'\u2912': '$\\UpArrowBar$', +u'\u2913': '$\\DownArrowBar$', +u'\u2923': '$\\ElsevierGlyph{E20C}$', +u'\u2924': '$\\ElsevierGlyph{E20D}$', +u'\u2925': '$\\ElsevierGlyph{E20B}$', +u'\u2926': '$\\ElsevierGlyph{E20A}$', +u'\u2927': '$\\ElsevierGlyph{E211}$', +u'\u2928': '$\\ElsevierGlyph{E20E}$', +u'\u2929': '$\\ElsevierGlyph{E20F}$', +u'\u292a': '$\\ElsevierGlyph{E210}$', +u'\u2933': '$\\ElsevierGlyph{E21C}$', +u'\u2936': '$\\ElsevierGlyph{E21A}$', +u'\u2937': '$\\ElsevierGlyph{E219}$', +u'\u2940': '$\\Elolarr$', +u'\u2941': '$\\Elorarr$', +u'\u2942': '$\\ElzRlarr$', +u'\u2944': '$\\ElzrLarr$', +u'\u2947': '$\\Elzrarrx$', +u'\u294e': '$\\LeftRightVector$', +u'\u294f': '$\\RightUpDownVector$', +u'\u2950': '$\\DownLeftRightVector$', +u'\u2951': '$\\LeftUpDownVector$', +u'\u2952': '$\\LeftVectorBar$', +u'\u2953': '$\\RightVectorBar$', +u'\u2954': '$\\RightUpVectorBar$', +u'\u2955': '$\\RightDownVectorBar$', +u'\u2956': '$\\DownLeftVectorBar$', +u'\u2957': '$\\DownRightVectorBar$', +u'\u2958': '$\\LeftUpVectorBar$', +u'\u2959': '$\\LeftDownVectorBar$', +u'\u295a': '$\\LeftTeeVector$', +u'\u295b': '$\\RightTeeVector$', +u'\u295c': '$\\RightUpTeeVector$', +u'\u295d': '$\\RightDownTeeVector$', +u'\u295e': '$\\DownLeftTeeVector$', +u'\u295f': '$\\DownRightTeeVector$', +u'\u2960': '$\\LeftUpTeeVector$', +u'\u2961': '$\\LeftDownTeeVector$', +u'\u296e': '$\\UpEquilibrium$', +u'\u296f': '$\\ReverseUpEquilibrium$', +u'\u2970': '$\\RoundImplies$', +u'\u297c': '$\\ElsevierGlyph{E214}$', +u'\u297d': '$\\ElsevierGlyph{E215}$', +u'\u2980': '$\\Elztfnc$', +u'\u2985': '$\\ElsevierGlyph{3018}$', +u'\u2986': '$\\Elroang$', +u'\u2993': '$<\\kern-0.58em($', +u'\u2994': '$\\ElsevierGlyph{E291}$', +u'\u2999': '$\\Elzddfnc$', +u'\u299c': '$\\Angle$', +u'\u29a0': '$\\Elzlpargt$', +u'\u29b5': '$\\ElsevierGlyph{E260}$', +u'\u29b6': '$\\ElsevierGlyph{E61B}$', +u'\u29ca': '$\\ElzLap$', +u'\u29cb': '$\\Elzdefas$', +u'\u29cf': '$\\LeftTriangleBar$', +u'\u29d0': '$\\RightTriangleBar$', +u'\u29dc': '$\\ElsevierGlyph{E372}$', +u'\u29eb': '$\\blacklozenge$', +u'\u29f4': '$\\RuleDelayed$', +u'\u2a04': '$\\Elxuplus$', +u'\u2a05': '$\\ElzThr$', +u'\u2a06': '$\\Elxsqcup$', +u'\u2a07': '$\\ElzInf$', +u'\u2a08': '$\\ElzSup$', +u'\u2a0d': '$\\ElzCint$', +u'\u2a0f': '$\\clockoint$', +u'\u2a10': '$\\ElsevierGlyph{E395}$', +u'\u2a16': '$\\sqrint$', +u'\u2a25': '$\\ElsevierGlyph{E25A}$', +u'\u2a2a': '$\\ElsevierGlyph{E25B}$', +u'\u2a2d': '$\\ElsevierGlyph{E25C}$', +u'\u2a2e': '$\\ElsevierGlyph{E25D}$', +u'\u2a2f': '$\\ElzTimes$', +u'\u2a34': '$\\ElsevierGlyph{E25E}$', +u'\u2a35': '$\\ElsevierGlyph{E25E}$', +u'\u2a3c': '$\\ElsevierGlyph{E259}$', +u'\u2a3f': '$\\amalg$', +u'\u2a53': '$\\ElzAnd$', +u'\u2a54': '$\\ElzOr$', +u'\u2a55': '$\\ElsevierGlyph{E36E}$', +u'\u2a56': '$\\ElOr$', +u'\u2a5e': '$\\perspcorrespond$', +u'\u2a5f': '$\\Elzminhat$', +u'\u2a63': '$\\ElsevierGlyph{225A}$', +u'\u2a6e': '$\\stackrel{*}{=}$', +u'\u2a75': '$\\Equal$', +u'\u2a7d': '$\\leqslant$', +u'\u2a7e': '$\\geqslant$', +u'\u2a85': '$\\lessapprox$', +u'\u2a86': '$\\gtrapprox$', +u'\u2a87': '$\\lneq$', +u'\u2a88': '$\\gneq$', +u'\u2a89': '$\\lnapprox$', +u'\u2a8a': '$\\gnapprox$', +u'\u2a8b': '$\\lesseqqgtr$', +u'\u2a8c': '$\\gtreqqless$', +u'\u2a95': '$\\eqslantless$', +u'\u2a96': '$\\eqslantgtr$', +u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', +u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', +u'\u2aa1': '$\\NestedLessLess$', +u'\u2aa2': '$\\NestedGreaterGreater$', +u'\u2aaf': '$\\preceq$', +u'\u2ab0': '$\\succeq$', +u'\u2ab5': '$\\precneqq$', +u'\u2ab6': '$\\succneqq$', +u'\u2ab7': '$\\precapprox$', +u'\u2ab8': '$\\succapprox$', +u'\u2ab9': '$\\precnapprox$', +u'\u2aba': '$\\succnapprox$', +u'\u2ac5': '$\\subseteqq$', +u'\u2ac6': '$\\supseteqq$', +u'\u2acb': '$\\subsetneqq$', +u'\u2acc': '$\\supsetneqq$', +u'\u2aeb': '$\\ElsevierGlyph{E30D}$', +u'\u2af6': '$\\Elztdcol$', +u'\u2afd': '${{/}\\!\\!{/}}$', +u'\u300a': '$\\ElsevierGlyph{300A}$', +u'\u300b': '$\\ElsevierGlyph{300B}$', +u'\u3018': '$\\ElsevierGlyph{3018}$', +u'\u3019': '$\\ElsevierGlyph{3019}$', +u'\u301a': '$\\openbracketleft$', +u'\u301b': '$\\openbracketright$', +u'\ufb00': '{ff}', +u'\ufb01': '{fi}', +u'\ufb02': '{fl}', +u'\ufb03': '{ffi}', +u'\ufb04': '{ffl}', +u'\U0001d400': '$\\mathbf{A}$', +u'\U0001d401': '$\\mathbf{B}$', +u'\U0001d402': '$\\mathbf{C}$', +u'\U0001d403': '$\\mathbf{D}$', +u'\U0001d404': '$\\mathbf{E}$', +u'\U0001d405': '$\\mathbf{F}$', +u'\U0001d406': '$\\mathbf{G}$', +u'\U0001d407': '$\\mathbf{H}$', +u'\U0001d408': '$\\mathbf{I}$', +u'\U0001d409': '$\\mathbf{J}$', +u'\U0001d40a': '$\\mathbf{K}$', +u'\U0001d40b': '$\\mathbf{L}$', +u'\U0001d40c': '$\\mathbf{M}$', +u'\U0001d40d': '$\\mathbf{N}$', +u'\U0001d40e': '$\\mathbf{O}$', +u'\U0001d40f': '$\\mathbf{P}$', +u'\U0001d410': '$\\mathbf{Q}$', +u'\U0001d411': '$\\mathbf{R}$', +u'\U0001d412': '$\\mathbf{S}$', +u'\U0001d413': '$\\mathbf{T}$', +u'\U0001d414': '$\\mathbf{U}$', +u'\U0001d415': '$\\mathbf{V}$', +u'\U0001d416': '$\\mathbf{W}$', +u'\U0001d417': '$\\mathbf{X}$', +u'\U0001d418': '$\\mathbf{Y}$', +u'\U0001d419': '$\\mathbf{Z}$', +u'\U0001d41a': '$\\mathbf{a}$', +u'\U0001d41b': '$\\mathbf{b}$', +u'\U0001d41c': '$\\mathbf{c}$', +u'\U0001d41d': '$\\mathbf{d}$', +u'\U0001d41e': '$\\mathbf{e}$', +u'\U0001d41f': '$\\mathbf{f}$', +u'\U0001d420': '$\\mathbf{g}$', +u'\U0001d421': '$\\mathbf{h}$', +u'\U0001d422': '$\\mathbf{i}$', +u'\U0001d423': '$\\mathbf{j}$', +u'\U0001d424': '$\\mathbf{k}$', +u'\U0001d425': '$\\mathbf{l}$', +u'\U0001d426': '$\\mathbf{m}$', +u'\U0001d427': '$\\mathbf{n}$', +u'\U0001d428': '$\\mathbf{o}$', +u'\U0001d429': '$\\mathbf{p}$', +u'\U0001d42a': '$\\mathbf{q}$', +u'\U0001d42b': '$\\mathbf{r}$', +u'\U0001d42c': '$\\mathbf{s}$', +u'\U0001d42d': '$\\mathbf{t}$', +u'\U0001d42e': '$\\mathbf{u}$', +u'\U0001d42f': '$\\mathbf{v}$', +u'\U0001d430': '$\\mathbf{w}$', +u'\U0001d431': '$\\mathbf{x}$', +u'\U0001d432': '$\\mathbf{y}$', +u'\U0001d433': '$\\mathbf{z}$', +u'\U0001d434': '$\\mathsl{A}$', +u'\U0001d435': '$\\mathsl{B}$', +u'\U0001d436': '$\\mathsl{C}$', +u'\U0001d437': '$\\mathsl{D}$', +u'\U0001d438': '$\\mathsl{E}$', +u'\U0001d439': '$\\mathsl{F}$', +u'\U0001d43a': '$\\mathsl{G}$', +u'\U0001d43b': '$\\mathsl{H}$', +u'\U0001d43c': '$\\mathsl{I}$', +u'\U0001d43d': '$\\mathsl{J}$', +u'\U0001d43e': '$\\mathsl{K}$', +u'\U0001d43f': '$\\mathsl{L}$', +u'\U0001d440': '$\\mathsl{M}$', +u'\U0001d441': '$\\mathsl{N}$', +u'\U0001d442': '$\\mathsl{O}$', +u'\U0001d443': '$\\mathsl{P}$', +u'\U0001d444': '$\\mathsl{Q}$', +u'\U0001d445': '$\\mathsl{R}$', +u'\U0001d446': '$\\mathsl{S}$', +u'\U0001d447': '$\\mathsl{T}$', +u'\U0001d448': '$\\mathsl{U}$', +u'\U0001d449': '$\\mathsl{V}$', +u'\U0001d44a': '$\\mathsl{W}$', +u'\U0001d44b': '$\\mathsl{X}$', +u'\U0001d44c': '$\\mathsl{Y}$', +u'\U0001d44d': '$\\mathsl{Z}$', +u'\U0001d44e': '$\\mathsl{a}$', +u'\U0001d44f': '$\\mathsl{b}$', +u'\U0001d450': '$\\mathsl{c}$', +u'\U0001d451': '$\\mathsl{d}$', +u'\U0001d452': '$\\mathsl{e}$', +u'\U0001d453': '$\\mathsl{f}$', +u'\U0001d454': '$\\mathsl{g}$', +u'\U0001d456': '$\\mathsl{i}$', +u'\U0001d457': '$\\mathsl{j}$', +u'\U0001d458': '$\\mathsl{k}$', +u'\U0001d459': '$\\mathsl{l}$', +u'\U0001d45a': '$\\mathsl{m}$', +u'\U0001d45b': '$\\mathsl{n}$', +u'\U0001d45c': '$\\mathsl{o}$', +u'\U0001d45d': '$\\mathsl{p}$', +u'\U0001d45e': '$\\mathsl{q}$', +u'\U0001d45f': '$\\mathsl{r}$', +u'\U0001d460': '$\\mathsl{s}$', +u'\U0001d461': '$\\mathsl{t}$', +u'\U0001d462': '$\\mathsl{u}$', +u'\U0001d463': '$\\mathsl{v}$', +u'\U0001d464': '$\\mathsl{w}$', +u'\U0001d465': '$\\mathsl{x}$', +u'\U0001d466': '$\\mathsl{y}$', +u'\U0001d467': '$\\mathsl{z}$', +u'\U0001d468': '$\\mathbit{A}$', +u'\U0001d469': '$\\mathbit{B}$', +u'\U0001d46a': '$\\mathbit{C}$', +u'\U0001d46b': '$\\mathbit{D}$', +u'\U0001d46c': '$\\mathbit{E}$', +u'\U0001d46d': '$\\mathbit{F}$', +u'\U0001d46e': '$\\mathbit{G}$', +u'\U0001d46f': '$\\mathbit{H}$', +u'\U0001d470': '$\\mathbit{I}$', +u'\U0001d471': '$\\mathbit{J}$', +u'\U0001d472': '$\\mathbit{K}$', +u'\U0001d473': '$\\mathbit{L}$', +u'\U0001d474': '$\\mathbit{M}$', +u'\U0001d475': '$\\mathbit{N}$', +u'\U0001d476': '$\\mathbit{O}$', +u'\U0001d477': '$\\mathbit{P}$', +u'\U0001d478': '$\\mathbit{Q}$', +u'\U0001d479': '$\\mathbit{R}$', +u'\U0001d47a': '$\\mathbit{S}$', +u'\U0001d47b': '$\\mathbit{T}$', +u'\U0001d47c': '$\\mathbit{U}$', +u'\U0001d47d': '$\\mathbit{V}$', +u'\U0001d47e': '$\\mathbit{W}$', +u'\U0001d47f': '$\\mathbit{X}$', +u'\U0001d480': '$\\mathbit{Y}$', +u'\U0001d481': '$\\mathbit{Z}$', +u'\U0001d482': '$\\mathbit{a}$', +u'\U0001d483': '$\\mathbit{b}$', +u'\U0001d484': '$\\mathbit{c}$', +u'\U0001d485': '$\\mathbit{d}$', +u'\U0001d486': '$\\mathbit{e}$', +u'\U0001d487': '$\\mathbit{f}$', +u'\U0001d488': '$\\mathbit{g}$', +u'\U0001d489': '$\\mathbit{h}$', +u'\U0001d48a': '$\\mathbit{i}$', +u'\U0001d48b': '$\\mathbit{j}$', +u'\U0001d48c': '$\\mathbit{k}$', +u'\U0001d48d': '$\\mathbit{l}$', +u'\U0001d48e': '$\\mathbit{m}$', +u'\U0001d48f': '$\\mathbit{n}$', +u'\U0001d490': '$\\mathbit{o}$', +u'\U0001d491': '$\\mathbit{p}$', +u'\U0001d492': '$\\mathbit{q}$', +u'\U0001d493': '$\\mathbit{r}$', +u'\U0001d494': '$\\mathbit{s}$', +u'\U0001d495': '$\\mathbit{t}$', +u'\U0001d496': '$\\mathbit{u}$', +u'\U0001d497': '$\\mathbit{v}$', +u'\U0001d498': '$\\mathbit{w}$', +u'\U0001d499': '$\\mathbit{x}$', +u'\U0001d49a': '$\\mathbit{y}$', +u'\U0001d49b': '$\\mathbit{z}$', +u'\U0001d49c': '$\\mathscr{A}$', +u'\U0001d49e': '$\\mathscr{C}$', +u'\U0001d49f': '$\\mathscr{D}$', +u'\U0001d4a2': '$\\mathscr{G}$', +u'\U0001d4a5': '$\\mathscr{J}$', +u'\U0001d4a6': '$\\mathscr{K}$', +u'\U0001d4a9': '$\\mathscr{N}$', +u'\U0001d4aa': '$\\mathscr{O}$', +u'\U0001d4ab': '$\\mathscr{P}$', +u'\U0001d4ac': '$\\mathscr{Q}$', +u'\U0001d4ae': '$\\mathscr{S}$', +u'\U0001d4af': '$\\mathscr{T}$', +u'\U0001d4b0': '$\\mathscr{U}$', +u'\U0001d4b1': '$\\mathscr{V}$', +u'\U0001d4b2': '$\\mathscr{W}$', +u'\U0001d4b3': '$\\mathscr{X}$', +u'\U0001d4b4': '$\\mathscr{Y}$', +u'\U0001d4b5': '$\\mathscr{Z}$', +u'\U0001d4b6': '$\\mathscr{a}$', +u'\U0001d4b7': '$\\mathscr{b}$', +u'\U0001d4b8': '$\\mathscr{c}$', +u'\U0001d4b9': '$\\mathscr{d}$', +u'\U0001d4bb': '$\\mathscr{f}$', +u'\U0001d4bd': '$\\mathscr{h}$', +u'\U0001d4be': '$\\mathscr{i}$', +u'\U0001d4bf': '$\\mathscr{j}$', +u'\U0001d4c0': '$\\mathscr{k}$', +u'\U0001d4c1': '$\\mathscr{l}$', +u'\U0001d4c2': '$\\mathscr{m}$', +u'\U0001d4c3': '$\\mathscr{n}$', +u'\U0001d4c5': '$\\mathscr{p}$', +u'\U0001d4c6': '$\\mathscr{q}$', +u'\U0001d4c7': '$\\mathscr{r}$', +u'\U0001d4c8': '$\\mathscr{s}$', +u'\U0001d4c9': '$\\mathscr{t}$', +u'\U0001d4ca': '$\\mathscr{u}$', +u'\U0001d4cb': '$\\mathscr{v}$', +u'\U0001d4cc': '$\\mathscr{w}$', +u'\U0001d4cd': '$\\mathscr{x}$', +u'\U0001d4ce': '$\\mathscr{y}$', +u'\U0001d4cf': '$\\mathscr{z}$', +u'\U0001d4d0': '$\\mathmit{A}$', +u'\U0001d4d1': '$\\mathmit{B}$', +u'\U0001d4d2': '$\\mathmit{C}$', +u'\U0001d4d3': '$\\mathmit{D}$', +u'\U0001d4d4': '$\\mathmit{E}$', +u'\U0001d4d5': '$\\mathmit{F}$', +u'\U0001d4d6': '$\\mathmit{G}$', +u'\U0001d4d7': '$\\mathmit{H}$', +u'\U0001d4d8': '$\\mathmit{I}$', +u'\U0001d4d9': '$\\mathmit{J}$', +u'\U0001d4da': '$\\mathmit{K}$', +u'\U0001d4db': '$\\mathmit{L}$', +u'\U0001d4dc': '$\\mathmit{M}$', +u'\U0001d4dd': '$\\mathmit{N}$', +u'\U0001d4de': '$\\mathmit{O}$', +u'\U0001d4df': '$\\mathmit{P}$', +u'\U0001d4e0': '$\\mathmit{Q}$', +u'\U0001d4e1': '$\\mathmit{R}$', +u'\U0001d4e2': '$\\mathmit{S}$', +u'\U0001d4e3': '$\\mathmit{T}$', +u'\U0001d4e4': '$\\mathmit{U}$', +u'\U0001d4e5': '$\\mathmit{V}$', +u'\U0001d4e6': '$\\mathmit{W}$', +u'\U0001d4e7': '$\\mathmit{X}$', +u'\U0001d4e8': '$\\mathmit{Y}$', +u'\U0001d4e9': '$\\mathmit{Z}$', +u'\U0001d4ea': '$\\mathmit{a}$', +u'\U0001d4eb': '$\\mathmit{b}$', +u'\U0001d4ec': '$\\mathmit{c}$', +u'\U0001d4ed': '$\\mathmit{d}$', +u'\U0001d4ee': '$\\mathmit{e}$', +u'\U0001d4ef': '$\\mathmit{f}$', +u'\U0001d4f0': '$\\mathmit{g}$', +u'\U0001d4f1': '$\\mathmit{h}$', +u'\U0001d4f2': '$\\mathmit{i}$', +u'\U0001d4f3': '$\\mathmit{j}$', +u'\U0001d4f4': '$\\mathmit{k}$', +u'\U0001d4f5': '$\\mathmit{l}$', +u'\U0001d4f6': '$\\mathmit{m}$', +u'\U0001d4f7': '$\\mathmit{n}$', +u'\U0001d4f8': '$\\mathmit{o}$', +u'\U0001d4f9': '$\\mathmit{p}$', +u'\U0001d4fa': '$\\mathmit{q}$', +u'\U0001d4fb': '$\\mathmit{r}$', +u'\U0001d4fc': '$\\mathmit{s}$', +u'\U0001d4fd': '$\\mathmit{t}$', +u'\U0001d4fe': '$\\mathmit{u}$', +u'\U0001d4ff': '$\\mathmit{v}$', +u'\U0001d500': '$\\mathmit{w}$', +u'\U0001d501': '$\\mathmit{x}$', +u'\U0001d502': '$\\mathmit{y}$', +u'\U0001d503': '$\\mathmit{z}$', +u'\U0001d504': '$\\mathfrak{A}$', +u'\U0001d505': '$\\mathfrak{B}$', +u'\U0001d507': '$\\mathfrak{D}$', +u'\U0001d508': '$\\mathfrak{E}$', +u'\U0001d509': '$\\mathfrak{F}$', +u'\U0001d50a': '$\\mathfrak{G}$', +u'\U0001d50d': '$\\mathfrak{J}$', +u'\U0001d50e': '$\\mathfrak{K}$', +u'\U0001d50f': '$\\mathfrak{L}$', +u'\U0001d510': '$\\mathfrak{M}$', +u'\U0001d511': '$\\mathfrak{N}$', +u'\U0001d512': '$\\mathfrak{O}$', +u'\U0001d513': '$\\mathfrak{P}$', +u'\U0001d514': '$\\mathfrak{Q}$', +u'\U0001d516': '$\\mathfrak{S}$', +u'\U0001d517': '$\\mathfrak{T}$', +u'\U0001d518': '$\\mathfrak{U}$', +u'\U0001d519': '$\\mathfrak{V}$', +u'\U0001d51a': '$\\mathfrak{W}$', +u'\U0001d51b': '$\\mathfrak{X}$', +u'\U0001d51c': '$\\mathfrak{Y}$', +u'\U0001d51e': '$\\mathfrak{a}$', +u'\U0001d51f': '$\\mathfrak{b}$', +u'\U0001d520': '$\\mathfrak{c}$', +u'\U0001d521': '$\\mathfrak{d}$', +u'\U0001d522': '$\\mathfrak{e}$', +u'\U0001d523': '$\\mathfrak{f}$', +u'\U0001d524': '$\\mathfrak{g}$', +u'\U0001d525': '$\\mathfrak{h}$', +u'\U0001d526': '$\\mathfrak{i}$', +u'\U0001d527': '$\\mathfrak{j}$', +u'\U0001d528': '$\\mathfrak{k}$', +u'\U0001d529': '$\\mathfrak{l}$', +u'\U0001d52a': '$\\mathfrak{m}$', +u'\U0001d52b': '$\\mathfrak{n}$', +u'\U0001d52c': '$\\mathfrak{o}$', +u'\U0001d52d': '$\\mathfrak{p}$', +u'\U0001d52e': '$\\mathfrak{q}$', +u'\U0001d52f': '$\\mathfrak{r}$', +u'\U0001d530': '$\\mathfrak{s}$', +u'\U0001d531': '$\\mathfrak{t}$', +u'\U0001d532': '$\\mathfrak{u}$', +u'\U0001d533': '$\\mathfrak{v}$', +u'\U0001d534': '$\\mathfrak{w}$', +u'\U0001d535': '$\\mathfrak{x}$', +u'\U0001d536': '$\\mathfrak{y}$', +u'\U0001d537': '$\\mathfrak{z}$', +u'\U0001d538': '$\\mathbb{A}$', +u'\U0001d539': '$\\mathbb{B}$', +u'\U0001d53b': '$\\mathbb{D}$', +u'\U0001d53c': '$\\mathbb{E}$', +u'\U0001d53d': '$\\mathbb{F}$', +u'\U0001d53e': '$\\mathbb{G}$', +u'\U0001d540': '$\\mathbb{I}$', +u'\U0001d541': '$\\mathbb{J}$', +u'\U0001d542': '$\\mathbb{K}$', +u'\U0001d543': '$\\mathbb{L}$', +u'\U0001d544': '$\\mathbb{M}$', +u'\U0001d546': '$\\mathbb{O}$', +u'\U0001d54a': '$\\mathbb{S}$', +u'\U0001d54b': '$\\mathbb{T}$', +u'\U0001d54c': '$\\mathbb{U}$', +u'\U0001d54d': '$\\mathbb{V}$', +u'\U0001d54e': '$\\mathbb{W}$', +u'\U0001d54f': '$\\mathbb{X}$', +u'\U0001d550': '$\\mathbb{Y}$', +u'\U0001d552': '$\\mathbb{a}$', +u'\U0001d553': '$\\mathbb{b}$', +u'\U0001d554': '$\\mathbb{c}$', +u'\U0001d555': '$\\mathbb{d}$', +u'\U0001d556': '$\\mathbb{e}$', +u'\U0001d557': '$\\mathbb{f}$', +u'\U0001d558': '$\\mathbb{g}$', +u'\U0001d559': '$\\mathbb{h}$', +u'\U0001d55a': '$\\mathbb{i}$', +u'\U0001d55b': '$\\mathbb{j}$', +u'\U0001d55c': '$\\mathbb{k}$', +u'\U0001d55d': '$\\mathbb{l}$', +u'\U0001d55e': '$\\mathbb{m}$', +u'\U0001d55f': '$\\mathbb{n}$', +u'\U0001d560': '$\\mathbb{o}$', +u'\U0001d561': '$\\mathbb{p}$', +u'\U0001d562': '$\\mathbb{q}$', +u'\U0001d563': '$\\mathbb{r}$', +u'\U0001d564': '$\\mathbb{s}$', +u'\U0001d565': '$\\mathbb{t}$', +u'\U0001d566': '$\\mathbb{u}$', +u'\U0001d567': '$\\mathbb{v}$', +u'\U0001d568': '$\\mathbb{w}$', +u'\U0001d569': '$\\mathbb{x}$', +u'\U0001d56a': '$\\mathbb{y}$', +u'\U0001d56b': '$\\mathbb{z}$', +u'\U0001d56c': '$\\mathslbb{A}$', +u'\U0001d56d': '$\\mathslbb{B}$', +u'\U0001d56e': '$\\mathslbb{C}$', +u'\U0001d56f': '$\\mathslbb{D}$', +u'\U0001d570': '$\\mathslbb{E}$', +u'\U0001d571': '$\\mathslbb{F}$', +u'\U0001d572': '$\\mathslbb{G}$', +u'\U0001d573': '$\\mathslbb{H}$', +u'\U0001d574': '$\\mathslbb{I}$', +u'\U0001d575': '$\\mathslbb{J}$', +u'\U0001d576': '$\\mathslbb{K}$', +u'\U0001d577': '$\\mathslbb{L}$', +u'\U0001d578': '$\\mathslbb{M}$', +u'\U0001d579': '$\\mathslbb{N}$', +u'\U0001d57a': '$\\mathslbb{O}$', +u'\U0001d57b': '$\\mathslbb{P}$', +u'\U0001d57c': '$\\mathslbb{Q}$', +u'\U0001d57d': '$\\mathslbb{R}$', +u'\U0001d57e': '$\\mathslbb{S}$', +u'\U0001d57f': '$\\mathslbb{T}$', +u'\U0001d580': '$\\mathslbb{U}$', +u'\U0001d581': '$\\mathslbb{V}$', +u'\U0001d582': '$\\mathslbb{W}$', +u'\U0001d583': '$\\mathslbb{X}$', +u'\U0001d584': '$\\mathslbb{Y}$', +u'\U0001d585': '$\\mathslbb{Z}$', +u'\U0001d586': '$\\mathslbb{a}$', +u'\U0001d587': '$\\mathslbb{b}$', +u'\U0001d588': '$\\mathslbb{c}$', +u'\U0001d589': '$\\mathslbb{d}$', +u'\U0001d58a': '$\\mathslbb{e}$', +u'\U0001d58b': '$\\mathslbb{f}$', +u'\U0001d58c': '$\\mathslbb{g}$', +u'\U0001d58d': '$\\mathslbb{h}$', +u'\U0001d58e': '$\\mathslbb{i}$', +u'\U0001d58f': '$\\mathslbb{j}$', +u'\U0001d590': '$\\mathslbb{k}$', +u'\U0001d591': '$\\mathslbb{l}$', +u'\U0001d592': '$\\mathslbb{m}$', +u'\U0001d593': '$\\mathslbb{n}$', +u'\U0001d594': '$\\mathslbb{o}$', +u'\U0001d595': '$\\mathslbb{p}$', +u'\U0001d596': '$\\mathslbb{q}$', +u'\U0001d597': '$\\mathslbb{r}$', +u'\U0001d598': '$\\mathslbb{s}$', +u'\U0001d599': '$\\mathslbb{t}$', +u'\U0001d59a': '$\\mathslbb{u}$', +u'\U0001d59b': '$\\mathslbb{v}$', +u'\U0001d59c': '$\\mathslbb{w}$', +u'\U0001d59d': '$\\mathslbb{x}$', +u'\U0001d59e': '$\\mathslbb{y}$', +u'\U0001d59f': '$\\mathslbb{z}$', +u'\U0001d5a0': '$\\mathsf{A}$', +u'\U0001d5a1': '$\\mathsf{B}$', +u'\U0001d5a2': '$\\mathsf{C}$', +u'\U0001d5a3': '$\\mathsf{D}$', +u'\U0001d5a4': '$\\mathsf{E}$', +u'\U0001d5a5': '$\\mathsf{F}$', +u'\U0001d5a6': '$\\mathsf{G}$', +u'\U0001d5a7': '$\\mathsf{H}$', +u'\U0001d5a8': '$\\mathsf{I}$', +u'\U0001d5a9': '$\\mathsf{J}$', +u'\U0001d5aa': '$\\mathsf{K}$', +u'\U0001d5ab': '$\\mathsf{L}$', +u'\U0001d5ac': '$\\mathsf{M}$', +u'\U0001d5ad': '$\\mathsf{N}$', +u'\U0001d5ae': '$\\mathsf{O}$', +u'\U0001d5af': '$\\mathsf{P}$', +u'\U0001d5b0': '$\\mathsf{Q}$', +u'\U0001d5b1': '$\\mathsf{R}$', +u'\U0001d5b2': '$\\mathsf{S}$', +u'\U0001d5b3': '$\\mathsf{T}$', +u'\U0001d5b4': '$\\mathsf{U}$', +u'\U0001d5b5': '$\\mathsf{V}$', +u'\U0001d5b6': '$\\mathsf{W}$', +u'\U0001d5b7': '$\\mathsf{X}$', +u'\U0001d5b8': '$\\mathsf{Y}$', +u'\U0001d5b9': '$\\mathsf{Z}$', +u'\U0001d5ba': '$\\mathsf{a}$', +u'\U0001d5bb': '$\\mathsf{b}$', +u'\U0001d5bc': '$\\mathsf{c}$', +u'\U0001d5bd': '$\\mathsf{d}$', +u'\U0001d5be': '$\\mathsf{e}$', +u'\U0001d5bf': '$\\mathsf{f}$', +u'\U0001d5c0': '$\\mathsf{g}$', +u'\U0001d5c1': '$\\mathsf{h}$', +u'\U0001d5c2': '$\\mathsf{i}$', +u'\U0001d5c3': '$\\mathsf{j}$', +u'\U0001d5c4': '$\\mathsf{k}$', +u'\U0001d5c5': '$\\mathsf{l}$', +u'\U0001d5c6': '$\\mathsf{m}$', +u'\U0001d5c7': '$\\mathsf{n}$', +u'\U0001d5c8': '$\\mathsf{o}$', +u'\U0001d5c9': '$\\mathsf{p}$', +u'\U0001d5ca': '$\\mathsf{q}$', +u'\U0001d5cb': '$\\mathsf{r}$', +u'\U0001d5cc': '$\\mathsf{s}$', +u'\U0001d5cd': '$\\mathsf{t}$', +u'\U0001d5ce': '$\\mathsf{u}$', +u'\U0001d5cf': '$\\mathsf{v}$', +u'\U0001d5d0': '$\\mathsf{w}$', +u'\U0001d5d1': '$\\mathsf{x}$', +u'\U0001d5d2': '$\\mathsf{y}$', +u'\U0001d5d3': '$\\mathsf{z}$', +u'\U0001d5d4': '$\\mathsfbf{A}$', +u'\U0001d5d5': '$\\mathsfbf{B}$', +u'\U0001d5d6': '$\\mathsfbf{C}$', +u'\U0001d5d7': '$\\mathsfbf{D}$', +u'\U0001d5d8': '$\\mathsfbf{E}$', +u'\U0001d5d9': '$\\mathsfbf{F}$', +u'\U0001d5da': '$\\mathsfbf{G}$', +u'\U0001d5db': '$\\mathsfbf{H}$', +u'\U0001d5dc': '$\\mathsfbf{I}$', +u'\U0001d5dd': '$\\mathsfbf{J}$', +u'\U0001d5de': '$\\mathsfbf{K}$', +u'\U0001d5df': '$\\mathsfbf{L}$', +u'\U0001d5e0': '$\\mathsfbf{M}$', +u'\U0001d5e1': '$\\mathsfbf{N}$', +u'\U0001d5e2': '$\\mathsfbf{O}$', +u'\U0001d5e3': '$\\mathsfbf{P}$', +u'\U0001d5e4': '$\\mathsfbf{Q}$', +u'\U0001d5e5': '$\\mathsfbf{R}$', +u'\U0001d5e6': '$\\mathsfbf{S}$', +u'\U0001d5e7': '$\\mathsfbf{T}$', +u'\U0001d5e8': '$\\mathsfbf{U}$', +u'\U0001d5e9': '$\\mathsfbf{V}$', +u'\U0001d5ea': '$\\mathsfbf{W}$', +u'\U0001d5eb': '$\\mathsfbf{X}$', +u'\U0001d5ec': '$\\mathsfbf{Y}$', +u'\U0001d5ed': '$\\mathsfbf{Z}$', +u'\U0001d5ee': '$\\mathsfbf{a}$', +u'\U0001d5ef': '$\\mathsfbf{b}$', +u'\U0001d5f0': '$\\mathsfbf{c}$', +u'\U0001d5f1': '$\\mathsfbf{d}$', +u'\U0001d5f2': '$\\mathsfbf{e}$', +u'\U0001d5f3': '$\\mathsfbf{f}$', +u'\U0001d5f4': '$\\mathsfbf{g}$', +u'\U0001d5f5': '$\\mathsfbf{h}$', +u'\U0001d5f6': '$\\mathsfbf{i}$', +u'\U0001d5f7': '$\\mathsfbf{j}$', +u'\U0001d5f8': '$\\mathsfbf{k}$', +u'\U0001d5f9': '$\\mathsfbf{l}$', +u'\U0001d5fa': '$\\mathsfbf{m}$', +u'\U0001d5fb': '$\\mathsfbf{n}$', +u'\U0001d5fc': '$\\mathsfbf{o}$', +u'\U0001d5fd': '$\\mathsfbf{p}$', +u'\U0001d5fe': '$\\mathsfbf{q}$', +u'\U0001d5ff': '$\\mathsfbf{r}$', +u'\U0001d600': '$\\mathsfbf{s}$', +u'\U0001d601': '$\\mathsfbf{t}$', +u'\U0001d602': '$\\mathsfbf{u}$', +u'\U0001d603': '$\\mathsfbf{v}$', +u'\U0001d604': '$\\mathsfbf{w}$', +u'\U0001d605': '$\\mathsfbf{x}$', +u'\U0001d606': '$\\mathsfbf{y}$', +u'\U0001d607': '$\\mathsfbf{z}$', +u'\U0001d608': '$\\mathsfsl{A}$', +u'\U0001d609': '$\\mathsfsl{B}$', +u'\U0001d60a': '$\\mathsfsl{C}$', +u'\U0001d60b': '$\\mathsfsl{D}$', +u'\U0001d60c': '$\\mathsfsl{E}$', +u'\U0001d60d': '$\\mathsfsl{F}$', +u'\U0001d60e': '$\\mathsfsl{G}$', +u'\U0001d60f': '$\\mathsfsl{H}$', +u'\U0001d610': '$\\mathsfsl{I}$', +u'\U0001d611': '$\\mathsfsl{J}$', +u'\U0001d612': '$\\mathsfsl{K}$', +u'\U0001d613': '$\\mathsfsl{L}$', +u'\U0001d614': '$\\mathsfsl{M}$', +u'\U0001d615': '$\\mathsfsl{N}$', +u'\U0001d616': '$\\mathsfsl{O}$', +u'\U0001d617': '$\\mathsfsl{P}$', +u'\U0001d618': '$\\mathsfsl{Q}$', +u'\U0001d619': '$\\mathsfsl{R}$', +u'\U0001d61a': '$\\mathsfsl{S}$', +u'\U0001d61b': '$\\mathsfsl{T}$', +u'\U0001d61c': '$\\mathsfsl{U}$', +u'\U0001d61d': '$\\mathsfsl{V}$', +u'\U0001d61e': '$\\mathsfsl{W}$', +u'\U0001d61f': '$\\mathsfsl{X}$', +u'\U0001d620': '$\\mathsfsl{Y}$', +u'\U0001d621': '$\\mathsfsl{Z}$', +u'\U0001d622': '$\\mathsfsl{a}$', +u'\U0001d623': '$\\mathsfsl{b}$', +u'\U0001d624': '$\\mathsfsl{c}$', +u'\U0001d625': '$\\mathsfsl{d}$', +u'\U0001d626': '$\\mathsfsl{e}$', +u'\U0001d627': '$\\mathsfsl{f}$', +u'\U0001d628': '$\\mathsfsl{g}$', +u'\U0001d629': '$\\mathsfsl{h}$', +u'\U0001d62a': '$\\mathsfsl{i}$', +u'\U0001d62b': '$\\mathsfsl{j}$', +u'\U0001d62c': '$\\mathsfsl{k}$', +u'\U0001d62d': '$\\mathsfsl{l}$', +u'\U0001d62e': '$\\mathsfsl{m}$', +u'\U0001d62f': '$\\mathsfsl{n}$', +u'\U0001d630': '$\\mathsfsl{o}$', +u'\U0001d631': '$\\mathsfsl{p}$', +u'\U0001d632': '$\\mathsfsl{q}$', +u'\U0001d633': '$\\mathsfsl{r}$', +u'\U0001d634': '$\\mathsfsl{s}$', +u'\U0001d635': '$\\mathsfsl{t}$', +u'\U0001d636': '$\\mathsfsl{u}$', +u'\U0001d637': '$\\mathsfsl{v}$', +u'\U0001d638': '$\\mathsfsl{w}$', +u'\U0001d639': '$\\mathsfsl{x}$', +u'\U0001d63a': '$\\mathsfsl{y}$', +u'\U0001d63b': '$\\mathsfsl{z}$', +u'\U0001d63c': '$\\mathsfbfsl{A}$', +u'\U0001d63d': '$\\mathsfbfsl{B}$', +u'\U0001d63e': '$\\mathsfbfsl{C}$', +u'\U0001d63f': '$\\mathsfbfsl{D}$', +u'\U0001d640': '$\\mathsfbfsl{E}$', +u'\U0001d641': '$\\mathsfbfsl{F}$', +u'\U0001d642': '$\\mathsfbfsl{G}$', +u'\U0001d643': '$\\mathsfbfsl{H}$', +u'\U0001d644': '$\\mathsfbfsl{I}$', +u'\U0001d645': '$\\mathsfbfsl{J}$', +u'\U0001d646': '$\\mathsfbfsl{K}$', +u'\U0001d647': '$\\mathsfbfsl{L}$', +u'\U0001d648': '$\\mathsfbfsl{M}$', +u'\U0001d649': '$\\mathsfbfsl{N}$', +u'\U0001d64a': '$\\mathsfbfsl{O}$', +u'\U0001d64b': '$\\mathsfbfsl{P}$', +u'\U0001d64c': '$\\mathsfbfsl{Q}$', +u'\U0001d64d': '$\\mathsfbfsl{R}$', +u'\U0001d64e': '$\\mathsfbfsl{S}$', +u'\U0001d64f': '$\\mathsfbfsl{T}$', +u'\U0001d650': '$\\mathsfbfsl{U}$', +u'\U0001d651': '$\\mathsfbfsl{V}$', +u'\U0001d652': '$\\mathsfbfsl{W}$', +u'\U0001d653': '$\\mathsfbfsl{X}$', +u'\U0001d654': '$\\mathsfbfsl{Y}$', +u'\U0001d655': '$\\mathsfbfsl{Z}$', +u'\U0001d656': '$\\mathsfbfsl{a}$', +u'\U0001d657': '$\\mathsfbfsl{b}$', +u'\U0001d658': '$\\mathsfbfsl{c}$', +u'\U0001d659': '$\\mathsfbfsl{d}$', +u'\U0001d65a': '$\\mathsfbfsl{e}$', +u'\U0001d65b': '$\\mathsfbfsl{f}$', +u'\U0001d65c': '$\\mathsfbfsl{g}$', +u'\U0001d65d': '$\\mathsfbfsl{h}$', +u'\U0001d65e': '$\\mathsfbfsl{i}$', +u'\U0001d65f': '$\\mathsfbfsl{j}$', +u'\U0001d660': '$\\mathsfbfsl{k}$', +u'\U0001d661': '$\\mathsfbfsl{l}$', +u'\U0001d662': '$\\mathsfbfsl{m}$', +u'\U0001d663': '$\\mathsfbfsl{n}$', +u'\U0001d664': '$\\mathsfbfsl{o}$', +u'\U0001d665': '$\\mathsfbfsl{p}$', +u'\U0001d666': '$\\mathsfbfsl{q}$', +u'\U0001d667': '$\\mathsfbfsl{r}$', +u'\U0001d668': '$\\mathsfbfsl{s}$', +u'\U0001d669': '$\\mathsfbfsl{t}$', +u'\U0001d66a': '$\\mathsfbfsl{u}$', +u'\U0001d66b': '$\\mathsfbfsl{v}$', +u'\U0001d66c': '$\\mathsfbfsl{w}$', +u'\U0001d66d': '$\\mathsfbfsl{x}$', +u'\U0001d66e': '$\\mathsfbfsl{y}$', +u'\U0001d66f': '$\\mathsfbfsl{z}$', +u'\U0001d670': '$\\mathtt{A}$', +u'\U0001d671': '$\\mathtt{B}$', +u'\U0001d672': '$\\mathtt{C}$', +u'\U0001d673': '$\\mathtt{D}$', +u'\U0001d674': '$\\mathtt{E}$', +u'\U0001d675': '$\\mathtt{F}$', +u'\U0001d676': '$\\mathtt{G}$', +u'\U0001d677': '$\\mathtt{H}$', +u'\U0001d678': '$\\mathtt{I}$', +u'\U0001d679': '$\\mathtt{J}$', +u'\U0001d67a': '$\\mathtt{K}$', +u'\U0001d67b': '$\\mathtt{L}$', +u'\U0001d67c': '$\\mathtt{M}$', +u'\U0001d67d': '$\\mathtt{N}$', +u'\U0001d67e': '$\\mathtt{O}$', +u'\U0001d67f': '$\\mathtt{P}$', +u'\U0001d680': '$\\mathtt{Q}$', +u'\U0001d681': '$\\mathtt{R}$', +u'\U0001d682': '$\\mathtt{S}$', +u'\U0001d683': '$\\mathtt{T}$', +u'\U0001d684': '$\\mathtt{U}$', +u'\U0001d685': '$\\mathtt{V}$', +u'\U0001d686': '$\\mathtt{W}$', +u'\U0001d687': '$\\mathtt{X}$', +u'\U0001d688': '$\\mathtt{Y}$', +u'\U0001d689': '$\\mathtt{Z}$', +u'\U0001d68a': '$\\mathtt{a}$', +u'\U0001d68b': '$\\mathtt{b}$', +u'\U0001d68c': '$\\mathtt{c}$', +u'\U0001d68d': '$\\mathtt{d}$', +u'\U0001d68e': '$\\mathtt{e}$', +u'\U0001d68f': '$\\mathtt{f}$', +u'\U0001d690': '$\\mathtt{g}$', +u'\U0001d691': '$\\mathtt{h}$', +u'\U0001d692': '$\\mathtt{i}$', +u'\U0001d693': '$\\mathtt{j}$', +u'\U0001d694': '$\\mathtt{k}$', +u'\U0001d695': '$\\mathtt{l}$', +u'\U0001d696': '$\\mathtt{m}$', +u'\U0001d697': '$\\mathtt{n}$', +u'\U0001d698': '$\\mathtt{o}$', +u'\U0001d699': '$\\mathtt{p}$', +u'\U0001d69a': '$\\mathtt{q}$', +u'\U0001d69b': '$\\mathtt{r}$', +u'\U0001d69c': '$\\mathtt{s}$', +u'\U0001d69d': '$\\mathtt{t}$', +u'\U0001d69e': '$\\mathtt{u}$', +u'\U0001d69f': '$\\mathtt{v}$', +u'\U0001d6a0': '$\\mathtt{w}$', +u'\U0001d6a1': '$\\mathtt{x}$', +u'\U0001d6a2': '$\\mathtt{y}$', +u'\U0001d6a3': '$\\mathtt{z}$', +u'\U0001d6a8': '$\\mathbf{\\Alpha}$', +u'\U0001d6a9': '$\\mathbf{\\Beta}$', +u'\U0001d6aa': '$\\mathbf{\\Gamma}$', +u'\U0001d6ab': '$\\mathbf{\\Delta}$', +u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', +u'\U0001d6ad': '$\\mathbf{\\Zeta}$', +u'\U0001d6ae': '$\\mathbf{\\Eta}$', +u'\U0001d6af': '$\\mathbf{\\Theta}$', +u'\U0001d6b0': '$\\mathbf{\\Iota}$', +u'\U0001d6b1': '$\\mathbf{\\Kappa}$', +u'\U0001d6b2': '$\\mathbf{\\Lambda}$', +u'\U0001d6b3': '$M$', +u'\U0001d6b4': '$N$', +u'\U0001d6b5': '$\\mathbf{\\Xi}$', +u'\U0001d6b6': '$O$', +u'\U0001d6b7': '$\\mathbf{\\Pi}$', +u'\U0001d6b8': '$\\mathbf{\\Rho}$', +u'\U0001d6b9': '{\\mathbf{\\vartheta}}', +u'\U0001d6ba': '$\\mathbf{\\Sigma}$', +u'\U0001d6bb': '$\\mathbf{\\Tau}$', +u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', +u'\U0001d6bd': '$\\mathbf{\\Phi}$', +u'\U0001d6be': '$\\mathbf{\\Chi}$', +u'\U0001d6bf': '$\\mathbf{\\Psi}$', +u'\U0001d6c0': '$\\mathbf{\\Omega}$', +u'\U0001d6c1': '$\\mathbf{\\nabla}$', +u'\U0001d6c2': '$\\mathbf{\\Alpha}$', +u'\U0001d6c3': '$\\mathbf{\\Beta}$', +u'\U0001d6c4': '$\\mathbf{\\Gamma}$', +u'\U0001d6c5': '$\\mathbf{\\Delta}$', +u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', +u'\U0001d6c7': '$\\mathbf{\\Zeta}$', +u'\U0001d6c8': '$\\mathbf{\\Eta}$', +u'\U0001d6c9': '$\\mathbf{\\theta}$', +u'\U0001d6ca': '$\\mathbf{\\Iota}$', +u'\U0001d6cb': '$\\mathbf{\\Kappa}$', +u'\U0001d6cc': '$\\mathbf{\\Lambda}$', +u'\U0001d6cd': '$M$', +u'\U0001d6ce': '$N$', +u'\U0001d6cf': '$\\mathbf{\\Xi}$', +u'\U0001d6d0': '$O$', +u'\U0001d6d1': '$\\mathbf{\\Pi}$', +u'\U0001d6d2': '$\\mathbf{\\Rho}$', +u'\U0001d6d3': '$\\mathbf{\\varsigma}$', +u'\U0001d6d4': '$\\mathbf{\\Sigma}$', +u'\U0001d6d5': '$\\mathbf{\\Tau}$', +u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', +u'\U0001d6d7': '$\\mathbf{\\Phi}$', +u'\U0001d6d8': '$\\mathbf{\\Chi}$', +u'\U0001d6d9': '$\\mathbf{\\Psi}$', +u'\U0001d6da': '$\\mathbf{\\Omega}$', +u'\U0001d6db': '$\\partial$', +u'\U0001d6dc': '$\\in$', +u'\U0001d6dd': '{\\mathbf{\\vartheta}}', +u'\U0001d6de': '{\\mathbf{\\varkappa}}', +u'\U0001d6df': '{\\mathbf{\\phi}}', +u'\U0001d6e0': '{\\mathbf{\\varrho}}', +u'\U0001d6e1': '{\\mathbf{\\varpi}}', +u'\U0001d6e2': '$\\mathsl{\\Alpha}$', +u'\U0001d6e3': '$\\mathsl{\\Beta}$', +u'\U0001d6e4': '$\\mathsl{\\Gamma}$', +u'\U0001d6e5': '$\\mathsl{\\Delta}$', +u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', +u'\U0001d6e7': '$\\mathsl{\\Zeta}$', +u'\U0001d6e8': '$\\mathsl{\\Eta}$', +u'\U0001d6e9': '$\\mathsl{\\Theta}$', +u'\U0001d6ea': '$\\mathsl{\\Iota}$', +u'\U0001d6eb': '$\\mathsl{\\Kappa}$', +u'\U0001d6ec': '$\\mathsl{\\Lambda}$', +u'\U0001d6ed': '$M$', +u'\U0001d6ee': '$N$', +u'\U0001d6ef': '$\\mathsl{\\Xi}$', +u'\U0001d6f0': '$O$', +u'\U0001d6f1': '$\\mathsl{\\Pi}$', +u'\U0001d6f2': '$\\mathsl{\\Rho}$', +u'\U0001d6f3': '{\\mathsl{\\vartheta}}', +u'\U0001d6f4': '$\\mathsl{\\Sigma}$', +u'\U0001d6f5': '$\\mathsl{\\Tau}$', +u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', +u'\U0001d6f7': '$\\mathsl{\\Phi}$', +u'\U0001d6f8': '$\\mathsl{\\Chi}$', +u'\U0001d6f9': '$\\mathsl{\\Psi}$', +u'\U0001d6fa': '$\\mathsl{\\Omega}$', +u'\U0001d6fb': '$\\mathsl{\\nabla}$', +u'\U0001d6fc': '$\\mathsl{\\Alpha}$', +u'\U0001d6fd': '$\\mathsl{\\Beta}$', +u'\U0001d6fe': '$\\mathsl{\\Gamma}$', +u'\U0001d6ff': '$\\mathsl{\\Delta}$', +u'\U0001d700': '$\\mathsl{\\Epsilon}$', +u'\U0001d701': '$\\mathsl{\\Zeta}$', +u'\U0001d702': '$\\mathsl{\\Eta}$', +u'\U0001d703': '$\\mathsl{\\Theta}$', +u'\U0001d704': '$\\mathsl{\\Iota}$', +u'\U0001d705': '$\\mathsl{\\Kappa}$', +u'\U0001d706': '$\\mathsl{\\Lambda}$', +u'\U0001d707': '$M$', +u'\U0001d708': '$N$', +u'\U0001d709': '$\\mathsl{\\Xi}$', +u'\U0001d70a': '$O$', +u'\U0001d70b': '$\\mathsl{\\Pi}$', +u'\U0001d70c': '$\\mathsl{\\Rho}$', +u'\U0001d70d': '$\\mathsl{\\varsigma}$', +u'\U0001d70e': '$\\mathsl{\\Sigma}$', +u'\U0001d70f': '$\\mathsl{\\Tau}$', +u'\U0001d710': '$\\mathsl{\\Upsilon}$', +u'\U0001d711': '$\\mathsl{\\Phi}$', +u'\U0001d712': '$\\mathsl{\\Chi}$', +u'\U0001d713': '$\\mathsl{\\Psi}$', +u'\U0001d714': '$\\mathsl{\\Omega}$', +u'\U0001d715': '$\\partial$', +u'\U0001d716': '$\\in$', +u'\U0001d717': '{\\mathsl{\\vartheta}}', +u'\U0001d718': '{\\mathsl{\\varkappa}}', +u'\U0001d719': '{\\mathsl{\\phi}}', +u'\U0001d71a': '{\\mathsl{\\varrho}}', +u'\U0001d71b': '{\\mathsl{\\varpi}}', +u'\U0001d71c': '$\\mathbit{\\Alpha}$', +u'\U0001d71d': '$\\mathbit{\\Beta}$', +u'\U0001d71e': '$\\mathbit{\\Gamma}$', +u'\U0001d71f': '$\\mathbit{\\Delta}$', +u'\U0001d720': '$\\mathbit{\\Epsilon}$', +u'\U0001d721': '$\\mathbit{\\Zeta}$', +u'\U0001d722': '$\\mathbit{\\Eta}$', +u'\U0001d723': '$\\mathbit{\\Theta}$', +u'\U0001d724': '$\\mathbit{\\Iota}$', +u'\U0001d725': '$\\mathbit{\\Kappa}$', +u'\U0001d726': '$\\mathbit{\\Lambda}$', +u'\U0001d727': '$M$', +u'\U0001d728': '$N$', +u'\U0001d729': '$\\mathbit{\\Xi}$', +u'\U0001d72a': '$O$', +u'\U0001d72b': '$\\mathbit{\\Pi}$', +u'\U0001d72c': '$\\mathbit{\\Rho}$', +u'\U0001d72d': '{\\mathbit{O}}', +u'\U0001d72e': '$\\mathbit{\\Sigma}$', +u'\U0001d72f': '$\\mathbit{\\Tau}$', +u'\U0001d730': '$\\mathbit{\\Upsilon}$', +u'\U0001d731': '$\\mathbit{\\Phi}$', +u'\U0001d732': '$\\mathbit{\\Chi}$', +u'\U0001d733': '$\\mathbit{\\Psi}$', +u'\U0001d734': '$\\mathbit{\\Omega}$', +u'\U0001d735': '$\\mathbit{\\nabla}$', +u'\U0001d736': '$\\mathbit{\\Alpha}$', +u'\U0001d737': '$\\mathbit{\\Beta}$', +u'\U0001d738': '$\\mathbit{\\Gamma}$', +u'\U0001d739': '$\\mathbit{\\Delta}$', +u'\U0001d73a': '$\\mathbit{\\Epsilon}$', +u'\U0001d73b': '$\\mathbit{\\Zeta}$', +u'\U0001d73c': '$\\mathbit{\\Eta}$', +u'\U0001d73d': '$\\mathbit{\\Theta}$', +u'\U0001d73e': '$\\mathbit{\\Iota}$', +u'\U0001d73f': '$\\mathbit{\\Kappa}$', +u'\U0001d740': '$\\mathbit{\\Lambda}$', +u'\U0001d741': '$M$', +u'\U0001d742': '$N$', +u'\U0001d743': '$\\mathbit{\\Xi}$', +u'\U0001d744': '$O$', +u'\U0001d745': '$\\mathbit{\\Pi}$', +u'\U0001d746': '$\\mathbit{\\Rho}$', +u'\U0001d747': '$\\mathbit{\\varsigma}$', +u'\U0001d748': '$\\mathbit{\\Sigma}$', +u'\U0001d749': '$\\mathbit{\\Tau}$', +u'\U0001d74a': '$\\mathbit{\\Upsilon}$', +u'\U0001d74b': '$\\mathbit{\\Phi}$', +u'\U0001d74c': '$\\mathbit{\\Chi}$', +u'\U0001d74d': '$\\mathbit{\\Psi}$', +u'\U0001d74e': '$\\mathbit{\\Omega}$', +u'\U0001d74f': '$\\partial$', +u'\U0001d750': '$\\in$', +u'\U0001d751': '{\\mathbit{\\vartheta}}', +u'\U0001d752': '{\\mathbit{\\varkappa}}', +u'\U0001d753': '{\\mathbit{\\phi}}', +u'\U0001d754': '{\\mathbit{\\varrho}}', +u'\U0001d755': '{\\mathbit{\\varpi}}', +u'\U0001d756': '$\\mathsfbf{\\Alpha}$', +u'\U0001d757': '$\\mathsfbf{\\Beta}$', +u'\U0001d758': '$\\mathsfbf{\\Gamma}$', +u'\U0001d759': '$\\mathsfbf{\\Delta}$', +u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', +u'\U0001d75c': '$\\mathsfbf{\\Eta}$', +u'\U0001d75d': '$\\mathsfbf{\\Theta}$', +u'\U0001d75e': '$\\mathsfbf{\\Iota}$', +u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', +u'\U0001d760': '$\\mathsfbf{\\Lambda}$', +u'\U0001d761': '$M$', +u'\U0001d762': '$N$', +u'\U0001d763': '$\\mathsfbf{\\Xi}$', +u'\U0001d764': '$O$', +u'\U0001d765': '$\\mathsfbf{\\Pi}$', +u'\U0001d766': '$\\mathsfbf{\\Rho}$', +u'\U0001d767': '{\\mathsfbf{\\vartheta}}', +u'\U0001d768': '$\\mathsfbf{\\Sigma}$', +u'\U0001d769': '$\\mathsfbf{\\Tau}$', +u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d76b': '$\\mathsfbf{\\Phi}$', +u'\U0001d76c': '$\\mathsfbf{\\Chi}$', +u'\U0001d76d': '$\\mathsfbf{\\Psi}$', +u'\U0001d76e': '$\\mathsfbf{\\Omega}$', +u'\U0001d76f': '$\\mathsfbf{\\nabla}$', +u'\U0001d770': '$\\mathsfbf{\\Alpha}$', +u'\U0001d771': '$\\mathsfbf{\\Beta}$', +u'\U0001d772': '$\\mathsfbf{\\Gamma}$', +u'\U0001d773': '$\\mathsfbf{\\Delta}$', +u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d775': '$\\mathsfbf{\\Zeta}$', +u'\U0001d776': '$\\mathsfbf{\\Eta}$', +u'\U0001d777': '$\\mathsfbf{\\Theta}$', +u'\U0001d778': '$\\mathsfbf{\\Iota}$', +u'\U0001d779': '$\\mathsfbf{\\Kappa}$', +u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', +u'\U0001d77b': '$M$', +u'\U0001d77c': '$N$', +u'\U0001d77d': '$\\mathsfbf{\\Xi}$', +u'\U0001d77e': '$O$', +u'\U0001d77f': '$\\mathsfbf{\\Pi}$', +u'\U0001d780': '$\\mathsfbf{\\Rho}$', +u'\U0001d781': '$\\mathsfbf{\\varsigma}$', +u'\U0001d782': '$\\mathsfbf{\\Sigma}$', +u'\U0001d783': '$\\mathsfbf{\\Tau}$', +u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d785': '$\\mathsfbf{\\Phi}$', +u'\U0001d786': '$\\mathsfbf{\\Chi}$', +u'\U0001d787': '$\\mathsfbf{\\Psi}$', +u'\U0001d788': '$\\mathsfbf{\\Omega}$', +u'\U0001d789': '$\\partial$', +u'\U0001d78a': '$\\in$', +u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', +u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', +u'\U0001d78d': '{\\mathsfbf{\\phi}}', +u'\U0001d78e': '{\\mathsfbf{\\varrho}}', +u'\U0001d78f': '{\\mathsfbf{\\varpi}}', +u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d79b': '$M$', +u'\U0001d79c': '$N$', +u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d79e': '$O$', +u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', +u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d7b5': '$M$', +u'\U0001d7b6': '$N$', +u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d7b8': '$O$', +u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', +u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7c3': '$\\partial$', +u'\U0001d7c4': '$\\in$', +u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', +u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', +u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', +u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', +u'\U0001d7ce': '$\\mathbf{0}$', +u'\U0001d7cf': '$\\mathbf{1}$', +u'\U0001d7d0': '$\\mathbf{2}$', +u'\U0001d7d1': '$\\mathbf{3}$', +u'\U0001d7d2': '$\\mathbf{4}$', +u'\U0001d7d3': '$\\mathbf{5}$', +u'\U0001d7d4': '$\\mathbf{6}$', +u'\U0001d7d5': '$\\mathbf{7}$', +u'\U0001d7d6': '$\\mathbf{8}$', +u'\U0001d7d7': '$\\mathbf{9}$', +u'\U0001d7d8': '$\\mathbb{0}$', +u'\U0001d7d9': '$\\mathbb{1}$', +u'\U0001d7da': '$\\mathbb{2}$', +u'\U0001d7db': '$\\mathbb{3}$', +u'\U0001d7dc': '$\\mathbb{4}$', +u'\U0001d7dd': '$\\mathbb{5}$', +u'\U0001d7de': '$\\mathbb{6}$', +u'\U0001d7df': '$\\mathbb{7}$', +u'\U0001d7e0': '$\\mathbb{8}$', +u'\U0001d7e1': '$\\mathbb{9}$', +u'\U0001d7e2': '$\\mathsf{0}$', +u'\U0001d7e3': '$\\mathsf{1}$', +u'\U0001d7e4': '$\\mathsf{2}$', +u'\U0001d7e5': '$\\mathsf{3}$', +u'\U0001d7e6': '$\\mathsf{4}$', +u'\U0001d7e7': '$\\mathsf{5}$', +u'\U0001d7e8': '$\\mathsf{6}$', +u'\U0001d7e9': '$\\mathsf{7}$', +u'\U0001d7ea': '$\\mathsf{8}$', +u'\U0001d7eb': '$\\mathsf{9}$', +u'\U0001d7ec': '$\\mathsfbf{0}$', +u'\U0001d7ed': '$\\mathsfbf{1}$', +u'\U0001d7ee': '$\\mathsfbf{2}$', +u'\U0001d7ef': '$\\mathsfbf{3}$', +u'\U0001d7f0': '$\\mathsfbf{4}$', +u'\U0001d7f1': '$\\mathsfbf{5}$', +u'\U0001d7f2': '$\\mathsfbf{6}$', +u'\U0001d7f3': '$\\mathsfbf{7}$', +u'\U0001d7f4': '$\\mathsfbf{8}$', +u'\U0001d7f5': '$\\mathsfbf{9}$', +u'\U0001d7f6': '$\\mathtt{0}$', +u'\U0001d7f7': '$\\mathtt{1}$', +u'\U0001d7f8': '$\\mathtt{2}$', +u'\U0001d7f9': '$\\mathtt{3}$', +u'\U0001d7fa': '$\\mathtt{4}$', +u'\U0001d7fb': '$\\mathtt{5}$', +u'\U0001d7fc': '$\\mathtt{6}$', +u'\U0001d7fd': '$\\mathtt{7}$', +u'\U0001d7fe': '$\\mathtt{8}$', +u'\U0001d7ff': '$\\mathtt{9}$'} -- cgit v1.2.1 From 21cbefe762f8fa767902ec12dfcd47b85638e24a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 16 Jun 2005 23:45:08 +0000 Subject: fixed test case with broken path in test output; this fix is somewhat ugly, I admit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3501 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/test_include.py | 36 +++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index 330dfd8c8..f7280a3d4 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -11,6 +11,7 @@ Tests for misc.py "include" directive. """ import os.path +import re import sys from __init__ import DocutilsTestSupport @@ -18,6 +19,9 @@ from __init__ import DocutilsTestSupport def suite(): s = DocutilsTestSupport.ParserTestSuite() s.generateTests(totest) + s.addTestCase( + SpecialIncludeTestCase, 'test_parser', + SpecialIncludeTestCase.input, SpecialIncludeTestCase.expected_regex) return s mydir = 'test_parsers/test_rst/test_directives/' @@ -373,23 +377,39 @@ Standard include data file: <substitution_definition names="b.gammad"> \\u03dd """], -["""\ +] + + +class SpecialIncludeTestCase(DocutilsTestSupport.ParserTestCase): + + def test_parser(self): + if self.run_in_debugger: + pdb.set_trace() + document = DocutilsTestSupport.utils.new_document( + 'test data', self.settings) + # Remove any additions made by "role" directives: + DocutilsTestSupport.roles._roles = {} + self.parser.parse(self.input, document) + output = document.pformat() + self.assert_(re.match(self.expected_regex, output), "Real output:\n" + + output + "\nExpected output:\n" + self.expected_regex) + + input = """\ Nonexistent standard include data file: .. include:: <nonexistent> -""", -"""\ -<document source="test data"> +""" + expected_regex = \ +r"""^<document source="test data"> <paragraph> Nonexistent standard include data file: <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: [Errno 2] No such file or directory: '../docutils/parsers/rst/include/nonexistent'. + IOError: \[Errno 2\] No such file or directory: .*\. <literal_block xml:space="preserve"> - .. include:: <nonexistent> -"""], -] + \.\. include:: <nonexistent> +$""" # Skip tests whose output contains "UnicodeDecodeError" if we are not -- cgit v1.2.1 From 8b7c50c33f64055a2be9342baadeb836dc07d6c8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 00:05:32 +0000 Subject: updated link to OpenOffice writer; Aahz says Patrick has a more recent version (a quick test shows that it works) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3502 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 1e463e0a2..313fb84f8 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -47,10 +47,7 @@ expect all of them to run out of the box. * Gunnar Schwant's DocFactory_ is a wxPython GUI application for Docutils. -* Aahz has begun an `OpenOffice.org Writer`_. - - .. Can anyone confirm that this works and maybe provide installation - instructions? (Emailed Aahz about that.) +* Patrick O'Brien has taken over the `OpenOffice.org Writer`_. * For Wikis, please see the `FAQ entry about Wikis`_. @@ -76,7 +73,7 @@ expect all of them to run out of the box. .. _DocBook Writer: http://docutils.sf.net/sandbox/oliverr/docbook/ .. _HT2HTML integration: http://docutils.sf.net/sandbox/oliverr/ht/ .. _DocFactory: http://docutils.sf.net/sandbox/gschwant/docfactory/doc/ -.. _OpenOffice.org Writer: http://docutils.sf.net/sandbox/aahz/OO/ +.. _OpenOffice.org Writer: http://docutils.sf.net/sandbox/pobrien/OpenOffice/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ .. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ -- cgit v1.2.1 From efefd166b752519c6af782b182d87963a8e47f30 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 13:46:10 +0000 Subject: corrected internal links; improved layout a bit git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3503 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index e391763c2..cdda16c68 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -123,14 +123,14 @@ <td nowrap><samp>reference_</samp> <td><a href="#hyperlink-targets">reference</a> <td>A simple, one-word hyperlink reference. See <a - href="#hyperlinks" >Hyperlinks</a>. + href="#hyperlink-targets">Hyperlink Targets</a>. <tr valign="top"> <td nowrap><samp>`phrase reference`_</samp> <td><a href="#hyperlink-targets">phrase reference</a> <td>A hyperlink reference with spaces or punctuation needs to be quoted with backquotes. See <a - href="#hyperlink-targets">Hyperlinks</a>. + href="#hyperlink-targets">Hyperlink Targets</a>. <tr valign="top"> <td nowrap><samp>anonymous__</samp> @@ -138,13 +138,13 @@ <td>With two underscores instead of one, both simple and phrase references may be anonymous (the reference text is not repeated at the target). See <a - href="#hyperlink-targets">Hyperlinks</a>. + href="#hyperlink-targets">Hyperlink Targets</a>. <tr valign="top"> <td nowrap><samp>_`inline internal target`</samp> <td><a name="inline-internal-target">inline internal target</a> <td>A crossreference target within text. - See <a href="#hyperlink-targets">Hyperlinks</a>. + See <a href="#hyperlink-targets">Hyperlink Targets</a>. <tr valign="top"> <td nowrap><samp>|substitution reference|</samp> @@ -1063,7 +1063,7 @@ A transition marker is a horizontal line <tbody> <tr valign="top"> - <td> + <td rowspan="2"> <samp>External hyperlinks, like Python_.</samp> <p><samp>.. _Python: http://www.python.org/</samp> @@ -1072,6 +1072,10 @@ A transition marker is a horizontal line <tr bgcolor="#99CCFF"><td><em>Fold-in form</em> <tr><td>Indirect hyperlinks, like <a href="http://www.python.org">Python</a>. + </table> + <tr valign="top"> + <td> + <table width="100%"> <tr bgcolor="#99CCFF"><td><em>Call-out form</em> <tr><td>External hyperlinks, like <a href="#labPython"><i>Python</i></a>. @@ -1102,7 +1106,7 @@ A transition marker is a horizontal line <tbody> <tr valign="top"> - <td><samp>Internal crossreferences, like example_.</samp> + <td rowspan="2"><samp>Internal crossreferences, like example_.</samp> <p><samp>.. _example:</samp> @@ -1117,6 +1121,10 @@ A transition marker is a horizontal line <tr><td>Internal crossreferences, like <a href="#example-foldin">example</a> <p><a name="example-foldin">This</a> is an example crossreference target. + </table> + <tr valign="top"> + <td> + <table width="100%"> <tr><td bgcolor="#99CCFF"><em>Call-out form</em> <tr><td>Internal crossreferences, like <a href="#example-callout">example</a> -- cgit v1.2.1 From d1368a7bed991b9a20a12b51373ccf974c23cad0 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 14:19:17 +0000 Subject: added link to default-role directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3504 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/roles.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/roles.txt b/docs/ref/rst/roles.txt index 1cb2e540b..b396af2eb 100644 --- a/docs/ref/rst/roles.txt +++ b/docs/ref/rst/roles.txt @@ -1,6 +1,7 @@ ========================================= reStructuredText Interpreted Text Roles ========================================= + :Author: David Goodger :Contact: goodger@users.sourceforge.net :Revision: $Revision$ @@ -20,7 +21,8 @@ with colons. For example:: A default role may be defined by applications of reStructuredText; it is used if no explicit ``:role:`` prefix or suffix is given. The -"default default role" is `:title-reference:`_. +"default default role" is `:title-reference:`_. It can be changed +using the default-role_ directive. See the `Interpreted Text`_ section in the `reStructuredText Markup Specification`_ for syntax details. For details on the hierarchy of @@ -30,6 +32,7 @@ implementation details, see `Creating reStructuredText Interpreted Text Roles`_. .. _"role" directive: directives.html#role +.. _default-role: directives.html#default-role .. _Interpreted Text: restructuredtext.html#interpreted-text .. _reStructuredText Markup Specification: restructuredtext.html .. _The Docutils Document Tree: ../doctree.html -- cgit v1.2.1 From 25229d1cf6672933c6d9d50e9b0c656265dceab3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 15:12:51 +0000 Subject: added embedded URI example; corrected link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3505 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index cdda16c68..fdb9a8adb 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -1070,8 +1070,8 @@ A transition marker is a horizontal line <td> <table width="100%"> <tr bgcolor="#99CCFF"><td><em>Fold-in form</em> - <tr><td>Indirect hyperlinks, like - <a href="http://www.python.org">Python</a>. + <tr><td>External hyperlinks, like + <a href="http://www.python.org/">Python</a>. </table> <tr valign="top"> <td> @@ -1094,6 +1094,28 @@ A transition marker is a horizontal line printed documents, where the link needs to be presented explicitly, for example as a footnote. + <p>reStructuredText also provides for <b>embedded URIs</b> (<a + href="../../ref/rst/restructuredtext.html#embedded-uris">details</a>), + a convenience at the expense of readability. A hyperlink + reference may directly embed a target URI inline, within angle + brackets. The following is exactly equivalent to the example above: + + <p><table border="1" width="100%" bgcolor="#ffffcc" cellpadding="3"> + <thead> + <tr align="left" bgcolor="#99CCFF"> + <th width="50%">Plain text + <th width="50%">Typical result + </thead> + <tbody> + + <tr valign="top"> + <td rowspan="2"> + <samp>External hyperlinks, like `Python +<br><http://www.python.org/>`_.</samp> + <td>External hyperlinks, like + <a href="http://www.python.org/">Python</a>. + </table> + <h4><a href="#contents" name="internal-hyperlink-targets" class="backref" >Internal Hyperlink Targets</a></h4> -- cgit v1.2.1 From 7fcc4af21966bb94d513017d40c68cc8335640f7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 15:20:28 +0000 Subject: added "New in Docutils 3.4.10" for units git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3506 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 8 +++++--- docs/ref/rst/restructuredtext.txt | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 73614b043..73c0b39ca 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -202,15 +202,17 @@ The following options are recognized: specified, they are combined. For example, a height of 200 and a scale of 50 is equivalent to a height of 100 with no scale. - It is also possible to specify a `length value`_. + New in Docutils 3.4.10: It is also possible to specify a `length + value`_. ``width`` : integer The width of the image in pixels, used to reserve space or scale the image horizontally. As with "height" above, when the "scale" option is also specified, they are combined. - It is also possible to specify a length_ or `percentage value`_ - (which is relative to the current line width). + New in Docutils 3.4.10: It is also possible to specify a length_ + or `percentage value`_ (which is relative to the current line + width). .. _length: .. _length value: restructuredtext.html#length-units diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 0823cc8eb..2282beac2 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2784,6 +2784,8 @@ characters (see `Escaping Mechanism`_ above). Units ===== +(New in Docutils 3.4.10.) + All measures consist of a positive floating point number in standard (non-scientific) notation and a unit, possibly separated by one or more spaces. -- cgit v1.2.1 From 70baa3875664998e598f5537ec067826c7143726 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 21:02:26 +0000 Subject: fixed handling of scale image attribute, so that David doesn't claim I just want to remove it because I'm too lazy to fix it ;-) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3507 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 1dae18b5c..e5c1c261e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -880,16 +880,17 @@ class HTMLTranslator(nodes.NodeVisitor): pass else: if not atts.has_key('width'): - atts['width'] = im.size[0] + atts['width'] = str(im.size[0]) if not atts.has_key('height'): - atts['height'] = im.size[1] + atts['height'] = str(im.size[1]) del im - if atts.has_key('width'): - atts['width'] = int(round(node['width'] - * (float(node['scale']) / 100))) - if atts.has_key('height'): - atts['height'] = int(round(node['height'] - * (float(node['scale']) / 100))) + for att_name in 'width', 'height': + if atts.has_key(att_name): + match = re.match(r'([0-9.]+)(.*)', atts[att_name]) + assert match + atts[att_name] = '%s%s' % ( + float(match.group(1)) * (float(node['scale']) / 100), + match.group(2)) style = [] for att_name in 'width', 'height': if atts.has_key(att_name): -- cgit v1.2.1 From 40318ee61cd1ad384d6ecae2ace8d3e734cfc7d7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 22:23:45 +0000 Subject: fixed path bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3508 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../test_rst/test_directives/test_include.py | 41 +++++++--------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index f7280a3d4..cf6ada106 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -11,17 +11,14 @@ Tests for misc.py "include" directive. """ import os.path -import re import sys +from docutils.parsers.rst import states from __init__ import DocutilsTestSupport def suite(): s = DocutilsTestSupport.ParserTestSuite() s.generateTests(totest) - s.addTestCase( - SpecialIncludeTestCase, 'test_parser', - SpecialIncludeTestCase.input, SpecialIncludeTestCase.expected_regex) return s mydir = 'test_parsers/test_rst/test_directives/' @@ -36,8 +33,10 @@ include11 = os.path.join(mydir, 'include 11.txt') include11rel = DocutilsTestSupport.utils.relative_path(None, include11) utf_16_file = os.path.join(mydir, 'utf-16.csv') utf_16_file_rel = DocutilsTestSupport.utils.relative_path(None, utf_16_file) +nonexistent = os.path.join(os.path.dirname(states.__file__), + 'include', 'nonexistent') nonexistent_rel = DocutilsTestSupport.utils.relative_path( - None, '../docutils/parsers/rst/include/nonexistent') + os.path.join(DocutilsTestSupport.testroot, 'dummy'), nonexistent) totest = {} @@ -377,39 +376,23 @@ Standard include data file: <substitution_definition names="b.gammad"> \\u03dd """], -] - - -class SpecialIncludeTestCase(DocutilsTestSupport.ParserTestCase): - - def test_parser(self): - if self.run_in_debugger: - pdb.set_trace() - document = DocutilsTestSupport.utils.new_document( - 'test data', self.settings) - # Remove any additions made by "role" directives: - DocutilsTestSupport.roles._roles = {} - self.parser.parse(self.input, document) - output = document.pformat() - self.assert_(re.match(self.expected_regex, output), "Real output:\n" + - output + "\nExpected output:\n" + self.expected_regex) - - input = """\ +["""\ Nonexistent standard include data file: .. include:: <nonexistent> -""" - expected_regex = \ -r"""^<document source="test data"> +""", +"""\ +<document source="test data"> <paragraph> Nonexistent standard include data file: <system_message level="4" line="3" source="test data" type="SEVERE"> <paragraph> Problems with "include" directive path: - IOError: \[Errno 2\] No such file or directory: .*\. + IOError: [Errno 2] No such file or directory: '%s'. <literal_block xml:space="preserve"> - \.\. include:: <nonexistent> -$""" + .. include:: <nonexistent> +""" % nonexistent_rel], +] # Skip tests whose output contains "UnicodeDecodeError" if we are not -- cgit v1.2.1 From 0bb885fc5af28e2476186ce446ff991fe2f8438f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 17 Jun 2005 22:24:13 +0000 Subject: fixed false assumption about path git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3509 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/__init__.py | 2 +- test/test_parsers/test_rst/__init__.py | 2 +- test/test_parsers/test_rst/test_directives/__init__.py | 2 +- test/test_readers/__init__.py | 2 +- test/test_readers/test_pep/__init__.py | 2 +- test/test_readers/test_python/__init__.py | 2 +- test/test_transforms/__init__.py | 2 +- test/test_writers/__init__.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test_parsers/__init__.py b/test/test_parsers/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_parsers/__init__.py +++ b/test/test_parsers/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_parsers/test_rst/__init__.py b/test/test_parsers/test_rst/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_parsers/test_rst/__init__.py +++ b/test/test_parsers/test_rst/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_parsers/test_rst/test_directives/__init__.py b/test/test_parsers/test_rst/test_directives/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_parsers/test_rst/test_directives/__init__.py +++ b/test/test_parsers/test_rst/test_directives/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_readers/__init__.py b/test/test_readers/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_readers/__init__.py +++ b/test/test_readers/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_readers/test_pep/__init__.py b/test/test_readers/test_pep/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_readers/test_pep/__init__.py +++ b/test/test_readers/test_pep/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_readers/test_python/__init__.py b/test/test_readers/test_python/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_readers/test_python/__init__.py +++ b/test/test_readers/test_python/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_transforms/__init__.py b/test/test_transforms/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_transforms/__init__.py +++ b/test/test_transforms/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: diff --git a/test/test_writers/__init__.py b/test/test_writers/__init__.py index 2fe79c55c..46fc50e06 100644 --- a/test/test_writers/__init__.py +++ b/test/test_writers/__init__.py @@ -2,7 +2,7 @@ import os import os.path import sys -sys.path.insert(0, os.path.abspath(os.curdir)) +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) prev = '' while sys.path[0] != prev: try: -- cgit v1.2.1 From 4220823618786ebcf147ce3dee195b6acdd4bb00 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 18 Jun 2005 00:09:14 +0000 Subject: added link to rst2chm git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3510 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 313fb84f8..22c8a9706 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -18,9 +18,13 @@ Related Projects ================ These are projects users of Docutils and reStructuredText may find -useful. Many of them projects are hosted in the `Docutils Sandbox`_. -All projects are usable by end users in some way, however do not -expect all of them to run out of the box. +useful, listed in no particular order. Many of them projects are +hosted in the `Docutils Sandbox`_. All projects are usable by end +users in some way, however do not expect all of them to run out of the +box. + +* rst2chm_, written by Oliver Rutherfurd, generates Microsoft HTML + Help files from reStructuredText files. * rest2web_, by Michael Foord, is a tool for creating web sites with reStructuredText. @@ -61,6 +65,7 @@ expect all of them to run out of the box. * Beni Cherniavsky maintains a Makefile_ for driving Docutils, hoping to handle everything one might do with docutils. +.. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ .. _rest2web: http://www.voidspace.org.uk/python/rest2web/ .. _Docutils Sandbox: http://docutils.sf.net/sandbox/README.html .. _ZReST: http://docutils.sf.net/sandbox/richard/ZReST/ -- cgit v1.2.1 From d90d048247c7f3012414659a52078b6c8a89765f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 19 Jun 2005 14:51:42 +0000 Subject: added deactivation of config file reading (for easier testing) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3511 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 5 +++++ test/DocutilsTestSupport.py | 35 ++++++++++++++++++++++------------ test/test_writers/test_docutils_xml.py | 6 ++---- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 679a648be..2fcf33e95 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -41,6 +41,9 @@ import optparse from optparse import SUPPRESS_HELP +_globally_deactivate_config_files = 0 +"""Deactivate reading of config files; for testing purposes.""" + def store_multiple(option, opt, value, parser, *args, **kwargs): """ Store multiple values in `parser.values`. (Option callback.) @@ -531,6 +534,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): def get_standard_config_files(self): """Return list of config files, from environment or standard.""" + if _globally_deactivate_config_files: + return [] try: config_files = os.environ['DOCUTILSCONFIG'].split(os.pathsep) except KeyError: diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index d9f78f774..5aadf91bb 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -17,6 +17,7 @@ Exports the following: - `tableparser` is 'docutils.parsers.rst.tableparser' :Classes: + - `StandardTestCase` - `CustomTestCase` - `CustomTestSuite` - `TransformTestCase` @@ -88,16 +89,29 @@ class DevNull: pass -class CustomTestCase(unittest.TestCase): +class StandardTestCase(unittest.TestCase): + + """ + Helper class, providing the same interface as unittest.TestCase, + but with useful setUp and tearDown methods. + """ + + def setUp(self): + os.chdir(testroot) + frontend._globally_deactivate_config_files = 1 + + def tearDown(self): + frontend._globally_deactivate_config_files = 0 + + +class CustomTestCase(StandardTestCase): """ Helper class, providing extended functionality over unittest.TestCase. - This isn't specific to Docutils but of general use when dealing - with large amounts of text. The methods failUnlessEqual and - failIfEqual have been overwritten to provide better support for - multi-line strings. Furthermore, see the compare_output method - and the parameter list of __init__. + The methods failUnlessEqual and failIfEqual have been overwritten + to provide better support for multi-line strings. Furthermore, + see the compare_output method and the parameter list of __init__. """ compare = docutils_difflib.Differ().compare @@ -135,11 +149,11 @@ class CustomTestCase(unittest.TestCase): def compare_output(self, input, output, expected): """`input`, `output`, and `expected` should all be strings.""" - if type(input) == UnicodeType: + if isinstance(input, UnicodeType): input = input.encode('raw_unicode_escape') - if type(output) == UnicodeType: + if isinstance(output, UnicodeType): output = output.encode('raw_unicode_escape') - if type(expected) == UnicodeType: + if isinstance(expected, UnicodeType): expected = expected.encode('raw_unicode_escape') try: self.assertEquals(output, expected) @@ -167,9 +181,6 @@ class CustomTestCase(unittest.TestCase): raise self.failureException, \ (msg or '%s == %s' % _format_str(first, second)) - def setUp(self): - os.chdir(testroot) - # Synonyms for assertion methods assertEqual = assertEquals = failUnlessEqual diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index 26c842761..1b9790c6a 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -11,12 +11,13 @@ Test for docutils XML writer. """ import unittest +from __init__ import DocutilsTestSupport import docutils import docutils.core -class DocutilsXMLTestCase(unittest.TestCase, docutils.SettingsSpec): +class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): input = 'Test\n====\n\nSubsection\n----------\n\nTest\n\n----------\n\nTest.' xmldecl = '<?xml version="1.0" encoding="iso-8859-1"?>\n' @@ -27,8 +28,6 @@ class DocutilsXMLTestCase(unittest.TestCase, docutils.SettingsSpec): bodynewlines = '<document ids="test" names="test" source="<string>">\n<title>\nTest\n\n\nSubsection\n\n\nTest\n\n\n\nTest.\n\n\n' bodyindents = '\n \n Test\n \n \n Subsection\n \n \n Test\n \n \n \n Test.\n \n\n' - settings_default_overrides = {'_disable_config': 1} - def test_publish(self): settings = {'output_encoding': 'iso-8859-1'} for settings['newlines'] in 0, 1: @@ -53,7 +52,6 @@ class DocutilsXMLTestCase(unittest.TestCase, docutils.SettingsSpec): (source=self.input, reader_name='standalone', writer_name='docutils_xml', - settings_spec=self, settings_overrides=settings), expected) -- cgit v1.2.1 From b30cbb0571acc552f53b3021ad9c63508a14330c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Jun 2005 15:26:13 +0000 Subject: made xmlcharrefreplace the default output encoding error handler for HTML and XML writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3512 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 +++++++ docs/dev/todo.txt | 4 ---- docutils/writers/docutils_xml.py | 2 ++ docutils/writers/html4css1.py | 2 ++ test/test_writers/test_docutils_xml.py | 12 ++++++------ test/test_writers/test_html4css1.py | 16 ++++++++++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 5cb822a0f..a76eb4abe 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -47,6 +47,13 @@ Changes Since 0.3.9 * docutils/writers/html4css1.py: - Added support for image width and height units. + - Made ``xmlcharrefreplace`` the default output encoding error + handler. + +* docutils/writers/docutils_xml.py: + + - Made ``xmlcharrefreplace`` the default output encoding error + handler. * docs/user/links.txt: Added to project; link list. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 481a99142..2727aeb43 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -122,10 +122,6 @@ General from "--generator", "--source-link", and "--date" etc.), allowing translations. -* Need a Unicode to HTML entities codec for HTML writer? No, the - "xmlcharrefreplace" output error handler is sufficient. - Make it the default for HTML & XML writers? - * Add validation? See http://pytrex.sourceforge.net, RELAX NG, pyRXP. * Ask Python-dev for opinions (GvR for a pronouncement) on special diff --git a/docutils/writers/docutils_xml.py b/docutils/writers/docutils_xml.py index 1b1164977..2362e6b78 100644 --- a/docutils/writers/docutils_xml.py +++ b/docutils/writers/docutils_xml.py @@ -39,6 +39,8 @@ class Writer(writers.Writer): {'dest': 'doctype_declaration', 'default': 1, 'action': 'store_false', 'validator': frontend.validate_boolean}),)) + settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} + config_section = 'docutils_xml writer' config_section_dependencies = ('writers',) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e5c1c261e..f77d6d8e8 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -108,6 +108,8 @@ class Writer(writers.Writer): ['--cloak-email-addresses'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} + relative_path_settings = ('stylesheet_path',) config_section = 'html4css1 writer' diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index 1b9790c6a..f5cf18b3f 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # Author: Felix Wiemann # Contact: Felix_Wiemann@ososo.de @@ -19,17 +20,16 @@ import docutils.core class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): - input = 'Test\n====\n\nSubsection\n----------\n\nTest\n\n----------\n\nTest.' + input = 'Test\n====\n\nSubsection\n----------\n\nTest\n\n----------\n\nTest. äöü€' xmldecl = '\n' doctypedecl = '\n' generatedby = '\n' % docutils.__version__ - bodynormal = 'TestSubsectionTestTest.' - bodynormal = 'TestSubsectionTestTest.' - bodynewlines = '\n\nTest\n\n\nSubsection\n\n\nTest\n\n\n\nTest.\n\n\n' - bodyindents = '\n \n Test\n \n \n Subsection\n \n \n Test\n \n \n \n Test.\n \n\n' + bodynormal = 'TestSubsectionTestTest. \xe4\xf6\xfc€' + bodynewlines = '\n\nTest\n\n\nSubsection\n\n\nTest\n\n\n\nTest. \xe4\xf6\xfc€\n\n\n' + bodyindents = '\n \n Test\n \n \n Subsection\n \n \n Test\n \n \n \n Test. \xe4\xf6\xfc€\n \n\n' def test_publish(self): - settings = {'output_encoding': 'iso-8859-1'} + settings = {'input_encoding': 'utf8', 'output_encoding': 'iso-8859-1'} for settings['newlines'] in 0, 1: for settings['indents'] in 0, 1: for settings['xml_declaration'] in 0, 1: diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 70d3be772..1cc15bd5e 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +# -*- coding: utf-8 -*- # Author: reggie dugard # Contact: reggie@users.sourceforge.net @@ -14,11 +15,16 @@ dictionaries (redundant), along with 'meta' and 'stylesheet' entries with standard values, and any entries with empty values. """ +from docutils import core + +import unittest from __init__ import DocutilsTestSupport def suite(): s = DocutilsTestSupport.HtmlPublishPartsTestSuite() s.generateTests(totest) + import test_html4css1 + s.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_html4css1)) return s @@ -317,6 +323,16 @@ And even more stuff ]) +class EncodingTestCase(DocutilsTestSupport.StandardTestCase): + + def test_xmlcharrefreplace(self): + # Test that xmlcharrefreplace is the default output encoding + # error handler. + self.assert_('\xe4\xf6\xfc€' in core.publish_string( + 'äöü€', writer_name='html4css1', + settings_overrides={'output_encoding': 'latin1'})) + + if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') -- cgit v1.2.1 From 0b2a9c1f38b64f72e1d5e387bea0db076c1d8f13 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Jun 2005 18:25:59 +0000 Subject: simplified test code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3516 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 5aadf91bb..e37d8698b 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -629,15 +629,19 @@ class PythonModuleParserTestSuite(CustomTestSuite): run_in_debugger=run_in_debugger) -class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): +class WriterPublishTestCase(CustomTestCase): """ Test case for publish. """ - settings_default_overrides = {'_disable_config': 1, 'strict_visitor': 1} writer_name = '' # override in subclasses + def __init__(self, *args, **kwargs): + self.writer_name = kwargs['writer_name'] + del kwargs['writer_name'] + CustomTestCase.__init__(self, *args, **kwargs) + def test_publish(self): if self.run_in_debugger: pdb.set_trace() @@ -646,34 +650,19 @@ class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): reader_name='standalone', parser_name='restructuredtext', writer_name=self.writer_name, - settings_spec=self) + settings_overrides={'strict_visitor': 1}) self.compare_output(self.input, output, self.expected) -class LatexWriterPublishTestCase(WriterPublishTestCase): - """Test case for Latex writer.""" - writer_name = 'latex' - - -class PseudoXMLWriterPublishTestCase(WriterPublishTestCase): - """Test case for pseudo-XML writer.""" - writer_name = 'pseudoxml' - - class PublishTestSuite(CustomTestSuite): - TEST_CLASSES = { - 'latex': LatexWriterPublishTestCase, - 'pseudoxml': PseudoXMLWriterPublishTestCase, - } - def __init__(self, writer_name): """ - `writer_name` is the name of the writer - to use. It must be a key in `TEST_CLASSES`. + `writer_name` is the name of the writer to use. """ CustomTestSuite.__init__(self) - self.test_class = self.TEST_CLASSES[writer_name] + self.test_class = WriterPublishTestCase + self.writer_name = writer_name def generateTests(self, dict, dictname='totest'): for name, cases in dict.items(): @@ -689,7 +678,9 @@ class PublishTestSuite(CustomTestSuite): self.test_class, 'test_publish', input=case[0], expected=case[1], id='%s[%r][%s]' % (dictname, name, casenum), - run_in_debugger=run_in_debugger) + run_in_debugger=run_in_debugger, + # Passed to constructor of self.test_class: + writer_name=self.writer_name) class HtmlPublishPartsTestSuite(CustomTestSuite): -- cgit v1.2.1 From 35f3e54cbfdeb7d4effa271bf0e7d07600ffd284 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Jun 2005 18:31:28 +0000 Subject: fixed error git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3517 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index e37d8698b..3f459bebf 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -629,17 +629,19 @@ class PythonModuleParserTestSuite(CustomTestSuite): run_in_debugger=run_in_debugger) -class WriterPublishTestCase(CustomTestCase): +class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): """ Test case for publish. """ - writer_name = '' # override in subclasses + settings_default_overrides = {'strict_visitor': 1} + writer_name = '' # set in subclasses or constructor def __init__(self, *args, **kwargs): - self.writer_name = kwargs['writer_name'] - del kwargs['writer_name'] + if kwargs.has_key('writer_name'): + self.writer_name = kwargs['writer_name'] + del kwargs['writer_name'] CustomTestCase.__init__(self, *args, **kwargs) def test_publish(self): @@ -650,7 +652,7 @@ class WriterPublishTestCase(CustomTestCase): reader_name='standalone', parser_name='restructuredtext', writer_name=self.writer_name, - settings_overrides={'strict_visitor': 1}) + settings_spec=self) self.compare_output(self.input, output, self.expected) -- cgit v1.2.1 From 441b917b41e9d168ad1d4150d2f46007623699b8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Jun 2005 18:31:40 +0000 Subject: made Null writer return an empty string git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3518 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/null.py | 2 +- test/test_writers/test_null.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100755 test/test_writers/test_null.py diff --git a/docutils/writers/null.py b/docutils/writers/null.py index cf3566480..faf7bbfad 100644 --- a/docutils/writers/null.py +++ b/docutils/writers/null.py @@ -20,4 +20,4 @@ class Writer(writers.Writer): config_section_dependencies = ('writers',) def translate(self): - pass + self.output = u'' diff --git a/test/test_writers/test_null.py b/test/test_writers/test_null.py new file mode 100755 index 000000000..9f8d8fe19 --- /dev/null +++ b/test/test_writers/test_null.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test for Null writer. +""" + +from __init__ import DocutilsTestSupport + +def suite(): + s = DocutilsTestSupport.PublishTestSuite('null') + s.generateTests(totest) + return s + +totest = {} + +totest['basic'] = [ +["""\ +This is a paragraph. +""", +"""\ +"""] +] + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 99999e2956b38578f91417ad0bc2e80be6c961a7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Jun 2005 18:55:08 +0000 Subject: added history entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3519 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index a76eb4abe..2c233fd7b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -55,6 +55,10 @@ Changes Since 0.3.9 - Made ``xmlcharrefreplace`` the default output encoding error handler. +* docutils/writers/null.py: + + - The Null Writer now returns an empty string instead of None. + * docs/user/links.txt: Added to project; link list. * docs/ref/rst/substitutions.txt: "reStructuredText Standard -- cgit v1.2.1 From ac78efa666ab4f1d7f8dd5b46edb681a79e457e2 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 20 Jun 2005 03:35:33 +0000 Subject: added Publisher.document object attribute, for direct access to the doctree git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3520 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 302c39eb2..fa796a3db 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -39,6 +39,9 @@ class Publisher: a component name (`set_reader` sets the parser as well). """ + self.document = None + """The document tree (`docutils.nodes` objects).""" + self.reader = reader """A `docutils.readers.Reader` instance.""" @@ -168,11 +171,11 @@ class Publisher: encoding=self.settings.output_encoding, error_handler=self.settings.output_encoding_error_handler) - def apply_transforms(self, document): - document.transformer.populate_from_components( + def apply_transforms(self): + self.document.transformer.populate_from_components( (self.source, self.reader, self.reader.parser, self.writer, self.destination)) - document.transformer.apply_transforms() + self.document.transformer.apply_transforms() def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None, @@ -188,43 +191,43 @@ class Publisher: **(settings_overrides or {})) self.set_io() exit = None - document = None try: - document = self.reader.read(self.source, self.parser, - self.settings) - self.apply_transforms(document) - output = self.writer.write(document, self.destination) + self.document = self.reader.read(self.source, self.parser, + self.settings) + self.apply_transforms() + output = self.writer.write(self.document, self.destination) self.writer.assemble_parts() except Exception, error: if self.settings.traceback: # propagate exceptions? - self.debugging_dumps(document) + self.debugging_dumps() raise self.report_Exception(error) exit = 1 - self.debugging_dumps(document) - if (enable_exit_status and document - and (document.reporter.max_level + self.debugging_dumps() + if (enable_exit_status and self.document + and (self.document.reporter.max_level >= self.settings.exit_status_level)): - sys.exit(document.reporter.max_level + 10) + sys.exit(self.document.reporter.max_level + 10) elif exit: sys.exit(1) return output - def debugging_dumps(self, document): - if not document: + def debugging_dumps(self): + if not self.document: return if self.settings.dump_settings: print >>sys.stderr, '\n::: Runtime settings:' print >>sys.stderr, pprint.pformat(self.settings.__dict__) - if self.settings.dump_internals and document: + if self.settings.dump_internals: print >>sys.stderr, '\n::: Document internals:' - print >>sys.stderr, pprint.pformat(document.__dict__) - if self.settings.dump_transforms and document: + print >>sys.stderr, pprint.pformat(self.document.__dict__) + if self.settings.dump_transforms: print >>sys.stderr, '\n::: Transforms applied:' - print >>sys.stderr, pprint.pformat(document.transformer.applied) - if self.settings.dump_pseudo_xml and document: + print >>sys.stderr, pprint.pformat( + self.document.transformer.applied) + if self.settings.dump_pseudo_xml: print >>sys.stderr, '\n::: Pseudo-XML:' - print >>sys.stderr, document.pformat().encode( + print >>sys.stderr, self.document.pformat().encode( 'raw_unicode_escape') def report_Exception(self, error): -- cgit v1.2.1 From 9d4e4e72dcc057f707bf393570714fac91ec6d01 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 17:42:33 +0000 Subject: changed default PEP python home to http://www.python.org git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3526 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/pep_html.py | 6 +++--- tools/docutils.conf | 1 - tools/pep-html-template | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index f6601120a..1e9b8744a 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -25,9 +25,9 @@ class Writer(html4css1.Writer): (('Specify a template file. Default is "pep-html-template".', ['--template'], {'default': 'pep-html-template', 'metavar': ''}), - ('Python\'s home URL. Default is ".." (parent directory).', + ('Python\'s home URL. Default is "http://www.python.org".', ['--python-home'], - {'default': '..', 'metavar': ''}), + {'default': 'http://www.python.org', 'metavar': ''}), ('Home URL prefix for PEPs. Default is "." (current directory).', ['--pep-home'], {'default': '.', 'metavar': ''}), @@ -61,7 +61,7 @@ class Writer(html4css1.Writer): if pyhome == '..': subs['pepindex'] = '.' else: - subs['pepindex'] = pyhome + '/peps/' + subs['pepindex'] = pyhome + '/peps' index = self.document.first_child_matching_class(nodes.field_list) header = self.document[index] pepnum = header[0][1].astext() diff --git a/tools/docutils.conf b/tools/docutils.conf index 9f218d3bf..8d09a65a5 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -13,4 +13,3 @@ field-name-limit: 20 # These entries affect reStructuredText-style PEPs: template: pep-html-template stylesheet-path: stylesheets/pep.css -python-home: http://www.python.org diff --git a/tools/pep-html-template b/tools/pep-html-template index 94ecafb70..bbaeb64b2 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -20,7 +20,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! border="0" width="150" height="35" />
    %(body)s -- cgit v1.2.1 From 150b5f5083d215326c040df4393413379f62e8f4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 17:57:40 +0000 Subject: added Distributor's Guide; if there is agreement on this installation procedure, I'll send email to the package maintainers git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3527 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 159 ++++++++++++++++++++++++++++++++++++++++++++++ docs/index.txt | 1 + 2 files changed, 160 insertions(+) create mode 100644 docs/dev/distributing.txt diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt new file mode 100644 index 000000000..f7979a62f --- /dev/null +++ b/docs/dev/distributing.txt @@ -0,0 +1,159 @@ +.. -*- coding: utf-8 -*- + +=============================== + Docutils_ Distributor's Guide +=============================== + +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + +.. _Docutils: http://docutils.sourceforge.net/ + +.. contents:: + +This document describes how to create packages of Docutils (e.g. for +shipping them with a Linux distribution). If you have any questions, +please direct them to the Docutils-develop_ mailing list. + +First of all, please download the most current `release tarball`_ and +unpack it. + +.. _Docutils-develop: ../user/mailing-lists.html#docutils-develop +.. _release tarball: http://docutils.sourceforge.net/#download + + +Dependencies +============ + +Docutils has the following dependencies: + +* Python 2.1 or later is required. (While the compiler package from + the Tools/ directory of Python's source distribution must be + installed for the test suite to pass with Python 2.1, the + functionality available to end users should be available without the + compiler package as well. So just use >= Python 2.1 in the + dependencies.) + +* Docutils may optionally make use of the PIL (Python Imaging + Library). If PIL is present, it is automatically detected by + Docutils. + +* There are three files in the ``extras/`` directory of the Docutils + distribution, ``optparse.py``, ``textwrap.py``, and ``roman.py``. + For Python 2.1/2.2, all of them must be installed (into the + ``site-packages/`` directory). Python 2.3 and later versions have + ``textwrap`` and ``optparse`` included in the standard library, so + only ``roman.py`` is required here; installing the other files won't + hurt, though. + + These files are automatically installed by the setup script (when + calling "python setup.py install"). + + +Python Files +============ + +The Docutils Python files must be installed into the +``site-packages/`` directory of Python. Running ``python setup.py +install`` should do the trick, but if you want to place the files +yourself, you can just install the ``docutils/`` directory of the +Docutils tarball to ``/usr/lib/python/site-packages/docutils/``. In +this case you should also compile the Python files to ``.pyc`` and/or +``.pyo`` files so that Docutils doesn't need to be recompiled +everytime it's executed. + + +Binaries +======== + +The binaries are located in the ``tools/`` directory of the Docutils +tarball. + +The ``rst2*.py`` tools except ``rst2newlatex.py`` are intended for +end-users. You should install them to ``/usr/bin/``. You do not need +to change the names (e.g. to ``docutils-rst2html.py``) because the +``rst2`` prefix is unique. + + +Documentation +============= + +The documentation should be generated using ``buildhtml.py``. Go to +the ``tools/`` directory and run ``./buildhtml.py ..``. This will +create all HTML files. + +Then install the following files to ``/usr/share/doc/docutils/`` (or +however you like to call the documentation directory): + +* All ``.html`` and ``.txt`` files in the base directory. +* The ``docs/`` directory. (Do not install the contents of the + ``docs/`` directory directory directly to + ``/usr/share/doc/docutils/``—it's incomplete and would contain + invalid references!) +* The ``licenses/`` directory. +* ``tools/stylesheets/default.css``, creating the ``tools/`` and + ``tools/stylesheets/`` directory beforehand. This file is needed + for correct viewing of the HTML files. (You do not need to install + the other contents of the ``tools/`` or ``stylesheets/`` directory. + However, do not install ``default.css`` right into the documentation + base directory, or the references to the stylesheet will not work.) + + +Removing the ``.txt`` Files +--------------------------- + +If you are tight with disk space, you can remove all ``.txt`` files in +the tree except for: + +* those in the ``licenses/`` directory because they have not been + processed to HTML and +* ``user/rst/cheatsheet.txt`` and ``user/rst/demo.txt``, which should + be readable in source form. + +Before you remove the ``.txt`` files you should rerun ``buildhtml.py`` +as ``./buildhtml.py .. --no-source-link`` to avoid broken references +to the source files. + + +Other Files +=========== + +Install ``tools/stylesheets/`` to ``/usr/lib/docutils/stylesheets/`` +and ``tools/pep-html-template`` to +``/usr/lib/docutils/pep-html-template``. + +You may also want to install the Emacs-Lisp files +``tools/editors/emacs/*.el`` into the appropriate directory. + + +Configuration File +================== + +The system-wide configuration file is located in +``/etc/docutils.conf``. You should *not* install +``tools/docutils.conf`` into ``/etc/``. Instead, we recommend that +you create a new ``/etc/docutils.conf`` file containing references to +the appropriate files on your system:: + + [html4css1 writer] + # These entries affect HTML output: + stylesheet-path: /usr/lib/docutils/stylesheets/default.css + + [pep_html writer] + # These entries affect reStructuredText-style PEPs: + template: /usr/lib/docutils/pep-html-template + stylesheet-path: /usr/lib/docutils/stylesheets/pep.css + +(Adjust the paths as necessary.) + + +Tests +===== + +While you probably do not need to ship the tests with your +distribution, you can test your package by installing it and then +running ``alltests.py`` from the ``tests/`` directory of the Docutils +tarball. diff --git a/docs/index.txt b/docs/index.txt index 08fbddcf0..eeb8a5125 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -194,6 +194,7 @@ __ http://www.python.org/peps/pep-0287.html Docutils-general: * `Docutils Hacker's Guide `__ +* `Docutils Distributor's Guide `__ * `Docutils To Do List `__ * `Docutils Project Policies `__ * `Docutils Web Site `__ -- cgit v1.2.1 From cafd4ffdb9b3658d0d11e37d8839a1941661263b Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 17:59:01 +0000 Subject: added history entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3528 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 2c233fd7b..4b475b0e7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -59,6 +59,8 @@ Changes Since 0.3.9 - The Null Writer now returns an empty string instead of None. +* docs/dev/distributing.txt: Added to project; guide for distributors. + * docs/user/links.txt: Added to project; link list. * docs/ref/rst/substitutions.txt: "reStructuredText Standard -- cgit v1.2.1 From c38381105b2220a495e7cec712ede709417f23c8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 18:02:01 +0000 Subject: corrected syntax error in distributing.txt; mmmh... the spec should be changed, this error is unnecessary git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3529 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index f7979a62f..05aa4f2c6 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -91,7 +91,7 @@ however you like to call the documentation directory): * All ``.html`` and ``.txt`` files in the base directory. * The ``docs/`` directory. (Do not install the contents of the ``docs/`` directory directory directly to - ``/usr/share/doc/docutils/``—it's incomplete and would contain + ``/usr/share/doc/docutils/``\ —it's incomplete and would contain invalid references!) * The ``licenses/`` directory. * ``tools/stylesheets/default.css``, creating the ``tools/`` and -- cgit v1.2.1 From 6c5b25fc690b88490dc59b19ee1d30e26bf841cf Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 20 Jun 2005 18:56:47 +0000 Subject: updated character entity entry; whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3531 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 756fedc38..c5c2e06f4 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -257,12 +257,20 @@ inside or outside inline literals or literal blocks -- there's no character entity interpretation in either case. If you can't use a Unicode-compatible encoding and must rely on 7-bit -ASCII, there is a workaround. Files containing character entity set -substitution definitions using the "unicode_" directive `are -available`_ (tarball_). Please read the `description and +ASCII, there is a workaround. New in Docutils 0.3.10 is a set of +`Standard Substitution Definition Sets`_, which provide equivalents of +XML & HTML character entity sets as substitution definitions. For +example, the Japanese yen currency symbol can be used as follows:: + + .. include:: + + |yen| 600 for a complete meal? That's cheap! + +For earlier versions of Docutils, equivalent files containing +character entity set substitution definitions using the "unicode_" +directive `are available`_. Please read the `description and instructions`_ for use. Thanks to David Priest for the original idea. -Incorporating these files into Docutils is on the `to-do list`_. - + If you insist on using XML-style charents, you'll have to implement a pre-processing system to convert to UTF-8 or something. That introduces complications though; you can no longer *write* about @@ -286,9 +294,10 @@ bar``", rendered as "foo |--| bar; foo |---| bar". (Note that Mozilla and Firefox may render this incorrectly.) The ``:trim:`` option for the em dash is necessary because you cannot write "``foo|---|bar``"; thus you need to add spaces ("``foo |---| bar``") and advise the -reStructuredText parser to trim the spaces using the ``:trim:`` -option. +reStructuredText parser to trim the spaces. +.. _Standard Substitution Definition Sets: + http://docutils.sf.net/docs/ref/rst/substitutions.html .. _unicode: http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes .. _are available: http://docutils.sourceforge.net/tmp/charents/ @@ -345,8 +354,6 @@ Possible solutions include International, Input Menu tab, enable "Show input menu in menu bar", and be sure that Character Palette is enabled in the list. - Other options are welcome. - If anyone knows of other/better solutions, please `let us know`_. @@ -469,7 +476,7 @@ They all presently use LaTeX syntax or dialects of it. .. raw:: latex \[ x^3 + 3x^2a + 3xa^2 + a^3, \] - + For inline math you could use substitutions of the raw directive but the recently added `raw role`_ is more convenient. You must define a custom role based on it once in your document:: @@ -579,17 +586,17 @@ literal blocks, the typeface is not changed, and inline markup is recognized. For example:: | A one, two, a one two three four - | + | | Half a bee, philosophically, | must, *ipso facto*, half not be. | But half the bee has got to be, | *vis a vis* its entity. D'you see? - | + | | But can a bee be said to be | or not to be an entire bee, | when half the bee is not a bee, | due to some ancient injury? - | + | | Singing... __ http://docutils.sf.net/docs/ref/rst/restructuredtext.html#line-blocks -- cgit v1.2.1 From 2ce6724de5ff00aed429bcef45f1899661bee563 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 20 Jun 2005 18:59:29 +0000 Subject: tool for developers; moved git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3532 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/dev/unicode2rstsubs.py | 204 +++++++++++++++++++++++++++++++++++++++++++ tools/unicode2rstsubs.py | 204 ------------------------------------------- 2 files changed, 204 insertions(+), 204 deletions(-) create mode 100755 tools/dev/unicode2rstsubs.py delete mode 100755 tools/unicode2rstsubs.py diff --git a/tools/dev/unicode2rstsubs.py b/tools/dev/unicode2rstsubs.py new file mode 100755 index 000000000..abc85e48b --- /dev/null +++ b/tools/dev/unicode2rstsubs.py @@ -0,0 +1,204 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This program has been placed in the public domain. + +""" +unicode2subfiles.py -- produce character entity files (reSructuredText +substitutions) from the W3C master unicode.xml file. + +This program extracts character entity and entity set information from a +unicode.xml file and produces multiple reStructuredText files (in the current +directory) containing substitutions. Entity sets are from ISO 8879 & ISO +9573-13 (combined), MathML, and HTML4. One or two files are produced for each +entity set; a second file with a "-wide.txt" suffix is produced if there are +wide-Unicode characters in the set. + +The input file, unicode.xml, is maintained as part of the MathML 2 +Recommentation XML source, and is available from +. +""" + +import sys +import os +import optparse +import re +from xml.parsers.expat import ParserCreate + + +usage_msg = """Usage: %s [unicode.xml]""" + +def usage(prog, status=0, msg=None): + print >>sys.stderr, usage_msg % prog + if msg: + print >>sys.stderr, msg + sys.exit(status) + +def main(argv=None): + if argv is None: + argv = sys.argv + if len(argv) == 2: + inpath = argv[1] + elif len(argv) > 2: + usage(argv[0], 2, + 'Too many arguments (%s): only 1 expected.' % (len(argv) - 1)) + else: + inpath = 'unicode.xml' + if not os.path.isfile(inpath): + usage(argv[0], 1, 'No such file: "%s".' % inpath) + infile = open(inpath) + process(infile) + +def process(infile): + grouper = CharacterEntitySetExtractor(infile) + grouper.group() + grouper.write_sets() + + +class CharacterEntitySetExtractor: + + """ + Extracts character entity information from unicode.xml file, groups it by + entity set, and writes out reStructuredText substitution files. + """ + + unwanted_entity_sets = ['stix', # unknown, buggy set + 'predefined'] + + header = """\ +.. This data file has been placed in the public domain. +.. Derived from the Unicode character mappings available from + . + Processed by unicode2rstsubs.py, part of Docutils: + . +""" + + def __init__(self, infile): + self.infile = infile + """Input unicode.xml file.""" + + self.parser = self.setup_parser() + """XML parser.""" + + self.elements = [] + """Stack of element names. Last is current element.""" + + self.sets = {} + """Mapping of charent set name to set dict.""" + + self.charid = None + """Current character's "id" attribute value.""" + + self.descriptions = {} + """Mapping of character ID to description.""" + + def setup_parser(self): + parser = ParserCreate() + parser.StartElementHandler = self.StartElementHandler + parser.EndElementHandler = self.EndElementHandler + parser.CharacterDataHandler = self.CharacterDataHandler + return parser + + def group(self): + self.parser.ParseFile(self.infile) + + def StartElementHandler(self, name, attributes): + self.elements.append(name) + handler = name + '_start' + if hasattr(self, handler): + getattr(self, handler)(name, attributes) + + def EndElementHandler(self, name): + assert self.elements[-1] == name, \ + 'unknown end-tag %r (%r)' % (name, self.element) + self.elements.pop() + handler = name + '_end' + if hasattr(self, handler): + getattr(self, handler)(name) + + def CharacterDataHandler(self, data): + handler = self.elements[-1] + '_data' + if hasattr(self, handler): + getattr(self, handler)(data) + + def character_start(self, name, attributes): + self.charid = attributes['id'] + + def entity_start(self, name, attributes): + set = self.entity_set_name(attributes['set']) + if not set: + return + if not self.sets.has_key(set): + print 'bad set: %r' % set + return + entity = attributes['id'] + assert (not self.sets[set].has_key(entity) + or self.sets[set][entity] == self.charid), \ + ('sets[%r][%r] == %r (!= %r)' + % (set, entity, self.sets[set][entity], self.charid)) + self.sets[set][entity] = self.charid + + def description_data(self, data): + self.descriptions.setdefault(self.charid, '') + self.descriptions[self.charid] += data + + entity_set_name_pat = re.compile(r'[0-9-]*(.+)$') + """Pattern to strip ISO numbers off the beginning of set names.""" + + def entity_set_name(self, name): + """ + Return lowcased and standard-number-free entity set name. + Return ``None`` for unwanted entity sets. + """ + match = self.entity_set_name_pat.match(name) + name = match.group(1).lower() + if name in self.unwanted_entity_sets: + return None + self.sets.setdefault(name, {}) + return name + + def write_sets(self): + sets = self.sets.keys() + sets.sort() + for set_name in sets: + self.write_set(set_name) + + def write_set(self, set_name, wide=None): + if wide: + outname = set_name + '-wide.txt' + else: + outname = set_name + '.txt' + outfile = open(outname, 'w') + print 'writing file "%s"' % outname + print >>outfile, self.header + set = self.sets[set_name] + entities = [(e.lower(), e) for e in set.keys()] + entities.sort() + longest = 0 + for _, entity_name in entities: + longest = max(longest, len(entity_name)) + has_wide = None + for _, entity_name in entities: + has_wide = self.write_entity( + set, set_name, entity_name, outfile, longest, wide) or has_wide + if has_wide and not wide: + self.write_set(set_name, 1) + + def write_entity(self, set, set_name, entity_name, outfile, longest, + wide=None): + charid = set[entity_name] + if not wide: + for code in charid[1:].split('-'): + if int(code, 16) > 0xFFFF: + return 1 # wide-Unicode character + codes = ' '.join(['U+%s' % code for code in charid[1:].split('-')]) + print >>outfile, ('.. %-*s unicode:: %s .. %s' + % (longest + 2, '|' + entity_name + '|', + codes, self.descriptions[charid])) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/unicode2rstsubs.py b/tools/unicode2rstsubs.py deleted file mode 100755 index abc85e48b..000000000 --- a/tools/unicode2rstsubs.py +++ /dev/null @@ -1,204 +0,0 @@ -#! /usr/bin/env python - -# Author: David Goodger -# Contact: goodger@python.org -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This program has been placed in the public domain. - -""" -unicode2subfiles.py -- produce character entity files (reSructuredText -substitutions) from the W3C master unicode.xml file. - -This program extracts character entity and entity set information from a -unicode.xml file and produces multiple reStructuredText files (in the current -directory) containing substitutions. Entity sets are from ISO 8879 & ISO -9573-13 (combined), MathML, and HTML4. One or two files are produced for each -entity set; a second file with a "-wide.txt" suffix is produced if there are -wide-Unicode characters in the set. - -The input file, unicode.xml, is maintained as part of the MathML 2 -Recommentation XML source, and is available from -. -""" - -import sys -import os -import optparse -import re -from xml.parsers.expat import ParserCreate - - -usage_msg = """Usage: %s [unicode.xml]""" - -def usage(prog, status=0, msg=None): - print >>sys.stderr, usage_msg % prog - if msg: - print >>sys.stderr, msg - sys.exit(status) - -def main(argv=None): - if argv is None: - argv = sys.argv - if len(argv) == 2: - inpath = argv[1] - elif len(argv) > 2: - usage(argv[0], 2, - 'Too many arguments (%s): only 1 expected.' % (len(argv) - 1)) - else: - inpath = 'unicode.xml' - if not os.path.isfile(inpath): - usage(argv[0], 1, 'No such file: "%s".' % inpath) - infile = open(inpath) - process(infile) - -def process(infile): - grouper = CharacterEntitySetExtractor(infile) - grouper.group() - grouper.write_sets() - - -class CharacterEntitySetExtractor: - - """ - Extracts character entity information from unicode.xml file, groups it by - entity set, and writes out reStructuredText substitution files. - """ - - unwanted_entity_sets = ['stix', # unknown, buggy set - 'predefined'] - - header = """\ -.. This data file has been placed in the public domain. -.. Derived from the Unicode character mappings available from - . - Processed by unicode2rstsubs.py, part of Docutils: - . -""" - - def __init__(self, infile): - self.infile = infile - """Input unicode.xml file.""" - - self.parser = self.setup_parser() - """XML parser.""" - - self.elements = [] - """Stack of element names. Last is current element.""" - - self.sets = {} - """Mapping of charent set name to set dict.""" - - self.charid = None - """Current character's "id" attribute value.""" - - self.descriptions = {} - """Mapping of character ID to description.""" - - def setup_parser(self): - parser = ParserCreate() - parser.StartElementHandler = self.StartElementHandler - parser.EndElementHandler = self.EndElementHandler - parser.CharacterDataHandler = self.CharacterDataHandler - return parser - - def group(self): - self.parser.ParseFile(self.infile) - - def StartElementHandler(self, name, attributes): - self.elements.append(name) - handler = name + '_start' - if hasattr(self, handler): - getattr(self, handler)(name, attributes) - - def EndElementHandler(self, name): - assert self.elements[-1] == name, \ - 'unknown end-tag %r (%r)' % (name, self.element) - self.elements.pop() - handler = name + '_end' - if hasattr(self, handler): - getattr(self, handler)(name) - - def CharacterDataHandler(self, data): - handler = self.elements[-1] + '_data' - if hasattr(self, handler): - getattr(self, handler)(data) - - def character_start(self, name, attributes): - self.charid = attributes['id'] - - def entity_start(self, name, attributes): - set = self.entity_set_name(attributes['set']) - if not set: - return - if not self.sets.has_key(set): - print 'bad set: %r' % set - return - entity = attributes['id'] - assert (not self.sets[set].has_key(entity) - or self.sets[set][entity] == self.charid), \ - ('sets[%r][%r] == %r (!= %r)' - % (set, entity, self.sets[set][entity], self.charid)) - self.sets[set][entity] = self.charid - - def description_data(self, data): - self.descriptions.setdefault(self.charid, '') - self.descriptions[self.charid] += data - - entity_set_name_pat = re.compile(r'[0-9-]*(.+)$') - """Pattern to strip ISO numbers off the beginning of set names.""" - - def entity_set_name(self, name): - """ - Return lowcased and standard-number-free entity set name. - Return ``None`` for unwanted entity sets. - """ - match = self.entity_set_name_pat.match(name) - name = match.group(1).lower() - if name in self.unwanted_entity_sets: - return None - self.sets.setdefault(name, {}) - return name - - def write_sets(self): - sets = self.sets.keys() - sets.sort() - for set_name in sets: - self.write_set(set_name) - - def write_set(self, set_name, wide=None): - if wide: - outname = set_name + '-wide.txt' - else: - outname = set_name + '.txt' - outfile = open(outname, 'w') - print 'writing file "%s"' % outname - print >>outfile, self.header - set = self.sets[set_name] - entities = [(e.lower(), e) for e in set.keys()] - entities.sort() - longest = 0 - for _, entity_name in entities: - longest = max(longest, len(entity_name)) - has_wide = None - for _, entity_name in entities: - has_wide = self.write_entity( - set, set_name, entity_name, outfile, longest, wide) or has_wide - if has_wide and not wide: - self.write_set(set_name, 1) - - def write_entity(self, set, set_name, entity_name, outfile, longest, - wide=None): - charid = set[entity_name] - if not wide: - for code in charid[1:].split('-'): - if int(code, 16) > 0xFFFF: - return 1 # wide-Unicode character - codes = ' '.join(['U+%s' % code for code in charid[1:].split('-')]) - print >>outfile, ('.. %-*s unicode:: %s .. %s' - % (longest + 2, '|' + entity_name + '|', - codes, self.descriptions[charid])) - - -if __name__ == '__main__': - sys.exit(main()) -- cgit v1.2.1 From fbc14fc4439455bc8726051604c4148ed14e29ee Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:12:33 +0000 Subject: renamed tools/pep.py to rstpep2html.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3533 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docs/user/tools.txt | 28 ++++++++++++++-------------- tools/pep.py | 27 --------------------------- tools/rstpep2html.py | 27 +++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 41 deletions(-) delete mode 100755 tools/pep.py create mode 100755 tools/rstpep2html.py diff --git a/HISTORY.txt b/HISTORY.txt index 4b475b0e7..9be255b85 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -68,6 +68,8 @@ Changes Since 0.3.9 * test/coverage.sh: Added to project; test coverage script. +* tools/rstpep2html.py: Renamed from pep.py. + * tools/dev/profile_docutils.py: Added to project; profiler script. diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 9cd136988..28433005e 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -141,20 +141,20 @@ stylesheets override styles in imported stylesheets, enabling incremental experimentation. -pep.py ------- +rstpep2html.py +-------------- :Reader: PEP :Parser: reStructuredText :Writer: PEP/HTML -``pep.py`` reads a new-style PEP (marked up with reStructuredText) and -produces HTML. It requires a template file and a stylesheet. By -default, it makes use of a "``pep-html-template``" file and a -"``default.css``" stylesheet in the current directory, but these can -be overridden by command-line options or configuration files. The -"``tools/stylesheets/pep.css``" stylesheet is intended specifically -for PEP use. +``rstpep2html.py`` reads a new-style PEP (marked up with +reStructuredText) and produces HTML. It requires a template file and +a stylesheet. By default, it makes use of a "``pep-html-template``" +file and a "``default.css``" stylesheet in the current directory, but +these can be overridden by command-line options or configuration +files. The "``tools/stylesheets/pep.css``" stylesheet is intended +specifically for PEP use. The "``docutils.conf``" `configuration file`_ in the "``tools``" directory of Docutils contains a default setup for use in processing @@ -163,17 +163,17 @@ default template (``tools/pep-html-template``) and a default stylesheet (``tools/stylesheets/pep.css``). See Stylesheets_ above for more information. -``pep.py`` can be run from the ``tools`` directory or from the +``rstpep2html.py`` can be run from the ``tools`` directory or from the ``docs/peps/`` directory, by adjusting the settings. These two sets of commands are equivalent:: cd /tools # This will pick up the "docutils.conf" file automatically: - pep.py ../docs/peps/pep-0287.txt ../docs/peps/pep-0287.html + rstpep2html.py ../docs/peps/pep-0287.txt ../docs/peps/pep-0287.html cd /docs/peps # Must tell the tool where to find the config file: - ../../tools/pep.py --config ../../tools/docutils.conf \ + ../../tools/rstpep2html.py --config ../../tools/docutils.conf \ pep-0287.txt pep-0287.html @@ -191,8 +191,8 @@ indented or new-style reStructuredText) and processes accordingly. Since it does not use the Docutils front end mechanism (the common command-line options are not supported), it can only be configured using `configuration files`_. The template and stylesheet -requirements of ``pep2html.py`` are the same as those of `pep.py`_ -above. +requirements of ``pep2html.py`` are the same as those of +`rstpep2html.py`_ above. Arguments to ``pep2html.py`` may be a list of PEP numbers or .txt files. If no arguments are given, all files of the form diff --git a/tools/pep.py b/tools/pep.py deleted file mode 100755 index 5aa4b8afc..000000000 --- a/tools/pep.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -# Author: David Goodger -# Contact: goodger@users.sourceforge.net -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -A minimal front end to the Docutils Publisher, producing HTML from PEP -(Python Enhancement Proposal) documents. -""" - -try: - import locale - locale.setlocale(locale.LC_ALL, '') -except: - pass - -from docutils.core import publish_cmdline, default_description - - -description = ('Generates (X)HTML from reStructuredText-format PEP files. ' - + default_description) - -publish_cmdline(reader_name='pep', writer_name='pep_html', - description=description) diff --git a/tools/rstpep2html.py b/tools/rstpep2html.py new file mode 100755 index 000000000..5aa4b8afc --- /dev/null +++ b/tools/rstpep2html.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML from PEP +(Python Enhancement Proposal) documents. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML from reStructuredText-format PEP files. ' + + default_description) + +publish_cmdline(reader_name='pep', writer_name='pep_html', + description=description) -- cgit v1.2.1 From 71c59a6b9569fc2aafc4d4e41c21cca04b29cd65 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:20:00 +0000 Subject: moved create_unimap.py to tools/dev/ git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3534 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/dev/create_unimap.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 tools/dev/create_unimap.py diff --git a/tools/dev/create_unimap.py b/tools/dev/create_unimap.py new file mode 100755 index 000000000..260913ed3 --- /dev/null +++ b/tools/dev/create_unimap.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This file has been placed in the public domain. + +# Call: create_unimap.py < unicode.xml > unicode_latex.py +# +# Get unicode.xml from +# . + +from xml.dom import minidom +import sys +import pprint + +def w(s): + if isinstance(s, unicode): + s = s.encode('utf8') + sys.stdout.write(s) + +text_map = {} +math_map = {} + +class Visitor: + + """Node visitor for contents of unicode.xml.""" + + def visit_character(self, node): + for n in node.childNodes: + if n.nodeName == 'latex': + code = node.attributes['dec'].value + if '-' in code: + # I don't know what this means, but we probably + # don't need it.... + continue + if int(code) < 128: + # Wrong (maps "-" to "$-$", which is too wide) and + # unnecessary (maps "a" to "{a}"). + continue + latex_code = n.childNodes[0].nodeValue.encode('ascii').strip() + if node.attributes['mode'].value == 'math': + math_map[unichr(int(code))] = '$%s$' % latex_code + else: + text_map[unichr(int(code))] = '{%s}' % latex_code + +def call_visitor(node, visitor=Visitor()): + if isinstance(node, minidom.Text): + name = 'Text' + else: + name = node.nodeName.replace('#', '_') + if hasattr(visitor, 'visit_' + name): + getattr(visitor, 'visit_' + name)(node) + for child in node.childNodes: + call_visitor(child) + if hasattr(visitor, 'depart_' + name): + getattr(visitor, 'depart_' + name)(node) + +document = minidom.parse(sys.stdin) +call_visitor(document) + +unicode_map = math_map +unicode_map.update(text_map) +# Now unicode_map contains the text entries plus dollar-enclosed math +# entries for those chars for which no text entry exists. + +print '# Author: Felix Wiemann' +print '# Contact: Felix_Wiemann@ososo.de' +print '# Revision: $%s$' % 'Revision' +print '# Date: $%s$' % 'Date' +print '# Copyright: This file has been placed in the public domain.' +print '#' +print '# This is a mapping of Unicode characters to LaTeX' +print '# equivalents. The information has been extracted from' +print '# .' +print '# The extraction has been done by the "create_unimap.py"' +print '# script written by Felix Wiemann.' +print +print 'unicode_map = %s' % pprint.pformat(unicode_map, indent=0) -- cgit v1.2.1 From d3a60d28fa5ef090e66b3db54069811efc05afe6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:29:02 +0000 Subject: changed comment at the top of unicode_latex.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3535 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/unicode_latex.py | 12 +++++++----- tools/dev/create_unimap.py | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docutils/writers/unicode_latex.py b/docutils/writers/unicode_latex.py index 22830abbf..2998178f4 100644 --- a/docutils/writers/unicode_latex.py +++ b/docutils/writers/unicode_latex.py @@ -3,12 +3,14 @@ # Revision: $Revision$ # Date: $Date$ # Copyright: This file has been placed in the public domain. + +# This is a mapping of Unicode characters to LaTeX equivalents. +# The information has been extracted from +# , written by +# David Carlisle and Sebastian Rahtz. # -# This is a mapping of Unicode characters to LaTeX -# equivalents. The information has been extracted from -# . -# The extraction has been done by the "create_unimap.py" -# script written by Felix Wiemann. +# The extraction has been done by the "create_unimap.py" script +# located at . unicode_map = {u'\xa0': '$~$', u'\xa1': '{\\textexclamdown}', diff --git a/tools/dev/create_unimap.py b/tools/dev/create_unimap.py index 260913ed3..1d1a2f8a0 100755 --- a/tools/dev/create_unimap.py +++ b/tools/dev/create_unimap.py @@ -70,11 +70,13 @@ print '# Contact: Felix_Wiemann@ososo.de' print '# Revision: $%s$' % 'Revision' print '# Date: $%s$' % 'Date' print '# Copyright: This file has been placed in the public domain.' +print +print '# This is a mapping of Unicode characters to LaTeX equivalents.' +print '# The information has been extracted from' +print '# , written by' +print '# David Carlisle and Sebastian Rahtz.' print '#' -print '# This is a mapping of Unicode characters to LaTeX' -print '# equivalents. The information has been extracted from' -print '# .' -print '# The extraction has been done by the "create_unimap.py"' -print '# script written by Felix Wiemann.' +print '# The extraction has been done by the "create_unimap.py" script' +print '# located at .' print print 'unicode_map = %s' % pprint.pformat(unicode_map, indent=0) -- cgit v1.2.1 From 6d22d0350bced331e2eb4e70f6c557ab4fe1fd57 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:34:29 +0000 Subject: renamed "The Docutils Repository" to "The Docutils Subversion Repository" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3537 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 6 +++--- docs/index.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 7a3cfde60..dceb88f5d 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -1,6 +1,6 @@ -========================== - The Docutils_ Repository -========================== +===================================== + The Docutils_ Subversion Repository +===================================== :Author: Felix Wiemann :Contact: Felix.Wiemann@ososo.de diff --git a/docs/index.txt b/docs/index.txt index eeb8a5125..222d6759e 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -199,7 +199,7 @@ Docutils-general: * `Docutils Project Policies `__ * `Docutils Web Site `__ * `Docutils Release Procedure `__ -* `The Docutils Repository `__ +* `The Docutils Subversion Repository `__ * `Docutils Testing `__ * `Docstring Semantics `__ (incomplete) * `Python Source Reader `_ (incomplete) -- cgit v1.2.1 From 814741f4841bfabd6dd3681300d409611731e6f1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:45:50 +0000 Subject: clarified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3538 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index fd75a16df..bc7f289c3 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -896,7 +896,7 @@ _`_directories` _`_disable_config` Prevent standard configuration files from being read. For - internal use only. + programmatic use only. Default: config files enabled (None). No command-line options. -- cgit v1.2.1 From 4ed3edac78b63fbd77a12d9394040e420dea8ffb Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 19:47:07 +0000 Subject: added docs about using _disable_config git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3539 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 2fcf33e95..284d18ce7 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -42,7 +42,9 @@ from optparse import SUPPRESS_HELP _globally_deactivate_config_files = 0 -"""Deactivate reading of config files; for testing purposes.""" +"""Deactivate reading of config files globally; for testing purposes. +Use _disable_config instead when calling Docutils programatically: +""" def store_multiple(option, opt, value, parser, *args, **kwargs): """ -- cgit v1.2.1 From 7afb379506e3db099f7d0fedb9257f8b76b16232 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 21:00:37 +0000 Subject: added Revision docinfo field git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3541 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/FAQ.txt b/FAQ.txt index c5c2e06f4..ce1d35190 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -3,6 +3,7 @@ =========================================== :Date: $Date$ +:Revision: $Revision$ :Web site: http://docutils.sourceforge.net/ :Copyright: This document has been placed in the public domain. -- cgit v1.2.1 From f40247688ae8eb68afc4484ae1fbe9703e6e7590 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 21:49:29 +0000 Subject: Py21 compatibility fix (usage of "in" operator for strings) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3542 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_html4css1.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 1cc15bd5e..15f5f26f6 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -328,9 +328,10 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): def test_xmlcharrefreplace(self): # Test that xmlcharrefreplace is the default output encoding # error handler. - self.assert_('\xe4\xf6\xfc€' in core.publish_string( - 'äöü€', writer_name='html4css1', - settings_overrides={'output_encoding': 'latin1'})) + self.assert_(core.publish_string( + 'äöü€', writer_name='html4css1', settings_overrides={ + 'output_encoding': 'latin1', 'stylesheet': None}).find( + '\xe4\xf6\xfc€') != -1) if __name__ == '__main__': -- cgit v1.2.1 From 5eb7b3b1420555500ad3e2c8756f683175d17699 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 21:52:53 +0000 Subject: ensure that always a stylesheet path/URL is given; I've seen to many poor-looking documents on the web due to the missing stylesheet -- people seem to miss that quite frequently git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3543 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 16 ++++++++++++---- test/DocutilsTestSupport.py | 4 ++++ test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/tests/dangerous.py | 2 ++ test/functional/tests/field_name_limit.py | 2 ++ 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f77d6d8e8..0ac68f5e5 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -38,10 +38,11 @@ class Writer(writers.Writer): settings_spec = ( 'HTML-Specific Options', None, - (('Specify a stylesheet URL, used verbatim. Default is ' - '"default.css". Overrides --stylesheet-path.', + (('Specify a stylesheet URL, used verbatim. Overrides ' + '--stylesheet-path. Either --stylesheet or --stylesheet-path ' + 'must be specified.', ['--stylesheet'], - {'default': 'default.css', 'metavar': '', + {'default': -1, 'metavar': '', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' 'directory. The path is adjusted relative to the output HTML ' @@ -222,7 +223,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.stylesheet = [self.embedded_stylesheet % stylesheet_text] else: stylesheet = utils.get_stylesheet_reference(settings) - if stylesheet: + if stylesheet == -1: + raise ValueError( + 'No stylesheet path or URI given.\nUse the --stylesheet ' + 'or --stylesheet-path option to specify the location of\n' + 'default.css (in the tools/stylesheets/ directory ' + 'of the Docutils distribution).') + self.stylesheet = [] + elif stylesheet: self.stylesheet = [self.stylesheet_link % self.encode(stylesheet)] else: diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 3f459bebf..f1fa277a7 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -713,6 +713,10 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): writer_name = 'html' + settings_default_overrides = \ + WriterPublishTestCase.settings_default_overrides.copy() + settings_default_overrides['stylesheet'] = None + def __init__(self, *args, **kwargs): self.settings_overrides = kwargs['settings_overrides'] """Settings overrides to use for this test case.""" diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 779ea9479..9b9c321b6 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index 3b8b36a89..736b8b98b 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/tests/dangerous.py b/test/functional/tests/dangerous.py index 620a927ba..5611268eb 100644 --- a/test/functional/tests/dangerous.py +++ b/test/functional/tests/dangerous.py @@ -10,3 +10,5 @@ writer_name = "html" # Settings settings_overrides['file_insertion_enabled'] = 0 settings_overrides['raw_enabled'] = 0 +settings_overrides['stylesheet'] = None +settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" diff --git a/test/functional/tests/field_name_limit.py b/test/functional/tests/field_name_limit.py index db79d4c67..86ad59a46 100644 --- a/test/functional/tests/field_name_limit.py +++ b/test/functional/tests/field_name_limit.py @@ -10,3 +10,5 @@ writer_name = "html" # Settings settings_overrides['field_name_limit'] = 0 # no limit settings_overrides['docinfo_xform'] = 0 +settings_overrides['stylesheet'] = None +settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" -- cgit v1.2.1 From 85ab5a61024ec340f67491bf7f1b012e1fa59acc Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 22:16:59 +0000 Subject: added history entry; *sigh* forgot that again git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3544 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 9be255b85..adc38d08f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -49,6 +49,8 @@ Changes Since 0.3.9 - Added support for image width and height units. - Made ``xmlcharrefreplace`` the default output encoding error handler. + - Specifying either ``--stylesheet`` or ``--stylesheet-path`` is + mandatory now. * docutils/writers/docutils_xml.py: -- cgit v1.2.1 From b1f1348e970ab219e8f50d19ad871883c0c16e8f Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 22:28:07 +0000 Subject: check for missing stylesheet also when --embed-stylesheet; do not try to embed stylesheet when --stylesheet(-path)="" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3546 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0ac68f5e5..0fc85295c 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -58,7 +58,8 @@ class Writer(writers.Writer): 'file must be accessible during processing (--stylesheet-path is ' 'recommended). Default: link the stylesheet, do not embed it.', ['--embed-stylesheet'], - {'action': 'store_true', 'validator': frontend.validate_boolean}), + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), ('Specify the initial header level. Default is 1 for "

    ". ' 'Does not affect document title & subtitle (see --no-doc-title).', ['--initial-header-level'], @@ -215,22 +216,21 @@ class HTMLTranslator(nodes.NodeVisitor): self.head_prefix_template % (lcode, lcode)]) self.html_prolog.append(self.doctype) self.head = self.meta[:] - if settings.embed_stylesheet: + stylesheet = utils.get_stylesheet_reference(settings) + if stylesheet == -1: + raise ValueError( + 'No stylesheet path or URI given.\nUse the --stylesheet ' + 'or --stylesheet-path option to specify the location of\n' + 'default.css (in the tools/stylesheets/ directory ' + 'of the Docutils distribution).') + if settings.embed_stylesheet and stylesheet: stylesheet = utils.get_stylesheet_reference(settings, os.path.join(os.getcwd(), 'dummy')) settings.record_dependencies.add(stylesheet) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] else: - stylesheet = utils.get_stylesheet_reference(settings) - if stylesheet == -1: - raise ValueError( - 'No stylesheet path or URI given.\nUse the --stylesheet ' - 'or --stylesheet-path option to specify the location of\n' - 'default.css (in the tools/stylesheets/ directory ' - 'of the Docutils distribution).') - self.stylesheet = [] - elif stylesheet: + if stylesheet: self.stylesheet = [self.stylesheet_link % self.encode(stylesheet)] else: -- cgit v1.2.1 From acd13d4dec84b25fac3fe0572cb867fd42753fcf Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 22:32:21 +0000 Subject: enabled embed_stylesheet by default; people who don't care of getting their stylesheet uploaded wouldn't include the stylesheet otherwise, and people who do will find --link-stylesheet git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3547 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docs/user/config.txt | 2 +- docutils/writers/html4css1.py | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index adc38d08f..732e4c903 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -51,6 +51,8 @@ Changes Since 0.3.9 handler. - Specifying either ``--stylesheet`` or ``--stylesheet-path`` is mandatory now. + - Made ``--embed-stylesheet`` the default rather than + ``--link-stylesheet``. * docutils/writers/docutils_xml.py: diff --git a/docs/user/config.txt b/docs/user/config.txt index bc7f289c3..73444397f 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -588,7 +588,7 @@ _`embed_stylesheet` Embed the stylesheet in the output HTML file. The stylesheet file must be accessible during processing. - Default: link, don't embed (None). Options: ``--embed-stylesheet, + Default: enabled. Options: ``--embed-stylesheet, --link-stylesheet``. _`field_name_limit` diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 0fc85295c..387ebdf77 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -49,16 +49,16 @@ class Writer(writers.Writer): 'file. Overrides --stylesheet.', ['--stylesheet-path'], {'metavar': '', 'overrides': 'stylesheet'}), - ('Link to the stylesheet in the output HTML file. This is the ' - 'default.', + ('Link to the stylesheet in the output HTML file. Default: ' + 'embed the stylesheet, do not link to it.', ['--link-stylesheet'], {'dest': 'embed_stylesheet', 'action': 'store_false', 'validator': frontend.validate_boolean}), ('Embed the stylesheet in the output HTML file. The stylesheet ' 'file must be accessible during processing (--stylesheet-path is ' - 'recommended). Default: link the stylesheet, do not embed it.', + 'recommended). This is the default.', ['--embed-stylesheet'], - {'default': 0, 'action': 'store_true', + {'default': 1, 'action': 'store_true', 'validator': frontend.validate_boolean}), ('Specify the initial header level. Default is 1 for "

    ". ' 'Does not affect document title & subtitle (see --no-doc-title).', -- cgit v1.2.1 From 703c9a840cb8c0538326fe6b95c7393d9e0bf909 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 20 Jun 2005 22:38:19 +0000 Subject: fixed tests git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3548 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/tests/_default.py | 1 + test/test_dependencies.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/tests/_default.py b/test/functional/tests/_default.py index 63e82451a..2835c5b2e 100644 --- a/test/functional/tests/_default.py +++ b/test/functional/tests/_default.py @@ -4,3 +4,4 @@ settings_overrides['report_level'] = 2 settings_overrides['halt_level'] = 5 settings_overrides['warning_stream'] = '' settings_overrides['input_encoding'] = 'utf-8' +settings_overrides['embed_stylesheet'] = 0 diff --git a/test/test_dependencies.py b/test/test_dependencies.py index 61d19a6f2..c9f00518d 100755 --- a/test/test_dependencies.py +++ b/test/test_dependencies.py @@ -56,10 +56,10 @@ class RecordDependenciesTests(unittest.TestCase): pass def test_stylesheet_dependencies(self): - # Parameters to publish_file. s = {'settings_overrides': {}} so = s['settings_overrides'] + so['embed_stylesheet'] = 0 so['stylesheet_path'] = 'stylesheet.txt' so['stylesheet'] = None s['writer_name'] = 'html' -- cgit v1.2.1 From c04ee4d9948a2854fd9ea96eb9f1e22f56be29d5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 21 Jun 2005 00:11:44 +0000 Subject: issue a warning rather than an error when no stylesheet is given; default for "stylesheet" is now None, not -1 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3549 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++-- docs/user/config.txt | 9 +++++---- docutils/writers/html4css1.py | 17 +++++++---------- test/DocutilsTestSupport.py | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 732e4c903..6966f6949 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -49,8 +49,8 @@ Changes Since 0.3.9 - Added support for image width and height units. - Made ``xmlcharrefreplace`` the default output encoding error handler. - - Specifying either ``--stylesheet`` or ``--stylesheet-path`` is - mandatory now. + - A warning is now issued if neither ``--stylesheet`` nor + ``--stylesheet-path`` is specified. - Made ``--embed-stylesheet`` the default rather than ``--link-stylesheet``. diff --git a/docs/user/config.txt b/docs/user/config.txt index 73444397f..d7b08bf48 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -618,8 +618,6 @@ _`initial_header_level` Default: 1 (for "

    "). Option: ``--initial-header-level``. -.. _stylesheet [html4css1 writer]: - _`option_limit` The maximum width (in characters) for options in option lists. Longer options will span an entire row of the table used to render @@ -628,11 +626,14 @@ _`option_limit` Default: 14 characters. Option: ``--option-limit``. +.. _stylesheet [html4css1 writer]: + stylesheet CSS stylesheet URL, used verbatim. Overrides stylesheet_path - [#override]_. + [#override]_. Pass an empty string to deactivate stylesheet + inclusion. - Default: "default.css". Options: ``--stylesheet``. + Default: None. Options: ``--stylesheet``. (Setting also defined for the `LaTeX Writer`__.) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 387ebdf77..f20ff2105 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -42,8 +42,7 @@ class Writer(writers.Writer): '--stylesheet-path. Either --stylesheet or --stylesheet-path ' 'must be specified.', ['--stylesheet'], - {'default': -1, 'metavar': '', - 'overrides': 'stylesheet_path'}), + {'metavar': '', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' 'directory. The path is adjusted relative to the output HTML ' 'file. Overrides --stylesheet.', @@ -217,24 +216,22 @@ class HTMLTranslator(nodes.NodeVisitor): self.html_prolog.append(self.doctype) self.head = self.meta[:] stylesheet = utils.get_stylesheet_reference(settings) - if stylesheet == -1: - raise ValueError( + self.stylesheet = [] + if stylesheet is None: + self.document.reporter.warning( 'No stylesheet path or URI given.\nUse the --stylesheet ' 'or --stylesheet-path option to specify the location of\n' 'default.css (in the tools/stylesheets/ directory ' - 'of the Docutils distribution).') - if settings.embed_stylesheet and stylesheet: + 'of the Docutils distribution).\n') + elif settings.embed_stylesheet and stylesheet: stylesheet = utils.get_stylesheet_reference(settings, os.path.join(os.getcwd(), 'dummy')) settings.record_dependencies.add(stylesheet) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] - else: - if stylesheet: + elif stylesheet: self.stylesheet = [self.stylesheet_link % self.encode(stylesheet)] - else: - self.stylesheet = [] self.body_prefix = ['\n\n'] # document title, subtitle display self.body_pre_docinfo = [] diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index f1fa277a7..5452f1929 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -715,7 +715,7 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): settings_default_overrides = \ WriterPublishTestCase.settings_default_overrides.copy() - settings_default_overrides['stylesheet'] = None + settings_default_overrides['stylesheet'] = '' def __init__(self, *args, **kwargs): self.settings_overrides = kwargs['settings_overrides'] -- cgit v1.2.1 From 65c38ac0991dd6a6dac04fd7fffa8b940188d2f6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 21 Jun 2005 00:16:59 +0000 Subject: again a broken test; I should really rerun the test suite before committing changes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3550 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 15f5f26f6..51b47f81b 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -330,7 +330,7 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): # error handler. self.assert_(core.publish_string( 'äöü€', writer_name='html4css1', settings_overrides={ - 'output_encoding': 'latin1', 'stylesheet': None}).find( + 'output_encoding': 'latin1', 'stylesheet': ''}).find( '\xe4\xf6\xfc€') != -1) -- cgit v1.2.1 From 146697013053462711c6b70a1b4e2a67b0f79231 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 21 Jun 2005 11:37:50 +0000 Subject: deactivated embed_stylesheet for documentation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3551 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/docutils.conf b/tools/docutils.conf index 8d09a65a5..92392c2ed 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -3,6 +3,7 @@ source-link: yes datestamp: %Y-%m-%d %H:%M UTC generator: on +embed-stylesheet: no [html4css1 writer] # These entries affect HTML output: -- cgit v1.2.1 From fe122f72184f40ab6698091acd4c17c8c8db148e Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 22 Jun 2005 18:56:59 +0000 Subject: moved import of xml.dom.minidom into asdom methods; importing it takes 80 ms here git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3554 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 03e65200a..eb059e2d2 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -29,7 +29,6 @@ import re import copy import warnings import inspect -import xml.dom.minidom from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType from UserString import UserString @@ -66,8 +65,10 @@ class Node: """ return 1 - def asdom(self, dom=xml.dom.minidom): + def asdom(self, dom=None): """Return a DOM **fragment** representation of this Node.""" + if dom is None: + import xml.dom.minidom as dom domroot = dom.Document() return self._dom_node(domroot) @@ -836,8 +837,10 @@ class document(Root, Structural, Element): self.document = self - def asdom(self, dom=xml.dom.minidom): + def asdom(self, dom=None): """Return a DOM representation of this document.""" + if dom is None: + import xml.dom.minidom as dom domroot = dom.Document() domroot.appendChild(self._dom_node(domroot)) return domroot -- cgit v1.2.1 From 7c3a24d07b9240ef7f58df8c75ba54a73a093e4e Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 22 Jun 2005 19:02:08 +0000 Subject: removed import of "inspect" module; takes 55 ms to import here git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3555 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index eb059e2d2..02dcfee1a 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -28,9 +28,8 @@ import os import re import copy import warnings -import inspect from types import IntType, SliceType, StringType, UnicodeType, \ - TupleType, ListType + TupleType, ListType, ClassType from UserString import UserString @@ -205,7 +204,7 @@ class Node: r = [] if ascend: siblings=1 - if inspect.isclass(condition) and issubclass(condition, Node): + if isinstance(condition, ClassType) and issubclass(condition, Node): node_class = condition def condition(node, node_class=node_class): return isinstance(node, node_class) -- cgit v1.2.1 From 635da3c6831a67858695854d926776ec3fb0f6d5 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 22 Jun 2005 19:16:46 +0000 Subject: removed usage of "copy" module; test suite runs 1.6 seconds faster now git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3556 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 1 - docutils/nodes.py | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index 284d18ce7..c74419d50 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -32,7 +32,6 @@ import os import os.path import sys import types -import copy import warnings import ConfigParser as CP import codecs diff --git a/docutils/nodes.py b/docutils/nodes.py index 02dcfee1a..25b220cd0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -26,7 +26,6 @@ __docformat__ = 'reStructuredText' import sys import os import re -import copy import warnings from types import IntType, SliceType, StringType, UnicodeType, \ TupleType, ListType, ClassType @@ -354,9 +353,14 @@ class Element(Node): self.extend(children) # maintain parent info - self.attributes = copy.deepcopy(self.attr_defaults) + self.attributes = {} """Dictionary of attribute {name: value}.""" + # Copy default values. + for att, value in self.attr_defaults.items(): + # Default values are always lists (at the moment). + self.attributes[att] = value[:] + for att, value in attributes.items(): self.attributes[att.lower()] = value -- cgit v1.2.1 From dd317a449cc8c710a408da740ca4859f7c6d3cdb Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 22 Jun 2005 22:07:06 +0000 Subject: removed and added to-do list entries for latex writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3558 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex-notes.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt index 87e65abd2..92da02491 100644 --- a/tools/stylesheets/latex-notes.txt +++ b/tools/stylesheets/latex-notes.txt @@ -35,6 +35,5 @@ Regarding UTF-8: \usepackage{graphicx} \fi -Width of images needs cleanup, in the framework. Integers aren't -sufficient (virtually unusable in typeset documents). Need to discuss -on Docutils-develop and come up with a set of standard units. + +Need to handle paragraph indenting manually (in the writer). -- cgit v1.2.1 From cf6285576a6d35d2e7d8f26174c6ad7026b2eb44 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 22 Jun 2005 22:13:30 +0000 Subject: tweaks, clarifications, corrections git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3559 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 66 ++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index 05aa4f2c6..0a2e25d2b 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -15,11 +15,11 @@ .. contents:: This document describes how to create packages of Docutils (e.g. for -shipping them with a Linux distribution). If you have any questions, +shipping with a Linux distribution). If you have any questions, please direct them to the Docutils-develop_ mailing list. -First of all, please download the most current `release tarball`_ and -unpack it. +First, please download the most current `release tarball`_ and unpack +it. .. _Docutils-develop: ../user/mailing-lists.html#docutils-develop .. _release tarball: http://docutils.sourceforge.net/#download @@ -30,15 +30,15 @@ Dependencies Docutils has the following dependencies: -* Python 2.1 or later is required. (While the compiler package from +* Python 2.1 or later is required. While the compiler package from the Tools/ directory of Python's source distribution must be installed for the test suite to pass with Python 2.1, the functionality available to end users should be available without the - compiler package as well. So just use >= Python 2.1 in the - dependencies.) + compiler package as well. So just use ">= Python 2.1" in the + dependencies. -* Docutils may optionally make use of the PIL (Python Imaging - Library). If PIL is present, it is automatically detected by +* Docutils may optionally make use of the PIL (`Python Imaging + Library`). If PIL is present, it is automatically detected by Docutils. * There are three files in the ``extras/`` directory of the Docutils @@ -52,6 +52,8 @@ Docutils has the following dependencies: These files are automatically installed by the setup script (when calling "python setup.py install"). +.. _Python Imaging Library: http://www.pythonware.com/products/pil/ + Python Files ============ @@ -62,17 +64,17 @@ install`` should do the trick, but if you want to place the files yourself, you can just install the ``docutils/`` directory of the Docutils tarball to ``/usr/lib/python/site-packages/docutils/``. In this case you should also compile the Python files to ``.pyc`` and/or -``.pyo`` files so that Docutils doesn't need to be recompiled -everytime it's executed. +``.pyo`` files so that Docutils doesn't need to be recompiled every +time it's executed. -Binaries -======== +Executables +=========== -The binaries are located in the ``tools/`` directory of the Docutils -tarball. +The executable front-end tools are located in the ``tools/`` directory +of the Docutils tarball. -The ``rst2*.py`` tools except ``rst2newlatex.py`` are intended for +The ``rst2*.py`` tools (except ``rst2newlatex.py``) are intended for end-users. You should install them to ``/usr/bin/``. You do not need to change the names (e.g. to ``docutils-rst2html.py``) because the ``rst2`` prefix is unique. @@ -81,25 +83,34 @@ to change the names (e.g. to ``docutils-rst2html.py``) because the Documentation ============= -The documentation should be generated using ``buildhtml.py``. Go to -the ``tools/`` directory and run ``./buildhtml.py ..``. This will -create all HTML files. +The documentation should be generated using ``buildhtml.py``. To +generate HTML for all documentation files, go to the ``tools/`` +directory and run:: + + ./buildhtml.py .. Then install the following files to ``/usr/share/doc/docutils/`` (or -however you like to call the documentation directory): +wherever you install documentation): * All ``.html`` and ``.txt`` files in the base directory. -* The ``docs/`` directory. (Do not install the contents of the - ``docs/`` directory directory directly to - ``/usr/share/doc/docutils/``\ —it's incomplete and would contain - invalid references!) + +* The ``docs/`` directory. + + Do not install the contents of the ``docs/`` directory directly to + ``/usr/share/doc/docutils/`` —- it's incomplete and would contain + invalid references! + * The ``licenses/`` directory. + * ``tools/stylesheets/default.css``, creating the ``tools/`` and ``tools/stylesheets/`` directory beforehand. This file is needed - for correct viewing of the HTML files. (You do not need to install - the other contents of the ``tools/`` or ``stylesheets/`` directory. - However, do not install ``default.css`` right into the documentation - base directory, or the references to the stylesheet will not work.) + for correct viewing of the HTML files. The remaining contents of + the ``tools/`` and ``tools/stylesheets/`` directories are not + needed. + + Be sure not to install ``default.css`` into the root of the + documentation directory, or the relative references to the + stylesheet will not work. Removing the ``.txt`` Files @@ -110,6 +121,7 @@ the tree except for: * those in the ``licenses/`` directory because they have not been processed to HTML and + * ``user/rst/cheatsheet.txt`` and ``user/rst/demo.txt``, which should be readable in source form. -- cgit v1.2.1 From 21765adac8d10ef918eab2afc26672cfac2af4cd Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 22 Jun 2005 22:22:51 +0000 Subject: typos git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3560 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index 0a2e25d2b..a4d913655 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -38,7 +38,7 @@ Docutils has the following dependencies: dependencies. * Docutils may optionally make use of the PIL (`Python Imaging - Library`). If PIL is present, it is automatically detected by + Library`_). If PIL is present, it is automatically detected by Docutils. * There are three files in the ``extras/`` directory of the Docutils @@ -97,7 +97,7 @@ wherever you install documentation): * The ``docs/`` directory. Do not install the contents of the ``docs/`` directory directly to - ``/usr/share/doc/docutils/`` —- it's incomplete and would contain + ``/usr/share/doc/docutils/``\—it's incomplete and would contain invalid references! * The ``licenses/`` directory. -- cgit v1.2.1 From dfed077fc0a063a1e9d73627f0643738eacfcfab Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 23 Jun 2005 00:21:31 +0000 Subject: This wasn't a typo -- a single hyphen does not an em-dash make. The backslash is butt-ugly and unnecessary. Can we compromise on a semicolon? git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3562 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index a4d913655..c1cfc3603 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -97,7 +97,7 @@ wherever you install documentation): * The ``docs/`` directory. Do not install the contents of the ``docs/`` directory directly to - ``/usr/share/doc/docutils/``\—it's incomplete and would contain + ``/usr/share/doc/docutils/``; it's incomplete and would contain invalid references! * The ``licenses/`` directory. -- cgit v1.2.1 From 33abed9a56bc9451e6728c874a6127195cb5d457 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Jun 2005 10:43:30 +0000 Subject: added link to link list git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3564 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.txt b/docs/index.txt index 222d6759e..bb468e8d7 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -82,6 +82,7 @@ Docutils-general: * `Docutils Configuration Files `__ * `Docutils LaTeX Writer `__ * `Docutils Mailing Lists `__ +* `Docutils Links `__ `reStructuredText `_: -- cgit v1.2.1 From afb2adba710b0f21e9e2b03c1409807238eece6c Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 23 Jun 2005 13:13:31 +0000 Subject: also support "optik" instead of optparse; thanks to patch of Debian package git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3566 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index c74419d50..a0b76c96e 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -36,8 +36,12 @@ import warnings import ConfigParser as CP import codecs import docutils -import optparse -from optparse import SUPPRESS_HELP +try: + import optparse + from optparse import SUPPRESS_HELP +except ImportError: + import optik as optparse + from optik import SUPPRESS_HELP _globally_deactivate_config_files = 0 -- cgit v1.2.1 From 25934f67bf5d516f1bcdb32cc4d770f5d479d6fc Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 23 Jun 2005 17:35:19 +0000 Subject: removed docutils.frontend._globally_deactivate_config_files (reverting much of rev. 3511), since it duplicates settings._disable_config functionality git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3567 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 7 ------- test/DocutilsTestSupport.py | 7 ++----- test/test_writers/test_docutils_xml.py | 4 +++- test/test_writers/test_html4css1.py | 13 ++++++++----- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index a0b76c96e..8f357ae4b 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -44,11 +44,6 @@ except ImportError: from optik import SUPPRESS_HELP -_globally_deactivate_config_files = 0 -"""Deactivate reading of config files globally; for testing purposes. -Use _disable_config instead when calling Docutils programatically: -""" - def store_multiple(option, opt, value, parser, *args, **kwargs): """ Store multiple values in `parser.values`. (Option callback.) @@ -539,8 +534,6 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): def get_standard_config_files(self): """Return list of config files, from environment or standard.""" - if _globally_deactivate_config_files: - return [] try: config_files = os.environ['DOCUTILSCONFIG'].split(os.pathsep) except KeyError: diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 5452f1929..32c263982 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -98,10 +98,6 @@ class StandardTestCase(unittest.TestCase): def setUp(self): os.chdir(testroot) - frontend._globally_deactivate_config_files = 1 - - def tearDown(self): - frontend._globally_deactivate_config_files = 0 class CustomTestCase(StandardTestCase): @@ -635,7 +631,8 @@ class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): Test case for publish. """ - settings_default_overrides = {'strict_visitor': 1} + settings_default_overrides = {'_disable_config': 1, + 'strict_visitor': 1} writer_name = '' # set in subclasses or constructor def __init__(self, *args, **kwargs): diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index f5cf18b3f..c46c472a8 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -29,7 +29,9 @@ class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): bodyindents = '\n \n Test\n \n \n Subsection\n \n \n Test\n \n \n \n Test. \xe4\xf6\xfc€\n \n\n' def test_publish(self): - settings = {'input_encoding': 'utf8', 'output_encoding': 'iso-8859-1'} + settings = {'input_encoding': 'utf8', + 'output_encoding': 'iso-8859-1', + '_disable_config': 1} for settings['newlines'] in 0, 1: for settings['indents'] in 0, 1: for settings['xml_declaration'] in 0, 1: diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 51b47f81b..c3c69af08 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -328,12 +328,15 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): def test_xmlcharrefreplace(self): # Test that xmlcharrefreplace is the default output encoding # error handler. - self.assert_(core.publish_string( - 'äöü€', writer_name='html4css1', settings_overrides={ - 'output_encoding': 'latin1', 'stylesheet': ''}).find( - '\xe4\xf6\xfc€') != -1) + settings_overrides={ + 'output_encoding': 'latin1', + 'stylesheet': '', + '_disable_config': 1} + result = core.publish_string( + 'äöü€', writer_name='html4css1', + settings_overrides=settings_overrides) + self.assert_(result.find('\xe4\xf6\xfc€') != -1) if __name__ == '__main__': - import unittest unittest.main(defaultTest='suite') -- cgit v1.2.1 From 0f13566adac5f1de9e5016d1732b96f403b77eca Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 23 Jun 2005 17:47:00 +0000 Subject: clarified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3568 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6966f6949..e5030a2b0 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -65,7 +65,8 @@ Changes Since 0.3.9 * docs/dev/distributing.txt: Added to project; guide for distributors. -* docs/user/links.txt: Added to project; link list. +* docs/user/links.txt: Added to project; lists of Docutils-related + links. * docs/ref/rst/substitutions.txt: "reStructuredText Standard Substitution Definition Sets", added to project. -- cgit v1.2.1 From 09591364de69c1795067989feff7d328cedfc9a5 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 23 Jun 2005 17:56:05 +0000 Subject: moved import to guarded area git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3569 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_docutils_xml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index c46c472a8..f11b620f4 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -11,7 +11,6 @@ Test for docutils XML writer. """ -import unittest from __init__ import DocutilsTestSupport import docutils @@ -59,4 +58,5 @@ class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): if __name__ == '__main__': + import unittest unittest.main() -- cgit v1.2.1 From 04e690ceca66ae968d84e4689b91cac93828a195 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 23 Jun 2005 17:56:44 +0000 Subject: separated different types of tests git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3570 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_html4css1.py | 22 ++------------------ test/test_writers/test_html4css1_misc.py | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 test/test_writers/test_html4css1_misc.py diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index c3c69af08..6ce0c15cd 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -15,16 +15,12 @@ dictionaries (redundant), along with 'meta' and 'stylesheet' entries with standard values, and any entries with empty values. """ -from docutils import core - -import unittest from __init__ import DocutilsTestSupport +from docutils import core def suite(): s = DocutilsTestSupport.HtmlPublishPartsTestSuite() s.generateTests(totest) - import test_html4css1 - s.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_html4css1)) return s @@ -323,20 +319,6 @@ And even more stuff ]) -class EncodingTestCase(DocutilsTestSupport.StandardTestCase): - - def test_xmlcharrefreplace(self): - # Test that xmlcharrefreplace is the default output encoding - # error handler. - settings_overrides={ - 'output_encoding': 'latin1', - 'stylesheet': '', - '_disable_config': 1} - result = core.publish_string( - 'äöü€', writer_name='html4css1', - settings_overrides=settings_overrides) - self.assert_(result.find('\xe4\xf6\xfc€') != -1) - - if __name__ == '__main__': + import unittest unittest.main(defaultTest='suite') diff --git a/test/test_writers/test_html4css1_misc.py b/test/test_writers/test_html4css1_misc.py new file mode 100644 index 000000000..df07a7bd5 --- /dev/null +++ b/test/test_writers/test_html4css1_misc.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Miscellaneous HTML writer tests. +""" + +from __init__ import DocutilsTestSupport +from docutils import core + + +class EncodingTestCase(DocutilsTestSupport.StandardTestCase): + + def test_xmlcharrefreplace(self): + # Test that xmlcharrefreplace is the default output encoding + # error handler. + settings_overrides={ + 'output_encoding': 'latin1', + 'stylesheet': '', + '_disable_config': 1} + result = core.publish_string( + 'äöü€', writer_name='html4css1', + settings_overrides=settings_overrides) + self.assert_(result.find('\xe4\xf6\xfc€') != -1) + + +if __name__ == '__main__': + import unittest + unittest.main() -- cgit v1.2.1 From 23466c11fa5196e68efaa4336e18b61b0ff1cb1a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 24 Jun 2005 19:16:15 +0000 Subject: executable git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3574 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_html4css1_misc.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test/test_writers/test_html4css1_misc.py diff --git a/test/test_writers/test_html4css1_misc.py b/test/test_writers/test_html4css1_misc.py old mode 100644 new mode 100755 -- cgit v1.2.1 From bfc2500aadc16552de95fbab6ea663bf6f85c2bd Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 24 Jun 2005 19:46:00 +0000 Subject: correction git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3575 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6666de678..49b399f9e 100755 --- a/setup.py +++ b/setup.py @@ -57,8 +57,8 @@ what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'docutils.readers', 'docutils.readers.python', 'docutils.transforms', 'docutils.writers',], - 'data_files': [('docutils/parsers/rst/data', - glob.glob('docutils/parsers/rst/data/*.txt'))], + 'data_files': [('docutils/parsers/rst/include', + glob.glob('docutils/parsers/rst/include/*.txt'))], 'scripts' : ['tools/rst2html.py','tools/rst2latex.py'],} """Distutils setup parameters.""" -- cgit v1.2.1 From 5f3909e3c595d7835283272d14e927ac146b73c2 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 24 Jun 2005 19:53:49 +0000 Subject: for bug report 1227212 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3576 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS.txt b/THANKS.txt index 9dd6015f2..fa182b017 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -114,6 +114,7 @@ donations, tasty treats, and related projects: * Bill Sconce * Frank Siebenlist * Bruce Smith +* Nir Soffer * Asko Soukka * Darek Suchojad * Roman Suzi -- cgit v1.2.1 From 835cd6732507e8e4c76b0ef437bcc74177a9d174 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 22:20:27 +0000 Subject: merge trunk/docutils@3525 branches/blais_interrupt_render/docutils@HEAD trunk/docutils git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3581 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 132 +++++++++++++++++++++++++++++++++++++++- docutils/transforms/__init__.py | 24 +++++--- docutils/utils.py | 29 ++++++--- test/test_publish_doctree.py | 50 +++++++++++++++ tools/editors/emacs/rst-html.el | 62 +++++++++---------- 5 files changed, 249 insertions(+), 48 deletions(-) create mode 100755 test/test_publish_doctree.py diff --git a/docutils/core.py b/docutils/core.py index fa796a3db..7caa6cca7 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -19,7 +19,7 @@ __docformat__ = 'reStructuredText' import sys import pprint from docutils import __version__, __version_details__, SettingsSpec -from docutils import frontend, io, utils, readers, writers +from docutils import frontend, io, utils, readers, writers, parsers from docutils.frontend import OptionParser @@ -411,6 +411,135 @@ def publish_parts(source, source_path=None, destination_path=None, enable_exit_status=enable_exit_status) return pub.writer.parts +def publish_doctree(source, source_path=None, + source_class=io.StringInput, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None): + """ + Set up & run a `Publisher` for programmatic use with string I/O. Return + a pair of the encoded string or Unicode string output, and the parts. + + For encoded string output, be sure to set the 'output_encoding' setting to + the desired encoding. Set it to 'unicode' for unencoded Unicode string + output. Here's one way:: + + publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + + Similarly for Unicode string input (`source`):: + + publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + + Parameters: see `publish_programmatically`. + """ + output, pub = publish_programmatically( + source_class=source_class, source=source, source_path=source_path, + destination_class=io.NullOutput, + destination=None, destination_path=None, + reader=reader, reader_name=reader_name, + parser=parser, parser_name=parser_name, + writer=None, writer_name='null', + settings=settings, settings_spec=settings_spec, + settings_overrides=settings_overrides, + config_section=config_section, + enable_exit_status=enable_exit_status) + + # Note: clean up the document tree object by removing some things that are + # not needed anymore and that would not pickled well (this is the primary + # intended use of this publish method). + pub.document.transformer = None + pub.document.reporter = None + + return pub.document, pub.writer.parts + + +class DummyParser(parsers.Parser): + """ + Dummy parser that does nothing. + """ + supported = ('dummy',) + + settings_spec = ('Dummy Parser Options', None, ()) + + config_section = 'dummy parser' + config_section_dependencies = ('parsers',) + + def parse(self, inputstring, document): + "No-op" + +class DummyReader(readers.Reader): + """ + Dummy reader that is initialized with an existing document tree. + Its 'reading' consists in preparing and fixing up the document tree for the + writing phase. + """ + supported = ('dummy',) + + document = None + + settings_spec = ('Dummy Reader', None, (),) + + config_section = 'dummy reader' + config_section_dependencies = ('readers',) + + default_transforms = () + + def __init__( self, doctree ): + readers.Reader.__init__(self, parser=DummyParser()) + self._doctree = doctree + + def read(self, source, parser, settings): + # Fixup the document tree with a transformer and a reporter if it does + # not have them yet. + if self._doctree.transformer is None: + import docutils.transforms + self._doctree.transformer = docutils.transforms.Transformer( + self._doctree) + + if self._doctree.reporter is None: + self._doctree.reporter = utils.new_reporter( + source.source_path, settings) + + self._doctree.settings = settings + + return self._doctree + + +def publish_from_doctree(doctree, source_path=None, destination_path=None, + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None): + """ + + Set up & run a `Publisher` to render from an existing document tree data + structure, for programmatic use with string I/O. Return a pair of encoded + string output and document parts. + + For encoded string output, be sure to set the 'output_encoding' setting to + the desired encoding. Set it to 'unicode' for unencoded Unicode string + output. Here's one way:: + + publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + + Parameters: see `publish_programmatically`. + """ + output, pub = publish_programmatically( + source_class=io.NullInput, source='', source_path=source_path, + destination_class=io.StringOutput, + destination=None, destination_path=destination_path, + reader=DummyReader(doctree), reader_name=None, + parser=None, parser_name=None, + writer=writer, writer_name=writer_name, + settings=settings, settings_spec=settings_spec, + settings_overrides=settings_overrides, + config_section=config_section, + enable_exit_status=enable_exit_status) + + return output, pub.writer.parts + def publish_programmatically(source_class, source, source_path, destination_class, destination, destination_path, reader, reader_name, @@ -520,3 +649,4 @@ def publish_programmatically(source_class, source, source_path, pub.set_destination(destination, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) return output, pub + diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 5a372f202..8be802dc5 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -43,7 +43,7 @@ class Transform: default_priority = None """Numerical priority of this transform, 0 through 999 (override).""" - def __init__(self, document, startnode=None): + def __init__(self, document, startnode=None, data=None): """ Initial setup for in-place document transforms. """ @@ -60,6 +60,9 @@ class Transform: document.settings.language_code) """Language module local to this document.""" + self.data = data + """Data specific to this transform instance. You can use this + to parameterize the transform instance.""" def apply(self): """Override to apply the transform to the document tree.""" @@ -106,14 +109,18 @@ class Transformer(TransformSpec): """Internal serial number to keep track of the add order of transforms.""" - def add_transform(self, transform_class, priority=None): + def add_transform(self, transform_class, priority=None, data=None): """ Store a single transform. Use `priority` to override the default. + `data` is passed to the constructor as a keyword argument. + This can be used to pass application-specific data to the transformer + 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)) + self.transforms.append( + (priority_string, transform_class, None, data)) self.sorted = 0 def add_transforms(self, transform_list): @@ -121,7 +128,8 @@ class Transformer(TransformSpec): 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.transforms.append( + (priority_string, transform_class, None, None)) self.sorted = 0 def add_pending(self, pending, priority=None): @@ -130,7 +138,8 @@ class Transformer(TransformSpec): 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.transforms.append( + (priority_string, transform_class, pending, None)) self.sorted = 0 def get_priority_string(self, priority): @@ -174,7 +183,8 @@ class Transformer(TransformSpec): self.transforms.sort() self.transforms.reverse() self.sorted = 1 - priority, transform_class, pending = self.transforms.pop() - transform = transform_class(self.document, startnode=pending) + priority, transform_class, pending, data = self.transforms.pop() + transform = transform_class(self.document, + startnode=pending, data=data) transform.apply() self.applied.append((priority, transform_class, pending)) diff --git a/docutils/utils.py b/docutils/utils.py index 1d77d38d8..cb018bd55 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -80,6 +80,7 @@ class Reporter: - `encoding`: The encoding for stderr output. - `error_handler`: The error handler for stderr output encoding. """ + self.source = source """The path to or description of the source data.""" @@ -357,7 +358,24 @@ def extract_name_value(line): attlist.append((attname.lower(), data)) return attlist -def new_document(source, settings=None): +def new_reporter(source_path, settings): + """ + Return a new Reporter object. + + :Parameters: + `source` : string + The path to or description of the source text of the document. + `settings` : optparse.Values object + Runtime settings. If none provided, a default set will be used. + """ + reporter = Reporter( + source_path, settings.report_level, settings.halt_level, + stream=settings.warning_stream, debug=settings.debug, + encoding=settings.error_encoding, + error_handler=settings.error_encoding_error_handler) + return reporter + +def new_document(source_path, settings=None): """ Return a new empty document object. @@ -369,12 +387,9 @@ def new_document(source, settings=None): """ if settings is None: settings = frontend.OptionParser().get_default_values() - reporter = Reporter(source, settings.report_level, settings.halt_level, - stream=settings.warning_stream, debug=settings.debug, - encoding=settings.error_encoding, - error_handler=settings.error_encoding_error_handler) - document = nodes.document(settings, reporter, source=source) - document.note_source(source, -1) + reporter = new_reporter(source_path, settings) + document = nodes.document(settings, reporter, source=source_path) + document.note_source(source_path, -1) return document def clean_rcs_keywords(paragraph, keyword_substitutions): diff --git a/test/test_publish_doctree.py b/test/test_publish_doctree.py new file mode 100755 index 000000000..20b3cff79 --- /dev/null +++ b/test/test_publish_doctree.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Perform tests with publishing to a tree, and running a writer on that tree later. +""" + +import unittest +from types import DictType, StringType +import docutils.core +import docutils.nodes + + +test_document = """\ +Test Document +============= + +This is a test document. +""" + + +class PublishDoctreeTestCase(unittest.TestCase): + + def test_publish_doctree(self): + """Test publish_doctree and publish_from_doctree.""" + # Produce the document tree. + doctree, parts = docutils.core.publish_doctree( + source=test_document, + reader_name='standalone', + parser_name='restructuredtext', + settings_overrides={'_disable_config': 1}) + + self.assert_(isinstance(doctree, docutils.nodes.document)) + self.assert_(isinstance(parts, DictType)) + + # Write out the document. + output, parts = docutils.core.publish_from_doctree( + doctree, writer_name='pseudoxml') + + self.assert_(isinstance(output, StringType)) + assert isinstance(parts, dict) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/editors/emacs/rst-html.el b/tools/editors/emacs/rst-html.el index c9ebf33ef..57e4d0b55 100644 --- a/tools/editors/emacs/rst-html.el +++ b/tools/editors/emacs/rst-html.el @@ -1,32 +1,26 @@ ;;; rst-mode.el --- Goodies to automate converting reST documents to HTML. - -;; Copyright 2003 Martin Blais -;; -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2 of the License, or -;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +;;; +;;; Author: Martin Blais +;;; Contact: blais@furius.ca +;;; Revision: $Revision$ +;;; Date: $Date$ +;;; Copyright: This module has been placed in the public domain. +;;; +;;; This package provides a few functions and variables that can help in +;;; automating converting reST documents to HTML from within Emacs. You could +;;; use a makefile to do this, of use the compile command that this package +;;; provides. +;;; +;;; You can also bind a command to automate converting to HTML:: +;;; +;;; (defun user-rst-mode-hook () +;;; (local-set-key [(control c)(?9)] 'rst-html-compile)) +;;; (add-hook 'rst-mode-hook 'user-rst-mode-hook) +;;; ;;; Commentary: - -;; This package provides a few functions and variables that can help in -;; automating converting reST documents to HTML from within emacs. You could -;; use a makefile to do this, of use the compile command that this package -;; provides. - -;; You can also bind a command to automate converting to HTML: -;; (defun user-rst-mode-hook () -;; (local-set-key [(control c)(?9)] 'rst-html-compile)) -;; (add-hook 'rst-mode-hook 'user-rst-mode-hook) +;;; +;;; History: +;;; ;;; Code: @@ -35,7 +29,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defgroup rst-html nil +(defgroup rst-html nil "Settings for conversion to HTML available by \\[rst-html-compile]. Use of this functionality is discouraged. Get a proper `Makefile' instead." :group 'rst @@ -47,7 +41,7 @@ this functionality is discouraged. Get a proper `Makefile' instead." :type '(string)) (defcustom rst-html-stylesheet "" - "Stylesheet for reST to HTML conversion. Empty for no special stylesheet." + "Stylesheet for reST to HTML conversion. Empty for no special stylesheet." :group 'rst-html :type '(string)) @@ -86,8 +80,8 @@ Stylesheets are set by an own option." )) (defun rst-html-compile-with-conf () - "Compile command to convert reST document into HTML. Attempts to find -configuration file, if it can, overrides the options." + "Compile command to convert reST document into HTML. +Attempts to find configuration file, if it can, overrides the options." (interactive) (let ((conffile (rst-html-find-conf))) (if conffile @@ -118,7 +112,7 @@ configuration file, if it can, overrides the options." (while (and (or (not (string= "/" dir)) (setq dir nil) nil) (not (file-exists-p (concat dir file-name)))) ;; Move up to the parent dir and try again. - (setq dir (expand-file-name (file-name-directory + (setq dir (expand-file-name (file-name-directory (directory-file-name (file-name-directory dir))))) ) (or (and dir (concat dir file-name)) nil) @@ -126,4 +120,6 @@ configuration file, if it can, overrides the options." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; rst-mode.el ends here +(provide 'rst-html) + +;;; rst-html.el ends here -- cgit v1.2.1 From 0c69925dc24c30bea76b320410a49f2f04460fef Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 22:37:08 +0000 Subject: polished git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3582 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 7caa6cca7..30476c575 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -21,6 +21,7 @@ import pprint from docutils import __version__, __version_details__, SettingsSpec from docutils import frontend, io, utils, readers, writers, parsers from docutils.frontend import OptionParser +from docutils.transforms import Transformer class Publisher: @@ -456,55 +457,40 @@ def publish_doctree(source, source_path=None, class DummyParser(parsers.Parser): - """ - Dummy parser that does nothing. - """ - supported = ('dummy',) - settings_spec = ('Dummy Parser Options', None, ()) + """Dummy parser that does nothing. Used by `DummyReader`.""" - config_section = 'dummy parser' - config_section_dependencies = ('parsers',) + supported = ('dummy',) def parse(self, inputstring, document): - "No-op" + pass class DummyReader(readers.Reader): + """ Dummy reader that is initialized with an existing document tree. Its 'reading' consists in preparing and fixing up the document tree for the writing phase. """ + supported = ('dummy',) document = None - settings_spec = ('Dummy Reader', None, (),) - - config_section = 'dummy reader' - config_section_dependencies = ('readers',) - - default_transforms = () - - def __init__( self, doctree ): + def __init__(self, doctree): readers.Reader.__init__(self, parser=DummyParser()) - self._doctree = doctree + self.doctree = doctree def read(self, source, parser, settings): # Fixup the document tree with a transformer and a reporter if it does # not have them yet. - if self._doctree.transformer is None: - import docutils.transforms - self._doctree.transformer = docutils.transforms.Transformer( - self._doctree) - - if self._doctree.reporter is None: - self._doctree.reporter = utils.new_reporter( + if self.doctree.transformer is None: + self.doctree.transformer = Transformer(self.doctree) + if self.doctree.reporter is None: + self.doctree.reporter = utils.new_reporter( source.source_path, settings) - - self._doctree.settings = settings - - return self._doctree + self.doctree.settings = settings + return self.doctree def publish_from_doctree(doctree, source_path=None, destination_path=None, -- cgit v1.2.1 From d9322bf1a32f81f8a42d73a5cdedf8467aa40e23 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 22:41:29 +0000 Subject: removed unused "document" class variable of standalone and dummy reader git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3583 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 2 -- docutils/readers/standalone.py | 3 --- 2 files changed, 5 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 30476c575..30731b167 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -475,8 +475,6 @@ class DummyReader(readers.Reader): supported = ('dummy',) - document = None - def __init__(self, doctree): readers.Reader.__init__(self, parser=DummyParser()) self.doctree = doctree diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index c7772aa48..b1464898f 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -21,9 +21,6 @@ class Reader(readers.Reader): supported = ('standalone',) """Contexts this reader supports.""" - document = None - """A single document tree.""" - settings_spec = ( 'Standalone Reader', None, -- cgit v1.2.1 From 35e38fe655db71e85b67c962d854eaab5f764608 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 22:54:57 +0000 Subject: removed duplicate publish_doctree method; renamed publish_from_doctree to publish_doctree git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3585 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 64 +++++++------------------------------------- test/test_publish_doctree.py | 6 ++--- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 30731b167..d702c916f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -412,49 +412,6 @@ def publish_parts(source, source_path=None, destination_path=None, enable_exit_status=enable_exit_status) return pub.writer.parts -def publish_doctree(source, source_path=None, - source_class=io.StringInput, - reader=None, reader_name='standalone', - parser=None, parser_name='restructuredtext', - settings=None, settings_spec=None, - settings_overrides=None, config_section=None, - enable_exit_status=None): - """ - Set up & run a `Publisher` for programmatic use with string I/O. Return - a pair of the encoded string or Unicode string output, and the parts. - - For encoded string output, be sure to set the 'output_encoding' setting to - the desired encoding. Set it to 'unicode' for unencoded Unicode string - output. Here's one way:: - - publish_string(..., settings_overrides={'output_encoding': 'unicode'}) - - Similarly for Unicode string input (`source`):: - - publish_string(..., settings_overrides={'input_encoding': 'unicode'}) - - Parameters: see `publish_programmatically`. - """ - output, pub = publish_programmatically( - source_class=source_class, source=source, source_path=source_path, - destination_class=io.NullOutput, - destination=None, destination_path=None, - reader=reader, reader_name=reader_name, - parser=parser, parser_name=parser_name, - writer=None, writer_name='null', - settings=settings, settings_spec=settings_spec, - settings_overrides=settings_overrides, - config_section=config_section, - enable_exit_status=enable_exit_status) - - # Note: clean up the document tree object by removing some things that are - # not needed anymore and that would not pickled well (this is the primary - # intended use of this publish method). - pub.document.transformer = None - pub.document.reporter = None - - return pub.document, pub.writer.parts - class DummyParser(parsers.Parser): @@ -469,8 +426,10 @@ class DummyReader(readers.Reader): """ Dummy reader that is initialized with an existing document tree. - Its 'reading' consists in preparing and fixing up the document tree for the - writing phase. + Its 'reading' consists in preparing and fixing up the document + tree for the writing phase. + + Used by `publish_doctree`. """ supported = ('dummy',) @@ -491,13 +450,12 @@ class DummyReader(readers.Reader): return self.doctree -def publish_from_doctree(doctree, source_path=None, destination_path=None, - writer=None, writer_name='pseudoxml', - settings=None, settings_spec=None, - settings_overrides=None, config_section=None, - enable_exit_status=None): +def publish_doctree(doctree, source_path=None, destination_path=None, + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None): """ - Set up & run a `Publisher` to render from an existing document tree data structure, for programmatic use with string I/O. Return a pair of encoded string output and document parts. @@ -506,7 +464,7 @@ def publish_from_doctree(doctree, source_path=None, destination_path=None, the desired encoding. Set it to 'unicode' for unencoded Unicode string output. Here's one way:: - publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + publish_doctree(..., settings_overrides={'output_encoding': 'unicode'}) Parameters: see `publish_programmatically`. """ @@ -521,7 +479,6 @@ def publish_from_doctree(doctree, source_path=None, destination_path=None, settings_overrides=settings_overrides, config_section=config_section, enable_exit_status=enable_exit_status) - return output, pub.writer.parts def publish_programmatically(source_class, source, source_path, @@ -633,4 +590,3 @@ def publish_programmatically(source_class, source, source_path, pub.set_destination(destination, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) return output, pub - diff --git a/test/test_publish_doctree.py b/test/test_publish_doctree.py index 20b3cff79..d2b88b4ee 100755 --- a/test/test_publish_doctree.py +++ b/test/test_publish_doctree.py @@ -27,7 +27,7 @@ This is a test document. class PublishDoctreeTestCase(unittest.TestCase): def test_publish_doctree(self): - """Test publish_doctree and publish_from_doctree.""" + """Test publish_doctree and publish_doctree.""" # Produce the document tree. doctree, parts = docutils.core.publish_doctree( source=test_document, @@ -39,11 +39,11 @@ class PublishDoctreeTestCase(unittest.TestCase): self.assert_(isinstance(parts, DictType)) # Write out the document. - output, parts = docutils.core.publish_from_doctree( + output, parts = docutils.core.publish_doctree( doctree, writer_name='pseudoxml') self.assert_(isinstance(output, StringType)) - assert isinstance(parts, dict) + assert isinstance(parts, DictType) if __name__ == '__main__': -- cgit v1.2.1 From 86b1889e15d3cdbc3115746534623627e0c9edc2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 23:01:45 +0000 Subject: oh, publish_doctree was not a duplicate... 8-) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3586 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 55 +++++++++++++++++++++++++++++++++++++++----- test/test_publish_doctree.py | 4 ++-- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index d702c916f..aa511296f 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -412,6 +412,49 @@ def publish_parts(source, source_path=None, destination_path=None, enable_exit_status=enable_exit_status) return pub.writer.parts +def publish_doctree(source, source_path=None, + source_class=io.StringInput, + reader=None, reader_name='standalone', + parser=None, parser_name='restructuredtext', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None): + """ + Set up & run a `Publisher` for programmatic use with string I/O. Return + a pair of the encoded string or Unicode string output, and the parts. + + For encoded string output, be sure to set the 'output_encoding' setting to + the desired encoding. Set it to 'unicode' for unencoded Unicode string + output. Here's one way:: + + publish_string(..., settings_overrides={'output_encoding': 'unicode'}) + + Similarly for Unicode string input (`source`):: + + publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + + Parameters: see `publish_programmatically`. + """ + output, pub = publish_programmatically( + source_class=source_class, source=source, source_path=source_path, + destination_class=io.NullOutput, + destination=None, destination_path=None, + reader=reader, reader_name=reader_name, + parser=parser, parser_name=parser_name, + writer=None, writer_name='null', + settings=settings, settings_spec=settings_spec, + settings_overrides=settings_overrides, + config_section=config_section, + enable_exit_status=enable_exit_status) + + # Note: clean up the document tree object by removing some things that are + # not needed anymore and that would not pickled well (this is the primary + # intended use of this publish method). + pub.document.transformer = None + pub.document.reporter = None + + return pub.document, pub.writer.parts + class DummyParser(parsers.Parser): @@ -429,7 +472,7 @@ class DummyReader(readers.Reader): Its 'reading' consists in preparing and fixing up the document tree for the writing phase. - Used by `publish_doctree`. + Used by `publish_from_doctree`. """ supported = ('dummy',) @@ -450,11 +493,11 @@ class DummyReader(readers.Reader): return self.doctree -def publish_doctree(doctree, source_path=None, destination_path=None, - writer=None, writer_name='pseudoxml', - settings=None, settings_spec=None, - settings_overrides=None, config_section=None, - enable_exit_status=None): +def publish_from_doctree(doctree, source_path=None, destination_path=None, + writer=None, writer_name='pseudoxml', + settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None): """ Set up & run a `Publisher` to render from an existing document tree data structure, for programmatic use with string I/O. Return a pair of encoded diff --git a/test/test_publish_doctree.py b/test/test_publish_doctree.py index d2b88b4ee..3c37e45cf 100755 --- a/test/test_publish_doctree.py +++ b/test/test_publish_doctree.py @@ -27,7 +27,7 @@ This is a test document. class PublishDoctreeTestCase(unittest.TestCase): def test_publish_doctree(self): - """Test publish_doctree and publish_doctree.""" + """Test `publish_doctree` and `publish_from_doctree`.""" # Produce the document tree. doctree, parts = docutils.core.publish_doctree( source=test_document, @@ -39,7 +39,7 @@ class PublishDoctreeTestCase(unittest.TestCase): self.assert_(isinstance(parts, DictType)) # Write out the document. - output, parts = docutils.core.publish_doctree( + output, parts = docutils.core.publish_from_doctree( doctree, writer_name='pseudoxml') self.assert_(isinstance(output, StringType)) -- cgit v1.2.1 From 38e233c4e2d2e1736af4b4938d622e358204e564 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 23:09:59 +0000 Subject: publish_doctree now returns only the doctree, not an empty (useless) "parts" dictionary; polished git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3587 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 94 +++++++++++++++++++++----------------------- test/test_publish_doctree.py | 3 +- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index aa511296f..b198b3022 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -420,18 +420,14 @@ def publish_doctree(source, source_path=None, settings_overrides=None, config_section=None, enable_exit_status=None): """ - Set up & run a `Publisher` for programmatic use with string I/O. Return - a pair of the encoded string or Unicode string output, and the parts. + Set up & run a `Publisher` for programmatic use with string I/O. + Return the document tree. - For encoded string output, be sure to set the 'output_encoding' setting to + For encoded string input, be sure to set the 'input_encoding' setting to the desired encoding. Set it to 'unicode' for unencoded Unicode string - output. Here's one way:: + input. Here's one way:: - publish_string(..., settings_overrides={'output_encoding': 'unicode'}) - - Similarly for Unicode string input (`source`):: - - publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + publish_doctree(..., settings_overrides={'input_encoding': 'unicode'}) Parameters: see `publish_programmatically`. """ @@ -453,45 +449,7 @@ def publish_doctree(source, source_path=None, pub.document.transformer = None pub.document.reporter = None - return pub.document, pub.writer.parts - - -class DummyParser(parsers.Parser): - - """Dummy parser that does nothing. Used by `DummyReader`.""" - - supported = ('dummy',) - - def parse(self, inputstring, document): - pass - -class DummyReader(readers.Reader): - - """ - Dummy reader that is initialized with an existing document tree. - Its 'reading' consists in preparing and fixing up the document - tree for the writing phase. - - Used by `publish_from_doctree`. - """ - - supported = ('dummy',) - - def __init__(self, doctree): - readers.Reader.__init__(self, parser=DummyParser()) - self.doctree = doctree - - def read(self, source, parser, settings): - # Fixup the document tree with a transformer and a reporter if it does - # not have them yet. - if self.doctree.transformer is None: - self.doctree.transformer = Transformer(self.doctree) - if self.doctree.reporter is None: - self.doctree.reporter = utils.new_reporter( - source.source_path, settings) - self.doctree.settings = settings - return self.doctree - + return pub.document def publish_from_doctree(doctree, source_path=None, destination_path=None, writer=None, writer_name='pseudoxml', @@ -507,7 +465,8 @@ def publish_from_doctree(doctree, source_path=None, destination_path=None, the desired encoding. Set it to 'unicode' for unencoded Unicode string output. Here's one way:: - publish_doctree(..., settings_overrides={'output_encoding': 'unicode'}) + publish_from_doctree( + ..., settings_overrides={'output_encoding': 'unicode'}) Parameters: see `publish_programmatically`. """ @@ -633,3 +592,40 @@ def publish_programmatically(source_class, source, source_path, pub.set_destination(destination, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) return output, pub + + +class DummyParser(parsers.Parser): + + """Dummy parser that does nothing. Used by `DummyReader`.""" + + supported = ('dummy',) + + def parse(self, inputstring, document): + pass + +class DummyReader(readers.Reader): + + """ + Dummy reader that is initialized with an existing document tree. + Its 'reading' consists in preparing and fixing up the document + tree for the writing phase. + + Used by `publish_from_doctree`. + """ + + supported = ('dummy',) + + def __init__(self, doctree): + readers.Reader.__init__(self, parser=DummyParser()) + self.doctree = doctree + + def read(self, source, parser, settings): + # Fixup the document tree with a transformer and a reporter if it does + # not have them yet. + if self.doctree.transformer is None: + self.doctree.transformer = Transformer(self.doctree) + if self.doctree.reporter is None: + self.doctree.reporter = utils.new_reporter( + source.source_path, settings) + self.doctree.settings = settings + return self.doctree diff --git a/test/test_publish_doctree.py b/test/test_publish_doctree.py index 3c37e45cf..32f40d9ca 100755 --- a/test/test_publish_doctree.py +++ b/test/test_publish_doctree.py @@ -29,14 +29,13 @@ class PublishDoctreeTestCase(unittest.TestCase): def test_publish_doctree(self): """Test `publish_doctree` and `publish_from_doctree`.""" # Produce the document tree. - doctree, parts = docutils.core.publish_doctree( + doctree = docutils.core.publish_doctree( source=test_document, reader_name='standalone', parser_name='restructuredtext', settings_overrides={'_disable_config': 1}) self.assert_(isinstance(doctree, docutils.nodes.document)) - self.assert_(isinstance(parts, DictType)) # Write out the document. output, parts = docutils.core.publish_from_doctree( -- cgit v1.2.1 From 96334f7a48e86f3237d53fb728242a82c26f7081 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 26 Jun 2005 23:28:01 +0000 Subject: removed unnecessary imports git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3588 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 3ff069a28..f6ade89d2 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -11,9 +11,7 @@ This package contains Docutils Reader modules. __docformat__ = 'reStructuredText' -import sys from docutils import utils, parsers, Component -from docutils.transforms import universal class Reader(Component): -- cgit v1.2.1 From 3e889284c05f7fda58b49ae0e465a789b789a8cb Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 00:22:01 +0000 Subject: added "document = None" again; it serves documentation purposes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3589 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/standalone.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index b1464898f..c7772aa48 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -21,6 +21,9 @@ class Reader(readers.Reader): supported = ('standalone',) """Contexts this reader supports.""" + document = None + """A single document tree.""" + settings_spec = ( 'Standalone Reader', None, -- cgit v1.2.1 From 70461a0d6a58a0e74f4b880a495b1a0765717e19 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 00:42:40 +0000 Subject: make sure the Writer transforms get applied when calling publish_from_doctree; keep correct source_path; set correct doctree.settings object; I implemented all this blindly, without proper testing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3590 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index b198b3022..de82370cc 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -443,15 +443,17 @@ def publish_doctree(source, source_path=None, config_section=config_section, enable_exit_status=enable_exit_status) + # The transformer is not needed anymore. + del pub.document.transformer + # Note: clean up the document tree object by removing some things that are # not needed anymore and that would not pickled well (this is the primary # intended use of this publish method). - pub.document.transformer = None pub.document.reporter = None return pub.document -def publish_from_doctree(doctree, source_path=None, destination_path=None, +def publish_from_doctree(doctree, destination_path=None, writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, @@ -470,17 +472,23 @@ def publish_from_doctree(doctree, source_path=None, destination_path=None, Parameters: see `publish_programmatically`. """ - output, pub = publish_programmatically( - source_class=io.NullInput, source='', source_path=source_path, - destination_class=io.StringOutput, - destination=None, destination_path=destination_path, - reader=DummyReader(doctree), reader_name=None, - parser=None, parser_name=None, - writer=writer, writer_name=writer_name, - settings=settings, settings_spec=settings_spec, - settings_overrides=settings_overrides, - config_section=config_section, - enable_exit_status=enable_exit_status) + # Create fresh Transformer object. + doctree.transformer = Transformer(doctree) + # Create Publisher. + pub = Publisher(DummyReader(doctree), None, writer, settings=settings, + source_class=io.NullInput, + destination_class=io.StringOutput) + # Set Writer. There's no Reader and Parser because the document + # is already parsed. + pub.set_components(None, None, writer_name) + # Set settings. + pub.process_programmatic_settings( + settings_spec, settings_overrides, config_section) + # Override document settings with new settings. + doctree.settings = pub.settings + # Set destination path and run. + pub.set_destination(None, destination_path) + output = pub.publish(enable_exit_status=enable_exit_status) return output, pub.writer.parts def publish_programmatically(source_class, source, source_path, @@ -620,10 +628,7 @@ class DummyReader(readers.Reader): self.doctree = doctree def read(self, source, parser, settings): - # Fixup the document tree with a transformer and a reporter if it does - # not have them yet. - if self.doctree.transformer is None: - self.doctree.transformer = Transformer(self.doctree) + # Fixup the document tree with a reporter if it does not have it yet. if self.doctree.reporter is None: self.doctree.reporter = utils.new_reporter( source.source_path, settings) -- cgit v1.2.1 From 4460491ab1b043e0d112a63a859b9053337a10a0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 00:59:00 +0000 Subject: do not set reporter=None -- pickling is not the only use case; added documentation about doctree.settings object git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3591 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index de82370cc..5e511a98e 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -442,15 +442,9 @@ def publish_doctree(source, source_path=None, settings_overrides=settings_overrides, config_section=config_section, enable_exit_status=enable_exit_status) - - # The transformer is not needed anymore. + # The transformer is not needed anymore. (A new transformer will + # be created in `publish_from_doctree`.) del pub.document.transformer - - # Note: clean up the document tree object by removing some things that are - # not needed anymore and that would not pickled well (this is the primary - # intended use of this publish method). - pub.document.reporter = None - return pub.document def publish_from_doctree(doctree, destination_path=None, @@ -463,6 +457,9 @@ def publish_from_doctree(doctree, destination_path=None, structure, for programmatic use with string I/O. Return a pair of encoded string output and document parts. + Note that doctree.settings is overridden; if you want to use the settings + of the original `doctree` document, pass settings=doctree.settings. + For encoded string output, be sure to set the 'output_encoding' setting to the desired encoding. Set it to 'unicode' for unencoded Unicode string output. Here's one way:: @@ -472,7 +469,7 @@ def publish_from_doctree(doctree, destination_path=None, Parameters: see `publish_programmatically`. """ - # Create fresh Transformer object. + # Create fresh Transformer object, to be populated from Writer component. doctree.transformer = Transformer(doctree) # Create Publisher. pub = Publisher(DummyReader(doctree), None, writer, settings=settings, @@ -484,8 +481,6 @@ def publish_from_doctree(doctree, destination_path=None, # Set settings. pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) - # Override document settings with new settings. - doctree.settings = pub.settings # Set destination path and run. pub.set_destination(None, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) @@ -615,9 +610,6 @@ class DummyReader(readers.Reader): """ Dummy reader that is initialized with an existing document tree. - Its 'reading' consists in preparing and fixing up the document - tree for the writing phase. - Used by `publish_from_doctree`. """ @@ -628,9 +620,6 @@ class DummyReader(readers.Reader): self.doctree = doctree def read(self, source, parser, settings): - # Fixup the document tree with a reporter if it does not have it yet. - if self.doctree.reporter is None: - self.doctree.reporter = utils.new_reporter( - source.source_path, settings) + # Override document settings with new settings. self.doctree.settings = settings return self.doctree -- cgit v1.2.1 From 225cfed60f15481726d5a3d68beb3383e4a52a7a Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 01:13:51 +0000 Subject: fixed some docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3592 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 4 ++-- docutils/utils.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 5e511a98e..10fa13b06 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -395,7 +395,7 @@ def publish_parts(source, source_path=None, destination_path=None, the desired encoding. Set it to 'unicode' for unencoded Unicode string input. Here's how:: - publish_string(..., settings_overrides={'input_encoding': 'unicode'}) + publish_parts(..., settings_overrides={'input_encoding': 'unicode'}) Parameters: see `publish_programmatically`. """ @@ -427,7 +427,7 @@ def publish_doctree(source, source_path=None, the desired encoding. Set it to 'unicode' for unencoded Unicode string input. Here's one way:: - publish_doctree(..., settings_overrides={'input_encoding': 'unicode'}) + publish_doctree(..., settings_overrides={'input_encoding': 'unicode'}) Parameters: see `publish_programmatically`. """ diff --git a/docutils/utils.py b/docutils/utils.py index cb018bd55..100f8671d 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -366,7 +366,7 @@ def new_reporter(source_path, settings): `source` : string The path to or description of the source text of the document. `settings` : optparse.Values object - Runtime settings. If none provided, a default set will be used. + Runtime settings. """ reporter = Reporter( source_path, settings.report_level, settings.halt_level, -- cgit v1.2.1 From 98f4ec4fb3daf08766943a909740833cc1ab82f2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 01:20:00 +0000 Subject: in DummyReader.read: restore doctree.reporter if necessary; otherwise things get a bit more complicated for pickling applications because new_reporter requires a fully set-up settings object, which is most conveniently created by the publish_* functions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3593 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docutils/core.py b/docutils/core.py index 10fa13b06..bf1ad460d 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -620,6 +620,10 @@ class DummyReader(readers.Reader): self.doctree = doctree def read(self, source, parser, settings): + # Useful for pickling, where the reporter is destroyed. + if self.doctree.reporter is None: + self.doctree.reporter = utils.new_reporter( + source.source_path, settings) # Override document settings with new settings. self.doctree.settings = settings return self.doctree -- cgit v1.2.1 From ddba601498ad2c7e472daa384357b384e6ac2f45 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 02:04:39 +0000 Subject: moved Dummy reader and parser to readers/dummy.py and parsers/dummy.py, resp.; removed "restructuredtext" default for parser_name when initializing a reader git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3594 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 46 ++++++++------------------------------------ docutils/parsers/dummy.py | 21 ++++++++++++++++++++ docutils/readers/__init__.py | 2 +- docutils/readers/dummy.py | 29 ++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 39 deletions(-) create mode 100644 docutils/parsers/dummy.py create mode 100644 docutils/readers/dummy.py diff --git a/docutils/core.py b/docutils/core.py index bf1ad460d..5ffe6c911 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -19,7 +19,7 @@ __docformat__ = 'reStructuredText' import sys import pprint from docutils import __version__, __version_details__, SettingsSpec -from docutils import frontend, io, utils, readers, writers, parsers +from docutils import frontend, io, utils, readers, writers from docutils.frontend import OptionParser from docutils.transforms import Transformer @@ -471,13 +471,15 @@ def publish_from_doctree(doctree, destination_path=None, """ # Create fresh Transformer object, to be populated from Writer component. doctree.transformer = Transformer(doctree) + # Create reader with existing doctree. + from docutils.readers import dummy + reader = dummy.Reader(doctree) # Create Publisher. - pub = Publisher(DummyReader(doctree), None, writer, settings=settings, - source_class=io.NullInput, + pub = Publisher(reader, None, writer, + settings=settings, source_class=io.NullInput, destination_class=io.StringOutput) - # Set Writer. There's no Reader and Parser because the document - # is already parsed. - pub.set_components(None, None, writer_name) + # Set parser and writer name. + pub.set_components(None, 'dummy', writer_name) # Set settings. pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) @@ -595,35 +597,3 @@ def publish_programmatically(source_class, source, source_path, pub.set_destination(destination, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) return output, pub - - -class DummyParser(parsers.Parser): - - """Dummy parser that does nothing. Used by `DummyReader`.""" - - supported = ('dummy',) - - def parse(self, inputstring, document): - pass - -class DummyReader(readers.Reader): - - """ - Dummy reader that is initialized with an existing document tree. - Used by `publish_from_doctree`. - """ - - supported = ('dummy',) - - def __init__(self, doctree): - readers.Reader.__init__(self, parser=DummyParser()) - self.doctree = doctree - - def read(self, source, parser, settings): - # Useful for pickling, where the reporter is destroyed. - if self.doctree.reporter is None: - self.doctree.reporter = utils.new_reporter( - source.source_path, settings) - # Override document settings with new settings. - self.doctree.settings = settings - return self.doctree diff --git a/docutils/parsers/dummy.py b/docutils/parsers/dummy.py new file mode 100644 index 000000000..5fd646c7a --- /dev/null +++ b/docutils/parsers/dummy.py @@ -0,0 +1,21 @@ +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +"""Dummy parser that does nothing.""" + +from docutils import parsers + +class Parser(parsers.Parser): + + """Dummy parser that does nothing.""" + + supported = ('dummy',) + + config_section = 'dummy parser' + config_section_dependencies = ('parsers',) + + def parse(self, inputstring, document): + pass diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index f6ade89d2..36a5264bf 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -28,7 +28,7 @@ class Reader(Component): component_type = 'reader' config_section = 'readers' - def __init__(self, parser=None, parser_name='restructuredtext'): + def __init__(self, parser=None, parser_name=None): """ Initialize the Reader instance. diff --git a/docutils/readers/dummy.py b/docutils/readers/dummy.py new file mode 100644 index 000000000..a63301e17 --- /dev/null +++ b/docutils/readers/dummy.py @@ -0,0 +1,29 @@ +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +"""Dummy reader that is initialized with an existing document tree.""" + +from docutils import readers + +class Reader(readers.Reader): + + """Dummy reader that is initialized with an existing document tree.""" + + supported = ('dummy',) + + def __init__(self, doctree): + readers.Reader.__init__(self) + self.doctree = doctree + + def read(self, source, parser, settings): + # Useful for document serialization, where the reporter is destroyed. + if self.doctree.reporter is None: + self.doctree.reporter = utils.new_reporter( + source.source_path, settings) + # Override document settings with new settings. + self.doctree.settings = settings + # Call base-class method and return document tree. + return readers.Reader.read(self, source, parser, settings) -- cgit v1.2.1 From 180de2ad7ed7e496b973c1715789986ac1d3bdfc Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 02:44:40 +0000 Subject: replaced data argument to Transform constructor with **kwargs; Transform.data contains now the kwargs dictionary; added transform instance to Transformer.applied tuples again -- this shouldn't cause problems with pickling because the Transformer isn't pickled; if it does cause any problems, please follow up on Docutils-develop git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3596 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 25 ++++++++++++------------- test/test_transforms.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 13 deletions(-) create mode 100755 test/test_transforms.py diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 8be802dc5..ef827fd50 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -43,7 +43,7 @@ class Transform: default_priority = None """Numerical priority of this transform, 0 through 999 (override).""" - def __init__(self, document, startnode=None, data=None): + def __init__(self, document, startnode=None, **kwargs): """ Initial setup for in-place document transforms. """ @@ -60,7 +60,7 @@ class Transform: document.settings.language_code) """Language module local to this document.""" - self.data = data + self.data = kwargs """Data specific to this transform instance. You can use this to parameterize the transform instance.""" @@ -109,18 +109,17 @@ class Transformer(TransformSpec): """Internal serial number to keep track of the add order of transforms.""" - def add_transform(self, transform_class, priority=None, data=None): + def add_transform(self, transform_class, priority=None, **kwargs): """ Store a single transform. Use `priority` to override the default. - `data` is passed to the constructor as a keyword argument. - This can be used to pass application-specific data to the transformer - instance. + `kwargs` are passed on to the constructor 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, data)) + (priority_string, transform_class, None, kwargs)) self.sorted = 0 def add_transforms(self, transform_list): @@ -129,7 +128,7 @@ class Transformer(TransformSpec): priority_string = self.get_priority_string( transform_class.default_priority) self.transforms.append( - (priority_string, transform_class, None, None)) + (priority_string, transform_class, None, {})) self.sorted = 0 def add_pending(self, pending, priority=None): @@ -139,7 +138,7 @@ class Transformer(TransformSpec): priority = transform_class.default_priority priority_string = self.get_priority_string(priority) self.transforms.append( - (priority_string, transform_class, pending, None)) + (priority_string, transform_class, pending, {})) self.sorted = 0 def get_priority_string(self, priority): @@ -183,8 +182,8 @@ class Transformer(TransformSpec): self.transforms.sort() self.transforms.reverse() self.sorted = 1 - priority, transform_class, pending, data = self.transforms.pop() - transform = transform_class(self.document, - startnode=pending, data=data) + priority, transform_class, pending, kwargs = self.transforms.pop() + transform = transform_class(self.document, startnode=pending, + **kwargs) transform.apply() - self.applied.append((priority, transform_class, pending)) + self.applied.append((transform, priority, transform_class, pending)) diff --git a/test/test_transforms.py b/test/test_transforms.py new file mode 100755 index 000000000..3356cb05f --- /dev/null +++ b/test/test_transforms.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for transforms/__init__.py. +""" + +from docutils import transforms, utils + +import unittest + +class TestTransform(transforms.Transform): + + default_priority = 100 + + applied = 0 + def apply(self): + self.applied += 1 + +class KwargsTestCase(unittest.TestCase): + + def test_kwargs(self): + transformer = transforms.Transformer(utils.new_document('test data')) + transformer.add_transform(TestTransform, foo=42) + transformer.apply_transforms() + self.assertEqual(len(transformer.applied), 1) + self.assertEqual(len(transformer.applied[0]), 4) + transform = transformer.applied[0][0] + self.assertEqual(transform.__class__, TestTransform) + self.assertEqual(transform.data, {'foo': 42}) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.1 From d6649c9ccd1a002ab28b59c11d12bbaf96a5d2a9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 11:10:08 +0000 Subject: added link targets; note to self: need to document publish_(from_)doctree git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3597 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/api/publisher.txt | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index 79bac6202..98d84235f 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -97,39 +97,39 @@ the "whole" part. Parts Provided By All Writers ----------------------------- -whole +_`whole` ``parts['whole']`` contains the entire formatted document. Parts Provided By the HTML Writer --------------------------------- -body +_`body` ``parts['body']`` is equivalent to ``parts['fragment']``. -docinfo +_`docinfo` ``parts['docinfo']`` contains the document bibliographic data. -footer +_`footer` ``parts['footer']`` contains the document footer content, meant to appear at the bottom of a web page, or repeated at the bottom of every printed page. -fragment +_`fragment` ``parts['fragment']`` contains the document body (*not* the HTML ````). In other words, it contains the entire document, less the document title, subtitle, docinfo, header, and footer. -header +_`header` ``parts['header']`` contains the document header content, meant to appear at the top of a web page, or repeated at the top of every printed page. -html_body +_`html_body` ``parts['html_body']`` contains the HTML ```` content, less the ```` and ```` tags themselves. -html_head +_`html_head` ``parts['html_head']`` contains the HTML ```` content, less the stylesheet link and the ```` and ```` tags themselves. Since ``publish_parts`` returns Unicode strings and @@ -140,7 +140,7 @@ html_head The interpolation should be done by client code. -html_prolog +_`html_prolog` ``parts['html_prolog]`` contains the XML declaration and the doctype declaration. The XML declaration's "encoding" attribute's value is left unresolved, as "%s":: @@ -149,27 +149,27 @@ html_prolog The interpolation should be done by client code. -html_subtitle +_`html_subtitle` ``parts['html_subtitle']`` contains the document subtitle, including the enclosing ``

    `` & ``

    `` tags. -html_title +_`html_title` ``parts['html_title']`` contains the document title, including the enclosing ``

    `` & ``

    `` tags. -meta +_`meta` ``parts['meta']`` contains all ```` tags. -stylesheet +_`stylesheet` ``parts['stylesheet']`` contains the document stylesheet link. -subtitle +_`subtitle` ``parts['subtitle']`` contains the document subtitle text and any inline markup. It does not include the enclosing ``

    `` & ``

    `` tags. -title +_`title` ``parts['title']`` contains the document title text and any inline markup. It does not include the enclosing ``

    `` & ``

    `` tags. -- cgit v1.2.1 From cbcb754503fce8880ecf7354c82089bde9e4ed22 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 11:19:35 +0000 Subject: changed html_fragment example to the more common html_body git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3598 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/examples.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docutils/examples.py b/docutils/examples.py index 3b099b482..96f6a0522 100644 --- a/docutils/examples.py +++ b/docutils/examples.py @@ -50,14 +50,13 @@ def html_parts(input_string, source_path=None, destination_path=None, writer_name='html', settings_overrides=overrides) return parts -def html_fragment(input_string, source_path=None, destination_path=None, - input_encoding='unicode', output_encoding='unicode', - doctitle=1, initial_header_level=1): +def html_body(input_string, source_path=None, destination_path=None, + input_encoding='unicode', output_encoding='unicode', + doctitle=1, initial_header_level=1): """ Given an input string, returns an HTML fragment as a string. - The return value is the contents of the tag, less the title, - subtitle, and docinfo. + The return value is the contents of the element. Parameters (see `html_parts()` for the remainder): @@ -69,7 +68,7 @@ def html_fragment(input_string, source_path=None, destination_path=None, destination_path=destination_path, input_encoding=input_encoding, doctitle=doctitle, initial_header_level=initial_header_level) - fragment = parts['fragment'] + fragment = parts['html_body'] if output_encoding != 'unicode': fragment = fragment.encode(output_encoding) return fragment -- cgit v1.2.1 From 9d1a45f051d1fea540749eab04bd0b549bdd0fc4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 11:25:47 +0000 Subject: added more links; added note about body != html_body git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3599 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/api/publisher.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/api/publisher.txt b/docs/api/publisher.txt index 98d84235f..73cfc0ef2 100644 --- a/docs/api/publisher.txt +++ b/docs/api/publisher.txt @@ -19,19 +19,19 @@ then call its ``publish`` method. ``docutils.core.Publisher.publish`` handles everything else. There are five convenience functions in the ``docutils.core`` module: -* ``publish_cmdline``: for command-line front-end tools, like +:_`publish_cmdline`: for command-line front-end tools, like ``rst2html.py``. There are several examples in the ``tools/`` directory. A detailed analysis of one such tool is in `Inside A Docutils Command-Line Front-End Tool`_ -* ``publish_file``: for programmatic use with file-like I/O. In +:_`publish_file`: for programmatic use with file-like I/O. In addition to writing the encoded output to a file, also returns the encoded output as a string. -* ``publish_string``: for programmatic use with string I/O. Returns +:_`publish_string`: for programmatic use with string I/O. Returns the encoded output as a string. -* ``publish_parts``: for programmatic use with string input; returns a +:_`publish_parts`: for programmatic use with string input; returns a dictionary of document parts. Dictionary keys are the names of parts, and values are Unicode strings; encoding is up to the client. Useful when only portions of the processed document are desired. @@ -39,7 +39,7 @@ handles everything else. There are five convenience functions in the There are usage examples in the `docutils/examples.py`_ module. -* ``publish_programmatically``: for custom programmatic use. This +:_`publish_programmatically`: for custom programmatic use. This function implements common code and is used by ``publish_file``, ``publish_string``, and ``publish_parts``. It returns a 2-tuple: the encoded string output and the Publisher object. @@ -105,7 +105,8 @@ Parts Provided By the HTML Writer --------------------------------- _`body` - ``parts['body']`` is equivalent to ``parts['fragment']``. + ``parts['body']`` is equivalent to parts['fragment_']. It is + *not* equivalent to parts['html_body_']. _`docinfo` ``parts['docinfo']`` contains the document bibliographic data. -- cgit v1.2.1 From 19db6451379135005a4c480a509bc6f013ee97f3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 11:26:08 +0000 Subject: added FAQ entry about retrieving the HTML body git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3600 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/FAQ.txt b/FAQ.txt index ce1d35190..7bbb1cc68 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -886,6 +886,21 @@ of the output. It must also match the document encoding. For UTF-8:: http://docutils.sourceforge.net/docs/ref/rst/directives.html#sectnum +How can I retrieve the body of the HTML document? +------------------------------------------------- + +(This is usually needed when using Docutils in conjunction with a +templating system.) + +You can use the `docutils.core.publish_parts()`_ function, which +returns a dictionary containing an 'html_body_' entry. + +.. _docutils.core.publish_parts(): + docs/api/publisher.html#publisher-convenience-functions +.. _html_body: + docs/api/publisher.html#html-body + + Python Source Reader ==================== -- cgit v1.2.1 From 73fcd7ce8916b5ae0c2307204c693d4f07ef2f23 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 11:40:32 +0000 Subject: improved links; don't claim it's HTML 4.01 compatible -- it's not really compatible e.g. because of ; and people who care of "what kind of HTML" usually know of the partial compatibility of XHTML and HTML git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3601 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 7bbb1cc68..674604c89 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -173,7 +173,7 @@ The abbreviations "reSTX" and "rSTX"/"rstx" should **not** be used; they overemphasize reStructuredText's precedessor, Zope's StructuredText. -__ http://www.xml.com/pub/a/2002/02/06/rest.html +__ http://en.wikipedia.org/wiki/Representational_State_Transfer What's the standard filename extension for a reStructuredText file? @@ -706,14 +706,12 @@ web templating). Alternate implementations are welcome. What kind of HTML does it produce? ---------------------------------- -It produces XHTML compatible with the `HTML 4.01`_ and `XHTML 1.0`_ -specifications (within reason; there are some incompatibilities -between the specs). A cascading style sheet ("default.css" by -default) is required for proper viewing with a modern graphical -browser. Correct rendering of the HTML produced depends on the CSS -support of the browser. +It produces XHTML compatible with the `XHTML 1.0`_ specification. A +cascading style sheet (provided as "tools/stylesheets/default.css") is +required for proper viewing with a modern graphical browser. Correct +rendering of the HTML produced depends on the CSS support of the +browser. -.. _HTML 4.01: http://www.w3.org/TR/html4/ .. _XHTML 1.0: http://www.w3.org/TR/xhtml1/ @@ -896,7 +894,7 @@ You can use the `docutils.core.publish_parts()`_ function, which returns a dictionary containing an 'html_body_' entry. .. _docutils.core.publish_parts(): - docs/api/publisher.html#publisher-convenience-functions + docs/api/publisher.html#publish-parts .. _html_body: docs/api/publisher.html#html-body -- cgit v1.2.1 From 44460ad0092895cb934afef3caac756500397a18 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 12:28:56 +0000 Subject: renamed test_publish_doctree.py to more generic test_publisher.py; polished git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3602 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publish_doctree.py | 49 ----------------------------------------- test/test_publisher.py | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 49 deletions(-) delete mode 100755 test/test_publish_doctree.py create mode 100755 test/test_publisher.py diff --git a/test/test_publish_doctree.py b/test/test_publish_doctree.py deleted file mode 100755 index 32f40d9ca..000000000 --- a/test/test_publish_doctree.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -# Author: Martin Blais -# Contact: blais@furius.ca -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Perform tests with publishing to a tree, and running a writer on that tree later. -""" - -import unittest -from types import DictType, StringType -import docutils.core -import docutils.nodes - - -test_document = """\ -Test Document -============= - -This is a test document. -""" - - -class PublishDoctreeTestCase(unittest.TestCase): - - def test_publish_doctree(self): - """Test `publish_doctree` and `publish_from_doctree`.""" - # Produce the document tree. - doctree = docutils.core.publish_doctree( - source=test_document, - reader_name='standalone', - parser_name='restructuredtext', - settings_overrides={'_disable_config': 1}) - - self.assert_(isinstance(doctree, docutils.nodes.document)) - - # Write out the document. - output, parts = docutils.core.publish_from_doctree( - doctree, writer_name='pseudoxml') - - self.assert_(isinstance(output, StringType)) - assert isinstance(parts, DictType) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_publisher.py b/test/test_publisher.py new file mode 100755 index 000000000..d62c320f6 --- /dev/null +++ b/test/test_publisher.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test the `Publisher` facade and the ``publish_*`` convenience functions. +""" + +import unittest +from types import DictType, StringType +from docutils import core, nodes + + +test_document = """\ +Test Document +============= + +This is a test document. +""" + + +class PublishDoctreeTestCase(unittest.TestCase): + + def test_publish_doctree(self): + """Test `publish_doctree` and `publish_from_doctree`.""" + # Produce the document tree. + doctree = core.publish_doctree( + source=test_document, + reader_name='standalone', + parser_name='restructuredtext', + settings_overrides={'_disable_config': 1}) + + self.assert_(isinstance(doctree, nodes.document)) + # Assert transforms have been applied (in this case the + # DocTitle transform). + self.assert_(isinstance(doctree[0], nodes.title)) + self.assert_(isinstance(doctree[1], nodes.paragraph)) + + # Write out the document. + output, parts = core.publish_from_doctree( + doctree, writer_name='pseudoxml') + + self.assert_(isinstance(output, StringType)) + assert isinstance(parts, DictType) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.1 From 133e6176272678623431d07c7187147ec8172150 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 12:47:29 +0000 Subject: added note about slowdown git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3603 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/coverage.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/coverage.sh b/test/coverage.sh index e2005448d..3edea0e2a 100755 --- a/test/coverage.sh +++ b/test/coverage.sh @@ -15,7 +15,10 @@ fi if test "$1"; then proj="$1" fi -echo Performing code coverage test for project \""$proj"\"... +echo "Performing code coverage test for project \"$proj\"..." +echo +echo "Please be patient; coverage tracking slows test execution down by more" +echo "than factor 10." echo cd test rm -rf cover -- cgit v1.2.1 From 40f643d01a54d73857a7a6fadd64794d654fcde4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 14:21:27 +0000 Subject: pass kwargs as single parameter to add_transform; to not pass on the kwargs to Transform.__init__ but to Transform.apply git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3604 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/__init__.py | 20 ++++++++------------ test/test_transforms.py | 8 +++++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index ef827fd50..45a32fb8c 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -43,7 +43,7 @@ class Transform: default_priority = None """Numerical priority of this transform, 0 through 999 (override).""" - def __init__(self, document, startnode=None, **kwargs): + def __init__(self, document, startnode=None): """ Initial setup for in-place document transforms. """ @@ -60,11 +60,7 @@ class Transform: document.settings.language_code) """Language module local to this document.""" - self.data = kwargs - """Data specific to this transform instance. You can use this - to parameterize the transform instance.""" - - def apply(self): + def apply(self, **kwargs): """Override to apply the transform to the document tree.""" raise NotImplementedError('subclass must override this method') @@ -109,11 +105,12 @@ class Transformer(TransformSpec): """Internal serial number to keep track of the add order of transforms.""" - def add_transform(self, transform_class, priority=None, **kwargs): + def add_transform(self, transform_class, priority=None, kwargs={}): """ Store a single transform. Use `priority` to override the default. - `kwargs` are passed on to the constructor of the transform. This can - be used to pass application-specific data to the transform instance. + `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 @@ -183,7 +180,6 @@ class Transformer(TransformSpec): self.transforms.reverse() self.sorted = 1 priority, transform_class, pending, kwargs = self.transforms.pop() - transform = transform_class(self.document, startnode=pending, - **kwargs) - transform.apply() + transform = transform_class(self.document, startnode=pending) + transform.apply(**kwargs) self.applied.append((transform, priority, transform_class, pending)) diff --git a/test/test_transforms.py b/test/test_transforms.py index 3356cb05f..450c4e498 100755 --- a/test/test_transforms.py +++ b/test/test_transforms.py @@ -19,20 +19,22 @@ class TestTransform(transforms.Transform): default_priority = 100 applied = 0 - def apply(self): + + def apply(self, **kwargs): self.applied += 1 + self.kwargs = kwargs class KwargsTestCase(unittest.TestCase): def test_kwargs(self): transformer = transforms.Transformer(utils.new_document('test data')) - transformer.add_transform(TestTransform, foo=42) + transformer.add_transform(TestTransform, kwargs={'foo': 42}) transformer.apply_transforms() self.assertEqual(len(transformer.applied), 1) self.assertEqual(len(transformer.applied[0]), 4) transform = transformer.applied[0][0] self.assertEqual(transform.__class__, TestTransform) - self.assertEqual(transform.data, {'foo': 42}) + self.assertEqual(transform.kwargs, {'foo': 42}) if __name__ == '__main__': -- cgit v1.2.1 From 1dbe0e3b6756d6401fd7f4e10b7b5a1f873215e2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 14:45:14 +0000 Subject: beautified --dump-transforms output git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3605 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 2 +- docutils/transforms/__init__.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 5ffe6c911..82d7fb918 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -225,7 +225,7 @@ class Publisher: if self.settings.dump_transforms: print >>sys.stderr, '\n::: Transforms applied:' print >>sys.stderr, pprint.pformat( - self.document.transformer.applied) + [a[1:] for a in self.document.transformer.applied]) if self.settings.dump_pseudo_xml: print >>sys.stderr, '\n::: Pseudo-XML:' print >>sys.stderr, self.document.pformat().encode( diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 45a32fb8c..4d9bebbde 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -182,4 +182,5 @@ class Transformer(TransformSpec): priority, transform_class, pending, kwargs = self.transforms.pop() transform = transform_class(self.document, startnode=pending) transform.apply(**kwargs) - self.applied.append((transform, priority, transform_class, pending)) + self.applied.append((transform, priority, + transform_class.__name__, pending)) -- cgit v1.2.1 From 8e3d3b9a20ccb700b2269885de7daa65d45c797f Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 20:29:10 +0000 Subject: added assert to get a helpful error message when passing things like "writer='html'" to publish_* git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3606 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 6 ++++++ test/test_transforms.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/docutils/core.py b/docutils/core.py index 82d7fb918..a3f1c9ac1 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -18,6 +18,7 @@ __docformat__ = 'reStructuredText' import sys import pprint +from types import StringType from docutils import __version__, __version_details__, SettingsSpec from docutils import frontend, io, utils, readers, writers from docutils.frontend import OptionParser @@ -52,6 +53,11 @@ class Publisher: self.writer = writer """A `docutils.writers.Writer` instance.""" + for component in 'reader', 'parser', 'writer': + assert not isinstance(getattr(self, component), StringType), \ + ('passed string as "%s" parameter; use "%s_name" instead' + % (getattr(self, component), component, component)) + self.source = source """The source of input data, a `docutils.io.Input` instance.""" diff --git a/test/test_transforms.py b/test/test_transforms.py index 450c4e498..12780ee29 100755 --- a/test/test_transforms.py +++ b/test/test_transforms.py @@ -14,6 +14,7 @@ from docutils import transforms, utils import unittest + class TestTransform(transforms.Transform): default_priority = 100 @@ -24,6 +25,7 @@ class TestTransform(transforms.Transform): self.applied += 1 self.kwargs = kwargs + class KwargsTestCase(unittest.TestCase): def test_kwargs(self): -- cgit v1.2.1 From cb6b50bc802610f43831642cb08d3c845b6515bf Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 27 Jun 2005 20:49:51 +0000 Subject: added Document Conventions section git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3607 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 2bede5ffd..ed4d69789 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -104,6 +104,44 @@ Conventions`_ PEPs, with the following clarifications and extensions: .. _Docutils Internationalization: ../howto/i18n.html#python-code +Documentation Conventions +========================= + +* Docutils documentation is written using reStructuredText, of course. + +* Use 7-bit ASCII if at all possible. + +* Use the following section title adornment styles:: + + ================ + Document Title + ================ + + ------------------------------ + Document Subtitle (optional) + ------------------------------ + + Section + ======= + + Subsection + ---------- + + If you need subsubsections and further, these characters are + recommended for title underlines:: + + ` . + +* Use two blank lines before each section/subsection/etc. title. One + blank line is sufficient between immediately adjacent titles. + +* Add a bibliographic field list immediately after the document + title/subtitle. See the beginning of this document for an example. + +* Add an Emacs local variables block in a comment at the end of the + document. See the end of this document for an example. + + Copyrights and Licensing ======================== -- cgit v1.2.1 From 97f17ab24ee18309def82364e244897ade13fc2d Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 27 Jun 2005 21:00:22 +0000 Subject: Pythonicized kwargs; further beautified --dump-transforms git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3608 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 7 ++++++- docutils/transforms/__init__.py | 7 +++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index a3f1c9ac1..d0e518c1d 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -230,8 +230,13 @@ class Publisher: print >>sys.stderr, pprint.pformat(self.document.__dict__) if self.settings.dump_transforms: print >>sys.stderr, '\n::: Transforms applied:' + print >>sys.stderr, (' (priority, transform class, ' + 'pending node details, keyword args)') print >>sys.stderr, pprint.pformat( - [a[1:] for a in self.document.transformer.applied]) + [(priority, '%s.%s' % (xclass.__module__, xclass.__name__), + pending and pending.details, kwargs) + for priority, xclass, pending, kwargs + in self.document.transformer.applied]) if self.settings.dump_pseudo_xml: print >>sys.stderr, '\n::: Pseudo-XML:' print >>sys.stderr, self.document.pformat().encode( diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 4d9bebbde..971d12a72 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -105,7 +105,7 @@ class Transformer(TransformSpec): """Internal serial number to keep track of the add order of transforms.""" - def add_transform(self, transform_class, priority=None, kwargs={}): + 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 @@ -159,7 +159,7 @@ class Transformer(TransformSpec): self.add_transforms(component.default_transforms) self.components[component.component_type] = component self.sorted = 0 - # Setup all of the reference resolvers for this transformer. Each + # 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 = [] @@ -182,5 +182,4 @@ class Transformer(TransformSpec): priority, transform_class, pending, kwargs = self.transforms.pop() transform = transform_class(self.document, startnode=pending) transform.apply(**kwargs) - self.applied.append((transform, priority, - transform_class.__name__, pending)) + self.applied.append((priority, transform_class, pending, kwargs)) -- cgit v1.2.1 From 327bdfb407e87fb085488a17fb9e8d0a17a4c8e8 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 27 Jun 2005 21:01:17 +0000 Subject: Pythonicized kwargs --dump-transforms git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3609 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/test_transforms.py b/test/test_transforms.py index 12780ee29..6ea982d2e 100755 --- a/test/test_transforms.py +++ b/test/test_transforms.py @@ -11,7 +11,6 @@ Test module for transforms/__init__.py. """ from docutils import transforms, utils - import unittest @@ -30,13 +29,13 @@ class KwargsTestCase(unittest.TestCase): def test_kwargs(self): transformer = transforms.Transformer(utils.new_document('test data')) - transformer.add_transform(TestTransform, kwargs={'foo': 42}) + transformer.add_transform(TestTransform, foo=42) transformer.apply_transforms() self.assertEqual(len(transformer.applied), 1) self.assertEqual(len(transformer.applied[0]), 4) - transform = transformer.applied[0][0] - self.assertEqual(transform.__class__, TestTransform) - self.assertEqual(transform.kwargs, {'foo': 42}) + transform_record = transformer.applied[0] + self.assertEqual(transform_record[1], TestTransform) + self.assertEqual(transform_record[3], {'foo': 42}) if __name__ == '__main__': -- cgit v1.2.1 From 7d0ef2330d86d0f0e06e5287296de625d44b0836 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 27 Jun 2005 21:02:29 +0000 Subject: moved & renamed to remove overlap between file & directory/package git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3610 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms.py | 42 ----------------------------------- test/test_transforms/test___init__.py | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 42 deletions(-) delete mode 100755 test/test_transforms.py create mode 100755 test/test_transforms/test___init__.py diff --git a/test/test_transforms.py b/test/test_transforms.py deleted file mode 100755 index 6ea982d2e..000000000 --- a/test/test_transforms.py +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env python - -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Test module for transforms/__init__.py. -""" - -from docutils import transforms, utils -import unittest - - -class TestTransform(transforms.Transform): - - default_priority = 100 - - applied = 0 - - def apply(self, **kwargs): - self.applied += 1 - self.kwargs = kwargs - - -class KwargsTestCase(unittest.TestCase): - - def test_kwargs(self): - transformer = transforms.Transformer(utils.new_document('test data')) - transformer.add_transform(TestTransform, foo=42) - transformer.apply_transforms() - self.assertEqual(len(transformer.applied), 1) - self.assertEqual(len(transformer.applied[0]), 4) - transform_record = transformer.applied[0] - self.assertEqual(transform_record[1], TestTransform) - self.assertEqual(transform_record[3], {'foo': 42}) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_transforms/test___init__.py b/test/test_transforms/test___init__.py new file mode 100755 index 000000000..6ea982d2e --- /dev/null +++ b/test/test_transforms/test___init__.py @@ -0,0 +1,42 @@ +#! /usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for transforms/__init__.py. +""" + +from docutils import transforms, utils +import unittest + + +class TestTransform(transforms.Transform): + + default_priority = 100 + + applied = 0 + + def apply(self, **kwargs): + self.applied += 1 + self.kwargs = kwargs + + +class KwargsTestCase(unittest.TestCase): + + def test_kwargs(self): + transformer = transforms.Transformer(utils.new_document('test data')) + transformer.add_transform(TestTransform, foo=42) + transformer.apply_transforms() + self.assertEqual(len(transformer.applied), 1) + self.assertEqual(len(transformer.applied[0]), 4) + transform_record = transformer.applied[0] + self.assertEqual(transform_record[1], TestTransform) + self.assertEqual(transform_record[3], {'foo': 42}) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.1 From 86ddd0517bc30549b974d681c9f090bfbec34665 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 21:30:54 +0000 Subject: clarified docstrings; simplified code git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3611 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- docutils/transforms/references.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 25b220cd0..dc2dbcb32 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -751,10 +751,10 @@ class document(Root, Structural, Element): """System message generator.""" self.external_targets = [] - """List of external target nodes.""" + """List of external named target nodes.""" self.internal_targets = [] - """List of internal target nodes.""" + """List of internal block-level target nodes.""" self.indirect_targets = [] """List of indirect target nodes.""" diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 9a7479c5f..52f1d65be 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -43,10 +43,10 @@ class PropagateTargets(Transform): def apply(self): for target in self.document.internal_targets: - if not (len(target) == 0 and - not (target.attributes.has_key('refid') or - target.attributes.has_key('refuri') or - target.attributes.has_key('refname'))): + assert len(target) == 0, ('only block-level targets expected in ' + 'document.internal_targets') + if (target.hasattr('refid') or target.hasattr('refuri') or + target.hasattr('refname')): continue next_node = target.next_node(ascend=1) # Do not move names and ids into Invisibles (we'd lose the -- cgit v1.2.1 From b8fad6a8d7f091ac515f9de12fbe62abe2f5751d Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 21:53:45 +0000 Subject: temporarily removed warning when no stylesheet is given git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3612 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f20ff2105..ac095859a 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -218,11 +218,14 @@ class HTMLTranslator(nodes.NodeVisitor): stylesheet = utils.get_stylesheet_reference(settings) self.stylesheet = [] if stylesheet is None: - self.document.reporter.warning( - 'No stylesheet path or URI given.\nUse the --stylesheet ' - 'or --stylesheet-path option to specify the location of\n' - 'default.css (in the tools/stylesheets/ directory ' - 'of the Docutils distribution).\n') + # Creating a warning is a bad idea as long as it breaks + # existing scripts which use Docutils programmatically. + #self.document.reporter.warning( + # 'No stylesheet path or URI given.\nUse the --stylesheet ' + # 'or --stylesheet-path option to specify the location of\n' + # 'default.css (in the tools/stylesheets/ directory ' + # 'of the Docutils distribution).\n') + pass elif settings.embed_stylesheet and stylesheet: stylesheet = utils.get_stylesheet_reference(settings, os.path.join(os.getcwd(), 'dummy')) -- cgit v1.2.1 From 93fbf6330205a3d66a55d4ed57b5f183528ac111 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 22:05:07 +0000 Subject: added assert to make sure the kwargs get passed to apply() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3613 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms/test___init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_transforms/test___init__.py b/test/test_transforms/test___init__.py index 6ea982d2e..a126d8854 100755 --- a/test/test_transforms/test___init__.py +++ b/test/test_transforms/test___init__.py @@ -22,7 +22,7 @@ class TestTransform(transforms.Transform): def apply(self, **kwargs): self.applied += 1 - self.kwargs = kwargs + assert kwargs == {'foo': 42} class KwargsTestCase(unittest.TestCase): -- cgit v1.2.1 From a8601c75767ed7185b1ca7ccec1b16e4e71c8c53 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 22:25:11 +0000 Subject: do not double apply default transforms in publish_from_doctree; this does not look very clean... and there are still no tests which cover that behavior git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3614 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docutils/core.py b/docutils/core.py index d0e518c1d..9602f4a7b 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -482,6 +482,8 @@ def publish_from_doctree(doctree, destination_path=None, """ # Create fresh Transformer object, to be populated from Writer component. doctree.transformer = Transformer(doctree) + # Don't double apply default transforms. + doctree.transformer.default_transforms = () # Create reader with existing doctree. from docutils.readers import dummy reader = dummy.Reader(doctree) -- cgit v1.2.1 From 643021dced731e9c3d207d5c595c1f6bb94d9b6a Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 27 Jun 2005 22:52:04 +0000 Subject: added link to FAQ entry about reST-blogs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3615 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 22c8a9706..d663e416b 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -20,8 +20,12 @@ Related Projects These are projects users of Docutils and reStructuredText may find useful, listed in no particular order. Many of them projects are hosted in the `Docutils Sandbox`_. All projects are usable by end -users in some way, however do not expect all of them to run out of the -box. +users in some way, however please do not expect all of them to run +straight out of the box. + +* For Wikis, please see the `FAQ entry about Wikis`_. + +* For Blogs (Weblogs), please see the `FAQ entry about Blogs`_. * rst2chm_, written by Oliver Rutherfurd, generates Microsoft HTML Help files from reStructuredText files. @@ -53,8 +57,6 @@ box. * Patrick O'Brien has taken over the `OpenOffice.org Writer`_. -* For Wikis, please see the `FAQ entry about Wikis`_. - * Bill Bumgarner has written a `simple HTML writer`_ that doesn't rely on CSS (stylesheets). @@ -63,8 +65,10 @@ box. both LaTeX and HTML output on top of it. * Beni Cherniavsky maintains a Makefile_ for driving Docutils, hoping - to handle everything one might do with docutils. + to handle everything one might do with Docutils. +.. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax +.. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax .. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ .. _rest2web: http://www.voidspace.org.uk/python/rest2web/ .. _Docutils Sandbox: http://docutils.sf.net/sandbox/README.html @@ -79,7 +83,6 @@ box. .. _HT2HTML integration: http://docutils.sf.net/sandbox/oliverr/ht/ .. _DocFactory: http://docutils.sf.net/sandbox/gschwant/docfactory/doc/ .. _OpenOffice.org Writer: http://docutils.sf.net/sandbox/pobrien/OpenOffice/ -.. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ .. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ .. _Makefile: http://docutils.sf.net/sandbox/cben/make/ -- cgit v1.2.1 From 3266e3acfa404e8967106e13c0b48168f3ab2fe4 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 28 Jun 2005 13:11:20 +0000 Subject: added JED mode link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3616 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 1 + tools/editors/README.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/THANKS.txt b/THANKS.txt index fa182b017..66f32d952 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -88,6 +88,7 @@ donations, tasty treats, and related projects: * Mark McEahern * Vincent McIntyre * John F Meinel Jr +* Günter Milde * Skip Montanaro * Paul Moore * Nigel W. Moriarty diff --git a/tools/editors/README.txt b/tools/editors/README.txt index f3786ef2e..517c0558a 100644 --- a/tools/editors/README.txt +++ b/tools/editors/README.txt @@ -14,6 +14,10 @@ External links: * `reStructuredText syntax highlighting mode for vim `__ +* `rst mode `__ for the `JED`_ + programmers editor + Additions are welcome. .. _reStructuredText: http://docutils.sf.net/rst.html +.. _JED: http://www.jedsoft.org/jed/ -- cgit v1.2.1 From fb247a2c98d8fffdca2a6ede5235f1b9e28a27ae Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 28 Jun 2005 13:49:10 +0000 Subject: Added ``_stylesheet_required`` internal setting, docutils.transforms.html.StylesheetCheck transform, docs, tests, and support. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3617 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 ++++++++ docs/ref/transforms.txt | 3 +++ docs/user/config.txt | 5 +++++ docutils/frontend.py | 3 ++- docutils/transforms/html.py | 30 ++++++++++++++++++++++++++++++ docutils/writers/html4css1.py | 27 +++++++++++---------------- test/DocutilsTestSupport.py | 1 + test/functional/tests/_default.py | 1 + test/test_dependencies.py | 1 + test/test_writers/test_html4css1_misc.py | 3 ++- 10 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 docutils/transforms/html.py diff --git a/HISTORY.txt b/HISTORY.txt index e5030a2b0..453736e92 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -22,6 +22,10 @@ Changes Since 0.3.9 - Added ``__version_details__`` attribute to describe code source (repository/snapshot/release). +* docutils/frontend.py: + + - Added ``_stylesheet_required`` internal setting. + * docutils/parsers/rst/__init__.py: - Added validator to tab_width setting, with test. Closes SF bug @@ -44,6 +48,9 @@ Changes Since 0.3.9 standard data files for the "include" directive. Initial contents: character entity substitution definition sets. +* docutils/transforms/html.py: Added to project; transforms specific + to the html4css1 Writer. + * docutils/writers/html4css1.py: - Added support for image width and height units. @@ -53,6 +60,7 @@ Changes Since 0.3.9 ``--stylesheet-path`` is specified. - Made ``--embed-stylesheet`` the default rather than ``--link-stylesheet``. + - Added writer-specific transform to check the stylesheet setting. * docutils/writers/docutils_xml.py: diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 079bedaaa..7bdcee1de 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -40,6 +40,8 @@ peps.Headers pep (r) 360 peps.Contents pep (r) 380 +html.StylesheetCheck html4css1 (w) 420 + references.AnonymousHyperlinks standalone (r), pep (r) 440 references.IndirectHyperlinks standalone (r), pep (r) 460 @@ -83,6 +85,7 @@ misc.CallBack n/a 990 Key: * (r): Reader +* (w): Writer * (d): Directive * (t): Transform * (/p): Via a "pending" node diff --git a/docs/user/config.txt b/docs/user/config.txt index d7b08bf48..3b7e8c2d0 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -911,6 +911,11 @@ _`_source` Default: stdin (None). No command-line options. +_`_stylesheet_required` + Used to disable stylesheet checking in writers that use + stylesheets. For programmatic use only. + + Default: required (1). No command-line options. .. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html diff --git a/docutils/frontend.py b/docutils/frontend.py index 8f357ae4b..62037b5f7 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -461,7 +461,8 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): settings_defaults = {'_disable_config': None, '_source': None, - '_destination': None} + '_destination': None, + '_stylesheet_required': 1,} """Defaults for settings that don't have command-line option equivalents.""" relative_path_settings = ('warning_stream',) diff --git a/docutils/transforms/html.py b/docutils/transforms/html.py new file mode 100644 index 000000000..202fab37d --- /dev/null +++ b/docutils/transforms/html.py @@ -0,0 +1,30 @@ +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Transforms specific to the HTML writer. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes, utils +from docutils.transforms import Transform, TransformError + + +class StylesheetCheck(Transform): + + """Check for a proper stylesheet setting.""" + + default_priority = 420 + + def apply(self): + if ( self.document.settings._stylesheet_required + and not utils.get_stylesheet_reference(self.document.settings)): + self.document.reporter.warning( + 'No stylesheet path or URI given. Use the --stylesheet ' + 'or --stylesheet-path option to specify the location of ' + 'default.css (in the tools/stylesheets/ directory of the ' + 'Docutils distribution).') diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ac095859a..749982a14 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -28,6 +28,7 @@ except ImportError: Image = None import docutils from docutils import frontend, nodes, utils, writers, languages +from docutils.transforms import html class Writer(writers.Writer): @@ -116,6 +117,8 @@ class Writer(writers.Writer): config_section = 'html4css1 writer' config_section_dependencies = ('writers',) + default_transforms = (html.StylesheetCheck,) + def __init__(self): writers.Writer.__init__(self) self.translator_class = HTMLTranslator @@ -217,22 +220,14 @@ class HTMLTranslator(nodes.NodeVisitor): self.head = self.meta[:] stylesheet = utils.get_stylesheet_reference(settings) self.stylesheet = [] - if stylesheet is None: - # Creating a warning is a bad idea as long as it breaks - # existing scripts which use Docutils programmatically. - #self.document.reporter.warning( - # 'No stylesheet path or URI given.\nUse the --stylesheet ' - # 'or --stylesheet-path option to specify the location of\n' - # 'default.css (in the tools/stylesheets/ directory ' - # 'of the Docutils distribution).\n') - pass - elif settings.embed_stylesheet and stylesheet: - stylesheet = utils.get_stylesheet_reference(settings, - os.path.join(os.getcwd(), 'dummy')) - settings.record_dependencies.add(stylesheet) - stylesheet_text = open(stylesheet).read() - self.stylesheet = [self.embedded_stylesheet % stylesheet_text] - elif stylesheet: + if stylesheet: + if settings.embed_stylesheet: + stylesheet = utils.get_stylesheet_reference( + settings, os.path.join(os.getcwd(), 'dummy')) + settings.record_dependencies.add(stylesheet) + stylesheet_text = open(stylesheet).read() + self.stylesheet = [self.embedded_stylesheet % stylesheet_text] + else: self.stylesheet = [self.stylesheet_link % self.encode(stylesheet)] self.body_prefix = ['\n\n'] diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 32c263982..72d5cdbc2 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -632,6 +632,7 @@ class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): """ settings_default_overrides = {'_disable_config': 1, + '_stylesheet_required': 0, 'strict_visitor': 1} writer_name = '' # set in subclasses or constructor diff --git a/test/functional/tests/_default.py b/test/functional/tests/_default.py index 2835c5b2e..4c72c04c8 100644 --- a/test/functional/tests/_default.py +++ b/test/functional/tests/_default.py @@ -5,3 +5,4 @@ settings_overrides['halt_level'] = 5 settings_overrides['warning_stream'] = '' settings_overrides['input_encoding'] = 'utf-8' settings_overrides['embed_stylesheet'] = 0 +settings_overrides['_stylesheet_required'] = 0 diff --git a/test/test_dependencies.py b/test/test_dependencies.py index c9f00518d..e1ccc24ef 100755 --- a/test/test_dependencies.py +++ b/test/test_dependencies.py @@ -30,6 +30,7 @@ class RecordDependenciesTests(unittest.TestCase): settings.setdefault('settings_overrides', {}) settings['settings_overrides'] = settings['settings_overrides'].copy() settings['settings_overrides']['_disable_config'] = 1 + settings['settings_overrides']['_stylesheet_required'] = 0 if not settings['settings_overrides'].has_key('record_dependencies'): settings['settings_overrides']['record_dependencies'] = \ docutils.utils.DependencyList(recordfile) diff --git a/test/test_writers/test_html4css1_misc.py b/test/test_writers/test_html4css1_misc.py index df07a7bd5..940f99482 100755 --- a/test/test_writers/test_html4css1_misc.py +++ b/test/test_writers/test_html4css1_misc.py @@ -23,7 +23,8 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): settings_overrides={ 'output_encoding': 'latin1', 'stylesheet': '', - '_disable_config': 1} + '_disable_config': 1, + '_stylesheet_required': 0,} result = core.publish_string( 'äöü€', writer_name='html4css1', settings_overrides=settings_overrides) -- cgit v1.2.1 From 319f1f199e45bc596b8f2654344ffe7fdf037459 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Jun 2005 20:28:17 +0000 Subject: added to-do list entries about directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3618 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 2727aeb43..d2741faf8 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1078,6 +1078,12 @@ Directives below are often referred to as "module.directive", the directive function. The "module." is not part of the directive name when used in a document. +* Make the directive interface object-oriented + (http://article.gmane.org/gmane.text.docutils.user/1871). + +* Unify table implementations and unify options of table directives + (http://article.gmane.org/gmane.text.docutils.user/1857). + * Allow directives to be added at run-time? * Use the language module for directive option names? -- cgit v1.2.1 From 62ed4778b682fb915f13ff6b37b57e1156ac1da1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Jun 2005 21:54:42 +0000 Subject: another two to do list entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3619 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index d2741faf8..a35643d48 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -484,6 +484,9 @@ User Docs server and that it's terribly slow. See the first paragraphs in . +* Add document about what Docutils has previously been used for + (web/use-cases.txt?). + Developer Docs -------------- @@ -662,6 +665,9 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* Complain about bad URI characters + (http://article.gmane.org/gmane.text.docutils.user/2046). + * Create ``info``-level system messages for unnecessarily backslash-escaped characters (as in ``"\something"``, rendered as "something") to allow checking for errors which silently slipped -- cgit v1.2.1 From fe22e775c610696e3311ab0d6cec0e836c259576 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 28 Jun 2005 22:42:35 +0000 Subject: added history and to-do list entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3620 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 19 ++++++++++++++++++- docs/dev/todo.txt | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 453736e92..4d99b209b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -71,11 +71,20 @@ Changes Since 0.3.9 - The Null Writer now returns an empty string instead of None. -* docs/dev/distributing.txt: Added to project; guide for distributors. +* docutils/writers/unicode_latex.py: Added to project; mapping of + Unicode characters to LaTeX equivalents. + +* docs/dev/distributing.txt: Added to project; guide for distributors + (package maintainers). + +* docs/dev/hacking.txt: Added to project; guide for developers. * 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/ref/rst/substitutions.txt: "reStructuredText Standard Substitution Definition Sets", added to project. @@ -83,8 +92,13 @@ Changes Since 0.3.9 * 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. + Release 0.3.9 (2005-05-26) ========================== @@ -251,6 +265,9 @@ Release 0.3.9 (2005-05-26) - 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 diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a35643d48..b4f1c962f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -665,6 +665,10 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* Change the specification so that more punctuation is allowed + before/after inline markup start/end string + (http://article.gmane.org/gmane.text.docutils.cvs/3824). + * Complain about bad URI characters (http://article.gmane.org/gmane.text.docutils.user/2046). -- cgit v1.2.1 From 87d7a29637a909f7bb7c0a321d09d131fc45d7f8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 29 Jun 2005 11:26:25 +0000 Subject: move metadata title into document['title'] git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3621 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/misc.py | 2 +- docutils/transforms/frontmatter.py | 39 ++++++++++++++++++---- docutils/writers/html4css1.py | 18 ++-------- .../expected/standalone_rst_pseudoxml.txt | 2 +- test/test_transforms/test_doctitle.py | 20 ++++++----- test/test_writers/test_docutils_xml.py | 8 ++--- test/test_writers/test_pseudoxml.py | 15 +++------ 7 files changed, 57 insertions(+), 47 deletions(-) diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index de50d3c6b..71c097b33 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -358,7 +358,7 @@ default_role.arguments = (0, 1, 0) def title(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - state_machine.document.settings.title = arguments[0] + state_machine.document['title'] = arguments[0] return [] title.arguments = (1, 0, 1) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index 6fe6860e3..b03388f72 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -9,10 +9,13 @@ 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, and promote a remaining lone top-level section's - title to the document subtitle. + 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. -- `SectionTitle`: Used to transform a lone subsection into a subtitle. +- `SectionSubTitle`: Used to transform a lone subsection into a + subtitle. - `DocInfo`: Used to transform a bibliographic field list into docinfo elements. @@ -195,15 +198,37 @@ class DocTitle(TitlePromoter): 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']). """ 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 not getattr(self.document.settings, 'doctitle_xform', 1): - return - if self.promote_title(self.document): - self.promote_subtitle(self.document) + 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): diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 749982a14..f401dae83 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -634,14 +634,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('\n\n') def visit_document(self, node): - # empty or untitled document? - if not len(node) or not isinstance(node[0], nodes.title): - if self.settings.title: - self.head.append('%s\n' - % self.encode(self.settings.title)) - else: - # for XHTML conformance, modulo IE6 appeasement: - self.head.append('\n') + self.head.append('%s\n' + % self.encode(node.get('title', ''))) def depart_document(self, node): self.fragment.extend(self.body) @@ -1368,13 +1362,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.starttag(node, 'caption', '')) check_id = 1 close_tag = '\n' - elif self.section_level == 0: # document title - assert node.parent is self.document - if self.settings.title: - title = self.settings.title - else: - title = node.astext() - self.head.append('%s\n' % self.encode(title)) + elif isinstance(node.parent, nodes.document): self.body.append(self.starttag(node, 'h1', '', CLASS='title')) self.context.append('

    \n') self.in_document_title = len(self.body) diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index d7f4d0103..2ae7e5c3b 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1,4 +1,4 @@ - + reStructuredText Test Document <subtitle ids="examples-of-syntax-constructs subtitle" names="examples of syntax constructs subtitle"> diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 3a672d1c2..22629c45a 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -33,7 +33,7 @@ Title Paragraph. """, """\ -<document ids="title" names="title" source="test data"> +<document ids="title" names="title" source="test data" title="Title"> <title> Title <comment xml:space="preserve"> @@ -47,7 +47,7 @@ Title Paragraph (no blank line). """, """\ -<document ids="title" names="title" source="test data"> +<document ids="title" names="title" source="test data" title="Title"> <title> Title <paragraph> @@ -78,16 +78,18 @@ Title Subtitle -------- -Test title & subtitle. +.. title:: Another Title + +Test title, subtitle, and title metadata. """, """\ -<document ids="title" names="title" source="test data"> +<document ids="title" names="title" source="test data" title="Another Title"> <title> Title <subtitle ids="subtitle" names="subtitle"> Subtitle <paragraph> - Test title & subtitle. + Test title, subtitle, and title metadata. """], ["""\ Title @@ -96,7 +98,7 @@ Title Test short underline. """, """\ -<document ids="title" names="title" source="test data"> +<document ids="title" names="title" source="test data" title="Title"> <title> Title <system_message level="2" line="2" source="test data" type="WARNING"> @@ -118,7 +120,7 @@ The system_message should move after the document title (it was before the beginning of the section). """, """\ -<document ids="long-title" names="long title" source="test data"> +<document ids="long-title" names="long title" source="test data" title="Long Title"> <title> Long Title <system_message level="2" line="1" source="test data" type="WARNING"> @@ -149,7 +151,7 @@ Title 3 Paragraph 3. """, """\ -<document ids="title-1" names="title 1" source="test data"> +<document ids="title-1" names="title 1" source="test data" title="Title 1"> <title> Title 1 <comment xml:space="preserve"> @@ -178,7 +180,7 @@ This title should be the document title despite the substitution_definition. """, """\ -<document ids="title" names="title" source="test data"> +<document ids="title" names="title" source="test data" title="Title"> <title> Title <substitution_definition names="foo"> diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index f11b620f4..1dab576c2 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -19,13 +19,13 @@ import docutils.core class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): - input = 'Test\n====\n\nSubsection\n----------\n\nTest\n\n----------\n\nTest. äöü€' + input = 'Test\n\n----------\n\nTest. äöü€' xmldecl = '<?xml version="1.0" encoding="iso-8859-1"?>\n' doctypedecl = '<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n' generatedby = '<!-- Generated by Docutils %s -->\n' % docutils.__version__ - bodynormal = '<document ids="test" names="test" source="<string>"><title>TestSubsectionTestTest. \xe4\xf6\xfc€' - bodynewlines = '\n\nTest\n\n\nSubsection\n\n\nTest\n\n\n\nTest. \xe4\xf6\xfc€\n\n\n' - bodyindents = '\n \n Test\n \n \n Subsection\n \n \n Test\n \n \n \n Test. \xe4\xf6\xfc€\n \n\n' + bodynormal = 'TestTest. \xe4\xf6\xfc€' + bodynewlines = '\n\nTest\n\n\n\nTest. \xe4\xf6\xfc€\n\n\n' + bodyindents = '\n \n Test\n \n \n \n Test. \xe4\xf6\xfc€\n \n\n' def test_publish(self): settings = {'input_encoding': 'utf8', diff --git a/test/test_writers/test_pseudoxml.py b/test/test_writers/test_pseudoxml.py index 66bfef480..45b320b8b 100755 --- a/test/test_writers/test_pseudoxml.py +++ b/test/test_writers/test_pseudoxml.py @@ -22,33 +22,28 @@ totest = {} totest['basic'] = [ # input ["""\ -This is the title -================= - This is a paragraph. ---------- This is another paragraph. -A subsection ------------- +A Section +--------- Foo. """, # output """\ - - - This is the title +<document source="<string>"> <paragraph> This is a paragraph. <transition> <paragraph> This is another paragraph. - <section ids="a-subsection" names="a subsection"> + <section ids="a-section" names="a section"> <title> - A subsection + A Section <paragraph> Foo. """] -- cgit v1.2.1 From 8d2b940d5d23fd968831db94e5fb7208cd27268b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 12:09:04 +0000 Subject: added "title" attribute to document tree reference git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3622 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 21 +++++++++++++++++++-- docs/ref/docutils.dtd | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index f432ed1f6..68bfb408f 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -1785,8 +1785,11 @@ See the `%structure.model;`_ parameter entity for details of the body of a ``document``. :Attributes: - The ``document`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + The ``document`` element contains the `common attributes`_ (id_, + name_, dupname_, source_, and class_), plus an optional title__ + attribute which stores the document title metadata. + + __ `title (attribute)`_ Examples @@ -3975,6 +3978,8 @@ Pseudo-XML_ fragment from simple parsing:: 15% if the service is good. +.. _title: + ``title`` ========= @@ -4577,6 +4582,18 @@ whitespace. The attribute value should not be set in a document instance. +.. _title (attribute): + +``title`` +========= + +`Attribute type`_: ``CDATA``. Default value: none. + +The ``title`` attribute stores the title metadata of a document. This +title is typically not part of the rendered document. It may for +example be used in HTML's ``title`` element. + + ---------------------------- Parameter Entity Reference ---------------------------- diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index fd47b6c91..f6628684a 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -196,7 +196,9 @@ http://www.oasis-open.org/html/tm9901.htm). decoration?, (docinfo, transition?)?, %structure.model; )> -<!ATTLIST document %basic.atts;> +<!ATTLIST document + %basic.atts; + title CDATA #IMPLIED> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.1 From 59faeb587bf4a9f98d3541fea3f02fca6ab6a1be Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 13:50:38 +0000 Subject: converted to real multi-line literal strings for readability git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3623 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_writers/test_docutils_xml.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index 1dab576c2..eeb5bc94a 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -19,13 +19,38 @@ import docutils.core class DocutilsXMLTestCase(DocutilsTestSupport.StandardTestCase): - input = 'Test\n\n----------\n\nTest. äöü€' + input = """\ +Test + +---------- + +Test. äöü€""" xmldecl = '<?xml version="1.0" encoding="iso-8859-1"?>\n' doctypedecl = '<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n' generatedby = '<!-- Generated by Docutils %s -->\n' % docutils.__version__ bodynormal = '<document source="<string>"><paragraph>Test</paragraph><transition/><paragraph>Test. \xe4\xf6\xfc€</paragraph></document>' - bodynewlines = '<document source="<string>">\n<paragraph>\nTest\n</paragraph>\n<transition/>\n<paragraph>\nTest. \xe4\xf6\xfc€\n</paragraph>\n</document>\n' - bodyindents = '<document source="<string>">\n <paragraph>\n Test\n </paragraph>\n <transition/>\n <paragraph>\n Test. \xe4\xf6\xfc€\n </paragraph>\n</document>\n' + bodynewlines = """\ +<document source="<string>"> +<paragraph> +Test +</paragraph> +<transition/> +<paragraph> +Test. \xe4\xf6\xfc€ +</paragraph> +</document> +""" + bodyindents = """\ +<document source="<string>"> + <paragraph> + Test + </paragraph> + <transition/> + <paragraph> + Test. \xe4\xf6\xfc€ + </paragraph> +</document> +""" def test_publish(self): settings = {'input_encoding': 'utf8', -- cgit v1.2.1 From 2e400f133f82a1419d816187770c546165d68eab Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 16:11:49 +0000 Subject: Fixed non-working dummy reader to make publish_from_doctree work again. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3624 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/dummy.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docutils/readers/dummy.py b/docutils/readers/dummy.py index a63301e17..89d39970d 100644 --- a/docutils/readers/dummy.py +++ b/docutils/readers/dummy.py @@ -6,7 +6,7 @@ """Dummy reader that is initialized with an existing document tree.""" -from docutils import readers +from docutils import readers, utils class Reader(readers.Reader): @@ -16,14 +16,14 @@ class Reader(readers.Reader): def __init__(self, doctree): readers.Reader.__init__(self) - self.doctree = doctree + self.document = doctree def read(self, source, parser, settings): # Useful for document serialization, where the reporter is destroyed. - if self.doctree.reporter is None: - self.doctree.reporter = utils.new_reporter( + if self.document.reporter is None: + self.document.reporter = utils.new_reporter( source.source_path, settings) # Override document settings with new settings. - self.doctree.settings = settings - # Call base-class method and return document tree. - return readers.Reader.read(self, source, parser, settings) + self.document.settings = settings + # Return document tree. No parsing necessary. + return self.document -- cgit v1.2.1 From 15d51dcd2e1dc82ea8c5120b983ed269350c72bb Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 16:26:22 +0000 Subject: added test for publish_from_doctree git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3625 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publisher.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/test_publisher.py b/test/test_publisher.py index d62c320f6..388253902 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -22,6 +22,14 @@ Test Document This is a test document. """ +pseudoxml_output = """\ +<document ids="test-document" names="test document" source="<string>" title="Test Document"> + <title> + Test Document + <paragraph> + This is a test document. +""" + class PublishDoctreeTestCase(unittest.TestCase): @@ -42,9 +50,10 @@ class PublishDoctreeTestCase(unittest.TestCase): # Write out the document. output, parts = core.publish_from_doctree( - doctree, writer_name='pseudoxml') + doctree, writer_name='pseudoxml', + settings_overrides={'_disable_config': 1}) - self.assert_(isinstance(output, StringType)) + self.assertEquals(output, pseudoxml_output) assert isinstance(parts, DictType) -- cgit v1.2.1 From f0bd13cec3b724e5b23f406d2d5c8bd081b3c2fc Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:44:43 +0000 Subject: Added ``DocTreeInput`` class, for reprocessing existing documents. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3626 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docutils/io.py b/docutils/io.py index 665766605..090231336 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -345,3 +345,18 @@ class NullOutput(Output): def write(self, data): """Do nothing ([don't even] send data to the bit bucket).""" pass + + +class DocTreeInput(Input): + + """ + Adapter for document tree input. + + The document tree must be passed in the ``source`` parameter. + """ + + default_source_path = 'doctree input' + + def read(self): + """Return the document tree.""" + return self.source -- cgit v1.2.1 From 6d8e20e47dc5ff3e07c555cf850937a8a8bcc99d Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:44:52 +0000 Subject: Added ``docutils.TransformSpec.reprocess_transforms`` and ``docutils.transforms.Transformer.reprocess_transforms`` attributes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3627 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/__init__.py | 4 ++++ docutils/transforms/__init__.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/docutils/__init__.py b/docutils/__init__.py index eeb54a413..26587b1ad 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -139,6 +139,10 @@ class TransformSpec: default_transforms = () """Transforms required by this class. Override in subclasses.""" + + reprocess_transforms = () + """Transforms suggested as replacements for `default_transforms` when + reprocessing a document tree.""" unknown_reference_resolvers = () """List of functions to try to resolve unknown references. Unknown diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 971d12a72..6039e1a63 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -80,6 +80,12 @@ class Transformer(TransformSpec): universal.FilterMessages) """These transforms are applied to all document trees.""" + reprocess_transforms = (universal.FinalChecks, + universal.Messages, + universal.FilterMessages) + """This set of transforms is a suggested replacement for + `default_transforms` when reprocessing a document tree.""" + def __init__(self, document): self.transforms = [] """List of transforms to apply. Each item is a 3-tuple: -- cgit v1.2.1 From ab590797d28eadbe3580501e2d74e3f665aa0030 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:45:15 +0000 Subject: renaming "dummy" parser to "null" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3628 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/dummy.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/dummy.py b/docutils/parsers/dummy.py index 5fd646c7a..61702dfaf 100644 --- a/docutils/parsers/dummy.py +++ b/docutils/parsers/dummy.py @@ -4,17 +4,18 @@ # Date: $Date$ # Copyright: This module has been placed in the public domain. -"""Dummy parser that does nothing.""" +"""A do-nothing parser.""" from docutils import parsers + class Parser(parsers.Parser): - """Dummy parser that does nothing.""" + """A do-nothing parser.""" - supported = ('dummy',) + supported = ('null',) - config_section = 'dummy parser' + config_section = 'null parser' config_section_dependencies = ('parsers',) def parse(self, inputstring, document): -- cgit v1.2.1 From 7e0a64e309a60fabda5f1d52afa6fc3c1c66ae46 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:45:35 +0000 Subject: renamed "dummy" parser to "null" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3629 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/dummy.py | 22 ---------------------- docutils/parsers/null.py | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 22 deletions(-) delete mode 100644 docutils/parsers/dummy.py create mode 100644 docutils/parsers/null.py diff --git a/docutils/parsers/dummy.py b/docutils/parsers/dummy.py deleted file mode 100644 index 61702dfaf..000000000 --- a/docutils/parsers/dummy.py +++ /dev/null @@ -1,22 +0,0 @@ -# Author: Martin Blais -# Contact: blais@furius.ca -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -"""A do-nothing parser.""" - -from docutils import parsers - - -class Parser(parsers.Parser): - - """A do-nothing parser.""" - - supported = ('null',) - - config_section = 'null parser' - config_section_dependencies = ('parsers',) - - def parse(self, inputstring, document): - pass diff --git a/docutils/parsers/null.py b/docutils/parsers/null.py new file mode 100644 index 000000000..61702dfaf --- /dev/null +++ b/docutils/parsers/null.py @@ -0,0 +1,22 @@ +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +"""A do-nothing parser.""" + +from docutils import parsers + + +class Parser(parsers.Parser): + + """A do-nothing parser.""" + + supported = ('null',) + + config_section = 'null parser' + config_section_dependencies = ('parsers',) + + def parse(self, inputstring, document): + pass -- cgit v1.2.1 From f3b641c8dce544b1b466a6cf47c78b6f5de5f1ba Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:45:44 +0000 Subject: reworked to conform to existing API; renaming "dummy" reader to "doctree" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3630 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/dummy.py | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/docutils/readers/dummy.py b/docutils/readers/dummy.py index 89d39970d..dfb1bc804 100644 --- a/docutils/readers/dummy.py +++ b/docutils/readers/dummy.py @@ -4,26 +4,42 @@ # Date: $Date$ # Copyright: This module has been placed in the public domain. -"""Dummy reader that is initialized with an existing document tree.""" +"""Reader for existing document trees.""" from docutils import readers, utils + class Reader(readers.Reader): - """Dummy reader that is initialized with an existing document tree.""" + """ + Adapt the Reader API for an existing document tree. + + The existing document tree must be passed as the ``source`` parameter to + the `docutils.core.Publisher` initializer, wrapped in a + `docutils.io.DoctreeInput` object:: + + pub = docutils.core.Publisher( + ..., source=docutils.io.DoctreeInput(document), ...) + + The original document settings are overridden; if you want to use the + settings of the original document, pass ``settings=document.settings`` to + the Publisher call above. + """ - supported = ('dummy',) + supported = ('doctree',) - def __init__(self, doctree): - readers.Reader.__init__(self) - self.document = doctree + config_section = 'doctree reader' + config_section_dependencies = ('readers',) - def read(self, source, parser, settings): - # Useful for document serialization, where the reporter is destroyed. + def parse(self): + """ + No parsing to do; refurbish the document tree instead. + Overrides the inherited method. + """ + self.document = self.input + # Restore the reporter after document serialization: if self.document.reporter is None: self.document.reporter = utils.new_reporter( - source.source_path, settings) - # Override document settings with new settings. - self.document.settings = settings - # Return document tree. No parsing necessary. - return self.document + self.document.source_path, self.settings) + # Override document settings with new settings: + self.document.settings = self.settings -- cgit v1.2.1 From 6aebf13bdef4a9defd7a5c68cf4621f4a684b622 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:45:56 +0000 Subject: renamed "dummy" reader to "doctree" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3631 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/doctree.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ docutils/readers/dummy.py | 45 --------------------------------------------- 2 files changed, 45 insertions(+), 45 deletions(-) create mode 100644 docutils/readers/doctree.py delete mode 100644 docutils/readers/dummy.py diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py new file mode 100644 index 000000000..dfb1bc804 --- /dev/null +++ b/docutils/readers/doctree.py @@ -0,0 +1,45 @@ +# Author: Martin Blais +# Contact: blais@furius.ca +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +"""Reader for existing document trees.""" + +from docutils import readers, utils + + +class Reader(readers.Reader): + + """ + Adapt the Reader API for an existing document tree. + + The existing document tree must be passed as the ``source`` parameter to + the `docutils.core.Publisher` initializer, wrapped in a + `docutils.io.DoctreeInput` object:: + + pub = docutils.core.Publisher( + ..., source=docutils.io.DoctreeInput(document), ...) + + The original document settings are overridden; if you want to use the + settings of the original document, pass ``settings=document.settings`` to + the Publisher call above. + """ + + supported = ('doctree',) + + config_section = 'doctree reader' + config_section_dependencies = ('readers',) + + def parse(self): + """ + No parsing to do; refurbish the document tree instead. + Overrides the inherited method. + """ + self.document = self.input + # Restore the reporter after document serialization: + if self.document.reporter is None: + self.document.reporter = utils.new_reporter( + self.document.source_path, self.settings) + # Override document settings with new settings: + self.document.settings = self.settings diff --git a/docutils/readers/dummy.py b/docutils/readers/dummy.py deleted file mode 100644 index dfb1bc804..000000000 --- a/docutils/readers/dummy.py +++ /dev/null @@ -1,45 +0,0 @@ -# Author: Martin Blais -# Contact: blais@furius.ca -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -"""Reader for existing document trees.""" - -from docutils import readers, utils - - -class Reader(readers.Reader): - - """ - Adapt the Reader API for an existing document tree. - - The existing document tree must be passed as the ``source`` parameter to - the `docutils.core.Publisher` initializer, wrapped in a - `docutils.io.DoctreeInput` object:: - - pub = docutils.core.Publisher( - ..., source=docutils.io.DoctreeInput(document), ...) - - The original document settings are overridden; if you want to use the - settings of the original document, pass ``settings=document.settings`` to - the Publisher call above. - """ - - supported = ('doctree',) - - config_section = 'doctree reader' - config_section_dependencies = ('readers',) - - def parse(self): - """ - No parsing to do; refurbish the document tree instead. - Overrides the inherited method. - """ - self.document = self.input - # Restore the reporter after document serialization: - if self.document.reporter is None: - self.document.reporter = utils.new_reporter( - self.document.source_path, self.settings) - # Override document settings with new settings: - self.document.settings = self.settings -- cgit v1.2.1 From 57d2f142c45280b6c47448797b560c8ec013db1b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:46:05 +0000 Subject: updated to support changes in revisions 3626-; revised ``publish_from_doctree`` API for consistency git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3632 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 9602f4a7b..b7caf9cc5 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -23,6 +23,7 @@ from docutils import __version__, __version_details__, SettingsSpec from docutils import frontend, io, utils, readers, writers from docutils.frontend import OptionParser from docutils.transforms import Transformer +import docutils.readers.doctree class Publisher: @@ -453,12 +454,12 @@ def publish_doctree(source, source_path=None, settings_overrides=settings_overrides, config_section=config_section, enable_exit_status=enable_exit_status) - # The transformer is not needed anymore. (A new transformer will - # be created in `publish_from_doctree`.) + # The transformer is not needed any more + # (a new transformer will be created in `publish_from_doctree`): del pub.document.transformer return pub.document -def publish_from_doctree(doctree, destination_path=None, +def publish_from_doctree(document, destination_path=None, writer=None, writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=None, config_section=None, @@ -468,8 +469,8 @@ def publish_from_doctree(doctree, destination_path=None, structure, for programmatic use with string I/O. Return a pair of encoded string output and document parts. - Note that doctree.settings is overridden; if you want to use the settings - of the original `doctree` document, pass settings=doctree.settings. + Note that document.settings is overridden; if you want to use the settings + of the original `document` document, pass settings=document.settings. For encoded string output, be sure to set the 'output_encoding' setting to the desired encoding. Set it to 'unicode' for unencoded Unicode string @@ -481,22 +482,17 @@ def publish_from_doctree(doctree, destination_path=None, Parameters: see `publish_programmatically`. """ # Create fresh Transformer object, to be populated from Writer component. - doctree.transformer = Transformer(doctree) - # Don't double apply default transforms. - doctree.transformer.default_transforms = () - # Create reader with existing doctree. - from docutils.readers import dummy - reader = dummy.Reader(doctree) - # Create Publisher. + document.transformer = Transformer(document) + # Don't apply default transforms twice: + document.transformer.default_transforms = (document.transformer + .reprocess_transforms) + reader = docutils.readers.doctree.Reader(parser_name='null') pub = Publisher(reader, None, writer, - settings=settings, source_class=io.NullInput, - destination_class=io.StringOutput) - # Set parser and writer name. - pub.set_components(None, 'dummy', writer_name) - # Set settings. + source=io.DocTreeInput(document), + destination_class=io.StringOutput, settings=settings) + pub.set_writer(writer_name) pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) - # Set destination path and run. pub.set_destination(None, destination_path) output = pub.publish(enable_exit_status=enable_exit_status) return output, pub.writer.parts -- cgit v1.2.1 From a73f790481e8996fa6c2830ff6f68cbdef458f96 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:47:03 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3633 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 19 +++++++++++++++++++ test/test_publisher.py | 12 ++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 4d99b209b..ce106df1b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -21,11 +21,23 @@ Changes Since 0.3.9 - Added ``__version_details__`` attribute to describe code source (repository/snapshot/release). + - Added ``TransformSpec.reprocess_transforms`` attribute. + +* docutils/core.py: + + - Added ``publish_doctree`` and ``publish_from_doctree`` convenience + functions, for document tree extraction and reprocessing. * docutils/frontend.py: - Added ``_stylesheet_required`` internal setting. +* docutils/io.py: + + - Added ``DocTreeInput`` class, for reprocessing existing documents. + +* 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 @@ -48,6 +60,13 @@ Changes Since 0.3.9 standard data files for the "include" directive. Initial contents: character entity substitution definition sets. +* docutils/readers/doctree.py: Added to project; a reader for existing + document trees. + +* docutils/transforms/__init__.py: + + - Added ``Transformer.reprocess_transforms`` attribute. + * docutils/transforms/html.py: Added to project; transforms specific to the html4css1 Writer. diff --git a/test/test_publisher.py b/test/test_publisher.py index 388253902..ebca64b70 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -21,7 +21,6 @@ Test Document This is a test document. """ - pseudoxml_output = """\ <document ids="test-document" names="test document" source="<string>" title="Test Document"> <title> @@ -41,20 +40,17 @@ class PublishDoctreeTestCase(unittest.TestCase): reader_name='standalone', parser_name='restructuredtext', settings_overrides={'_disable_config': 1}) - self.assert_(isinstance(doctree, nodes.document)) - # Assert transforms have been applied (in this case the - # DocTitle transform). + # Confirm that transforms have been applied (in this case, the + # DocTitle transform): self.assert_(isinstance(doctree[0], nodes.title)) self.assert_(isinstance(doctree[1], nodes.paragraph)) - - # Write out the document. + # Write out the document: output, parts = core.publish_from_doctree( doctree, writer_name='pseudoxml', settings_overrides={'_disable_config': 1}) - self.assertEquals(output, pseudoxml_output) - assert isinstance(parts, DictType) + self.assert_(isinstance(parts, DictType)) if __name__ == '__main__': -- cgit v1.2.1 From 94b4ee517017362ffc7b56ab5ba945c056da1d7a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 19:54:50 +0000 Subject: stricter regex git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3634 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index f401dae83..5a1138522 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -885,7 +885,7 @@ class HTMLTranslator(nodes.NodeVisitor): del im for att_name in 'width', 'height': if atts.has_key(att_name): - match = re.match(r'([0-9.]+)(.*)', atts[att_name]) + match = re.match(r'([0-9.]+)(\S*)$', atts[att_name]) assert match atts[att_name] = '%s%s' % ( float(match.group(1)) * (float(node['scale']) / 100), -- cgit v1.2.1 From 77f04a55cc598dbfeb97703d5f115048daa01822 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 20:01:19 +0000 Subject: implemented units for image widths; implemented language-support (e.g. for hyphenation) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3635 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 166 +++++++++++++---------------------- test/functional/input/data/latex.txt | 3 +- tools/stylesheets/latex.tex | 30 ++++--- 3 files changed, 82 insertions(+), 117 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 49f00e0a5..e508fdcea 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -83,15 +83,37 @@ class Writer(writers.Writer): self.body = visitor.body -class Babel: - """Language specifics for LaTeX.""" - # country code by a.schlock. - # partly manually converted from iso and babel stuff, dialects and some - _ISO639_TO_BABEL = { - 'no': 'norsk', # added by hand ( forget about nynorsk?) +class LaTeXException(Exception): + """ + Exception base class to for exceptions which influence the + automatic generation of LaTeX code. + """ + + +class SkipAttrParentLaTeX(LaTeXException): + """ + Do not generate \Dattr and \renewcommand{\Dparent}{...} for this + node. + + To be raised from before_... methods. + """ + + +class SkipParentLaTeX(LaTeXException): + """ + Do not generate \renewcommand{\DNparent}{...} for this node. + + To be raised from before_... methods. + """ + + +class LaTeXTranslator(nodes.SparseNodeVisitor): + + # Country code by a.schlock. + # Partly manually converted from iso and babel stuff. + iso639_to_babel = { + 'no': 'norsk', # added by hand 'gd': 'scottish', # added by hand - 'hu': 'magyar', # added by hand - 'pt': 'portuguese',# added by hand 'sl': 'slovenian', 'af': 'afrikaans', 'bg': 'bulgarian', @@ -102,7 +124,7 @@ class Babel: 'da': 'danish', 'fr': 'french', # french, francais, canadien, acadian - 'de': 'ngerman', # rather than german + 'de': 'ngerman', # ngerman, naustrian, german, germanb, austrian 'el': 'greek', 'en': 'english', @@ -132,46 +154,6 @@ class Babel: 'uk': 'ukrainian' } - def __init__(self, lang): - self.language = lang - - def get_language(self): - if self._ISO639_TO_BABEL.has_key(self.language): - return self._ISO639_TO_BABEL[self.language] - else: - # Support dialects. - l = self.language.split("_")[0] - if self._ISO639_TO_BABEL.has_key(l): - return self._ISO639_TO_BABEL[l] - return None - - -class LaTeXException(Exception): - """ - Exception base class to for exceptions which influence the - automatic generation of LaTeX code. - """ - - -class SkipAttrParentLaTeX(LaTeXException): - """ - Do not generate \Dattr and \renewcommand{\Dparent}{...} for this - node. - - To be raised from before_... methods. - """ - - -class SkipParentLaTeX(LaTeXException): - """ - Do not generate \renewcommand{\DNparent}{...} for this node. - - To be raised from before_... methods. - """ - - -class LaTeXTranslator(nodes.SparseNodeVisitor): - # Start with left double quote. left_quote = 1 @@ -194,8 +176,6 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): if self.user_stylesheet_path: self.settings.record_dependencies.add(self.user_stylesheet_path) self.write_header() - for key, value in self.character_map.items(): - self.character_map[key] = '{%s}' % value def write_header(self): a = self.header.append @@ -207,7 +187,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a('% Docutils stylesheet:') a(r'\input{%s}' % self.stylesheet_path) a('') - a('% Definitions for Docutils Nodes:') + a('% Default definitions for Docutils nodes:') for node_name in nodes.node_class_names: a(r'\providecommand{\DN%s}[1]{#1}' % node_name.replace('_', '')) a('') @@ -219,52 +199,14 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dtitleastext}{x}') a(r'\providecommand{\Dsinglebackref}{} % variable') a(r'\providecommand{\Dmultiplebackrefs}{} % variable') + a('') + a('% Docutils settings:') + lang = self.settings.language_code or '' + a(r'\providecommand{\Dlanguageiso}{%s}' % lang) + a(r'\providecommand{\Dlanguagebabel}{%s}' % self.iso639_to_babel.get( + lang, self.iso639_to_babel.get(lang.split('_')[0], ''))) a('\n\n') - def to_latex_encoding(self,docutils_encoding): - """ - Translate docutils encoding name into latex's. - - Default fallback method is remove "-" and "_" chars from - docutils_encoding. - """ - tr = { "iso-8859-1": "latin1", # west european - "iso-8859-2": "latin2", # east european - "iso-8859-3": "latin3", # esperanto, maltese - "iso-8859-4": "latin4", # north european,scandinavian, baltic - "iso-8859-5": "iso88595", # cyrillic (ISO) - "iso-8859-9": "latin5", # turkish - "iso-8859-15": "latin9", # latin9, update to latin1. - "mac_cyrillic": "maccyr", # cyrillic (on Mac) - "windows-1251": "cp1251", # cyrillic (on Windows) - "koi8-r": "koi8-r", # cyrillic (Russian) - "koi8-u": "koi8-u", # cyrillic (Ukrainian) - "windows-1250": "cp1250", # - "windows-1252": "cp1252", # - "us-ascii": "ascii", # ASCII (US) - # unmatched encodings - #"": "applemac", - #"": "ansinew", # windows 3.1 ansi - #"": "ascii", # ASCII encoding for the range 32--127. - #"": "cp437", # dos latine us - #"": "cp850", # dos latin 1 - #"": "cp852", # dos latin 2 - #"": "decmulti", - #"": "latin10", - #"iso-8859-6": "" # arabic - #"iso-8859-7": "" # greek - #"iso-8859-8": "" # hebrew - #"iso-8859-10": "" # latin6, more complete iso-8859-4 - } - if tr.has_key(docutils_encoding.lower()): - return tr[docutils_encoding.lower()] - return docutils_encoding.translate(string.maketrans("",""),"_-").lower() - - def language_label(self, docutil_label): - return self.language.labels[docutil_label] - - #special_map = {'\n': ' ', '\r': ' ', '\t': ' ', '\v': ' ', '\f': ' '} - # Get comprehensive Unicode map. from unicode_latex import unicode_map # Fix problems with unimap.py. @@ -317,13 +259,27 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): } att_map.update(unicode_map) - def encode(self, text, attval=0): + def encode(self, text, attval=None): """ Encode special characters in ``text`` and return it. - If attval is true, preserve as much as possible verbatim (used in - attribute value encoding). + If attval is true, preserve as much as possible verbatim (used + in attribute value encoding). If attval is 'width' or + 'height', `text` is interpreted as a length value. """ + if attval in ('width', 'height'): + match = re.match(r'([0-9.]+)(\S*)$', text) + assert match, '%s="%s" must be a length' % (attval, text) + value, unit = match.groups() + if unit == '%': + value = str(float(value) / 100) + unit = r'\Drelativeunit' + elif unit in ('', 'px'): + # If \Dpixelunit is "pt", this gives the same notion + # of pixels as graphicx. + value = str(float(value) * 0.75) + unit = '\Dpixelunit' + return '%s%s' % (value, unit) if attval: get = self.att_map.get else: @@ -373,7 +329,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): return '~' * len(match.group()) def encode_replace_for_inline_literal_spaces(self, match): - return '{ }' + '~' * len(match.group() - 1) + return '{ }' + '~' * (len(match.group()) - 1) def astext(self): return '\n'.join(self.header) + (''.join(self.body)) @@ -641,14 +597,14 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) for i in range(len(value)): self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % - (i+1, key, self.encode(value[i], attval=1), + (i+1, key, self.encode(value[i], attval=key), node_name)) if not pass_contents: self.append('}') numatts += len(value) else: self.append(r'\Dattr{}{%s}{%s}{%s}{' % - (key, self.encode(unicode(value), attval=1), + (key, self.encode(unicode(value), attval=key), node_name)) if not pass_contents: self.append('}') @@ -708,11 +664,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.append(r'\renewcommand{\Dparent}{%s}' % self.node_name(node.parent)) for name, value in node.attlist(): - # @@@ Evaluate if this is really needed and refactor. if not isinstance(value, ListType) and not ':' in name: macro = r'\DcurrentN%sA%s' % (node_name, name) self.append(r'\def%s{%s}' % ( - macro, self.encode(unicode(value), attval=1))) + macro, self.encode(unicode(value), attval=name))) attribute_deleters.append(r'\let%s=\relax' % macro) self.context.append('\n'.join(attribute_deleters)) if self.pass_contents(node): @@ -764,8 +719,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): return ((isinstance(node, nodes.Body) or isinstance(node, nodes.topic) or #isinstance(node, nodes.rubric) or - isinstance(node, nodes.transition) or - isinstance(node, nodes.legend)) and + isinstance(node, nodes.transition)) and not (self.is_invisible(node) or isinstance(node.parent, nodes.TextElement))) diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt index df1f66d45..ee9c02a4d 100644 --- a/test/functional/input/data/latex.txt +++ b/test/functional/input/data/latex.txt @@ -113,8 +113,9 @@ Images Image with 20% width: .. image:: ../../../docs/user/rst/images/title.png - :width: 20 + :width: 20% Image with 100% width: .. image:: ../../../docs/user/rst/images/title.png + :width: 100% diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 88b6a8499..8937fe1ac 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -203,6 +203,16 @@ } +\providecommand{\DSlanguage}{% + % Set up babel. + \ifthenelse{\equal{\Dlanguagebabel}{}}{}{% + \usepackage[\Dlanguagebabel]{babel}% + } +} + + + + \providecommand{\DSearly}{} \providecommand{\DSlate}{} @@ -518,9 +528,6 @@ } -\providecommand{\Dlanguage}{english} -\usepackage[\Dlanguage]{babel} - % Single quote in literal mode. \textquotesingle from package % textcomp has wrong width when using package ae, so we use a normal % single curly quote here. @@ -952,7 +959,7 @@ % Insert image. We treat the URI like a path here. \renewcommand{\Dimagepath}{\Dimagebase#3}% \Difdefined{DcurrentNimageAwidth}{% - \Dpercentwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% + \Dwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% }{% \Dsimpleimage{\Dimagepath}% }% @@ -986,15 +993,12 @@ \Dwidthimage{\Dcurrentimagewidth}{#1}% }% } -% Auxiliary length. One percent of \linewidth. -\Dprovidelength{\Dlinewidthpercent}{0pt} -\providecommand{\Dpercentwidthimage}[2]{% +\providecommand{\Dwidthimage}[2]{% % Image with specified width. % Parameters: - % 1. Image width in percent of \linewidth (1 to 100). + % 1. Image width. % 2. Image path. - \setlength{\Dlinewidthpercent}{0.01\linewidth}% - \Dwidthimage{#1\Dlinewidthpercent}{#2}% + \Dwidthimage{#1}{#2}% } % Figures. @@ -1010,6 +1014,7 @@ %\let\DcurrentNimageAwidth=\relax% } \providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}} +\providecommand{\DNlegend}[1]{\Dauxiliaryspace#1} \providecommand{\DCborder}[1]{\fbox{#1}} % No padding between image and border. @@ -1067,6 +1072,11 @@ } +% For \Dpixelunit, the length value is pre-multiplied with 0.75, so by +% specifying "pt" we get the same notion of "pixel" as graphicx. +\providecommand{\Dpixelunit}{pt} +% Normally lengths are relative to the current linewidth. +\providecommand{\Drelativeunit}{\linewidth} %\usepackage{fixmath} -- cgit v1.2.1 From f5fe452d38fcd576e79684f83c9916ffaa62277b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 20:37:37 +0000 Subject: docstring update & parameter indent fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3636 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index b7caf9cc5..33098fe97 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -470,7 +470,7 @@ def publish_from_doctree(document, destination_path=None, string output and document parts. Note that document.settings is overridden; if you want to use the settings - of the original `document` document, pass settings=document.settings. + of the original `document`, pass settings=document.settings. For encoded string output, be sure to set the 'output_encoding' setting to the desired encoding. Set it to 'unicode' for unencoded Unicode string @@ -479,7 +479,10 @@ def publish_from_doctree(document, destination_path=None, publish_from_doctree( ..., settings_overrides={'output_encoding': 'unicode'}) - Parameters: see `publish_programmatically`. + Parameters: `document` is a `docutils.nodes.document` object, an existing + document tree. + + Other parameters: see `publish_programmatically`. """ # Create fresh Transformer object, to be populated from Writer component. document.transformer = Transformer(document) @@ -498,13 +501,13 @@ def publish_from_doctree(document, destination_path=None, return output, pub.writer.parts def publish_programmatically(source_class, source, source_path, - destination_class, destination, destination_path, - reader, reader_name, - parser, parser_name, - writer, writer_name, - settings, settings_spec, - settings_overrides, config_section, - enable_exit_status): + destination_class, destination, destination_path, + reader, reader_name, + parser, parser_name, + writer, writer_name, + settings, settings_spec, + settings_overrides, config_section, + enable_exit_status): """ Set up & run a `Publisher` for custom programmatic use. Return the encoded string output and the Publisher object. -- cgit v1.2.1 From 6a66e3e696c26896f3d5ffac5376beddd13a6f20 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 29 Jun 2005 22:34:44 +0000 Subject: removed document.internal_targets and document.external_targets; fixed bug (not sure yet if the code is clean -- needs refactoring) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3637 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 12 ---------- docutils/parsers/rst/states.py | 6 ----- docutils/transforms/references.py | 40 ++++++++++++++------------------- test/test_transforms/test_hyperlinks.py | 18 +++++++++++++++ tools/stylesheets/latex.tex | 6 ++--- 5 files changed, 38 insertions(+), 44 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index dc2dbcb32..b68f7e9f5 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -750,12 +750,6 @@ class document(Root, Structural, Element): self.reporter = reporter """System message generator.""" - self.external_targets = [] - """List of external named target nodes.""" - - self.internal_targets = [] - """List of internal block-level target nodes.""" - self.indirect_targets = [] """List of indirect target nodes.""" @@ -967,12 +961,6 @@ class document(Root, Structural, Element): def note_refid(self, node): self.refids.setdefault(node['refid'], []).append(node) - def note_external_target(self, target): - self.external_targets.append(target) - - def note_internal_target(self, target): - self.internal_targets.append(target) - def note_indirect_target(self, target): self.indirect_targets.append(target) if target['names']: diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 9f12bd560..4156fd682 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -788,7 +788,6 @@ class Inliner: if target: reference['refuri'] = uri target['names'].append(refname) - self.document.note_external_target(target) self.document.note_explicit_target(target, self.parent) node_list.append(target) else: @@ -1870,17 +1869,12 @@ class Body(RSTState): uri = self.inliner.adjust_uri(refuri) if uri: target['refuri'] = uri - self.document.note_external_target(target) else: raise ApplicationError('problem with URI: %r' % refuri) - else: - self.document.note_internal_target(target) self.document.note_explicit_target(target, self.parent) else: # anonymous target if refuri: target['refuri'] = refuri - else: - self.document.note_internal_target(target) target['anonymous'] = 1 self.document.note_anonymous_target(target) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 52f1d65be..cce95e3cb 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -42,12 +42,13 @@ class PropagateTargets(Transform): default_priority = 260 def apply(self): - for target in self.document.internal_targets: - assert len(target) == 0, ('only block-level targets expected in ' - 'document.internal_targets') - if (target.hasattr('refid') or target.hasattr('refuri') or - target.hasattr('refname')): + 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=1) # Do not move names and ids into Invisibles (we'd lose the # attributes) or different Targetables (e.g. footnotes). @@ -84,8 +85,6 @@ class PropagateTargets(Transform): target['ids'] = [] target['names'] = [] self.document.note_refid(target) - if isinstance(next_node, nodes.target): - self.document.note_internal_target(next_node) class AnonymousHyperlinks(Transform): @@ -242,8 +241,6 @@ class IndirectHyperlinks(Transform): del target.multiply_indirect if reftarget.hasattr('refuri'): target['refuri'] = reftarget['refuri'] - if target['names']: - self.document.note_external_target(target) if target.has_key('refid'): del target['refid'] elif reftarget.hasattr('refid'): @@ -295,12 +292,10 @@ class IndirectHyperlinks(Transform): def resolve_indirect_references(self, target): if target.hasattr('refid'): attname = 'refid' - call_if_named = 0 call_method = self.document.note_refid elif target.hasattr('refuri'): attname = 'refuri' - call_if_named = 1 - call_method = self.document.note_external_target + call_method = None else: return attval = target[attname] @@ -313,7 +308,7 @@ class IndirectHyperlinks(Transform): continue del ref['refname'] ref[attname] = attval - if not call_if_named or ref['names']: + if call_method: call_method(ref) ref.resolved = 1 if isinstance(ref, nodes.target): @@ -327,7 +322,7 @@ class IndirectHyperlinks(Transform): continue del ref['refid'] ref[attname] = attval - if not call_if_named or ref['names']: + if call_method: call_method(ref) ref.resolved = 1 if isinstance(ref, nodes.target): @@ -355,7 +350,7 @@ class ExternalTargets(Transform): default_priority = 640 def apply(self): - for target in self.document.external_targets: + for target in self.document.traverse(nodes.target): if target.hasattr('refuri'): refuri = target['refuri'] for name in target['names']: @@ -375,8 +370,9 @@ class InternalTargets(Transform): default_priority = 660 def apply(self): - for target in self.document.internal_targets: - self.resolve_reference_ids(target) + 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): """ @@ -395,9 +391,6 @@ class InternalTargets(Transform): direct internal <target id="id1" name="direct internal"> """ - if target.hasattr('refuri') or target.hasattr('refid') \ - or not target['names']: - return for name in target['names']: refid = self.document.nameids[name] reflist = self.document.refnames.get(name, []) @@ -721,10 +714,11 @@ class TargetNotes(Transform): def apply(self): notes = {} nodelist = [] - for target in self.document.external_targets: + for target in self.document.traverse(nodes.target): + # Only external targets. + if not target.hasattr('refuri'): + continue names = target['names'] - # Only named targets. - assert names refs = [] for name in names: refs.extend(self.document.refnames.get(name, [])) diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index cf218ee47..fc7441c5f 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -396,6 +396,24 @@ The results of the transform are not visible at the XML level. The results of the transform are not visible at the XML level. """], ["""\ +.. _chained: +__ http://anonymous + +Anonymous__ and chained_ both refer to the same URI. +""", +"""\ +<document source="test data"> + <target refid="chained"> + <target anonymous="1" ids="id1 chained" names="chained" refuri="http://anonymous"> + <paragraph> + <reference anonymous="1" name="Anonymous" refuri="http://anonymous"> + Anonymous + and \n\ + <reference name="chained" refuri="http://anonymous"> + chained + both refer to the same URI. +"""], +["""\ .. _a: .. _b: diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 8937fe1ac..a73d78822 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -205,11 +205,11 @@ \providecommand{\DSlanguage}{% % Set up babel. - \ifthenelse{\equal{\Dlanguagebabel}{}}{}{% - \usepackage[\Dlanguagebabel]{babel}% + \ifthenelse{\equal{\Dlanguagebabel}{}}{}{ + \usepackage[\Dlanguagebabel]{babel} } } - + -- cgit v1.2.1 From 992191ceb9e0efbfc0d3249f52966e1261c2bbe3 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 14:41:26 +0000 Subject: Fixed bug introduced in doctree reader, added pickle test back in. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3638 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/doctree.py | 2 +- test/test_publisher.py | 48 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py index dfb1bc804..5a4371983 100644 --- a/docutils/readers/doctree.py +++ b/docutils/readers/doctree.py @@ -40,6 +40,6 @@ class Reader(readers.Reader): # Restore the reporter after document serialization: if self.document.reporter is None: self.document.reporter = utils.new_reporter( - self.document.source_path, self.settings) + self.source.source_path, self.settings) # Override document settings with new settings: self.document.settings = self.settings diff --git a/test/test_publisher.py b/test/test_publisher.py index ebca64b70..b96bb64b6 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -11,8 +11,9 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. """ import unittest -from types import DictType, StringType +from types import DictType from docutils import core, nodes +import pickle test_document = """\ @@ -34,6 +35,7 @@ class PublishDoctreeTestCase(unittest.TestCase): def test_publish_doctree(self): """Test `publish_doctree` and `publish_from_doctree`.""" + # Produce the document tree. doctree = core.publish_doctree( source=test_document, @@ -41,10 +43,12 @@ class PublishDoctreeTestCase(unittest.TestCase): parser_name='restructuredtext', settings_overrides={'_disable_config': 1}) self.assert_(isinstance(doctree, nodes.document)) + # Confirm that transforms have been applied (in this case, the # DocTitle transform): self.assert_(isinstance(doctree[0], nodes.title)) self.assert_(isinstance(doctree[1], nodes.paragraph)) + # Write out the document: output, parts = core.publish_from_doctree( doctree, writer_name='pseudoxml', @@ -52,6 +56,48 @@ class PublishDoctreeTestCase(unittest.TestCase): self.assertEquals(output, pseudoxml_output) self.assert_(isinstance(parts, DictType)) + def test_publish_pickle(self): + """Test publishing a document tree with pickling and unpickling.""" + + # Produce the document tree. + doctree = core.publish_doctree( + source=test_document, + reader_name='standalone', + parser_name='restructuredtext', + settings_overrides={'_disable_config': 1}) + self.assert_(isinstance(doctree, nodes.document)) + + # Confirm that transforms have been applied (in this case, the + # DocTitle transform): + self.assert_(isinstance(doctree[0], nodes.title)) + self.assert_(isinstance(doctree[1], nodes.paragraph)) + + # Pickle the document. Note: if this fails, some unpickleable reference + # has been added somewhere within the document tree. If so, you need to + # fix that. + # + # Note: Please do not remove this test, this is an important + # requirement, applications will be built on the assumption that we can + # pickle the document. + + # remove the reporter before pickling. + doctree.reporter = None + + doctree_pickled = pickle.dumps(doctree) + self.assert_(isinstance(doctree_pickled, str)) + del doctree + + # Unpickle the document. + doctree_zombie = pickle.loads(doctree_pickled) + self.assert_(isinstance(doctree_zombie, nodes.document)) + + # Write out the document: + output, parts = core.publish_from_doctree( + doctree_zombie, writer_name='pseudoxml', + settings_overrides={'_disable_config': 1}) + self.assertEquals(output, pseudoxml_output) + self.assert_(isinstance(parts, DictType)) + if __name__ == '__main__': unittest.main() -- cgit v1.2.1 From c7543e9e482ccce8174319d9203a0240ee13eb86 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 15:54:03 +0000 Subject: Py21 compatibility fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3639 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publisher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_publisher.py b/test/test_publisher.py index b96bb64b6..f62a43374 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -11,7 +11,7 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. """ import unittest -from types import DictType +from types import DictType, StringType from docutils import core, nodes import pickle @@ -84,7 +84,7 @@ class PublishDoctreeTestCase(unittest.TestCase): doctree.reporter = None doctree_pickled = pickle.dumps(doctree) - self.assert_(isinstance(doctree_pickled, str)) + self.assert_(isinstance(doctree_pickled, StringType)) del doctree # Unpickle the document. -- cgit v1.2.1 From d349bc9360770f519cf48c48fb04d2bc96ce4a6e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 15:57:59 +0000 Subject: removed duplicate tests; wrapped lines git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3640 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publisher.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/test/test_publisher.py b/test/test_publisher.py index f62a43374..d5460694c 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -66,21 +66,16 @@ class PublishDoctreeTestCase(unittest.TestCase): parser_name='restructuredtext', settings_overrides={'_disable_config': 1}) self.assert_(isinstance(doctree, nodes.document)) - - # Confirm that transforms have been applied (in this case, the - # DocTitle transform): - self.assert_(isinstance(doctree[0], nodes.title)) - self.assert_(isinstance(doctree[1], nodes.paragraph)) - # Pickle the document. Note: if this fails, some unpickleable reference - # has been added somewhere within the document tree. If so, you need to - # fix that. + # Pickle the document. Note: if this fails, some unpickleable + # reference has been added somewhere within the document tree. + # If so, you need to fix that. # # Note: Please do not remove this test, this is an important - # requirement, applications will be built on the assumption that we can - # pickle the document. + # requirement, applications will be built on the assumption + # that we can pickle the document. - # remove the reporter before pickling. + # Remove the reporter before pickling. doctree.reporter = None doctree_pickled = pickle.dumps(doctree) -- cgit v1.2.1 From 67bba794ba0290728c6cb0a9d184a2ebc3a278de Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 17:19:48 +0000 Subject: Fixed bug with setting the writer in the publisher from doctree. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3641 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/core.py b/docutils/core.py index 33098fe97..d6c3ec973 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -493,7 +493,8 @@ def publish_from_doctree(document, destination_path=None, pub = Publisher(reader, None, writer, source=io.DocTreeInput(document), destination_class=io.StringOutput, settings=settings) - pub.set_writer(writer_name) + if not writer and writer_name: + pub.set_writer(writer_name) pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) pub.set_destination(None, destination_path) -- cgit v1.2.1 From df203f30c658d959e8cd8c38f495d5d32c0b1edb Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 17:52:00 +0000 Subject: deactivated _stylesheet_required for programmatic use; improved documentation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3642 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 4 ++-- docutils/core.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index 3b7e8c2d0..e0bd86a8e 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -912,8 +912,8 @@ _`_source` Default: stdin (None). No command-line options. _`_stylesheet_required` - Used to disable stylesheet checking in writers that use - stylesheets. For programmatic use only. + Used to disable stylesheet checking in writers that require a + stylesheet for correct rendering. For programmatic use only. Default: required (1). No command-line options. diff --git a/docutils/core.py b/docutils/core.py index d6c3ec973..15d67af51 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -135,6 +135,12 @@ class Publisher: defaults = (settings_overrides or {}).copy() # Propagate exceptions by default when used programmatically: defaults.setdefault('traceback', 1) + # Do not complain on missing stylesheet when used + # programmatically. A stylesheet is often not necessary + # because the application uses only snippets of the + # output, and requiring a stylesheet would break existing + # applications which use Docutils programmatically. + defaults.setdefault('_stylesheet_required', 0) self.get_settings(settings_spec=settings_spec, config_section=config_section, **defaults) -- cgit v1.2.1 From 72d6bf0c93a2ec340687ebdd3420f16327743b34 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 30 Jun 2005 17:53:17 +0000 Subject: do not complain when the user specifies --stylesheet="" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3643 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/transforms/html.py b/docutils/transforms/html.py index 202fab37d..59b8fb4a9 100644 --- a/docutils/transforms/html.py +++ b/docutils/transforms/html.py @@ -21,8 +21,8 @@ class StylesheetCheck(Transform): default_priority = 420 def apply(self): - if ( self.document.settings._stylesheet_required - and not utils.get_stylesheet_reference(self.document.settings)): + if ( self.document.settings._stylesheet_required and + utils.get_stylesheet_reference(self.document.settings) is None): self.document.reporter.warning( 'No stylesheet path or URI given. Use the --stylesheet ' 'or --stylesheet-path option to specify the location of ' -- cgit v1.2.1 From 21d87f8811b672fc2726cc2d69baf229240e0dd3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 1 Jul 2005 16:39:51 +0000 Subject: improved cloaking mechanism git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3644 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 10 +++++----- docutils/transforms/universal.py | 4 ++-- docutils/writers/html4css1.py | 13 +++++++++---- test/functional/expected/pep_html.html | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index e0bd86a8e..493f4aa53 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -565,14 +565,14 @@ attribution _`cloak_email_addresses` Scramble email addresses to confuse harvesters. In the visible - text of an email address, the "@" will be replaced by "at", and - all periods (".") will be replaced by "dot", with spaces added. - In the reference URI, the address will be replaced by %-escapes. - For example, "abc@example.org" will be output as:: + text of an email address, the "@" and all periods (".") will be + surrounded by ``<span>`` tags. In the reference URI, the address + will be replaced by %-escapes. For example, "abc@example.org" + will be output as:: <a class="reference" href="mailto:%61%62%63%40%65%78%61%6D%70%6C%65%2E%6F%72%67"> - abc at example dot org</a> + abc<span>@</span>example<span>.</span>org</a> Default: don't cloak (None). Option: ``--cloak-email-addresses``. diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index aac05a2e4..75dadd7bf 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -164,8 +164,8 @@ class FinalChecks(Transform): self.document.walk(visitor) # *After* resolving all references, check for unreferenced # targets: - for target in self.document.traverse(): - if isinstance(target, nodes.target) and not target.referenced: + for target in self.document.traverse(nodes.target): + if not target.referenced: if target['names']: naming = target['names'][0] elif target['ids']: diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 5a1138522..8201ec29e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -106,7 +106,8 @@ class Writer(writers.Writer): 'validator': frontend.validate_boolean}), ('Scramble email addresses to confuse harvesters. ' 'For example, "abc@example.org" will become ' - '``<a href="mailto:%61%62%63%40...">abc at example dot org</a>``.', + '``<a href="mailto:%61%62%63%40...">abc<span>@</span>' + 'example<span>.</span>org</a>``.', ['--cloak-email-addresses'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) @@ -286,11 +287,14 @@ class HTMLTranslator(nodes.NodeVisitor): query = '?' + query else: query = '' + # Bug: This destroys percent signs in email addresses. escaped = ['%%%02X' % ord(c) for c in addr] return 'mailto:%s%s' % (''.join(escaped), query) def cloak_email(self, addr): - return addr.replace('@', ' at ').replace('.', ' dot ') + addr = addr.replace('@', '<span>@</span>') + addr = addr.replace('.', '<span>.</span>') + return addr def attval(self, text, whitespace=re.compile('[\n\r\t\v\f]')): @@ -356,9 +360,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_Text(self, node): text = node.astext() + encoded = self.encode(text) if self.in_mailto and self.settings.cloak_email_addresses: - text = self.cloak_email(text) - self.body.append(self.encode(text)) + encoded = self.cloak_email(encoded) + self.body.append(encoded) def depart_Text(self, node): pass diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index f65f5d875..e12b15c0e 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -75,7 +75,7 @@ thing.</p> <table class="docutils footnote" frame="void" id="id2" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>PEP editors: <a class="reference" href="mailto:%70%65%70%73%40%70%79%74%68%6F%6E%2E%6F%72%67">peps at python dot org</a></td></tr> +<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>PEP editors: <a class="reference" href="mailto:%70%65%70%73%40%70%79%74%68%6F%6E%2E%6F%72%67">peps<span>@</span>python<span>.</span>org</a></td></tr> </tbody> </table> <table class="docutils footnote" frame="void" id="id3" rules="none"> -- cgit v1.2.1 From 4c9becf2db37c07284913497627b7c7a574ce30e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Jul 2005 23:08:35 +0000 Subject: encode Unicode strings only; wrapped a line git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3645 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 090231336..3c852e9f0 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -144,7 +144,8 @@ class Output(TransformSpec): raise NotImplementedError def encode(self, data): - if self.encoding and self.encoding.lower() == 'unicode': + if ( self.encoding and self.encoding.lower() == 'unicode' + or not isinstance(data, UnicodeType)): return data else: try: @@ -156,7 +157,8 @@ class Output(TransformSpec): # We are using xmlcharrefreplace with a Python # version that doesn't support it (2.1 or 2.2), so # we emulate its behavior. - return ''.join([self.xmlcharref_encode(char) for char in data]) + return ''.join([self.xmlcharref_encode(char) + for char in data]) else: raise -- cgit v1.2.1 From d04b3b06ae8404240bd8ab5cd22bebb34dfdb0f3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Jul 2005 23:08:53 +0000 Subject: revert docutils.writers.null.Writer.output to None, now with docutils.io.Output and test support git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3646 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/null.py | 2 +- test/DocutilsTestSupport.py | 20 +++++++++++++------- test/test_writers/test_null.py | 3 +-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/docutils/writers/null.py b/docutils/writers/null.py index faf7bbfad..cf3566480 100644 --- a/docutils/writers/null.py +++ b/docutils/writers/null.py @@ -20,4 +20,4 @@ class Writer(writers.Writer): config_section_dependencies = ('writers',) def translate(self): - self.output = u'' + pass diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 72d5cdbc2..c0c2c331b 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -153,13 +153,19 @@ class CustomTestCase(StandardTestCase): expected = expected.encode('raw_unicode_escape') try: self.assertEquals(output, expected) - except AssertionError: + except AssertionError, error: print >>sys.stderr, '\n%s\ninput:' % (self,) print >>sys.stderr, input - print >>sys.stderr, '-: expected\n+: output' - print >>sys.stderr, ''.join(self.compare(expected.splitlines(1), - output.splitlines(1))) - raise + try: + comparison = ''.join(self.compare(expected.splitlines(1), + output.splitlines(1))) + print >>sys.stderr, '-: expected\n+: output' + print >>sys.stderr, comparison + except AttributeError: # expected or output not a string + # alternative output for non-strings: + print >>sys.stderr, 'expected: %r' % expected + print >>sys.stderr, 'output: %r' % output + raise error def failUnlessEqual(self, first, second, msg=None): """Fail if the two objects are unequal as determined by the '==' @@ -819,8 +825,8 @@ def _format_str(*args): return_tuple = [] for i in args: r = repr(i) - if '\n' in i and (isinstance(i, StringType) or - isinstance(i, UnicodeType)): + if ( (isinstance(i, StringType) or isinstance(i, UnicodeType)) + and '\n' in i): stripped = '' if isinstance(i, UnicodeType): # stripped = 'u' or 'U' diff --git a/test/test_writers/test_null.py b/test/test_writers/test_null.py index 9f8d8fe19..da385e565 100755 --- a/test/test_writers/test_null.py +++ b/test/test_writers/test_null.py @@ -23,8 +23,7 @@ totest['basic'] = [ ["""\ This is a paragraph. """, -"""\ -"""] +None] ] if __name__ == '__main__': -- cgit v1.2.1 From a011c2922bba621c62c0651f1f9e40a8097bdd02 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Jul 2005 23:15:43 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3648 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ce106df1b..4dedde4ec 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -86,10 +86,6 @@ Changes Since 0.3.9 - Made ``xmlcharrefreplace`` the default output encoding error handler. -* docutils/writers/null.py: - - - The Null Writer now returns an empty string instead of None. - * docutils/writers/unicode_latex.py: Added to project; mapping of Unicode characters to LaTeX equivalents. -- cgit v1.2.1 From 601958dba675d1a3fc42e35b31782675cb108dce Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 2 Jul 2005 23:31:10 +0000 Subject: updated docstrings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3649 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index d36cd1795..4e262bb29 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -36,8 +36,8 @@ class Writer(Component): """The document to write (Docutils doctree); set by `write`.""" output = None - """Final translated form of `document` (Unicode string); - set by `translate`.""" + """Final translated form of `document` (Unicode string for text, binary + string for other forms); set by `translate`.""" language = None """Language module for the document; set by `write`.""" @@ -75,8 +75,8 @@ class Writer(Component): def translate(self): """ - Do final translation of `self.document` into `self.output` (Unicode - string). Called from `write`. Override in subclasses. + Do final translation of `self.document` into `self.output`. Called + from `write`. Override in subclasses. Usually done with a `docutils.nodes.NodeVisitor` subclass, in combination with a call to `docutils.nodes.Node.walk()` or -- cgit v1.2.1 From 7447045b6bd0c5099e874fa42664724b5e654384 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Jul 2005 01:15:56 +0000 Subject: better wrapping git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3650 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 15d67af51..694696f18 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -493,8 +493,8 @@ def publish_from_doctree(document, destination_path=None, # Create fresh Transformer object, to be populated from Writer component. document.transformer = Transformer(document) # Don't apply default transforms twice: - document.transformer.default_transforms = (document.transformer - .reprocess_transforms) + document.transformer.default_transforms = ( + document.transformer.reprocess_transforms) reader = docutils.readers.doctree.Reader(parser_name='null') pub = Publisher(reader, None, writer, source=io.DocTreeInput(document), -- cgit v1.2.1 From 28c3ed845373a35f47377fdf43476d73986cf8d4 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Jul 2005 08:39:39 +0000 Subject: added assertion and comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3651 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index 3c852e9f0..cfd24496c 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -67,8 +67,12 @@ class Input(TransformSpec): locale.setlocale(locale.LC_ALL, '') """ - if (self.encoding and self.encoding.lower() == 'unicode' - or isinstance(data, UnicodeType)): + if self.encoding and self.encoding.lower() == 'unicode': + assert isinstance(data, UnicodeType), ( + 'input encoding is "unicode" ' + 'but input is not a unicode object') + if isinstance(data, UnicodeType): + # Accept unicode even if self.encoding != 'unicode'. return data encodings = [self.encoding] if not self.encoding: -- cgit v1.2.1 From f68aa69a1c82b715976d82c9ed3a0b0071e49c71 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Jul 2005 08:40:17 +0000 Subject: added history entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3652 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index 4dedde4ec..d238b3750 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -35,6 +35,7 @@ Changes Since 0.3.9 * docutils/io.py: - Added ``DocTreeInput`` class, for reprocessing existing documents. + - Added support for non-Unicode (e.g. binary) writer output. * docutils/parsers/null.py: Added to project; a do-nothing parser. -- cgit v1.2.1 From da694cfd8f275688b7b4bdac01c6b3691dbf3b41 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Jul 2005 09:40:40 +0000 Subject: added assertion and comment git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3653 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docutils/io.py b/docutils/io.py index cfd24496c..91b70377e 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -148,8 +148,11 @@ class Output(TransformSpec): raise NotImplementedError def encode(self, data): - if ( self.encoding and self.encoding.lower() == 'unicode' - or not isinstance(data, UnicodeType)): + if self.encoding and self.encoding.lower() == 'unicode': + assert isinstance(data, UnicodeType), 'no unicode output' + return data + if not isinstance(data, UnicodeType): + # Non-unicode (e.g. binary) output. return data else: try: -- cgit v1.2.1 From 08851a456dbf5f4b731252e80d64c803e9b4257f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 3 Jul 2005 15:02:15 +0000 Subject: clarified assertion message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3654 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docutils/io.py b/docutils/io.py index 91b70377e..5a6672e15 100644 --- a/docutils/io.py +++ b/docutils/io.py @@ -149,7 +149,9 @@ class Output(TransformSpec): def encode(self, data): if self.encoding and self.encoding.lower() == 'unicode': - assert isinstance(data, UnicodeType), 'no unicode output' + assert isinstance(data, UnicodeType), ( + 'the encoding given is "unicode" but the output is not ' + 'a Unicode string') return data if not isinstance(data, UnicodeType): # Non-unicode (e.g. binary) output. -- cgit v1.2.1 From 94966c06ef09db664e9570ef16b9f2549c517fb7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Jul 2005 20:25:12 +0000 Subject: extended Hacker's guide git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3656 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/hacking.txt | 74 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/docs/dev/hacking.txt b/docs/dev/hacking.txt index d98823ba0..ab0c85259 100644 --- a/docs/dev/hacking.txt +++ b/docs/dev/hacking.txt @@ -1,5 +1,3 @@ -.. -*- coding: utf-8 -*- - ========================== Docutils_ Hacker's Guide ========================== @@ -51,6 +49,7 @@ While this looks very simple, it's enough to illustrate all internal processing stages of Docutils. Let's see how this document is processed from the reStructuredText source to the final HTML output: + Reading the Document -------------------- @@ -63,6 +62,7 @@ things, there is no need to change that. Since you probably won't need to touch readers, we will just move on to the next stage: + Parsing the Document -------------------- @@ -101,6 +101,7 @@ arranged as a class hierarchy (for example, both ``emphasis`` and overview of the node class hierarchy, use epydoc (type ``epydoc nodes.py``) and look at the class hierarchy tree. + Transforming the Document ------------------------- @@ -139,7 +140,7 @@ has changed after applying the Transforms, we use the For our small test document, the only change is that the ``refname`` attribute of the reference has been replaced by a ``refuri`` -attribute—the reference has been resolved. +attribute |---| the reference has been resolved. While this does not look very exciting, transforms are a powerful tool to apply any kind of transformation on the node tree. @@ -147,6 +148,7 @@ to apply any kind of transformation on the node tree. By the way, you can also get a "real" XML representation of the node tree by using ``rst2xml.py`` instead of ``rst2pseudoxml.py``. + Writing the Document -------------------- @@ -175,8 +177,8 @@ For HTML output, we can test this using the ``rst2html.py`` tool:: So here we finally have our HTML output. The actual document contents are in the fourth-last line. Note, by the way, that the HTML writer -did not render the (invisible) ``target`` node—only the ``paragraph`` -node and its children appear in the HTML output. +did not render the (invisible) ``target`` node |---| only the +``paragraph`` node and its children appear in the HTML output. Extending Docutils @@ -185,11 +187,11 @@ Extending Docutils Now you'll ask, "how do I actually extend Docutils?" First of all, once you are clear about *what* you want to achieve, you -have to decide *where* to implement it—in the Parser (e.g. by adding a -directive or role to the reStructuredText parser), as a Transform, or -in the Writer. There is often one obvious choice among those three -(Parser, Transform, Writer). If you are unsure, ask on the -Docutils-develop_ mailing list. +have to decide *where* to implement it |---| in the Parser (e.g. by +adding a directive or role to the reStructuredText parser), as a +Transform, or in the Writer. There is often one obvious choice among +those three (Parser, Transform, Writer). If you are unsure, ask on +the Docutils-develop_ mailing list. In order to find out how to start, it is often helpful to look at similar features which are already implemented. For example, if you @@ -198,6 +200,45 @@ the implementation of a similar directive in ``docutils/parsers/rst/directives/``. +Modifying the Document Tree Before It Is Written +------------------------------------------------ + +You can modify the document tree right before the writer is called. +One possibility is to use the publish_doctree_ and +publish_from_doctree_ functions. + +To retrieve the document tree, call:: + + document = docutils.core.publish_doctree(...) + +Please see the docstring of publish_doctree for a list of parameters. + +.. XXX Need to write a well-readable list of (commonly used) options + of the publish_* functions. Probably in api/publisher.txt. + +``document`` is the root node of the document tree. You can now +change the document by accessing the ``document`` node and its +children |---| see `The Node Interface`_ below. + +When you're done with modifying the document tree, you can write it +out by calling:: + + output = docutils.core.publish_from_doctree(document, ...) + +.. _publish_doctree: ../api/publisher.html#publish_doctree +.. _publish_from_doctree: ../api/publisher.html#publish_from_doctree + + +The Node Interface +------------------ + +As described in the overview above, Docutils' internal representation +of a document is a tree of nodes. We'll now have a look at the +interface of these nodes. + +(To be completed.) + + What Now? ========= @@ -208,3 +249,16 @@ on the Docutils-develop_ mailing list. .. _Docutils-develop: ../user/mailing-lists.html#docutils-develop + + +.. |---| unicode:: 8212 .. em-dash + :trim: + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: -- cgit v1.2.1 From 2703f7c25b10c10f59db93e0776cb81c1d181bca Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Jul 2005 20:29:55 +0000 Subject: moved transition transform logic from universal.FinalChecks to a separate transform, misc.Transitions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3657 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/transforms.txt | 2 + docutils/readers/standalone.py | 6 +- docutils/transforms/misc.py | 75 ++++++++ docutils/transforms/universal.py | 86 +-------- test/test_transforms/test_final_checks.py | 282 --------------------------- test/test_transforms/test_transitions.py | 308 ++++++++++++++++++++++++++++++ 6 files changed, 394 insertions(+), 365 deletions(-) create mode 100755 test/test_transforms/test_transitions.py diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 7bdcee1de..28b9c002f 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -71,6 +71,8 @@ components.Filter "meta" (d/p) 780 universal.Decorations Transformer 820 +misc.Transitions standalone (r) 830 + universal.FinalChecks Transformer 840 universal.Messages Transformer 860 diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index c7772aa48..930aa2bbb 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import frontend, readers -from docutils.transforms import frontmatter, references +from docutils.transforms import frontmatter, references, misc class Reader(readers.Reader): @@ -61,4 +61,6 @@ class Reader(readers.Reader): references.IndirectHyperlinks, references.Footnotes, references.ExternalTargets, - references.InternalTargets,) + references.InternalTargets, + misc.Transitions, + ) diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index fb01c6c72..eb50a1124 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -67,3 +67,78 @@ class ClassAttribute(Transform): nodes.literal_block(pending.rawsource, pending.rawsource), line=pending.line) pending.parent.replace(pending, error) + + +class Transitions(Transform): + + default_priority = 830 + + def apply(self): + for node in self.document.traverse(nodes.transition): + self.visit_transition(node) + + def visit_transition(self, node): + """ + 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> + ... + """ + 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.', + 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.', 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/universal.py b/docutils/transforms/universal.py index 75dadd7bf..53ddde878 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -160,8 +160,11 @@ class FinalChecks(Transform): self.document.transformer.unknown_reference_resolvers) self.document.walk(visitor) if self.document.settings.expose_internals: - visitor = InternalAttributeExposer(self.document) - self.document.walk(visitor) + for node in self.document.traverse(): + for att in self.document.settings.expose_internals: + value = getattr(node, att, None) + if value is not None: + node['internal:' + att] = value # *After* resolving all references, check for unreferenced # targets: for target in self.document.traverse(nodes.target): @@ -220,82 +223,3 @@ class FinalCheckVisitor(nodes.SparseNodeVisitor): node.resolved = 1 visit_footnote_reference = visit_citation_reference = visit_reference - - def visit_transition(self, node): - """ - 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> - ... - """ - 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.', - 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.', 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) - - -class InternalAttributeExposer(nodes.GenericNodeVisitor): - - def __init__(self, document): - nodes.GenericNodeVisitor.__init__(self, document) - self.internal_attributes = document.settings.expose_internals - - def default_visit(self, node): - for att in self.internal_attributes: - value = getattr(node, att, None) - if value is not None: - node['internal:' + att] = value diff --git a/test/test_transforms/test_final_checks.py b/test/test_transforms/test_final_checks.py index 4d8a4ef88..4d58b8dbc 100755 --- a/test/test_transforms/test_final_checks.py +++ b/test/test_transforms/test_final_checks.py @@ -72,288 +72,6 @@ Duplicate manual footnote labels, with reference ([1]_): ]) -# See DocutilsTestSupport.ParserTestSuite.generateTests for a -# description of the 'totest' data structure. -totest['transitions'] = ((FinalChecks,), [ -["""\ -Section 1 -========= - -Subsection 1 ------------- - -Some text. - ----------- - -Section 2 -========= - -Some text. -""", -"""\ -<document source="test data"> - <section ids="section-1" names="section 1"> - <title> - Section 1 - <section ids="subsection-1" names="subsection 1"> - <title> - Subsection 1 - <paragraph> - Some text. - <transition> - <section ids="section-2" names="section 2"> - <title> - Section 2 - <paragraph> - Some text. -"""], -["""\ -A paragraph. - ----------- - -Section 1 -========= - -Paragraph. -""", -"""\ -<document source="test data"> - <paragraph> - A paragraph. - <transition> - <section ids="section-1" names="section 1"> - <title> - Section 1 - <paragraph> - Paragraph. -"""], -["""\ --------- - -A section or document may not begin with a transition. - -The DTD specifies that two transitions may not -be adjacent: - --------- - --------- - --------- - -The DTD also specifies that a section or document -may not end with a transition. - --------- -""", -"""\ -<document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <paragraph> - A section or document may not begin with a transition. - <paragraph> - The DTD specifies that two transitions may not - be adjacent: - <transition> - <system_message level="3" line="10" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="12" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <paragraph> - The DTD also specifies that a section or document - may not end with a transition. - <transition> - <system_message level="3" line="17" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -["""\ -Sections with transitions at beginning and end. - -Section 1 -========= - ----------- - -The next transition is legal: - ----------- - -Section 2 -========= - ----------- -""", -"""\ -<document source="test data"> - <paragraph> - Sections with transitions at beginning and end. - <section ids="section-1" names="section 1"> - <title> - Section 1 - <system_message level="3" line="6" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <paragraph> - The next transition is legal: - <transition> - <section ids="section-2" names="section 2"> - <title> - Section 2 - <system_message level="3" line="15" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <system_message level="3" line="15" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -["""\ -A paragraph and two transitions. - ----------- - ----------- -""", # the same: -"""\ -<document source="test data"> - <paragraph> - A paragraph and two transitions. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -["""\ -A paragraph, two transitions, and a blank line. - ----------- - ----------- - -""", -"""\ -<document source="test data"> - <paragraph> - A paragraph, two transitions, and a blank line. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -["""\ ----------- - -Document beginning with a transition. -""", -"""\ -<document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <paragraph> - Document beginning with a transition. -"""], -["""\ -Section 1 -========= - ----------- - ----------- - ----------- - -Section 2 -========= - -Some text. -""", -"""\ -<document source="test data"> - <section ids="section-1" names="section 1"> - <title> - Section 1 - <system_message level="3" line="4" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <system_message level="3" line="6" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="8" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <section ids="section-2" names="section 2"> - <title> - Section 2 - <paragraph> - Some text. -"""], -["""\ ----------- - ----------- - ----------- -""", -"""\ -<document source="test data"> - <system_message level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Document or section may not begin with a transition. - <transition> - <system_message level="3" line="3" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - At least one body element must separate transitions; adjacent transitions are not allowed. - <transition> - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -["""\ -A paragraph. - ----------- - -""", -"""\ -<document source="test data"> - <paragraph> - A paragraph. - <transition> - <system_message level="3" line="3" source="test data" type="ERROR"> - <paragraph> - Document may not end with a transition. -"""], -]) - - if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') diff --git a/test/test_transforms/test_transitions.py b/test/test_transforms/test_transitions.py new file mode 100755 index 000000000..9711c4aee --- /dev/null +++ b/test/test_transforms/test_transitions.py @@ -0,0 +1,308 @@ +#! /usr/bin/env python + +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for transforms/__init__.py. +""" + +from docutils.transforms.misc import Transitions +from __init__ import DocutilsTestSupport +from docutils.parsers.rst import Parser + +def suite(): + parser = Parser() + s = DocutilsTestSupport.TransformTestSuite(parser) + s.generateTests(totest) + return s + + +totest = {} + +totest['transitions'] = ((Transitions,), [ +["""\ +Section 1 +========= + +Subsection 1 +------------ + +Some text. + +---------- + +Section 2 +========= + +Some text. +""", +"""\ +<document source="test data"> + <section ids="section-1" names="section 1"> + <title> + Section 1 + <section ids="subsection-1" names="subsection 1"> + <title> + Subsection 1 + <paragraph> + Some text. + <transition> + <section ids="section-2" names="section 2"> + <title> + Section 2 + <paragraph> + Some text. +"""], +["""\ +A paragraph. + +---------- + +Section 1 +========= + +Paragraph. +""", +"""\ +<document source="test data"> + <paragraph> + A paragraph. + <transition> + <section ids="section-1" names="section 1"> + <title> + Section 1 + <paragraph> + Paragraph. +"""], +["""\ +-------- + +A section or document may not begin with a transition. + +The DTD specifies that two transitions may not +be adjacent: + +-------- + +-------- + +-------- + +The DTD also specifies that a section or document +may not end with a transition. + +-------- +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <paragraph> + A section or document may not begin with a transition. + <paragraph> + The DTD specifies that two transitions may not + be adjacent: + <transition> + <system_message level="3" line="10" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="12" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <paragraph> + The DTD also specifies that a section or document + may not end with a transition. + <transition> + <system_message level="3" line="17" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +["""\ +Sections with transitions at beginning and end. + +Section 1 +========= + +---------- + +The next transition is legal: + +---------- + +Section 2 +========= + +---------- +""", +"""\ +<document source="test data"> + <paragraph> + Sections with transitions at beginning and end. + <section ids="section-1" names="section 1"> + <title> + Section 1 + <system_message level="3" line="6" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <paragraph> + The next transition is legal: + <transition> + <section ids="section-2" names="section 2"> + <title> + Section 2 + <system_message level="3" line="15" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <system_message level="3" line="15" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +["""\ +A paragraph and two transitions. + +---------- + +---------- +""", # the same: +"""\ +<document source="test data"> + <paragraph> + A paragraph and two transitions. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +["""\ +A paragraph, two transitions, and a blank line. + +---------- + +---------- + +""", +"""\ +<document source="test data"> + <paragraph> + A paragraph, two transitions, and a blank line. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +["""\ +---------- + +Document beginning with a transition. +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <paragraph> + Document beginning with a transition. +"""], +["""\ +Section 1 +========= + +---------- + +---------- + +---------- + +Section 2 +========= + +Some text. +""", +"""\ +<document source="test data"> + <section ids="section-1" names="section 1"> + <title> + Section 1 + <system_message level="3" line="4" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <system_message level="3" line="6" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="8" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <section ids="section-2" names="section 2"> + <title> + Section 2 + <paragraph> + Some text. +"""], +["""\ +---------- + +---------- + +---------- +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Document or section may not begin with a transition. + <transition> + <system_message level="3" line="3" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + At least one body element must separate transitions; adjacent transitions are not allowed. + <transition> + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +["""\ +A paragraph. + +---------- + +""", +"""\ +<document source="test data"> + <paragraph> + A paragraph. + <transition> + <system_message level="3" line="3" source="test data" type="ERROR"> + <paragraph> + Document may not end with a transition. +"""], +]) + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From e0a1eaac9d47da79a00c92c74ef7e789464421b7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Jul 2005 23:14:55 +0000 Subject: moved expose_internals logic out of FinalChecks into a separate transform, universal.ExposeInternals git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3658 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/transforms.txt | 4 ++- docutils/transforms/__init__.py | 1 + docutils/transforms/misc.py | 43 ++++++++++++++------------- docutils/transforms/universal.py | 25 +++++++++++----- test/test_transforms/test_expose_internals.py | 41 +++++++++++++++++++++++++ test/test_transforms/test_transitions.py | 2 +- 6 files changed, 86 insertions(+), 30 deletions(-) create mode 100755 test/test_transforms/test_expose_internals.py diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 28b9c002f..9468619fd 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -73,7 +73,9 @@ universal.Decorations Transformer 820 misc.Transitions standalone (r) 830 -universal.FinalChecks Transformer 840 +universal.ExposeInternals Transformer 840 + +universal.FinalChecks Transformer 850 universal.Messages Transformer 860 diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 6039e1a63..25c690f66 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -75,6 +75,7 @@ class Transformer(TransformSpec): from docutils.transforms import universal default_transforms = (universal.Decorations, + universal.ExposeInternals, universal.FinalChecks, universal.Messages, universal.FilterMessages) diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index eb50a1124..fd8ba6b25 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -71,6 +71,28 @@ class ClassAttribute(Transform): 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): @@ -78,27 +100,6 @@ class Transitions(Transform): self.visit_transition(node) def visit_transition(self, node): - """ - 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> - ... - """ index = node.parent.index(node) error = None if (index == 0 or diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 53ddde878..1918016fc 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -143,6 +143,23 @@ class TestMessages(Transform): self.document += msg +class ExposeInternals(Transform): + + """ + Expose internal attributes if ``expose_internals`` setting is set. + """ + + default_priority = 840 + + def apply(self): + if self.document.settings.expose_internals: + for node in self.document.traverse(): + for att in self.document.settings.expose_internals: + value = getattr(node, att, None) + if value is not None: + node['internal:' + att] = value + + class FinalChecks(Transform): """ @@ -152,19 +169,13 @@ class FinalChecks(Transform): - Check for illegal transitions, move transitions. """ - default_priority = 840 + default_priority = 850 def apply(self): visitor = FinalCheckVisitor( self.document, self.document.transformer.unknown_reference_resolvers) self.document.walk(visitor) - if self.document.settings.expose_internals: - for node in self.document.traverse(): - for att in self.document.settings.expose_internals: - value = getattr(node, att, None) - if value is not None: - node['internal:' + att] = value # *After* resolving all references, check for unreferenced # targets: for target in self.document.traverse(nodes.target): diff --git a/test/test_transforms/test_expose_internals.py b/test/test_transforms/test_expose_internals.py new file mode 100755 index 000000000..37747a68b --- /dev/null +++ b/test/test_transforms/test_expose_internals.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for universal.ExposeInternals transform. +""" + + +from docutils.transforms.universal import ExposeInternals +from __init__ import DocutilsTestSupport +from docutils.parsers.rst import Parser + +def suite(): + parser = Parser() + s = DocutilsTestSupport.TransformTestSuite(parser) + s.generateTests(totest) + return s + + +totest = {} + +totest['transitions'] = ((ExposeInternals,), [ +["""\ +This is a test. +""", +"""\ +[Test disabled at the moment. How do we activate the expose_internals +setting for this test suite?] +""", +0], +]) + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/test/test_transforms/test_transitions.py b/test/test_transforms/test_transitions.py index 9711c4aee..24a69bb52 100755 --- a/test/test_transforms/test_transitions.py +++ b/test/test_transforms/test_transitions.py @@ -7,7 +7,7 @@ # Copyright: This module has been placed in the public domain. """ -Test module for transforms/__init__.py. +Test module for misc.Transitions transform. """ from docutils.transforms.misc import Transitions -- cgit v1.2.1 From 88b1bd28140150e41265cd8a84b5d0ee55f05138 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 5 Jul 2005 23:36:14 +0000 Subject: renamed universal.FinalChecks to references.DanglingReferences; changed priority to 680 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3659 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/transforms.txt | 6 +- docutils/readers/pep.py | 7 +- docutils/readers/standalone.py | 1 + docutils/transforms/__init__.py | 4 +- docutils/transforms/references.py | 74 ++++++++ docutils/transforms/universal.py | 76 --------- .../expected/standalone_rst_html4css1.html | 186 ++++++++++----------- .../expected/standalone_rst_pseudoxml.txt | 178 ++++++++++---------- test/test_transforms/test_final_checks.py | 77 --------- test/test_transforms/test_hyperlinks.py | 52 +++++- 10 files changed, 314 insertions(+), 347 deletions(-) delete mode 100755 test/test_transforms/test_final_checks.py diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 9468619fd..cd9cf3fe8 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -60,6 +60,8 @@ references.ExternalTargets standalone (r), pep (r) 640 references.InternalTargets standalone (r), pep (r) 660 +references.DanglingReferences standalone (r), pep (r) 680 + parts.SectNum "sectnum" (d/p) 710 parts.Contents "contents" (d/p), 720 @@ -71,12 +73,10 @@ components.Filter "meta" (d/p) 780 universal.Decorations Transformer 820 -misc.Transitions standalone (r) 830 +misc.Transitions standalone (r), pep (r) 830 universal.ExposeInternals Transformer 840 -universal.FinalChecks Transformer 850 - universal.Messages Transformer 860 universal.FilterMessages Transformer 870 diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index b2326666f..3f2fc66cb 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' from docutils.readers import standalone -from docutils.transforms import peps, references +from docutils.transforms import peps, references, misc from docutils.parsers import rst @@ -39,7 +39,10 @@ class Reader(standalone.Reader): peps.TargetNotes, references.Footnotes, references.ExternalTargets, - references.InternalTargets,) + references.InternalTargets, + references.DanglingReferences, + misc.Transitions, + ) settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 930aa2bbb..1f5bd9dfc 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -62,5 +62,6 @@ class Reader(readers.Reader): references.Footnotes, references.ExternalTargets, references.InternalTargets, + references.DanglingReferences, misc.Transitions, ) diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 25c690f66..e575f42be 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -76,13 +76,11 @@ class Transformer(TransformSpec): default_transforms = (universal.Decorations, universal.ExposeInternals, - universal.FinalChecks, universal.Messages, universal.FilterMessages) """These transforms are applied to all document trees.""" - reprocess_transforms = (universal.FinalChecks, - universal.Messages, + reprocess_transforms = (universal.Messages, universal.FilterMessages) """This set of transforms is a suggested replacement for `default_transforms` when reprocessing a document tree.""" diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index cce95e3cb..a7e038809 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -773,6 +773,80 @@ class TargetNotes(Transform): return footnote +class DanglingReferences(Transform): + + """ + Check for dangling references (incl. footnote & citation) and for + unreferenced targets. + """ + + default_priority = 680 + + 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['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 self.document.nameids.has_key(refname): + msg = self.document.reporter.error( + 'Duplicate target name, cannot be used as a unique ' + 'reference: "%s".' % (node['refname']), base_node=node) + else: + msg = self.document.reporter.error( + 'Unknown target name: "%s".' % (node['refname']), + base_node=node) + msgid = self.document.set_id(msg) + prb = nodes.problematic( + node.rawsource, node.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + node.parent.replace(node, prb) + else: + del node['refname'] + node['refid'] = id + self.document.ids[id].note_referenced_by(id=id) + node.resolved = 1 + + visit_footnote_reference = visit_citation_reference = visit_reference + + def uniq(L): r = [] for item in L: diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 1918016fc..b28e8f06b 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -158,79 +158,3 @@ class ExposeInternals(Transform): value = getattr(node, att, None) if value is not None: node['internal:' + att] = value - - -class FinalChecks(Transform): - - """ - Perform last-minute checks and transforms. - - - Check for dangling references (incl. footnote & citation). - - Check for illegal transitions, move transitions. - """ - - default_priority = 850 - - def apply(self): - visitor = FinalCheckVisitor( - 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['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 FinalCheckVisitor(nodes.SparseNodeVisitor): - - def __init__(self, document, unknown_reference_resolvers): - nodes.SparseNodeVisitor.__init__(self, document) - self.document = document - self.unknown_reference_resolvers = unknown_reference_resolvers - - def unknown_visit(self, node): - pass - - 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 self.document.nameids.has_key(refname): - msg = self.document.reporter.error( - 'Duplicate target name, cannot be used as a unique ' - 'reference: "%s".' % (node['refname']), base_node=node) - else: - msg = self.document.reporter.error( - 'Unknown target name: "%s".' % (node['refname']), - base_node=node) - msgid = self.document.set_id(msg) - prb = nodes.problematic( - node.rawsource, node.rawsource, refid=msgid) - prbid = self.document.set_id(prb) - msg.add_backref(prbid) - node.parent.replace(node, prb) - else: - del node['refname'] - node['refid'] = id - self.document.ids[id].note_referenced_by(id=id) - node.resolved = 1 - - visit_footnote_reference = visit_citation_reference = visit_reference diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index e624dacb0..7e4c91546 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -88,67 +88,67 @@ They are transformed from section titles after parsing. --> <div class="contents topic" id="table-of-contents"> <p class="topic-title first"><a name="table-of-contents">Table of Contents</a></p> <ul class="auto-toc simple"> -<li><a class="reference" href="#structural-elements" id="id25" name="id25">1   Structural Elements</a><ul class="auto-toc"> -<li><a class="reference" href="#section-title" id="id26" name="id26">1.1   Section Title</a></li> -<li><a class="reference" href="#empty-section" id="id27" name="id27">1.2   Empty Section</a></li> -<li><a class="reference" href="#transitions" id="id28" name="id28">1.3   Transitions</a></li> +<li><a class="reference" href="#structural-elements" id="id33" name="id33">1   Structural Elements</a><ul class="auto-toc"> +<li><a class="reference" href="#section-title" id="id34" name="id34">1.1   Section Title</a></li> +<li><a class="reference" href="#empty-section" id="id35" name="id35">1.2   Empty Section</a></li> +<li><a class="reference" href="#transitions" id="id36" name="id36">1.3   Transitions</a></li> </ul> </li> -<li><a class="reference" href="#body-elements" id="id29" name="id29">2   Body Elements</a><ul class="auto-toc"> -<li><a class="reference" href="#paragraphs" id="id30" name="id30">2.1   Paragraphs</a><ul class="auto-toc"> -<li><a class="reference" href="#inline-markup" id="id31" name="id31">2.1.1   Inline Markup</a></li> +<li><a class="reference" href="#body-elements" id="id37" name="id37">2   Body Elements</a><ul class="auto-toc"> +<li><a class="reference" href="#paragraphs" id="id38" name="id38">2.1   Paragraphs</a><ul class="auto-toc"> +<li><a class="reference" href="#inline-markup" id="id39" name="id39">2.1.1   Inline Markup</a></li> </ul> </li> -<li><a class="reference" href="#bullet-lists" id="id32" name="id32">2.2   Bullet Lists</a></li> -<li><a class="reference" href="#enumerated-lists" id="id33" name="id33">2.3   Enumerated Lists</a></li> -<li><a class="reference" href="#definition-lists" id="id34" name="id34">2.4   Definition Lists</a></li> -<li><a class="reference" href="#field-lists" id="id35" name="id35">2.5   Field Lists</a></li> -<li><a class="reference" href="#option-lists" id="id36" name="id36">2.6   Option Lists</a></li> -<li><a class="reference" href="#literal-blocks" id="id37" name="id37">2.7   Literal Blocks</a></li> -<li><a class="reference" href="#line-blocks" id="id38" name="id38">2.8   Line Blocks</a></li> -<li><a class="reference" href="#block-quotes" id="id39" name="id39">2.9   Block Quotes</a></li> -<li><a class="reference" href="#doctest-blocks" id="id40" name="id40">2.10   Doctest Blocks</a></li> -<li><a class="reference" href="#footnotes" id="id41" name="id41">2.11   Footnotes</a></li> -<li><a class="reference" href="#citations" id="id42" name="id42">2.12   Citations</a></li> -<li><a class="reference" href="#targets" id="id43" name="id43">2.13   Targets</a><ul class="auto-toc"> -<li><a class="reference" href="#duplicate-target-names" id="id44" name="id44">2.13.1   Duplicate Target Names</a></li> -<li><a class="reference" href="#id18" id="id45" name="id45">2.13.2   Duplicate Target Names</a></li> +<li><a class="reference" href="#bullet-lists" id="id40" name="id40">2.2   Bullet Lists</a></li> +<li><a class="reference" href="#enumerated-lists" id="id41" name="id41">2.3   Enumerated Lists</a></li> +<li><a class="reference" href="#definition-lists" id="id42" name="id42">2.4   Definition Lists</a></li> +<li><a class="reference" href="#field-lists" id="id43" name="id43">2.5   Field Lists</a></li> +<li><a class="reference" href="#option-lists" id="id44" name="id44">2.6   Option Lists</a></li> +<li><a class="reference" href="#literal-blocks" id="id45" name="id45">2.7   Literal Blocks</a></li> +<li><a class="reference" href="#line-blocks" id="id46" name="id46">2.8   Line Blocks</a></li> +<li><a class="reference" href="#block-quotes" id="id47" name="id47">2.9   Block Quotes</a></li> +<li><a class="reference" href="#doctest-blocks" id="id48" name="id48">2.10   Doctest Blocks</a></li> +<li><a class="reference" href="#footnotes" id="id49" name="id49">2.11   Footnotes</a></li> +<li><a class="reference" href="#citations" id="id50" name="id50">2.12   Citations</a></li> +<li><a class="reference" href="#targets" id="id51" name="id51">2.13   Targets</a><ul class="auto-toc"> +<li><a class="reference" href="#duplicate-target-names" id="id52" name="id52">2.13.1   Duplicate Target Names</a></li> +<li><a class="reference" href="#id18" id="id53" name="id53">2.13.2   Duplicate Target Names</a></li> </ul> </li> -<li><a class="reference" href="#directives" id="id46" name="id46">2.14   Directives</a><ul class="auto-toc"> -<li><a class="reference" href="#document-parts" id="id47" name="id47">2.14.1   Document Parts</a></li> -<li><a class="reference" href="#images" id="id48" name="id48">2.14.2   Images</a></li> -<li><a class="reference" href="#admonitions" id="id49" name="id49">2.14.3   Admonitions</a></li> -<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id50" name="id50">2.14.4   Topics, Sidebars, and Rubrics</a></li> -<li><a class="reference" href="#target-footnotes" id="id51" name="id51">2.14.5   Target Footnotes</a></li> -<li><a class="reference" href="#replacement-text" id="id52" name="id52">2.14.6   Replacement Text</a></li> -<li><a class="reference" href="#compound-paragraph" id="id53" name="id53">2.14.7   Compound Paragraph</a></li> +<li><a class="reference" href="#directives" id="id54" name="id54">2.14   Directives</a><ul class="auto-toc"> +<li><a class="reference" href="#document-parts" id="id55" name="id55">2.14.1   Document Parts</a></li> +<li><a class="reference" href="#images" id="id56" name="id56">2.14.2   Images</a></li> +<li><a class="reference" href="#admonitions" id="id57" name="id57">2.14.3   Admonitions</a></li> +<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id58" name="id58">2.14.4   Topics, Sidebars, and Rubrics</a></li> +<li><a class="reference" href="#target-footnotes" id="id59" name="id59">2.14.5   Target Footnotes</a></li> +<li><a class="reference" href="#replacement-text" id="id60" name="id60">2.14.6   Replacement Text</a></li> +<li><a class="reference" href="#compound-paragraph" id="id61" name="id61">2.14.7   Compound Paragraph</a></li> </ul> </li> -<li><a class="reference" href="#substitution-definitions" id="id54" name="id54">2.15   Substitution Definitions</a></li> -<li><a class="reference" href="#comments" id="id55" name="id55">2.16   Comments</a></li> -<li><a class="reference" href="#raw-text" id="id56" name="id56">2.17   Raw text</a></li> -<li><a class="reference" href="#colspanning-tables" id="id57" name="id57">2.18   Colspanning tables</a></li> -<li><a class="reference" href="#rowspanning-tables" id="id58" name="id58">2.19   Rowspanning tables</a></li> -<li><a class="reference" href="#complex-tables" id="id59" name="id59">2.20   Complex tables</a></li> -<li><a class="reference" href="#list-tables" id="id60" name="id60">2.21   List Tables</a></li> +<li><a class="reference" href="#substitution-definitions" id="id62" name="id62">2.15   Substitution Definitions</a></li> +<li><a class="reference" href="#comments" id="id63" name="id63">2.16   Comments</a></li> +<li><a class="reference" href="#raw-text" id="id64" name="id64">2.17   Raw text</a></li> +<li><a class="reference" href="#colspanning-tables" id="id65" name="id65">2.18   Colspanning tables</a></li> +<li><a class="reference" href="#rowspanning-tables" id="id66" name="id66">2.19   Rowspanning tables</a></li> +<li><a class="reference" href="#complex-tables" id="id67" name="id67">2.20   Complex tables</a></li> +<li><a class="reference" href="#list-tables" id="id68" name="id68">2.21   List Tables</a></li> </ul> </li> -<li><a class="reference" href="#error-handling" id="id61" name="id61">3   Error Handling</a></li> +<li><a class="reference" href="#error-handling" id="id69" name="id69">3   Error Handling</a></li> </ul> </div> <div class="section" id="structural-elements"> -<h1><a class="toc-backref" href="#id25" name="structural-elements">1   Structural Elements</a></h1> +<h1><a class="toc-backref" href="#id33" name="structural-elements">1   Structural Elements</a></h1> <div class="section" id="section-title"> -<h2 class="with-subtitle"><a class="toc-backref" href="#id26" name="section-title">1.1   Section Title</a></h2> +<h2 class="with-subtitle"><a class="toc-backref" href="#id34" name="section-title">1.1   Section Title</a></h2> <h2 class="section-subtitle" id="section-subtitle"><span class="section-subtitle">Section Subtitle</span></h2> <p>That's it, the text just above this line.</p> </div> <div class="section" id="empty-section"> -<h2><a class="toc-backref" href="#id27" name="empty-section">1.2   Empty Section</a></h2> +<h2><a class="toc-backref" href="#id35" name="empty-section">1.2   Empty Section</a></h2> </div> <div class="section" id="transitions"> -<h2><a class="toc-backref" href="#id28" name="transitions">1.3   Transitions</a></h2> +<h2><a class="toc-backref" href="#id36" name="transitions">1.3   Transitions</a></h2> <p>Here's a transition:</p> <hr class="docutils" /> <p>It divides the section. Transitions may also occur between sections:</p> @@ -156,12 +156,12 @@ They are transformed from section titles after parsing. --> </div> <hr class="docutils" /> <div class="section" id="body-elements"> -<h1><a class="toc-backref" href="#id29" name="body-elements">2   Body Elements</a></h1> +<h1><a class="toc-backref" href="#id37" name="body-elements">2   Body Elements</a></h1> <div class="section" id="paragraphs"> -<h2><a class="toc-backref" href="#id30" name="paragraphs">2.1   Paragraphs</a></h2> +<h2><a class="toc-backref" href="#id38" name="paragraphs">2.1   Paragraphs</a></h2> <p>A paragraph.</p> <div class="section" id="inline-markup"> -<h3><a class="toc-backref" href="#id31" name="inline-markup">2.1.1   Inline Markup</a></h3> +<h3><a class="toc-backref" href="#id39" name="inline-markup">2.1.1   Inline Markup</a></h3> <p>Paragraphs contain text and may contain inline markup: <em>emphasis</em>, <strong>strong emphasis</strong>, <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literals</span></tt>, standalone hyperlinks (<a class="reference" href="http://www.python.org">http://www.python.org</a>), external hyperlinks (<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id21" id="id22" name="id22">[5]</a>), internal @@ -192,7 +192,7 @@ live link to PEP 258 here.</p> </div> </div> <div class="section" id="bullet-lists"> -<h2><a class="toc-backref" href="#id32" name="bullet-lists">2.2   Bullet Lists</a></h2> +<h2><a class="toc-backref" href="#id40" name="bullet-lists">2.2   Bullet Lists</a></h2> <ul> <li><p class="first">A bullet list</p> <ul class="simple"> @@ -217,7 +217,7 @@ live link to PEP 258 here.</p> </ul> </div> <div class="section" id="enumerated-lists"> -<h2><a class="toc-backref" href="#id33" name="enumerated-lists">2.3   Enumerated Lists</a></h2> +<h2><a class="toc-backref" href="#id41" name="enumerated-lists">2.3   Enumerated Lists</a></h2> <ol class="arabic"> <li><p class="first">Arabic numerals.</p> <ol class="loweralpha simple"> @@ -250,7 +250,7 @@ live link to PEP 258 here.</p> </ol> </div> <div class="section" id="definition-lists"> -<h2><a class="toc-backref" href="#id34" name="definition-lists">2.4   Definition Lists</a></h2> +<h2><a class="toc-backref" href="#id42" name="definition-lists">2.4   Definition Lists</a></h2> <dl class="docutils"> <dt>Term</dt> <dd>Definition</dd> @@ -265,7 +265,7 @@ live link to PEP 258 here.</p> </dl> </div> <div class="section" id="field-lists"> -<h2><a class="toc-backref" href="#id35" name="field-lists">2.5   Field Lists</a></h2> +<h2><a class="toc-backref" href="#id43" name="field-lists">2.5   Field Lists</a></h2> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> @@ -288,7 +288,7 @@ doesn't get stripped away.)</p> </table> </div> <div class="section" id="option-lists"> -<h2><a class="toc-backref" href="#id36" name="option-lists">2.6   Option Lists</a></h2> +<h2><a class="toc-backref" href="#id44" name="option-lists">2.6   Option Lists</a></h2> <p>For listing command-line options:</p> <table class="docutils option-list" frame="void" rules="none"> <col class="option" /> @@ -334,7 +334,7 @@ regardless of where it starts.</p> description.</p> </div> <div class="section" id="literal-blocks"> -<h2><a class="toc-backref" href="#id37" name="literal-blocks">2.7   Literal Blocks</a></h2> +<h2><a class="toc-backref" href="#id45" name="literal-blocks">2.7   Literal Blocks</a></h2> <p>Literal blocks are indicated with a double-colon ("::") at the end of the preceding paragraph (over there <tt class="docutils literal"><span class="pre">--></span></tt>). They can be indented:</p> <pre class="literal-block"> @@ -351,7 +351,7 @@ if literal_block: </pre> </div> <div class="section" id="line-blocks"> -<h2><a class="toc-backref" href="#id38" name="line-blocks">2.8   Line Blocks</a></h2> +<h2><a class="toc-backref" href="#id46" name="line-blocks">2.8   Line Blocks</a></h2> <p>This section tests line blocks. Line blocks are body elements which consist of lines and other line blocks. Nested line blocks cause indentation.</p> @@ -410,7 +410,7 @@ the left edge of the text above it.</div> </blockquote> </div> <div class="section" id="block-quotes"> -<h2><a class="toc-backref" href="#id39" name="block-quotes">2.9   Block Quotes</a></h2> +<h2><a class="toc-backref" href="#id47" name="block-quotes">2.9   Block Quotes</a></h2> <p>Block quotes consist of indented body elements:</p> <blockquote> <p>My theory by A. Elk. Brackets Miss, brackets. This theory goes @@ -422,7 +422,7 @@ own it, and what it is too.</p> </blockquote> </div> <div class="section" id="doctest-blocks"> -<h2><a class="toc-backref" href="#id40" name="doctest-blocks">2.10   Doctest Blocks</a></h2> +<h2><a class="toc-backref" href="#id48" name="doctest-blocks">2.10   Doctest Blocks</a></h2> <pre class="doctest-block"> >>> print 'Python-specific usage examples; begun with ">>>"' Python-specific usage examples; begun with ">>>" @@ -431,7 +431,7 @@ Python-specific usage examples; begun with ">>>" </pre> </div> <div class="section" id="footnotes"> -<h2><a class="toc-backref" href="#id41" name="footnotes">2.11   Footnotes</a></h2> +<h2><a class="toc-backref" href="#id49" name="footnotes">2.11   Footnotes</a></h2> <table class="docutils footnote" frame="void" id="id6" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -478,12 +478,12 @@ Here's a reference to the next footnote: <a class="footnote-reference" href="#id <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a name="id13">[4]</a></td><td>Here's an unreferenced footnote, with a reference to a -nonexistent footnote: <a href="#id69" name="id70"><span class="problematic" id="id70">[5]_</span></a>.</td></tr> +nonexistent footnote: <a href="#id25" name="id26"><span class="problematic" id="id26">[5]_</span></a>.</td></tr> </tbody> </table> </div> <div class="section" id="citations"> -<h2><a class="toc-backref" href="#id42" name="citations">2.12   Citations</a></h2> +<h2><a class="toc-backref" href="#id50" name="citations">2.12   Citations</a></h2> <table class="docutils citation" frame="void" id="cit2002" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -491,11 +491,11 @@ nonexistent footnote: <a href="#id69" name="id70"><span class="problematic" id=" rendered separately and differently from footnotes.</td></tr> </tbody> </table> -<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id71" name="id72"><span class="problematic" id="id72">[nonexistent]_</span></a> +<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id27" name="id28"><span class="problematic" id="id28">[nonexistent]_</span></a> citation.</p> </div> <div class="section" id="targets"> -<span id="another-target"></span><h2><a class="toc-backref" href="#id43" name="targets">2.13   Targets</a></h2> +<span id="another-target"></span><h2><a class="toc-backref" href="#id51" name="targets">2.13   Targets</a></h2> <p id="example">This paragraph is pointed to by the explicit "example" target. A reference can be found under <a class="reference" href="#inline-markup">Inline Markup</a>, above. <a class="reference" href="#inline-hyperlink-targets">Inline hyperlink targets</a> are also possible.</p> @@ -505,45 +505,45 @@ hyperlink targets</a> are also possible.</p> "<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id21" id="id23" name="id23">[5]</a>".</p> <p>Targets may be indirect and anonymous. Thus <a class="reference" href="#targets">this phrase</a> may also refer to the <a class="reference" href="#targets">Targets</a> section.</p> -<p>Here's a <a href="#id73" name="id74"><span class="problematic" id="id74">`hyperlink reference without a target`_</span></a>, which generates an +<p>Here's a <a href="#id29" name="id30"><span class="problematic" id="id30">`hyperlink reference without a target`_</span></a>, which generates an error.</p> <div class="section" id="duplicate-target-names"> -<h3><a class="toc-backref" href="#id44" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> +<h3><a class="toc-backref" href="#id52" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> <p>Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages.</p> </div> <div class="section" id="id18"> -<h3><a class="toc-backref" href="#id45" name="id18">2.13.2   Duplicate Target Names</a></h3> +<h3><a class="toc-backref" href="#id53" name="id18">2.13.2   Duplicate Target Names</a></h3> <p>Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: <a href="#id75" name="id76"><span class="problematic" id="id76">`Duplicate Target Names`_</span></a>), an error is generated.</p> +this: <a href="#id31" name="id32"><span class="problematic" id="id32">`Duplicate Target Names`_</span></a>), an error is generated.</p> </div> </div> <div class="section" id="directives"> -<h2><a class="toc-backref" href="#id46" name="directives">2.14   Directives</a></h2> +<h2><a class="toc-backref" href="#id54" name="directives">2.14   Directives</a></h2> <div class="contents local topic" id="contents"> <ul class="auto-toc simple"> -<li><a class="reference" href="#document-parts" id="id62" name="id62">2.14.1   Document Parts</a></li> -<li><a class="reference" href="#images" id="id63" name="id63">2.14.2   Images</a></li> -<li><a class="reference" href="#admonitions" id="id64" name="id64">2.14.3   Admonitions</a></li> -<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id65" name="id65">2.14.4   Topics, Sidebars, and Rubrics</a></li> -<li><a class="reference" href="#target-footnotes" id="id66" name="id66">2.14.5   Target Footnotes</a></li> -<li><a class="reference" href="#replacement-text" id="id67" name="id67">2.14.6   Replacement Text</a></li> -<li><a class="reference" href="#compound-paragraph" id="id68" name="id68">2.14.7   Compound Paragraph</a></li> +<li><a class="reference" href="#document-parts" id="id70" name="id70">2.14.1   Document Parts</a></li> +<li><a class="reference" href="#images" id="id71" name="id71">2.14.2   Images</a></li> +<li><a class="reference" href="#admonitions" id="id72" name="id72">2.14.3   Admonitions</a></li> +<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id73" name="id73">2.14.4   Topics, Sidebars, and Rubrics</a></li> +<li><a class="reference" href="#target-footnotes" id="id74" name="id74">2.14.5   Target Footnotes</a></li> +<li><a class="reference" href="#replacement-text" id="id75" name="id75">2.14.6   Replacement Text</a></li> +<li><a class="reference" href="#compound-paragraph" id="id76" name="id76">2.14.7   Compound Paragraph</a></li> </ul> </div> <p>These are just a sample of the many reStructuredText Directives. For others, please see <a class="reference" href="http://docutils.sourceforge.net/docs/ref/rst/directives.html">http://docutils.sourceforge.net/docs/ref/rst/directives.html</a>.</p> <div class="section" id="document-parts"> -<h3><a class="toc-backref" href="#id62" name="document-parts">2.14.1   Document Parts</a></h3> +<h3><a class="toc-backref" href="#id70" name="document-parts">2.14.1   Document Parts</a></h3> <p>An example of the "contents" directive can be seen above this section (a local, untitled table of <a class="reference" href="#contents">contents</a>) and at the beginning of the document (a document-wide <a class="reference" href="#table-of-contents">table of contents</a>).</p> </div> <div class="section" id="images"> -<h3><a class="toc-backref" href="#id63" name="images">2.14.2   Images</a></h3> +<h3><a class="toc-backref" href="#id71" name="images">2.14.2   Images</a></h3> <p>An image directive (also clickable -- a hyperlink reference):</p> <a class="reference image-reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a> <p>Image with multiple IDs:</p> @@ -605,7 +605,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="height: 3cm;" /> </div> <div class="section" id="admonitions"> -<h3><a class="toc-backref" href="#id64" name="admonitions">2.14.3   Admonitions</a></h3> +<h3><a class="toc-backref" href="#id72" name="admonitions">2.14.3   Admonitions</a></h3> <div class="attention"> <p class="first admonition-title">Attention!</p> <p class="last">Directives at large.</p> @@ -654,7 +654,7 @@ Reader discretion is strongly advised.</p> </div> </div> <div class="section" id="topics-sidebars-and-rubrics"> -<h3><a class="toc-backref" href="#id65" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> +<h3><a class="toc-backref" href="#id73" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> <div class="sidebar"> <p class="first sidebar-title">Sidebar Title</p> <p class="sidebar-subtitle">Optional Subtitle</p> @@ -671,7 +671,7 @@ background color.</p> <p class="rubric">This is a rubric</p> </div> <div class="section" id="target-footnotes"> -<h3><a class="toc-backref" href="#id66" name="target-footnotes">2.14.5   Target Footnotes</a></h3> +<h3><a class="toc-backref" href="#id74" name="target-footnotes">2.14.5   Target Footnotes</a></h3> <table class="docutils footnote" frame="void" id="id21" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -680,11 +680,11 @@ background color.</p> </table> </div> <div class="section" id="replacement-text"> -<h3><a class="toc-backref" href="#id67" name="replacement-text">2.14.6   Replacement Text</a></h3> +<h3><a class="toc-backref" href="#id75" name="replacement-text">2.14.6   Replacement Text</a></h3> <p>I recommend you try <a class="reference" href="http://www.python.org/">Python, <em>the</em> best language around</a> <a class="footnote-reference" href="#id21" id="id24" name="id24">[5]</a>.</p> </div> <div class="section" id="compound-paragraph"> -<h3><a class="toc-backref" href="#id68" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> +<h3><a class="toc-backref" href="#id76" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> <div class="some-class compound"> <p class="compound-first">Compound 1, paragraph 1.</p> <p class="compound-middle">Compound 1, paragraph 2.</p> @@ -752,12 +752,12 @@ paragraph.</td> </div> </div> <div class="section" id="substitution-definitions"> -<h2><a class="toc-backref" href="#id54" name="substitution-definitions">2.15   Substitution Definitions</a></h2> +<h2><a class="toc-backref" href="#id62" name="substitution-definitions">2.15   Substitution Definitions</a></h2> <p>An inline image (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" />) example:</p> <p>(Substitution definitions are not visible in the HTML source.)</p> </div> <div class="section" id="comments"> -<h2><a class="toc-backref" href="#id55" name="comments">2.16   Comments</a></h2> +<h2><a class="toc-backref" href="#id63" name="comments">2.16   Comments</a></h2> <p>Here's one:</p> <!-- Comments begin with two dots and a space. Anything may follow, except for the syntax of footnotes, hyperlink @@ -767,13 +767,13 @@ Double-dashes - - "- -" - - must be escaped somehow in HTML output. --> <p>(View the HTML source to see the comment.)</p> </div> <div class="section" id="raw-text"> -<h2><a class="toc-backref" href="#id56" name="raw-text">2.17   Raw text</a></h2> +<h2><a class="toc-backref" href="#id64" name="raw-text">2.17   Raw text</a></h2> <p>This does not necessarily look nice, because there may be missing white space.</p> <p>It's just there to freeze the behavior.</p> A test.Second test.<div class="myclass">Another test with myclass set.</div><p>This is the <span class="myrawroleclass">fourth test</span> with myrawroleclass set.</p> Fifth test in HTML.<br />Line two.</div> <div class="section" id="colspanning-tables"> -<h2><a class="toc-backref" href="#id57" name="colspanning-tables">2.18   Colspanning tables</a></h2> +<h2><a class="toc-backref" href="#id65" name="colspanning-tables">2.18   Colspanning tables</a></h2> <p>This table has a cell spanning two columns:</p> <table border="1" class="docutils"> <colgroup> @@ -811,7 +811,7 @@ Fifth test in HTML.<br />Line two.</div> </table> </div> <div class="section" id="rowspanning-tables"> -<h2><a class="toc-backref" href="#id58" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> +<h2><a class="toc-backref" href="#id66" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> <p>Here's a table with cells spanning several rows:</p> <table border="1" class="docutils"> <colgroup> @@ -844,7 +844,7 @@ cell.</td> </table> </div> <div class="section" id="complex-tables"> -<h2><a class="toc-backref" href="#id59" name="complex-tables">2.20   Complex tables</a></h2> +<h2><a class="toc-backref" href="#id67" name="complex-tables">2.20   Complex tables</a></h2> <p>Here's a complex table, which should test all features.</p> <table border="1" class="docutils"> <colgroup> @@ -893,7 +893,7 @@ empty: <tt class="docutils literal"><span class="pre">--></span></tt></td> </table> </div> <div class="section" id="list-tables"> -<h2><a class="toc-backref" href="#id60" name="list-tables">2.21   List Tables</a></h2> +<h2><a class="toc-backref" href="#id68" name="list-tables">2.21   List Tables</a></h2> <p>Here's a list table exercising all features:</p> <table border="1" class="test docutils"> <caption>list table with integral header</caption> @@ -927,7 +927,7 @@ crunchy, now would it?</td> </div> </div> <div class="section" id="error-handling"> -<h1><a class="toc-backref" href="#id61" name="error-handling">3   Error Handling</a></h1> +<h1><a class="toc-backref" href="#id69" name="error-handling">3   Error Handling</a></h1> <p>Any errors caught during processing will generate system messages.</p> <p>There should be five messages in the following, auto-generated section, "Docutils System Messages":</p> @@ -938,17 +938,17 @@ section, "Docutils System Messages":</p> <div class="system-message" id="id19"> <p class="system-message-title">System Message: <a name="id19">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 100); <em><a href="#id20">backlink</a></em></p> Undefined substitution referenced: "problematic".</div> -<div class="system-message" id="id69"> -<p class="system-message-title">System Message: <a name="id69">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 354); <em><a href="#id70">backlink</a></em></p> +<div class="system-message" id="id25"> +<p class="system-message-title">System Message: <a name="id25">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 354); <em><a href="#id26">backlink</a></em></p> Unknown target name: "5".</div> -<div class="system-message" id="id71"> -<p class="system-message-title">System Message: <a name="id71">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 363); <em><a href="#id72">backlink</a></em></p> +<div class="system-message" id="id27"> +<p class="system-message-title">System Message: <a name="id27">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 363); <em><a href="#id28">backlink</a></em></p> Unknown target name: "nonexistent".</div> -<div class="system-message" id="id73"> -<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 390); <em><a href="#id74">backlink</a></em></p> +<div class="system-message" id="id29"> +<p class="system-message-title">System Message: <a name="id29">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 390); <em><a href="#id30">backlink</a></em></p> Unknown target name: "hyperlink reference without a target".</div> -<div class="system-message" id="id75"> -<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 403); <em><a href="#id76">backlink</a></em></p> +<div class="system-message" id="id31"> +<p class="system-message-title">System Message: <a name="id31">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 403); <em><a href="#id32">backlink</a></em></p> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 2ae7e5c3b..c098ff0e0 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -91,238 +91,238 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id25" refid="structural-elements"> + <reference ids="id33" refid="structural-elements"> <generated classes="sectnum"> 1    Structural Elements <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id26" refid="section-title"> + <reference ids="id34" refid="section-title"> <generated classes="sectnum"> 1.1    Section Title <list_item> <paragraph> - <reference ids="id27" refid="empty-section"> + <reference ids="id35" refid="empty-section"> <generated classes="sectnum"> 1.2    Empty Section <list_item> <paragraph> - <reference ids="id28" refid="transitions"> + <reference ids="id36" refid="transitions"> <generated classes="sectnum"> 1.3    Transitions <list_item> <paragraph> - <reference ids="id29" refid="body-elements"> + <reference ids="id37" refid="body-elements"> <generated classes="sectnum"> 2    Body Elements <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id30" refid="paragraphs"> + <reference ids="id38" refid="paragraphs"> <generated classes="sectnum"> 2.1    Paragraphs <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id31" refid="inline-markup"> + <reference ids="id39" refid="inline-markup"> <generated classes="sectnum"> 2.1.1    Inline Markup <list_item> <paragraph> - <reference ids="id32" refid="bullet-lists"> + <reference ids="id40" refid="bullet-lists"> <generated classes="sectnum"> 2.2    Bullet Lists <list_item> <paragraph> - <reference ids="id33" refid="enumerated-lists"> + <reference ids="id41" refid="enumerated-lists"> <generated classes="sectnum"> 2.3    Enumerated Lists <list_item> <paragraph> - <reference ids="id34" refid="definition-lists"> + <reference ids="id42" refid="definition-lists"> <generated classes="sectnum"> 2.4    Definition Lists <list_item> <paragraph> - <reference ids="id35" refid="field-lists"> + <reference ids="id43" refid="field-lists"> <generated classes="sectnum"> 2.5    Field Lists <list_item> <paragraph> - <reference ids="id36" refid="option-lists"> + <reference ids="id44" refid="option-lists"> <generated classes="sectnum"> 2.6    Option Lists <list_item> <paragraph> - <reference ids="id37" refid="literal-blocks"> + <reference ids="id45" refid="literal-blocks"> <generated classes="sectnum"> 2.7    Literal Blocks <list_item> <paragraph> - <reference ids="id38" refid="line-blocks"> + <reference ids="id46" refid="line-blocks"> <generated classes="sectnum"> 2.8    Line Blocks <list_item> <paragraph> - <reference ids="id39" refid="block-quotes"> + <reference ids="id47" refid="block-quotes"> <generated classes="sectnum"> 2.9    Block Quotes <list_item> <paragraph> - <reference ids="id40" refid="doctest-blocks"> + <reference ids="id48" refid="doctest-blocks"> <generated classes="sectnum"> 2.10    Doctest Blocks <list_item> <paragraph> - <reference ids="id41" refid="footnotes"> + <reference ids="id49" refid="footnotes"> <generated classes="sectnum"> 2.11    Footnotes <list_item> <paragraph> - <reference ids="id42" refid="citations"> + <reference ids="id50" refid="citations"> <generated classes="sectnum"> 2.12    Citations <list_item> <paragraph> - <reference ids="id43" refid="targets"> + <reference ids="id51" refid="targets"> <generated classes="sectnum"> 2.13    Targets <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id44" refid="duplicate-target-names"> + <reference ids="id52" refid="duplicate-target-names"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names <list_item> <paragraph> - <reference ids="id45" refid="id18"> + <reference ids="id53" refid="id18"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names <list_item> <paragraph> - <reference ids="id46" refid="directives"> + <reference ids="id54" refid="directives"> <generated classes="sectnum"> 2.14    Directives <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id47" refid="document-parts"> + <reference ids="id55" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id48" refid="images"> + <reference ids="id56" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id49" refid="admonitions"> + <reference ids="id57" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id50" refid="topics-sidebars-and-rubrics"> + <reference ids="id58" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id51" refid="target-footnotes"> + <reference ids="id59" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id52" refid="replacement-text"> + <reference ids="id60" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id53" refid="compound-paragraph"> + <reference ids="id61" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph <list_item> <paragraph> - <reference ids="id54" refid="substitution-definitions"> + <reference ids="id62" refid="substitution-definitions"> <generated classes="sectnum"> 2.15    Substitution Definitions <list_item> <paragraph> - <reference ids="id55" refid="comments"> + <reference ids="id63" refid="comments"> <generated classes="sectnum"> 2.16    Comments <list_item> <paragraph> - <reference ids="id56" refid="raw-text"> + <reference ids="id64" refid="raw-text"> <generated classes="sectnum"> 2.17    Raw text <list_item> <paragraph> - <reference ids="id57" refid="colspanning-tables"> + <reference ids="id65" refid="colspanning-tables"> <generated classes="sectnum"> 2.18    Colspanning tables <list_item> <paragraph> - <reference ids="id58" refid="rowspanning-tables"> + <reference ids="id66" refid="rowspanning-tables"> <generated classes="sectnum"> 2.19    Rowspanning tables <list_item> <paragraph> - <reference ids="id59" refid="complex-tables"> + <reference ids="id67" refid="complex-tables"> <generated classes="sectnum"> 2.20    Complex tables <list_item> <paragraph> - <reference ids="id60" refid="list-tables"> + <reference ids="id68" refid="list-tables"> <generated classes="sectnum"> 2.21    List Tables <list_item> <paragraph> - <reference ids="id61" refid="error-handling"> + <reference ids="id69" refid="error-handling"> <generated classes="sectnum"> 3    Error Handling <section ids="structural-elements" names="structural elements"> - <title auto="1" refid="id25"> + <title auto="1" refid="id33"> <generated classes="sectnum"> 1    Structural Elements <section ids="section-title" names="section title"> - <title auto="1" refid="id26"> + <title auto="1" refid="id34"> <generated classes="sectnum"> 1.1    Section Title @@ -331,12 +331,12 @@ <paragraph> That's it, the text just above this line. <section ids="empty-section" names="empty section"> - <title auto="1" refid="id27"> + <title auto="1" refid="id35"> <generated classes="sectnum"> 1.2    Empty Section <section ids="transitions" names="transitions"> - <title auto="1" refid="id28"> + <title auto="1" refid="id36"> <generated classes="sectnum"> 1.3    Transitions @@ -347,19 +347,19 @@ It divides the section. Transitions may also occur between sections: <transition> <section ids="body-elements" names="body elements"> - <title auto="1" refid="id29"> + <title auto="1" refid="id37"> <generated classes="sectnum"> 2    Body Elements <section ids="paragraphs" names="paragraphs"> - <title auto="1" refid="id30"> + <title auto="1" refid="id38"> <generated classes="sectnum"> 2.1    Paragraphs <paragraph> A paragraph. <section ids="inline-markup" names="inline markup"> - <title auto="1" refid="id31"> + <title auto="1" refid="id39"> <generated classes="sectnum"> 2.1.1    Inline Markup @@ -484,7 +484,7 @@ option was supplied, there should be a live link to PEP 258 here. <section ids="bullet-lists" names="bullet lists"> - <title auto="1" refid="id32"> + <title auto="1" refid="id40"> <generated classes="sectnum"> 2.2    Bullet Lists @@ -528,7 +528,7 @@ <comment xml:space="preserve"> Even if this item contains a target and a comment. <section ids="enumerated-lists" names="enumerated lists"> - <title auto="1" refid="id33"> + <title auto="1" refid="id41"> <generated classes="sectnum"> 2.3    Enumerated Lists @@ -577,7 +577,7 @@ <paragraph> iv <section ids="definition-lists" names="definition lists"> - <title auto="1" refid="id34"> + <title auto="1" refid="id42"> <generated classes="sectnum"> 2.4    Definition Lists @@ -615,7 +615,7 @@ <paragraph> Definition <section ids="field-lists" names="field lists"> - <title auto="1" refid="id35"> + <title auto="1" refid="id43"> <generated classes="sectnum"> 2.5    Field Lists @@ -649,7 +649,7 @@ about credits but just for ensuring that the class attribute doesn't get stripped away.) <section ids="option-lists" names="option lists"> - <title auto="1" refid="id36"> + <title auto="1" refid="id44"> <generated classes="sectnum"> 2.6    Option Lists @@ -762,7 +762,7 @@ There must be at least two spaces between the option and the description. <section ids="literal-blocks" names="literal blocks"> - <title auto="1" refid="id37"> + <title auto="1" refid="id45"> <generated classes="sectnum"> 2.7    Literal Blocks @@ -784,7 +784,7 @@ > > Why didn't I think of that? <section ids="line-blocks" names="line blocks"> - <title auto="1" refid="id38"> + <title auto="1" refid="id46"> <generated classes="sectnum"> 2.8    Line Blocks @@ -862,7 +862,7 @@ <line> Singing... <section ids="block-quotes" names="block quotes"> - <title auto="1" refid="id39"> + <title auto="1" refid="id47"> <generated classes="sectnum"> 2.9    Block Quotes @@ -878,7 +878,7 @@ <attribution> Anne Elk (Miss) <section ids="doctest-blocks" names="doctest blocks"> - <title auto="1" refid="id40"> + <title auto="1" refid="id48"> <generated classes="sectnum"> 2.10    Doctest Blocks @@ -888,7 +888,7 @@ >>> print '(cut and pasted from interactive Python sessions)' (cut and pasted from interactive Python sessions) <section ids="footnotes" names="footnotes"> - <title auto="1" refid="id41"> + <title auto="1" refid="id49"> <generated classes="sectnum"> 2.11    Footnotes @@ -948,11 +948,11 @@ <paragraph> Here's an unreferenced footnote, with a reference to a nonexistent footnote: - <problematic ids="id70" refid="id69"> + <problematic ids="id26" refid="id25"> [5]_ . <section ids="citations" names="citations"> - <title auto="1" refid="id42"> + <title auto="1" refid="id50"> <generated classes="sectnum"> 2.12    Citations @@ -967,13 +967,13 @@ <citation_reference ids="id15" refid="cit2002"> CIT2002 , and a - <problematic ids="id72" refid="id71"> + <problematic ids="id28" refid="id27"> [nonexistent]_ citation. <target refid="another-target"> <section ids="targets another-target" names="targets another target"> - <title auto="1" refid="id43"> + <title auto="1" refid="id51"> <generated classes="sectnum"> 2.13    Targets @@ -1018,12 +1018,12 @@ <target anonymous="1" ids="id17" refid="targets"> <paragraph> Here's a - <problematic ids="id74" refid="id73"> + <problematic ids="id30" refid="id29"> `hyperlink reference without a target`_ , which generates an error. <section dupnames="duplicate target names" ids="duplicate-target-names"> - <title auto="1" refid="id44"> + <title auto="1" refid="id52"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names @@ -1032,7 +1032,7 @@ generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages. <section dupnames="duplicate target names" ids="id18"> - <title auto="1" refid="id45"> + <title auto="1" refid="id53"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names @@ -1040,11 +1040,11 @@ Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: - <problematic ids="id76" refid="id75"> + <problematic ids="id32" refid="id31"> `Duplicate Target Names`_ ), an error is generated. <section ids="directives" names="directives"> - <title auto="1" refid="id46"> + <title auto="1" refid="id54"> <generated classes="sectnum"> 2.14    Directives @@ -1052,43 +1052,43 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id62" refid="document-parts"> + <reference ids="id70" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id63" refid="images"> + <reference ids="id71" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id64" refid="admonitions"> + <reference ids="id72" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id65" refid="topics-sidebars-and-rubrics"> + <reference ids="id73" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id66" refid="target-footnotes"> + <reference ids="id74" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id67" refid="replacement-text"> + <reference ids="id75" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id68" refid="compound-paragraph"> + <reference ids="id76" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1099,7 +1099,7 @@ http://docutils.sourceforge.net/docs/ref/rst/directives.html . <section ids="document-parts" names="document parts"> - <title auto="1" refid="id62"> + <title auto="1" refid="id70"> <generated classes="sectnum"> 2.14.1    Document Parts @@ -1114,7 +1114,7 @@ table of contents ). <section ids="images" names="images"> - <title auto="1" refid="id63"> + <title auto="1" refid="id71"> <generated classes="sectnum"> 2.14.2    Images @@ -1206,7 +1206,7 @@ An image 3 cm high: <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> - <title auto="1" refid="id64"> + <title auto="1" refid="id72"> <generated classes="sectnum"> 2.14.3    Admonitions @@ -1256,7 +1256,7 @@ You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> <section ids="topics-sidebars-and-rubrics" names="topics, sidebars, and rubrics"> - <title auto="1" refid="id65"> + <title auto="1" refid="id73"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics @@ -1281,7 +1281,7 @@ <rubric> This is a rubric <section ids="target-footnotes" names="target footnotes"> - <title auto="1" refid="id66"> + <title auto="1" refid="id74"> <generated classes="sectnum"> 2.14.5    Target Footnotes @@ -1292,7 +1292,7 @@ <reference refuri="http://www.python.org/"> http://www.python.org/ <section ids="replacement-text" names="replacement text"> - <title auto="1" refid="id67"> + <title auto="1" refid="id75"> <generated classes="sectnum"> 2.14.6    Replacement Text @@ -1313,7 +1313,7 @@ the best language around <section ids="compound-paragraph" names="compound paragraph"> - <title auto="1" refid="id68"> + <title auto="1" refid="id76"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1398,7 +1398,7 @@ <paragraph> Compound 7, another paragraph. <section ids="substitution-definitions" names="substitution definitions"> - <title auto="1" refid="id54"> + <title auto="1" refid="id62"> <generated classes="sectnum"> 2.15    Substitution Definitions @@ -1411,7 +1411,7 @@ <paragraph> (Substitution definitions are not visible in the HTML source.) <section ids="comments" names="comments"> - <title auto="1" refid="id55"> + <title auto="1" refid="id63"> <generated classes="sectnum"> 2.16    Comments @@ -1426,7 +1426,7 @@ <paragraph> (View the HTML source to see the comment.) <section ids="raw-text" names="raw text"> - <title auto="1" refid="id56"> + <title auto="1" refid="id64"> <generated classes="sectnum"> 2.17    Raw text @@ -1450,7 +1450,7 @@ <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. <section ids="colspanning-tables" names="colspanning tables"> - <title auto="1" refid="id57"> + <title auto="1" refid="id65"> <generated classes="sectnum"> 2.18    Colspanning tables @@ -1521,7 +1521,7 @@ <paragraph> True <section ids="rowspanning-tables" names="rowspanning tables"> - <title auto="1" refid="id58"> + <title auto="1" refid="id66"> <generated classes="sectnum"> 2.19    Rowspanning tables @@ -1573,7 +1573,7 @@ <paragraph> body row 3 <section ids="complex-tables" names="complex tables"> - <title auto="1" refid="id59"> + <title auto="1" refid="id67"> <generated classes="sectnum"> 2.20    Complex tables @@ -1658,7 +1658,7 @@ --> <entry> <section ids="list-tables" names="list tables"> - <title auto="1" refid="id60"> + <title auto="1" refid="id68"> <generated classes="sectnum"> 2.21    List Tables @@ -1715,7 +1715,7 @@ <paragraph> On a stick! <section ids="error-handling" names="error handling"> - <title auto="1" refid="id61"> + <title auto="1" refid="id69"> <generated classes="sectnum"> 3    Error Handling @@ -1732,15 +1732,15 @@ <system_message backrefs="id20" ids="id19" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id70" ids="id69" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id26" ids="id25" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id72" ids="id71" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id28" ids="id27" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id74" ids="id73" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id30" ids="id29" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id76" ids="id75" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id32" ids="id31" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/test_transforms/test_final_checks.py b/test/test_transforms/test_final_checks.py deleted file mode 100755 index 4d58b8dbc..000000000 --- a/test/test_transforms/test_final_checks.py +++ /dev/null @@ -1,77 +0,0 @@ -#! /usr/bin/env python - -# Author: David Goodger -# Contact: goodger@users.sourceforge.net -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Tests for docutils.transforms.universal.FinalChecks. -""" - -from __init__ import DocutilsTestSupport -from docutils.transforms.universal import FinalChecks -from docutils.parsers.rst import Parser - - -def suite(): - parser = Parser() - s = DocutilsTestSupport.TransformTestSuite(parser) - s.generateTests(totest) - return s - -totest = {} - -totest['references'] = ((FinalChecks,), [ -["""\ -Unknown reference_. -""", -"""\ -<document source="test data"> - <paragraph> - Unknown \n\ - <problematic ids="id2" refid="id1"> - reference_ - . - <system_message backrefs="id2" ids="id1" level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Unknown target name: "reference". -"""], -["""\ -Duplicate manual footnote labels, with reference ([1]_): - -.. [1] Footnote. - -.. [1] Footnote. -""", -"""\ -<document source="test data"> - <paragraph> - Duplicate manual footnote labels, with reference ( - <problematic ids="id5" refid="id4"> - [1]_ - ): - <footnote dupnames="1" ids="id2"> - <label> - 1 - <paragraph> - Footnote. - <footnote dupnames="1" ids="id3"> - <label> - 1 - <system_message backrefs="id3" level="2" line="5" source="test data" type="WARNING"> - <paragraph> - Duplicate explicit target name: "1". - <paragraph> - Footnote. - <system_message backrefs="id5" ids="id4" level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Duplicate target name, cannot be used as a unique reference: "1". -"""], -]) - - -if __name__ == '__main__': - import unittest - unittest.main(defaultTest='suite') diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index fc7441c5f..85dfe9a87 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -13,9 +13,8 @@ Tests for docutils.transforms.references.Hyperlinks. from __init__ import DocutilsTestSupport from docutils.transforms.references import PropagateTargets, \ AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, \ - InternalTargets + InternalTargets, DanglingReferences -from docutils.transforms.universal import FinalChecks from docutils.parsers.rst import Parser @@ -33,7 +32,7 @@ totest = {} totest['exhaustive_hyperlinks'] = ((PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, InternalTargets, - FinalChecks), [ + DanglingReferences), [ ["""\ direct_ external @@ -347,7 +346,7 @@ An `anonymous embedded uri <http://direct>`__. totest['hyperlinks'] = ((PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, - InternalTargets, FinalChecks), [ + InternalTargets, DanglingReferences), [ ["""\ .. _internal hyperlink: @@ -763,6 +762,51 @@ Title <title> Title """], +["""\ +Unknown reference_. +""", +"""\ +<document source="test data"> + <paragraph> + Unknown \n\ + <problematic ids="id2" refid="id1"> + reference_ + . + <system_message backrefs="id2" ids="id1" level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Unknown target name: "reference". +"""], +["""\ +Duplicate manual footnote labels, with reference ([1]_): + +.. [1] Footnote. + +.. [1] Footnote. +""", +"""\ +<document source="test data"> + <paragraph> + Duplicate manual footnote labels, with reference ( + <problematic ids="id5" refid="id4"> + [1]_ + ): + <footnote dupnames="1" ids="id2"> + <label> + 1 + <paragraph> + Footnote. + <footnote dupnames="1" ids="id3"> + <label> + 1 + <system_message backrefs="id3" level="2" line="5" source="test data" type="WARNING"> + <paragraph> + Duplicate explicit target name: "1". + <paragraph> + Footnote. + <system_message backrefs="id5" ids="id4" level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Duplicate target name, cannot be used as a unique reference: "1". +"""], ]) -- cgit v1.2.1 From 5d0c3a22119855adddbf210fc607e3944bbad928 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Jul 2005 12:43:05 +0000 Subject: fixed TestMessages priority to conform to docs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3660 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index b28e8f06b..8d1b58d9b 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -133,9 +133,11 @@ class TestMessages(Transform): """ Append all post-parse system messages to the end of the document. + + Used for testing purposes. """ - default_priority = 890 + default_priority = 880 def apply(self): for msg in self.document.transform_messages: -- cgit v1.2.1 From da4273546b4b7aa3edcffc67b60c9dd00010dbbf Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Jul 2005 12:45:22 +0000 Subject: sorted transform declarations by priority git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3661 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 8d1b58d9b..227f6ce69 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -81,6 +81,23 @@ class Decorations(Transform): return None +class ExposeInternals(Transform): + + """ + Expose internal attributes if ``expose_internals`` setting is set. + """ + + default_priority = 840 + + def apply(self): + if self.document.settings.expose_internals: + for node in self.document.traverse(): + 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): """ @@ -143,20 +160,3 @@ class TestMessages(Transform): for msg in self.document.transform_messages: if not msg.parent: self.document += msg - - -class ExposeInternals(Transform): - - """ - Expose internal attributes if ``expose_internals`` setting is set. - """ - - default_priority = 840 - - def apply(self): - if self.document.settings.expose_internals: - for node in self.document.traverse(): - for att in self.document.settings.expose_internals: - value = getattr(node, att, None) - if value is not None: - node['internal:' + att] = value -- cgit v1.2.1 From 4687626a27fc714d021060ad45f4477c6dd904c8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 6 Jul 2005 16:37:24 +0000 Subject: moved comparison methods up to StandardTestCase git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3662 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index c0c2c331b..0466590fd 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -93,12 +93,34 @@ class StandardTestCase(unittest.TestCase): """ Helper class, providing the same interface as unittest.TestCase, - but with useful setUp and tearDown methods. + but with useful setUp and comparison methods. """ def setUp(self): os.chdir(testroot) + def failUnlessEqual(self, first, second, msg=None): + """Fail if the two objects are unequal as determined by the '==' + operator. + """ + if not first == second: + raise self.failureException, \ + (msg or '%s != %s' % _format_str(first, second)) + + def failIfEqual(self, first, second, msg=None): + """Fail if the two objects are equal as determined by the '==' + operator. + """ + if first == second: + raise self.failureException, \ + (msg or '%s == %s' % _format_str(first, second)) + + # Synonyms for assertion methods + + assertEqual = assertEquals = failUnlessEqual + + assertNotEqual = assertNotEquals = failIfEqual + class CustomTestCase(StandardTestCase): @@ -167,28 +189,6 @@ class CustomTestCase(StandardTestCase): print >>sys.stderr, 'output: %r' % output raise error - def failUnlessEqual(self, first, second, msg=None): - """Fail if the two objects are unequal as determined by the '==' - operator. - """ - if not first == second: - raise self.failureException, \ - (msg or '%s != %s' % _format_str(first, second)) - - def failIfEqual(self, first, second, msg=None): - """Fail if the two objects are equal as determined by the '==' - operator. - """ - if first == second: - raise self.failureException, \ - (msg or '%s == %s' % _format_str(first, second)) - - # Synonyms for assertion methods - - assertEqual = assertEquals = failUnlessEqual - - assertNotEqual = assertNotEquals = failIfEqual - class CustomTestSuite(unittest.TestSuite): -- cgit v1.2.1 From c5aecf0e115ab835a4c79657245bcaed911ad41e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 02:11:14 +0000 Subject: separated default (universal) transforms into two stages so that no transform is applied twice; do not delete document.transformer in publish_doctree (Martin, this may be important for the pickle writer -- you may need to delete document.transformer); regenerate reporter object unconditionally; do so in publish_from_doctree, not the doctree reader; added tests; I will post about all that on Docutils-develop in one or two days git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3663 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 55 ++++++++++++++++++----------- docutils/readers/doctree.py | 6 ---- docutils/transforms/__init__.py | 21 ++++++----- test/test_publisher.py | 78 +++++++++++++++++++++++++++++++---------- 4 files changed, 106 insertions(+), 54 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 694696f18..8375fbe89 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -193,11 +193,16 @@ class Publisher: def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None, - config_section=None, enable_exit_status=None): + config_section=None, enable_exit_status=None, stage=None): """ Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return `self.writer`'s output. + + Pass ``stage=1`` to set transformer.default_transforms to the + stage-1 transforms; dito for ``stage=2`` and stage-2 + transforms, resp. See the documentation in the + `transforms.Transformer` class. """ if self.settings is None: self.process_command_line( @@ -208,6 +213,13 @@ class Publisher: try: self.document = self.reader.read(self.source, self.parser, self.settings) + assert stage in (1, 2, None) + if stage == 1: + self.document.transformer.default_transforms = ( + self.document.transformer.stage1_transforms) + elif stage == 2: + self.document.transformer.default_transforms = ( + self.document.transformer.stage2_transforms) self.apply_transforms() output = self.writer.write(self.document, self.destination) self.writer.assemble_parts() @@ -449,20 +461,16 @@ def publish_doctree(source, source_path=None, Parameters: see `publish_programmatically`. """ - output, pub = publish_programmatically( - source_class=source_class, source=source, source_path=source_path, - destination_class=io.NullOutput, - destination=None, destination_path=None, - reader=reader, reader_name=reader_name, - parser=parser, parser_name=parser_name, - writer=None, writer_name='null', - settings=settings, settings_spec=settings_spec, - settings_overrides=settings_overrides, - config_section=config_section, - enable_exit_status=enable_exit_status) - # The transformer is not needed any more - # (a new transformer will be created in `publish_from_doctree`): - del pub.document.transformer + pub = Publisher(reader=reader, parser=parser, writer=None, + settings=settings, + source_class=source_class, + destination_class=io.NullOutput) + pub.set_components(reader_name, parser_name, 'null') + pub.process_programmatic_settings( + settings_spec, settings_overrides, config_section) + pub.set_source(source, source_path) + pub.set_destination(None, None) + output = pub.publish(enable_exit_status=enable_exit_status, stage=1) return pub.document def publish_from_doctree(document, destination_path=None, @@ -478,6 +486,9 @@ def publish_from_doctree(document, destination_path=None, Note that document.settings is overridden; if you want to use the settings of the original `document`, pass settings=document.settings. + Also, new document.transformer and document.reporter objects are + generated. + For encoded string output, be sure to set the 'output_encoding' setting to the desired encoding. Set it to 'unicode' for unencoded Unicode string output. Here's one way:: @@ -490,11 +501,6 @@ def publish_from_doctree(document, destination_path=None, Other parameters: see `publish_programmatically`. """ - # Create fresh Transformer object, to be populated from Writer component. - document.transformer = Transformer(document) - # Don't apply default transforms twice: - document.transformer.default_transforms = ( - document.transformer.reprocess_transforms) reader = docutils.readers.doctree.Reader(parser_name='null') pub = Publisher(reader, None, writer, source=io.DocTreeInput(document), @@ -503,8 +509,15 @@ def publish_from_doctree(document, destination_path=None, pub.set_writer(writer_name) pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) + # Create fresh Transformer object, to be populated from Writer component. + document.transformer = Transformer(document) + # Create fresh Reporter object because it is dependent on (new) settings. + document.reporter = utils.new_reporter(document.get('source', ''), + pub.settings) + # Replace existing settings object with new one. + document.settings = pub.settings pub.set_destination(None, destination_path) - output = pub.publish(enable_exit_status=enable_exit_status) + output = pub.publish(enable_exit_status=enable_exit_status, stage=2) return output, pub.writer.parts def publish_programmatically(source_class, source, source_path, diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py index 5a4371983..ec56e4099 100644 --- a/docutils/readers/doctree.py +++ b/docutils/readers/doctree.py @@ -37,9 +37,3 @@ class Reader(readers.Reader): Overrides the inherited method. """ self.document = self.input - # Restore the reporter after document serialization: - if self.document.reporter is None: - self.document.reporter = utils.new_reporter( - self.source.source_path, self.settings) - # Override document settings with new settings: - self.document.settings = self.settings diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index e575f42be..0bc302b77 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -74,17 +74,20 @@ class Transformer(TransformSpec): from docutils.transforms import universal - default_transforms = (universal.Decorations, - universal.ExposeInternals, - universal.Messages, - universal.FilterMessages) + stage1_transforms = (universal.Decorations, + universal.ExposeInternals) + """Suggested replacement for `default_transforms` when generating + a document tree without writing it.""" + + stage2_transforms = (universal.Messages, + universal.FilterMessages) + """Suggested replacement for `default_transforms` when writing a + previously-parsed document tree. Only transforms which *must* be applied + after writer-specific transforms should be added to this list.""" + + default_transforms = stage1_transforms + stage2_transforms """These transforms are applied to all document trees.""" - reprocess_transforms = (universal.Messages, - universal.FilterMessages) - """This set of transforms is a suggested replacement for - `default_transforms` when reprocessing a document tree.""" - def __init__(self, document): self.transforms = [] """List of transforms to apply. Each item is a 3-tuple: diff --git a/test/test_publisher.py b/test/test_publisher.py index d5460694c..39b68cf37 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -10,61 +10,101 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. """ -import unittest -from types import DictType, StringType -from docutils import core, nodes import pickle +from types import DictType, StringType + +import docutils +from docutils import core, nodes, io + +import DocutilsTestSupport test_document = """\ Test Document ============= -This is a test document. +This is a test document with a broken reference: nonexistent_ """ pseudoxml_output = """\ <document ids="test-document" names="test document" source="<string>" title="Test Document"> <title> Test Document <paragraph> - This is a test document. + This is a test document with a broken reference: \n\ + <problematic ids="id2" refid="id1"> + nonexistent_ + <section classes="system-messages"> + <title> + Docutils System Messages + <system_message backrefs="id2" ids="id1" level="3" line="4" source="<string>" type="ERROR"> + <paragraph> + Unknown target name: "nonexistent". +""" +exposed_pseudoxml_output = """\ +<document ids="test-document" internal:refnames="{u\'nonexistent\': [<reference: <#text: u\'nonexistent\'>>]}" names="test document" source="<string>" title="Test Document"> + <title> + Test Document + <paragraph> + This is a test document with a broken reference: \n\ + <problematic ids="id2" refid="id1"> + nonexistent_ + <section classes="system-messages"> + <title> + Docutils System Messages + <system_message backrefs="id2" ids="id1" level="3" line="4" source="<string>" type="ERROR"> + <paragraph> + Unknown target name: "nonexistent". """ -class PublishDoctreeTestCase(unittest.TestCase): +class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.SettingsSpec): + + settings_default_overrides = { + '_disable_config': 1, + 'warning_stream': io.NullOutput()} def test_publish_doctree(self): - """Test `publish_doctree` and `publish_from_doctree`.""" + # Test `publish_doctree` and `publish_from_doctree`. # Produce the document tree. doctree = core.publish_doctree( - source=test_document, - reader_name='standalone', - parser_name='restructuredtext', - settings_overrides={'_disable_config': 1}) + source=test_document, reader_name='standalone', + parser_name='restructuredtext', settings_spec=self, + settings_overrides={'expose_internals': + ['refnames', 'do_not_expose'], + 'report_level': 5}) self.assert_(isinstance(doctree, nodes.document)) - + # Confirm that transforms have been applied (in this case, the # DocTitle transform): self.assert_(isinstance(doctree[0], nodes.title)) self.assert_(isinstance(doctree[1], nodes.paragraph)) + # Confirm that the Messages transform has not yet been applied: + self.assertEquals(len(doctree), 2) + # The `do_not_expose` attribute may not show up in the + # pseudoxml output because the expose_internals transform may + # not be applied twice. + doctree.do_not_expose = 'test' # Write out the document: output, parts = core.publish_from_doctree( doctree, writer_name='pseudoxml', - settings_overrides={'_disable_config': 1}) - self.assertEquals(output, pseudoxml_output) + settings_spec=self, + settings_overrides={'expose_internals': + ['refnames', 'do_not_expose'], + 'report_level': 1}) + self.assertEquals(output, exposed_pseudoxml_output) self.assert_(isinstance(parts, DictType)) def test_publish_pickle(self): - """Test publishing a document tree with pickling and unpickling.""" + # Test publishing a document tree with pickling and unpickling. # Produce the document tree. doctree = core.publish_doctree( source=test_document, reader_name='standalone', parser_name='restructuredtext', - settings_overrides={'_disable_config': 1}) + settings_spec=self) self.assert_(isinstance(doctree, nodes.document)) # Pickle the document. Note: if this fails, some unpickleable @@ -75,8 +115,9 @@ class PublishDoctreeTestCase(unittest.TestCase): # requirement, applications will be built on the assumption # that we can pickle the document. - # Remove the reporter before pickling. + # Remove the reporter and the transformer before pickling. doctree.reporter = None + doctree.transformer = None doctree_pickled = pickle.dumps(doctree) self.assert_(isinstance(doctree_pickled, StringType)) @@ -89,10 +130,11 @@ class PublishDoctreeTestCase(unittest.TestCase): # Write out the document: output, parts = core.publish_from_doctree( doctree_zombie, writer_name='pseudoxml', - settings_overrides={'_disable_config': 1}) + settings_spec=self) self.assertEquals(output, pseudoxml_output) self.assert_(isinstance(parts, DictType)) if __name__ == '__main__': + import unittest unittest.main() -- cgit v1.2.1 From ec90f56d02442c7974aaf6177f51cfcf46c816d6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 02:12:44 +0000 Subject: removed unnecessary report_level checking -- this is done by FilterMessages transform git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3664 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 --- docutils/writers/latex2e.py | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 8201ec29e..c92b97130 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -1245,9 +1245,6 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</sup>') def visit_system_message(self, node): - if node['level'] < self.document.reporter.report_level: - # Level is too low to display: - raise nodes.SkipNode self.body.append(self.starttag(node, 'div', CLASS='system-message')) self.body.append('<p class="system-message-title">') attr = {} diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 0522ce0aa..02ebffc67 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1827,8 +1827,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_system_message(self, node): - if node['level'] < self.document.reporter.report_level: - raise nodes.SkipNode + pass def depart_system_message(self, node): self.body.append('\n') -- cgit v1.2.1 From 49e2f63bbebc20e2c097aab472d18e3de028ea6f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 02:14:50 +0000 Subject: simplified FilterMessages transform git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3665 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/universal.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 227f6ce69..2766ed41b 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -132,18 +132,9 @@ class FilterMessages(Transform): default_priority = 870 def apply(self): - visitor = SystemMessageFilterVisitor(self.document) - self.document.walk(visitor) - - -class SystemMessageFilterVisitor(nodes.SparseNodeVisitor): - - def unknown_visit(self, node): - pass - - def visit_system_message(self, node): - if node['level'] < self.document.reporter.report_level: - node.parent.remove(node) + for node in self.document.traverse(nodes.system_message): + if node['level'] < self.document.reporter.report_level: + node.parent.remove(node) class TestMessages(Transform): -- cgit v1.2.1 From 593340d0cad6ed4d6017c44e486092d8233844c1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 13:46:04 +0000 Subject: added history entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3666 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index d238b3750..6601bb25a 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -71,6 +71,23 @@ Changes Since 0.3.9 * docutils/transforms/html.py: Added to project; transforms specific to the html4css1 Writer. +* docutils/transforms/misc.py: + + - Added misc.Transitions transform, extracted from + universal.FinalChecks. + +* docutils/transforms/references.py: + + - Added references.DanglingReferences transform, extracted from + universal.FinalChecks. + +* docutils/transforms/universal.py: + + - Added universal.ExposeInternals transform, extracted from + universal.FinalChecks. + - Removed universal.FinalChecks transform (logic has been moved to + several new transforms). + * docutils/writers/html4css1.py: - Added support for image width and height units. -- cgit v1.2.1 From ca5818dc7398a4588dc04b4e84067f559c59b999 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 16:14:12 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3667 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b4f1c962f..ec1f8c38a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1299,6 +1299,8 @@ when used in a document. The ideas in `adaptable file extensions`_ above may also be applicable here. + SVG's "switch" statement may provide inspiration. + Here's an example of a directive that could produce multiple outputs (*both* raw troff pass-through *and* a GIF, for example) and allow the Writer to select. :: -- cgit v1.2.1 From f7067269fdfeeb21fcd825051da7727a286be988 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 23:17:41 +0000 Subject: added docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3668 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index b68f7e9f5..60af8298b 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -735,6 +735,13 @@ class Labeled: class document(Root, Structural, Element): + """ + The document root element. + + Do not instantiate this class directly; use + `docutils.utils.new_document()` instead. + """ + def __init__(self, settings, reporter, *args, **kwargs): Element.__init__(self, *args, **kwargs) -- cgit v1.2.1 From 8fe9a5c9e2913e4cea39c0660ee7e34d25a0a8b1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 7 Jul 2005 23:25:30 +0000 Subject: added docstring for system_message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3669 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 60af8298b..8ff275129 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1240,6 +1240,13 @@ class entry(Part, Element): pass class system_message(Special, BackLinkable, PreBibliographic, Element): + """ + System message element. + + Do not instantiate this class directly; use + ``document.reporter.info/warning/error/severe()`` instead. + """ + def __init__(self, message=None, *children, **attributes): if message: p = paragraph('', message) -- cgit v1.2.1 -- cgit v1.2.1 From dbe5d1f505a545190a1ed1adfc7d97772c710e38 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Jul 2005 00:29:32 +0000 Subject: do not return parts dictionary in publish_from_doctree; you could use publish_parts for that, I think, and returning a tuple unnecessarily complicates the interface git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3671 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 3 +-- test/test_publisher.py | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 8375fbe89..df35656ad 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -517,8 +517,7 @@ def publish_from_doctree(document, destination_path=None, # Replace existing settings object with new one. document.settings = pub.settings pub.set_destination(None, destination_path) - output = pub.publish(enable_exit_status=enable_exit_status, stage=2) - return output, pub.writer.parts + return pub.publish(enable_exit_status=enable_exit_status, stage=2) def publish_programmatically(source_class, source, source_path, destination_class, destination, destination_path, diff --git a/test/test_publisher.py b/test/test_publisher.py index 39b68cf37..9446c07c2 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -11,7 +11,7 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. """ import pickle -from types import DictType, StringType +from types import StringType import docutils from docutils import core, nodes, io @@ -87,14 +87,13 @@ class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.Sett # not be applied twice. doctree.do_not_expose = 'test' # Write out the document: - output, parts = core.publish_from_doctree( + output = core.publish_from_doctree( doctree, writer_name='pseudoxml', settings_spec=self, settings_overrides={'expose_internals': ['refnames', 'do_not_expose'], 'report_level': 1}) self.assertEquals(output, exposed_pseudoxml_output) - self.assert_(isinstance(parts, DictType)) def test_publish_pickle(self): # Test publishing a document tree with pickling and unpickling. @@ -128,11 +127,10 @@ class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.Sett self.assert_(isinstance(doctree_zombie, nodes.document)) # Write out the document: - output, parts = core.publish_from_doctree( + output = core.publish_from_doctree( doctree_zombie, writer_name='pseudoxml', settings_spec=self) self.assertEquals(output, pseudoxml_output) - self.assert_(isinstance(parts, DictType)) if __name__ == '__main__': -- cgit v1.2.1 From 9095b7661a8313d940241110472c25d7a5fe1997 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Jul 2005 01:03:11 +0000 Subject: restructured links document into "Users" and "Developers" sections; added link to pickle writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3673 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index d663e416b..8732e232b 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -8,20 +8,24 @@ :Date: $Date$ :Copyright: This document has been placed in the public domain. -.. _Docutils: http://docutils.sourceforge.net/ +.. contents:: + +This document contains links users of Docutils and reStructuredText +may find useful, listed in no particular order. Many of the project +listed here are hosted in the `Docutils Sandbox`_. If you have +something to publish, you can get write access, too! The most current version of this document can always be found at http://docutils.sourceforge.net/docs/user/links.html. -Related Projects -================ +Users +----- -These are projects users of Docutils and reStructuredText may find -useful, listed in no particular order. Many of them projects are -hosted in the `Docutils Sandbox`_. All projects are usable by end -users in some way, however please do not expect all of them to run -straight out of the box. +This section contains links which are interesting for all users of +Docutils. All projects listed here are usable by end users in some +way, however please do not expect all of them to run straight out of +the box. * For Wikis, please see the `FAQ entry about Wikis`_. @@ -36,14 +40,6 @@ straight out of the box. * ZReST_, by Richard Jones, is a "ReStructuredText Document for Zope" application that is complete and ready to install. -* PySource_, by Tony Ibbs, is an experimental Python source Reader. - In some form, it will soon become part of core Docutils. There is - some related code in David Goodger's sandbox (pysource_reader_) and - a `Python Source Reader`_ document. - - .. Is this usable for end users? Maybe move to a "Developers" - section? - * The Docutils interface to PythonPoint_, also by Richard Jones, produces PDF presentations using ReportLabs. @@ -67,6 +63,21 @@ straight out of the box. * Beni Cherniavsky maintains a Makefile_ for driving Docutils, hoping to handle everything one might do with Docutils. + +Developers +---------- + +This section contains links which are primarily interesting for +developers. + +* PySource_, by Tony Ibbs, is an experimental Python source Reader. + There is some related code in David Goodger's sandbox + (pysource_reader_) and a `Python Source Reader`_ document. + +* There is a `pickle writer`_, written by Martin Blais. + + +.. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax .. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ @@ -86,3 +97,4 @@ straight out of the box. .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ .. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ .. _Makefile: http://docutils.sf.net/sandbox/cben/make/ +.. _pickle writer: http://docutils.sf.net/sandbox/blais/pickle_writer/ -- cgit v1.2.1 From 019c9db1733295e6c56937d6a77005dba70b4fb9 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Jul 2005 01:32:57 +0000 Subject: moved document refurbishing logic to doctree reader; added source_class argument to publish_parts; improved docstring git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3674 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 27 +++++++++++---------------- docutils/readers/doctree.py | 11 ++++++++++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index df35656ad..b666006f3 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -409,7 +409,8 @@ def publish_string(source, source_path=None, destination_path=None, enable_exit_status=enable_exit_status) return output -def publish_parts(source, source_path=None, destination_path=None, +def publish_parts(source, source_path=None, source_class=io.StringInput, + destination_path=None, reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=None, writer_name='pseudoxml', @@ -430,7 +431,7 @@ def publish_parts(source, source_path=None, destination_path=None, Parameters: see `publish_programmatically`. """ output, pub = publish_programmatically( - source_class=io.StringInput, source=source, source_path=source_path, + source=source, source_path=source_path, source_class=source_class, destination_class=io.StringOutput, destination=None, destination_path=destination_path, reader=reader, reader_name=reader_name, @@ -509,13 +510,6 @@ def publish_from_doctree(document, destination_path=None, pub.set_writer(writer_name) pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) - # Create fresh Transformer object, to be populated from Writer component. - document.transformer = Transformer(document) - # Create fresh Reporter object because it is dependent on (new) settings. - document.reporter = utils.new_reporter(document.get('source', ''), - pub.settings) - # Replace existing settings object with new one. - document.settings = pub.settings pub.set_destination(None, destination_path) return pub.publish(enable_exit_status=enable_exit_status, stage=2) @@ -543,14 +537,15 @@ def publish_programmatically(source_class, source, source_path, * `source`: Type depends on `source_class`: - - `io.FileInput`: Either a file-like object (must have 'read' and - 'close' methods), or ``None`` (`source_path` is opened). If neither - `source` nor `source_path` are supplied, `sys.stdin` is used. + - If `source_class` is `io.FileInput`: Either a file-like object + (must have 'read' and 'close' methods), or ``None`` + (`source_path` is opened). If neither `source` nor + `source_path` are supplied, `sys.stdin` is used. - - `io.StringInput` **required**: The input string, either an encoded - 8-bit string (set the 'input_encoding' setting to the correct - encoding) or a Unicode string (set the 'input_encoding' setting to - 'unicode'). + - If `source_class` is `io.StringInput` **required**: The input + string, either an encoded 8-bit string (set the + 'input_encoding' setting to the correct encoding) or a Unicode + string (set the 'input_encoding' setting to 'unicode'). * `source_path`: Type depends on `source_class`: diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py index ec56e4099..4ae7bd792 100644 --- a/docutils/readers/doctree.py +++ b/docutils/readers/doctree.py @@ -6,7 +6,7 @@ """Reader for existing document trees.""" -from docutils import readers, utils +from docutils import readers, utils, transforms class Reader(readers.Reader): @@ -37,3 +37,12 @@ class Reader(readers.Reader): Overrides the inherited method. """ self.document = self.input + # Create fresh Transformer object, to be populated from Writer + # component. + self.document.transformer = transforms.Transformer(self.document) + # Replace existing settings object with new one. + self.document.settings = self.settings + # Create fresh Reporter object because it is dependent on + # (new) settings. + self.document.reporter = utils.new_reporter( + self.document.get('source', ''), self.document.settings) -- cgit v1.2.1 From 526bafba0ff4159728a02f9b068ce7f7a5d01cd6 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 8 Jul 2005 04:28:24 +0000 Subject: Added simple use case test for publishing document as parts. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3675 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publisher.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/test_publisher.py b/test/test_publisher.py index 9446c07c2..28fecff62 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -11,7 +11,7 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. """ import pickle -from types import StringType +from types import StringType, DictType import docutils from docutils import core, nodes, io @@ -95,6 +95,12 @@ class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.Sett 'report_level': 1}) self.assertEquals(output, exposed_pseudoxml_output) + # Test publishing parts using document as the source. + parts = core.publish_parts( + reader_name='doctree', source_class=io.DocTreeInput, source=doctree, + source_path='test', writer_name='html') + self.assert_(isinstance(parts, DictType)) + def test_publish_pickle(self): # Test publishing a document tree with pickling and unpickling. -- cgit v1.2.1 From 8c971c59a30b64858764817eece8107b5291c944 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 12 Jul 2005 02:51:42 +0000 Subject: fixed target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3742 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index 493f4aa53..4ad94c5a7 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -369,7 +369,7 @@ _`strict_visitor` Default: disabled (None). Option: ``--strict-visitor`` (hidden, for development use only). --`title` +_`title` The document title as metadata, which does not become part of the document body. It overrides a document-supplied title. For example, in HTML output the metadata document title appears in the -- cgit v1.2.1 From 4da3f78e325199d751f8c4d7a58d9adf69da32eb Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Jul 2005 09:17:04 +0000 Subject: added link to xhtml2rest git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3751 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/user/links.txt b/docs/user/links.txt index 8732e232b..dc19b277b 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -31,6 +31,9 @@ the box. * For Blogs (Weblogs), please see the `FAQ entry about Blogs`_. +* xhtml2rest_, written by Antonios Christofides, is a simple utility + to convert XHTML to reStructuredText. + * rst2chm_, written by Oliver Rutherfurd, generates Microsoft HTML Help files from reStructuredText files. @@ -80,6 +83,7 @@ developers. .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax +.. _xhtml2rest: http://docutils.sf.net/sandbox/felixwiemann/xhtml2rest/ .. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ .. _rest2web: http://www.voidspace.org.uk/python/rest2web/ .. _Docutils Sandbox: http://docutils.sf.net/sandbox/README.html -- cgit v1.2.1 From bb5cbfdbbbee01fe6f2ba086d4221f24c6615b44 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Jul 2005 09:49:04 +0000 Subject: replaced "document" with "link list" so that the file is found when googling for ``docutils link list`` git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3754 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index dc19b277b..a45d1f0d9 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -15,7 +15,7 @@ may find useful, listed in no particular order. Many of the project listed here are hosted in the `Docutils Sandbox`_. If you have something to publish, you can get write access, too! -The most current version of this document can always be found at +The most current version of this link list can always be found at http://docutils.sourceforge.net/docs/user/links.html. -- cgit v1.2.1 From 44dd1be96f0bddb777aaa4c14d27b4ba4469677d Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 14 Jul 2005 13:50:07 +0000 Subject: Moved rst2ht to link list; it's not a blog. Moved htmlnav to link list; it's not a blog either. Removed restblog; it's outdated and doesn't work. Removed ReSTWeb; the current URL is <http://wingware.com/pub/restweb/> and it doesn't look like it's maintained anymore. Removed redundant HT2HTML-integration link; it's the same as rst2ht. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3755 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 4 ---- docs/user/links.txt | 13 ++++++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 674604c89..d071ab86f 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -414,10 +414,6 @@ order: * `Firedrop <http://www.voidspace.org.uk/python/firedrop2/>`__ * `Python Desktop Server <http://pyds.muensterland.org/>`__ * `PyBloxsom <http://roughingit.subtlehints.net/pyblosxom/>`__ -* `rst2ht <http://www.rutherfurd.net/articles/rst-ht2html.html>`__ -* `htmlnav <http://docutils.sourceforge.net/sandbox/gschwant/htmlnav/>`__ -* `restblog <http://docutils.sourceforge.net/sandbox/mly/restblog/>`__ -* `ReSTWeb <http://wingide.com/opensource/restweb>`__ * `Lino WebMan <http://lino.sourceforge.net/webman.html>`__ Please `let us know`_ of any other reStructuredText Blogs. diff --git a/docs/user/links.txt b/docs/user/links.txt index a45d1f0d9..dff58ab0a 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -31,6 +31,12 @@ the box. * For Blogs (Weblogs), please see the `FAQ entry about Blogs`_. +* rst2ht_, by Oliver Rutherfurd, converts reStructuredText to an .ht + template, for use with ht2html_. + +* htmlnav_, by Gunnar Schwant, is an HTML writer which supports + navigation bars. + * xhtml2rest_, written by Antonios Christofides, is a simple utility to convert XHTML to reStructuredText. @@ -48,8 +54,7 @@ the box. * Engelbert Gruber has begun a `ManPage Writer`_. -* Oliver Rutherfurd has begun a `DocBook Writer`_ component and - `HT2HTML integration`_ component. +* Oliver Rutherfurd has begun a `DocBook Writer`_. * Gunnar Schwant's DocFactory_ is a wxPython GUI application for Docutils. @@ -83,6 +88,9 @@ developers. .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax +.. _rst2ht: http://www.rutherfurd.net/articles/rst-ht2html.html +.. _ht2html: http://ht2html.sourceforge.net/ +.. _htmlnav: http://docutils.sf.net/sandbox/gschwant/htmlnav/ .. _xhtml2rest: http://docutils.sf.net/sandbox/felixwiemann/xhtml2rest/ .. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ .. _rest2web: http://www.voidspace.org.uk/python/rest2web/ @@ -95,7 +103,6 @@ developers. .. _Manpage Writer: http://docutils.sf.net/sandbox/grubert/man/ .. _ReportLabs/PDF Writer: http://docutils.sf.net/sandbox/dreamcatcher/rlpdf/ .. _DocBook Writer: http://docutils.sf.net/sandbox/oliverr/docbook/ -.. _HT2HTML integration: http://docutils.sf.net/sandbox/oliverr/ht/ .. _DocFactory: http://docutils.sf.net/sandbox/gschwant/docfactory/doc/ .. _OpenOffice.org Writer: http://docutils.sf.net/sandbox/pobrien/OpenOffice/ .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ -- cgit v1.2.1 From 28495b77f0cef86904c8075b24a15a418dbb610c Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 15 Jul 2005 13:38:57 +0000 Subject: added an explicit reminder of expected errors, in the form of an error git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3756 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/demo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/user/rst/demo.txt b/docs/user/rst/demo.txt index 7e57b6bad..7a0abd033 100644 --- a/docs/user/rst/demo.txt +++ b/docs/user/rst/demo.txt @@ -544,7 +544,9 @@ Error Handling Any errors caught during processing will generate system messages. -There should be five messages in the following, auto-generated +|*** Expect 6 errors (including this one). ***| + +There should be six messages in the following, auto-generated section, "Docutils System Messages": .. section should be added by Docutils automatically -- cgit v1.2.1 From db5f6bea2e5a9cdb64d77f8bea90f04e6f98c121 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 15 Jul 2005 16:41:36 +0000 Subject: removed latex-notes.txt; moved to wiki: http://docutils.python-hosting.com/wiki/NewLatex git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3757 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex-notes.txt | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 tools/stylesheets/latex-notes.txt diff --git a/tools/stylesheets/latex-notes.txt b/tools/stylesheets/latex-notes.txt deleted file mode 100644 index 92da02491..000000000 --- a/tools/stylesheets/latex-notes.txt +++ /dev/null @@ -1,39 +0,0 @@ -Try the commands mentioned in -<http://groups.google.de/groups?selm=c7opho%248ts%241%40wsc10.lrz-muenchen.de>. - - -Regarding UTF-8: - -* Read <http://article.gmane.org/gmane.text.docutils.user/1863>. - -* From <http://article.gmane.org/gmane.text.docutils.user/1861>:: - - > The amssymb package and the postscript option were simply so that - > LaTeX could find the fonts and symbol definitions for the particular - > Unicode characters I used. - > However the DeclareUnicodeCharacter directive was to work around a - > missing or misnamed character in the UCS database. - - -<http://www.tug.org/applications/pdftex/pdfTeX-FAQ.pdf>:: - - 3.1.6. How can I make a document portable to both latex and pdflatex - Contributed by: Christian Kumpf - Check for the existence of the variable \pdfoutput: - \newif\ifpdf - \ifx\pdfoutput\undefined - \pdffalse % we are not running PDFLaTeX - \else - \pdfoutput=1 % we are running PDFLaTeX - \pdftrue - \fi - Then use your new variable \ifpdf - \ifpdf - \usepackage[pdftex]{graphicx} - \pdfcompresslevel=9 - \else - \usepackage{graphicx} - \fi - - -Need to handle paragraph indenting manually (in the writer). -- cgit v1.2.1 From dc98554c2fc0308774c70dcebc6fe45617f22e00 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 15 Jul 2005 21:28:22 +0000 Subject: more precise error message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3759 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 4 ++-- test/functional/expected/dangerous.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 87131277d..dadcdae68 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -117,8 +117,8 @@ def csv_table(name, arguments, options, content, lineno, if ( not state.document.settings.file_insertion_enabled and (options.has_key('file') or options.has_key('url')) ): warning = state_machine.reporter.warning( - '"%s" directive disabled.' % name, - nodes.literal_block(block_text, block_text), line=lineno) + 'File and URL access deactivated; ignoring "%s" directive.' % + name, nodes.literal_block(block_text,block_text), line=lineno) return [warning] check_requirements(name, lineno, block_text, state_machine) title, messages = make_title(arguments, state, lineno) diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 9b9c321b6..89e86864b 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -46,14 +46,14 @@ </div> <div class="system-message"> <p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">functional/input/dangerous.txt</tt>, line 13)</p> -<p>"csv-table" directive disabled.</p> +<p>File and URL access deactivated; ignoring "csv-table" directive.</p> <pre class="literal-block"> .. csv-table:: :file: /etc/passwd </pre> </div> <div class="system-message"> <p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">functional/input/dangerous.txt</tt>, line 14)</p> -<p>"csv-table" directive disabled.</p> +<p>File and URL access deactivated; ignoring "csv-table" directive.</p> <pre class="literal-block"> .. csv-table:: :url: file:///etc/passwd </pre> -- cgit v1.2.1 From ac59b2c6739587c69ab2b5e7f1212e1b17529651 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 15 Jul 2005 21:38:42 +0000 Subject: fixed test case (no settings_spec) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3760 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_publisher.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_publisher.py b/test/test_publisher.py index 28fecff62..f395eb419 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -97,8 +97,9 @@ class PublishDoctreeTestCase(DocutilsTestSupport.StandardTestCase, docutils.Sett # Test publishing parts using document as the source. parts = core.publish_parts( - reader_name='doctree', source_class=io.DocTreeInput, source=doctree, - source_path='test', writer_name='html') + reader_name='doctree', source_class=io.DocTreeInput, + source=doctree, source_path='test', writer_name='html', + settings_spec=self) self.assert_(isinstance(parts, DictType)) def test_publish_pickle(self): -- cgit v1.2.1 From 7da476da6fda4e6f2be21d683c9616844ed55c37 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Jul 2005 19:59:35 +0000 Subject: removed note on Unicode support of csv-table directive; ASCII NUL limitation isn't worth being documented (there is an explanatory error message); encoding option has been implemented git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3761 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 73c0b39ca..b5941c8de 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -744,12 +744,6 @@ Working limitations: .. Add "strict" option to verify input? -* Due to limitations of the CSV parser, this directive is not Unicode - compatible. It may also have problems with ASCII NUL characters. - Accordingly, CSV tables should be ASCII-printable safe. - - .. Test with Unicode; see if that's really so. "encoding" option? - The following options are recognized: ``class`` : text -- cgit v1.2.1 From 625b851763602bdb417647a4eac9cf2fb0365a2f Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Jul 2005 21:29:51 +0000 Subject: removed a lot of paragraph-handling code; some was unnecessary, some will be replaced by custom paragraph-indentation logic in the Python module; always add space around transitions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3762 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 68 ++++++++++++++++++++++++------------------ tools/stylesheets/latex.tex | 56 +++++++++++----------------------- 2 files changed, 56 insertions(+), 68 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index e508fdcea..c1579fa83 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -701,28 +701,38 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def is_invisible(self, node): # Return true if node is invisible or moved away in the LaTeX # rendering. - return (isinstance(node, nodes.Invisible) or - isinstance(node, nodes.footnote) or - isinstance(node, nodes.citation) or - # We never know what's inside raw nodes, and often - # they *are* invisible. So let's have the user take - # care of them. - isinstance(node, nodes.raw) or - # Horizontally aligned image or figure. - node.get('align', None) in ('left', 'center', 'right')) + return (not isinstance(node, nodes.Text) and + (isinstance(node, nodes.Invisible) or + isinstance(node, nodes.footnote) or + isinstance(node, nodes.citation) or + # We never know what's inside raw nodes, and often + # they *are* invisible. So let's have the user take + # care of them. + isinstance(node, nodes.raw) or + # Horizontally aligned image or figure. + node.get('align', None) in ('left', 'center', 'right'))) def is_visible(self, node): return not self.is_invisible(node) def needs_space(self, node): + """ + Two nodes for which `needs_space` is true need auxiliary space. + """ # Return true if node is a visible block-level element. return ((isinstance(node, nodes.Body) or - isinstance(node, nodes.topic) or - #isinstance(node, nodes.rubric) or - isinstance(node, nodes.transition)) and + isinstance(node, nodes.topic)) and not (self.is_invisible(node) or isinstance(node.parent, nodes.TextElement))) + def always_needs_space(self, node): + """ + Always add space around nodes for which `always_needs_space` + is true, regardless of whether the other node needs space as + well. (E.g. transition next to section.) + """ + return isinstance(node, nodes.transition) + def dispatch_departure(self, node): # Call departure method. nodes.SparseNodeVisitor.dispatch_departure(self, node) @@ -733,21 +743,21 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.append(self.context.pop() + self.context.pop()) # Delete \Dcurrent... attribute macros. self.append(self.context.pop()) - # Insert space. - if self.needs_space(node): - # Next sibling. - next_node = node.next_node( - ascend=0, siblings=1, descend=0, - condition=self.is_visible) - if self.needs_space(next_node): - # Insert space. - if isinstance(next_node, nodes.paragraph): - if isinstance(node, nodes.paragraph): - # Space between paragraphs. - self.append(r'\Dparagraphspace') - else: - # Space in front of a paragraph. - self.append(r'\Dauxiliaryparspace') + # Get next sibling. + next_node = node.next_node( + ascend=0, siblings=1, descend=0, + condition=self.is_visible) + # Insert space if necessary. + if (self.always_needs_space(node) or + self.always_needs_space(next_node) or + self.needs_space(node) and self.needs_space(next_node)): + if isinstance(next_node, nodes.paragraph): + if isinstance(node, nodes.paragraph): + # Space between paragraphs. + self.append(r'\Dparagraphspace') else: - # Space in front of something else than a paragraph. - self.append(r'\Dauxiliaryspace') + # Space in front of a paragraph. + self.append(r'\Dauxiliaryparspace') + else: + # Space in front of something else than a paragraph. + self.append(r'\Dauxiliaryspace') diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index a73d78822..dbbcddb3a 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -87,33 +87,17 @@ } \providecommand{\Dauxiliaryspace}{% \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \Dpar\noindent% + \par\noindent% } \providecommand{\Dauxiliaryparspace}{% \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \Dpar% + \par% } - \providecommand{\Dparagraphspace}{\Dpar} + \providecommand{\Dparagraphspace}{\par} \providecommand{\Dneedvspace}{true} } -\providecommand{\DSparagraphs}{ - \providecommand{\Dnextparindent}{} - \providecommand{\Dnextpar}{\par} - %\newcommand{\Dnextpar}{\par\Dnextparindent} - \providecommand{\Dpar}{% - \Dnextpar% - \Dnextparindent% - \protect\renewcommand{\Dnextpar}{\par}% - \protect\renewcommand{\Dnextparindent}{}% - } - \providecommand{\Dnopar}{% - \protect\renewcommand{\Dnextpar}{\par}% - \protect\renewcommand{\Dnextparindent}{}% - } -} - \providecommand{\DSlinks}{ % Targets and references. \usepackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} @@ -265,12 +249,12 @@ \providecommand{\Dtopictitle}[1]{% \noindent\Dformatboxtitle{#1}% \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% - \Dpar\noindent% + \par% } \providecommand{\Dtopicsubtitle}[1]{% - \Dformatboxsubtitle{#1}% + \noindent\Dformatboxsubtitle{#1}% \vspace{1em}% - \Dpar\noindent% + \par% } \providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}} \providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}} @@ -376,7 +360,6 @@ \par\noindent% #1% \addtocounter{Dtoclevel}{-1}% - \renewcommand{\Dnextparindent}{\noindent}% }{% \par\noindent% \Dmakebox{#1}% @@ -385,7 +368,7 @@ \providecommand{\Dformatrubric}[1]{\textbf{#1}} \Dprovidelength{\Dprerubricspace}{0.3em} \providecommand{\DNrubric}[1]{% - \vspace{\Dprerubricspace}\Dpar\noindent\Dformatrubric{#1}\Dpar\noindent% + \vspace{\Dprerubricspace}\par\noindent\Dformatrubric{#1}\par% } \providecommand{\Dbullet}{} @@ -683,7 +666,7 @@ \providecommand{\Dformatclassifier}[1]{\textsl{#1}} \providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} \providecommand{\Dformatdefinition}[1]{#1} -\providecommand{\DNdefinition}[1]{\Dpar\Dformatdefinition{#1}} +\providecommand{\DNdefinition}[1]{\par\Dformatdefinition{#1}} \providecommand{\Dlineblockindentation}{2.5em} \providecommand{\DNlineblock}[1]{% @@ -705,7 +688,7 @@ \providecommand{\DNtransition}{% - \Dpar\noindent{}\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}% + \hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}% } @@ -716,14 +699,12 @@ } \providecommand{\Dformatattribution}[1]{---\textup{#1}} \providecommand{\DNblockquote}[1]{% - \renewcommand{\Dnextparindent}{\noindent}% - \renewcommand{\Dnextpar}{}% \Dmakebox{% \Dformatblockquote{#1} }% } \providecommand{\DNattribution}[1]{% - \Dpar% + \par% \begin{flushright}\Dformatattribution{#1}\end{flushright}% } @@ -743,11 +724,10 @@ \Dprovidelength{\Dsidebarwidth}{0.45\linewidth} \providecommand{\DNsidebar}[1]{ \parpic[\Dsidebarposition]{% - \Dpar% - \begin{minipage}[t]{\Dsidebarwidth} + \begin{minipage}[t]{\Dsidebarwidth}% % Doing this with nested minipages is ugly, but I haven't found % another way to place vertical space before and after the fbox. - \vspace{\Dsidebarvmargin} + \vspace{\Dsidebarvmargin}% {% \setlength{\fboxrule}{\Dsidebarframewidth}% \setlength{\fboxsep}{\Dsidebarpadding}% @@ -758,7 +738,7 @@ \end{minipage}% }% }% - \vspace{\Dsidebarvmargin} + \vspace{\Dsidebarvmargin}% \end{minipage}% }% } @@ -783,8 +763,8 @@ }% } \providecommand{\DNcitationreference}[1]{{[}#1{]}} -\Dprovidelength{\Dfootnotesep}{5pt} -\providecommand{\Dfootnotespacing}{% +\Dprovidelength{\Dfootnotesep}{3.5pt} +\providecommand{\Dsetfootnotespacing}{% % Spacing commands executed at the beginning of footnotes. \setlength{\parindent}{0pt}% \hspace{1em}% @@ -793,7 +773,8 @@ % See ltfloat.dtx for details. {% \insert\footins{% - \Dnopar\vspace{\Dfootnotesep}\Dfootnotespacing% + \vspace{\Dfootnotesep}% + \Dsetfootnotespacing% \Dformatfootnote{#1}% }% }% @@ -826,8 +807,6 @@ }% % If there are multiple backrefs, add them now. \Dformatmultiplebackrefs{\Dmultiplebackrefs}% - % Supress next paragraph change. - \renewcommand{\Dnextpar}{}% } \providecommand{\Dsinglefootnotebacklink}[2]{% % Create normal backlink of a footnote label. Parameters: @@ -1088,7 +1067,6 @@ \DSboxcommands \DSfrenchspacing \DSauxiliaryspace -\DSparagraphs \DSlinks \DSsymbols \DSlate -- cgit v1.2.1 From ad50a0e2fa254098f6b7893e77c4ff14cac7ebae Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Jul 2005 23:08:06 +0000 Subject: split developers section into API and Core developers; added link to nabu git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3763 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index dff58ab0a..2332bc065 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -72,18 +72,31 @@ the box. to handle everything one might do with Docutils. -Developers ----------- +API Developers +-------------- This section contains links which are primarily interesting for -developers. +developers who use the Docutils API from within their own +applications. + +* nabu_, written by Martin Blais, is a publishing system which + extracts information from reStructuredText documents and stores it + in a database. Python knowledge is required to write extractor + functions (see `Writing an Extractor`_ for an example). + +* There is a `pickle writer`_, written by Martin Blais. + + +Core Developers +--------------- + +Links primarily interesting for developers who work with the Docutils +code base. * PySource_, by Tony Ibbs, is an experimental Python source Reader. There is some related code in David Goodger's sandbox (pysource_reader_) and a `Python Source Reader`_ document. -* There is a `pickle writer`_, written by Martin Blais. - .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax @@ -108,4 +121,6 @@ developers. .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ .. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ .. _Makefile: http://docutils.sf.net/sandbox/cben/make/ +.. _nabu: http://furius.ca/nabu/ +.. _Writing an Extractor: http://furius.ca/nabu/doc/nabu-extractor.html .. _pickle writer: http://docutils.sf.net/sandbox/blais/pickle_writer/ -- cgit v1.2.1 From 3d8992eb68df05f4e6c36fba2ad61be7f79df0d8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 17 Jul 2005 23:11:33 +0000 Subject: clarified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3764 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 2332bc065..8b1ba74c6 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -82,7 +82,8 @@ applications. * nabu_, written by Martin Blais, is a publishing system which extracts information from reStructuredText documents and stores it in a database. Python knowledge is required to write extractor - functions (see `Writing an Extractor`_ for an example). + functions (see `Writing an Extractor`_) and to retrieve the data + from the database again. * There is a `pickle writer`_, written by Martin Blais. -- cgit v1.2.1 From e930c4045e6caf9fabd9775bc8e319c8ac687128 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 18 Jul 2005 01:23:24 +0000 Subject: fixed error; added section about wiki git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3765 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index ed4d69789..a16d0ec24 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -351,7 +351,15 @@ Mailing Lists Developers are recommended to subscribe to all `mailing lists`_. -.. _mailing lists:: ../user/mailing-lists.html +.. _mailing lists: ../user/mailing-lists.html + + +The Wiki +======== + +There is a development wiki at http://docutils.python-hosting.com/ as +a scratchpad for transient notes. Please use the repository for +permament document storage. The Sandbox -- cgit v1.2.1 From bd5d3204ec71f70e01164372d96230af029fd1c6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 18 Jul 2005 23:10:42 +0000 Subject: Make use of \Dlanguagebabel. Added \Dprinting for output primarily for printing, not online viewing. Some clean-up in the LaTeX stylesheet. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3766 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 4 +- docutils/writers/newlatex2e.py | 15 ++-- tools/stylesheets/latex.tex | 182 +++++++++++++++++++++-------------------- 3 files changed, 105 insertions(+), 96 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 8b1ba74c6..3ea6035e9 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -79,7 +79,7 @@ This section contains links which are primarily interesting for developers who use the Docutils API from within their own applications. -* nabu_, written by Martin Blais, is a publishing system which +* Nabu_, written by Martin Blais, is a publishing system which extracts information from reStructuredText documents and stores it in a database. Python knowledge is required to write extractor functions (see `Writing an Extractor`_) and to retrieve the data @@ -122,6 +122,6 @@ code base. .. _simple HTML writer: http://docutils.sf.net/sandbox/bbum/DocArticle/ .. _preprocessing module: http://docutils.sf.net/sandbox/cben/rolehack/ .. _Makefile: http://docutils.sf.net/sandbox/cben/make/ -.. _nabu: http://furius.ca/nabu/ +.. _Nabu: http://furius.ca/nabu/ .. _Writing an Extractor: http://furius.ca/nabu/doc/nabu-extractor.html .. _pickle writer: http://docutils.sf.net/sandbox/blais/pickle_writer/ diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index c1579fa83..3701b41a9 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -179,8 +179,15 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def write_header(self): a = self.header.append - a('%% Generated by Docutils %s <http://docutils.sourceforge.net>.\n' + a('%% Generated by Docutils %s <http://docutils.sourceforge.net>.' % docutils.__version__) + a('') + a('% Docutils settings:') + lang = self.settings.language_code or '' + a(r'\providecommand{\Dlanguageiso}{%s}' % lang) + a(r'\providecommand{\Dlanguagebabel}{%s}' % self.iso639_to_babel.get( + lang, self.iso639_to_babel.get(lang.split('_')[0], ''))) + a('') if self.user_stylesheet_path: a('% User stylesheet:') a(r'\input{%s}' % self.user_stylesheet_path) @@ -199,12 +206,6 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dtitleastext}{x}') a(r'\providecommand{\Dsinglebackref}{} % variable') a(r'\providecommand{\Dmultiplebackrefs}{} % variable') - a('') - a('% Docutils settings:') - lang = self.settings.language_code or '' - a(r'\providecommand{\Dlanguageiso}{%s}' % lang) - a(r'\providecommand{\Dlanguagebabel}{%s}' % self.iso639_to_babel.get( - lang, self.iso639_to_babel.get(lang.split('_')[0], ''))) a('\n\n') # Get comprehensive Unicode map. diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index dbbcddb3a..aee91b56f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -1,14 +1,27 @@ \makeatletter -\providecommand{\DSpackages}{% - % All kinds of useful packages. - \usepackage{ifthen} -} +% Development notes at +% http://docutils.python-hosting.com/wiki/NewLatex + + +\providecommand{\Dprinting}{false} + + +\providecommand{\DSearly}{} +\providecommand{\DSlate}{} + +\providecommand{\Ddocumentclass}{scrartcl} +\providecommand{\Ddocumentoptions}{a4paper} + +\documentclass[\Ddocumentoptions]{\Ddocumentclass} + +\DSearly \providecommand{\DSfontencoding}{ - % T1-emulation. Provides most characters and features we're used - % from T1-encoded fonts but doesn't use bitmap fonts. + % Set up font encoding. + % AE is a T1-emulation. It provides most characters and features + % as T1-encoded fonts but doesn't use ugly bitmap fonts. \usepackage{ae} % Provide the characters not contained in AE from EC bitmap fonts. \usepackage{aecompl} @@ -18,9 +31,10 @@ \providecommand{\DSsymbols}{% + % Fix up symbols. % The Euro symbol in Computer Modern looks, um, funny. Let's get a % proper Euro symbol. - \usepackage{eurosym}% + \RequirePackage{eurosym}% \renewcommand{\texteuro}{\euro}% } @@ -44,63 +58,59 @@ \@ifundefined{c@#1}{\newcounter{#1}}{} } -\providecommand{\DSboxcommands}{ - \Dprovidelength{\Dboxparindent}{\parindent} - \providecommand{\Dmakeboxminipage}[1]{% - % Make minipage for use in a box created by \Dmakefbox. - \begin{minipage}[t]{0.9\linewidth}% - \setlength{\parindent}{\Dboxparindent}% - ##1% - \end{minipage}% - } - \providecommand{\Dmakefbox}[1]{% - % Make a centered, framed box. Useful e.g. for admonitions. - \vspace{0.4\baselineskip}% - \begin{center}% - \fbox{\Dmakeboxminipage{##1}}% - \end{center}% - \vspace{0.4\baselineskip}% - } - \providecommand{\Dmakebox}[1]{% - % Make a centered, frameless box. Useful e.g. for block quotes. - % Do not use minipages here, but create pseudo-lists to allow - % page-breaking. (Don't use KOMA-script's addmargin environment - % because it messes up bullet lists.) - \Dmakelistenvironment{}{}{% - \setlength{\parskip}{0pt}% - \setlength{\parindent}{\Dboxparindent}% - \item{##1}% - }% - } +\Dprovidelength{\Dboxparindent}{\parindent} +\providecommand{\Dmakeboxminipage}[1]{% + % Make minipage for use in a box created by \Dmakefbox. + \begin{minipage}[t]{0.9\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% +} +\providecommand{\Dmakefbox}[1]{% + % Make a centered, framed box. Useful e.g. for admonitions. + \vspace{0.4\baselineskip}% + \begin{center}% + \fbox{\Dmakeboxminipage{#1}}% + \end{center}% + \vspace{0.4\baselineskip}% +} +\providecommand{\Dmakebox}[1]{% + % Make a centered, frameless box. Useful e.g. for block quotes. + % Do not use minipages here, but create pseudo-lists to allow + % page-breaking. (Don't use KOMA-script's addmargin environment + % because it messes up bullet lists.) + \Dmakelistenvironment{}{}{% + \setlength{\parskip}{0pt}% + \setlength{\parindent}{\Dboxparindent}% + \item{#1}% + }% } -\providecommand{\DSfrenchspacing}{ - \frenchspacing -} +\RequirePackage{ifthen} +\providecommand{\Dfrenchspacing}{true} +\ifthenelse{\equal{\Dfrenchspacing}{true}}{\frenchspacing}{} -\providecommand{\DSauxiliaryspace}{ - \Dprovidelength{\Dblocklevelvspace}{% - % Space between block-level elements other than paragraphs. - 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% - } - \providecommand{\Dauxiliaryspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \par\noindent% - } - \providecommand{\Dauxiliaryparspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \par% - } - \providecommand{\Dparagraphspace}{\par} - \providecommand{\Dneedvspace}{true} +\Dprovidelength{\Dblocklevelvspace}{% + % Space between block-level elements other than paragraphs. + 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% +} +\providecommand{\Dauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \par\noindent% } +\providecommand{\Dauxiliaryparspace}{% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \par% +} +\providecommand{\Dparagraphspace}{\par} +\providecommand{\Dneedvspace}{true} \providecommand{\DSlinks}{ % Targets and references. - \usepackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} + \RequirePackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} \providecommand{\Draisedlink}[1]{\Hy@raisedlink{##1}} @@ -137,7 +147,6 @@ }% } % Targets. - \Dprovidelength{\Dorgbaselineskip}{0pt} \providecommand{\DAids}[5]{% \label{##3}% \ifthenelse{\equal{##4}{footnotereference}}{% @@ -145,7 +154,7 @@ \renewcommand{\HyperRaiseLinkDefault}{% % Dirty hack to make backrefs to footnote references work. % For some reason, \baselineskip is 0pt in fn references. - 0.5\Dorgbaselineskip% + 0.5\Doriginalbaselineskip% }% \Draisedlink{\hypertarget{##3}{}}##5% }% @@ -154,7 +163,7 @@ }% } % Color in references. - \usepackage{color} + \RequirePackage{color} \providecommand{\Dimplicitreference}[2]{% % Create implicit reference to ID. Implicit references occur % e.g. in TOC-backlinks of section titles. Parameters: @@ -171,18 +180,24 @@ % Ditto for citation references. \Dimplicitfootnotereference{##1}{##2}% } + \ifthenelse{\equal{\Dprinting}{true}}{ + \providecommand{\Dexplicitreferencecolor}{black} + }{ + \providecommand{\Dexplicitreferencecolor}{blue} + } \providecommand{\Dexplicitreference}[2]{% % Create explicit reference to ID, e.g. created with "foo_". % Parameters: % 1. Target. % 2. Link text. - \href{##1}{{\color{blue}##2}}% + \href{##1}{{\color{\Dexplicitreferencecolor}##2}}% } + \providecommand{\Durireferencecolor}{\Dexplicitreferencecolor} \providecommand{\Durireference}[2]{% % Create reference to URI. Parameters: % 1. Target. % 2. Link text. - \href{##1}{{\color{blue}##2}}% + \href{##1}{{\color{\Durireferencecolor}##2}}% } } @@ -190,24 +205,13 @@ \providecommand{\DSlanguage}{% % Set up babel. \ifthenelse{\equal{\Dlanguagebabel}{}}{}{ - \usepackage[\Dlanguagebabel]{babel} + \RequirePackage[\Dlanguagebabel]{babel} } } -\providecommand{\DSearly}{} -\providecommand{\DSlate}{} - -\providecommand{\Ddocumentclass}{scrartcl} -\providecommand{\Ddocumentoptions}{a4paper} - -\documentclass[\Ddocumentoptions]{\Ddocumentclass} - -\DSearly - - \providecommand{\DAclasses}[5]{% \Difdefined{DN#4C#3}{% % Pass only contents, nothing else! @@ -247,6 +251,7 @@ \providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} \providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} \providecommand{\Dtopictitle}[1]{% + \Difinsidetoc{\vspace{1em}\par}{}% \noindent\Dformatboxtitle{#1}% \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% \par% @@ -302,12 +307,15 @@ } \providecommand{\Dsectionsubtitlehook}[1]{#1} \Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} +\providecommand{\Dsectionsubtitlescaling}{0.85} \providecommand{\Dsectionsubtitle}[1]{% \Dsectionsubtitlehook{% % Move the subtitle nearer to the title. \vspace{-\Dsectionsubtitleraisedistance}% % Don't create a PDF bookmark. - \Ddispatchsectionsubtitle{\Dformatsectionsubtitle{\scalebox{.8}{#1}}}% + \Ddispatchsectionsubtitle{% + \Dformatsectionsubtitle{\scalebox{\Dsectionsubtitlescaling}{#1}}% + }% }% } % Boolean variable. @@ -347,7 +355,7 @@ % Treat doctest blocks the same as literal blocks. \DNliteralblock{#1}% } -\usepackage{hyphenat} +\RequirePackage{hyphenat} \providecommand{\DNliteral}[1]{\textnhtt{#1}} \providecommand{\DNemphasis}[1]{\emph{#1}} \providecommand{\DNstrong}[1]{\textbf{#1}} @@ -356,7 +364,6 @@ \providecommand{\DNtopic}[1]{% \ifthenelse{\equal{\DcurrentNtopicAcontents}{1}}{% \addtocounter{Dtoclevel}{1}% - \vspace{1em}% \par\noindent% #1% \addtocounter{Dtoclevel}{-1}% @@ -688,7 +695,7 @@ \providecommand{\DNtransition}{% - \hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}% + \raisebox{0.25em}{\parbox{\linewidth}{\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}}}% } @@ -710,7 +717,7 @@ % Sidebars: -\usepackage{picins} +\RequirePackage{picins} % Vertical and horizontal margins. \Dprovidelength{\Dsidebarvmargin}{0.5em} \Dprovidelength{\Dsidebarhmargin}{1em} @@ -755,10 +762,11 @@ }% } \providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}} +\Dprovidelength{\Doriginalbaselineskip}{0pt} \providecommand{\DNfootnotereference}[1]{% {% % \baselineskip is 0pt in \textsuperscript, so we save it here. - \setlength{\Dorgbaselineskip}{\baselineskip}% + \setlength{\Doriginalbaselineskip}{\baselineskip}% \textsuperscript{#1}% }% } @@ -786,7 +794,10 @@ \textsuperscript{\footnotesize#1{ }}% } \providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }} -\providecommand{\Dformatmultiplebackrefs}[1]{\textsl{#1}} +\providecommand{\Dformatmultiplebackrefs}[1]{% + % If in printing mode, do not write out multiple backrefs. + \ifthenelse{\equal{\Dprinting}{true}}{}{\textsl{#1}}% +} \providecommand{\Dthislabel}{} \providecommand{\DNlabel}[1]{% \renewcommand{\Dthislabel}{#1} @@ -826,7 +837,7 @@ \providecommand{\Dmulticitationbacklink}[2]{\Dmultifootnotebacklink{#1}{#2}} -\usepackage{longtable} +\RequirePackage{longtable} \providecommand{\Dmaketable}[2]{% % Make table. Parameters: % 1. Table spec (like "|p|p|"). @@ -867,7 +878,7 @@ \providecommand{\DNsystemmessage}[1]{% {% - \color{red}% + \ifthenelse{\equal{\Dprinting}{false}}{\color{red}}{}% \bfseries% #1% }% @@ -905,7 +916,7 @@ } -\usepackage{graphicx} +\RequirePackage{graphicx} % Maximum width of an image. \providecommand{\Dimagemaxwidth}{\linewidth} \providecommand{\Dfloatimagemaxwidth}{0.5\linewidth} @@ -1058,15 +1069,12 @@ \providecommand{\Drelativeunit}{\linewidth} -%\usepackage{fixmath} -%\usepackage{amsmath} +%\RequirePackage{fixmath} +%\RequirePackage{amsmath} -\DSpackages \DSfontencoding -\DSboxcommands -\DSfrenchspacing -\DSauxiliaryspace +\DSlanguage \DSlinks \DSsymbols \DSlate -- cgit v1.2.1 From 5c281b455660e3d49431c6545b14e66ffe55306c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 20 Jul 2005 15:06:38 +0000 Subject: merged todo2 branch to trunk git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3770 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 183 ++++++++++++++++++ docs/dev/todo.txt | 439 ++++++++++-------------------------------- 2 files changed, 283 insertions(+), 339 deletions(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 51930be3a..08b994834 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1,6 +1,7 @@ ================================================== A Record of reStructuredText Syntax Alternatives ================================================== + :Author: David Goodger :Contact: goodger@users.sourceforge.net :Revision: $Revision$ @@ -2563,6 +2564,53 @@ Allow for compound enumerators, such as "1.1." or "1.a." or "1(a)", to allow for nested enumerated lists without indentation? +Indented Lists +============== + +Allow for variant styles by interpreting indented lists as if they +weren't indented? For example, currently the list below will be +parsed as a list within a block quote:: + + paragraph + + * list item 1 + * list item 2 + +But a lot of people seem to write that way, and HTML browsers make it +look as if that's the way it should be. The parser could check the +contents of block quotes, and if they contain only a single list, +remove the block quote wrapper. There would be two problems: + +1. What if we actually *do* want a list inside a block quote? + +2. What if such a list comes immediately after an indented construct, + such as a literal block? + +Both could be solved using empty comments (problem 2 already exists +for a block quote after a literal block). But that's a hack. + +Perhaps a runtime setting, allowing or disabling this convenience, +would be appropriate. But that raises issues too: + + User A, who writes lists indented (and their config file is set up + to allow it), sends a file to user B, who doesn't (and their + config file disables indented lists). The result of processing by + the two users will be different. + +It may seem minor, but it adds ambiguity to the parser, which is bad. + +See the `Doc-SIG discussion starting 2001-04-18`__ with Ed Loper's +"Structuring: a summary; and an attempt at EBNF", item 4 (and +follow-ups, here__ and here__). Also `docutils-users, 2003-02-17`__ +and `beginning 2003-08-04`__. + +__ http://mail.python.org/pipermail/doc-sig/2001-April/001776.html +__ http://mail.python.org/pipermail/doc-sig/2001-April/001789.html +__ http://mail.python.org/pipermail/doc-sig/2001-April/001793.html +__ http://sourceforge.net/mailarchive/message.php?msg_id=3838913 +__ http://sf.net/mailarchive/forum.php?thread_id=2957175&forum_id=11444 + + Sloppy Indentation of List Items ================================ @@ -2892,6 +2940,141 @@ than of the character-encoding type. - Specifically, should the default be case-sensistive or -insensitive? + +Page Or Line Breaks +=================== + +* Should ^L (or something else in reST) be defined to mean + force/suggest page breaks in whatever output we have? + + A "break" or "page-break" directive would be easy to add. A new + doctree element would be required though (perhaps "break"). The + final behavior would be up to the Writer. The directive argument + could be one of page/column/recto/verso for added flexibility. + + Currently ^L (Python's ``\f``) characters are treated as whitespace. + They're converted to single spaces, actually, as are vertical tabs + (^K, Python's ``\v``). It would be possible to recognize form feeds + as markup, but it requires some thought and discussion first. Are + there any downsides? Many editing environments do not allow the + insertion of control characters. Will it cause any harm? It would + be useful as a shorthand for the directive. + + It's common practice to use ^L before Emacs "Local Variables" + lists:: + + ^L + .. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: + + These are already present in many PEPs and Docutils project + documents. From the Emacs manual (info): + + A "local variables list" goes near the end of the file, in the + last page. (It is often best to put it on a page by itself.) + + It would be unfortunate if this construct caused a final blank page + to be generated (for those Writers that recognize the page breaks). + We'll have to add a transform that looks for a "break" plus zero or + more comments at the end of a document, and removes them. + + Probably a bad idea because there is no such thing as a page in a + generic document format. + +* Could the "break" concept above be extended to inline forms? + E.g. "^L" in the middle of a sentence could cause a line break. + Only recognize it at the end of a line (i.e., ``\f\n``)? + + Or is formfeed inappropriate? Perhaps vertical tab (``\v``), but + even that's a stretch. Can't use carriage returns, since they're + commonly used for line endings. + + Probably a bad idea as well because we do not want to use control + characters for well-readable and well-writable markup, and after all + we have the line block syntax for line breaks. + + +Superscript Markup +================== + +Add ``^superscript^`` inline markup? The only common non-markup uses +of "^" I can think of are as short hand for "superscript" itself and +for describing control characters ("^C to cancel"). The former +supports the proposed syntax, and it could be argued that the latter +ought to be literal text anyhow (e.g. "``^C`` to cancel"). + +However, superscripts are seldom needed, and new syntax would break +existing documents. When it's needed, the ``:superscript:`` +(``:sup:``) role can we used as well. + + +Code Execution +============== + +Add the following directives? + +- "exec": Execute Python code & insert the results. Call it + "python" to allow for other languages? + +- "system": Execute an ``os.system()`` call, and insert the results + (possibly as a literal block). Definitely dangerous! How to make + it safe? Perhaps such processing should be left outside of the + document, in the user's production system (a makefile or a script or + whatever). Or, the directive could be disabled by default and only + enabled with an explicit command-line option or config file setting. + Even then, an interactive prompt may be useful, such as: + + The file.txt document you are processing contains a "system" + directive requesting that the ``sudo rm -rf /`` command be + executed. Allow it to execute? (y/N) + +- "eval": Evaluate an expression & insert the text. At parse + time or at substitution time? Dangerous? Perhaps limit to canned + macros; see text.date_ below. + +It's too dangerous (or too complicated in the case of "eval"). We do +not want to have such things in the core. + + +``encoding`` Directive +====================== + +Add an "encoding" directive to specify the character encoding of the +input data? Not a good idea for the following reasons: + +- When it sees the directive, the parser will already have read the + input data, and encoding determination will already have been done. + +- If a file with an "encoding" directive is edited and saved with + a different encoding, the directive may cause data corruption. + + +Support for Annotations +======================= + +Add an "annotation" role, as the equivalent of the HTML "title" +attribute? This is secondary information that may "pop up" when the +pointer hovers over the main text. A corresponding directive would be +required to associate annotations with the original text (by name, or +positionally as in anonymous targets?). + +There have not been many requests for such feature, though. Also, +cluttering WYSIWYG plaintext with annotations may not seem like a good +idea, and there is no "tool tip" in formats other than HTML. + + +``term`` Role +============= + +Add a "term" role for unfamiliar or specialized terminology? Probably +not; there is no real use case, and emphasis is enough for most cases. + + .. Local Variables: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index ec1f8c38a..b308b759f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -20,26 +20,19 @@ require more thought and debate; they are potential to-do's. Many of these items are awaiting champions. If you see something you'd like to tackle, please do! If there's something you'd like to -see done but are unable to implement it yourself, `please consider -contributing`__ in other ways. +see done but are unable to implement it yourself, please consider +donating to Docutils: |donate| -__ http://docutils.sf.net/#please-contribute +.. |donate| image:: http://images.sourceforge.net/images/project-support.jpg + :target: http://sourceforge.net/donate/index.php?group_id=38414 + :align: middle + :width: 88 + :height: 32 + :alt: Support the Docutils project! +Please see also the Bugs_ document for a list of bugs in Docutils. -Priorities -========== - -* Always high priority: `FIX BUGS!`__ - - __ ../../BUGS.html - -* A Python Source Reader component (Python auto-documentation) will be - added. See the document `"Plan for Enthought API Documentation - Tool"`__ for details. If you'd like to help, let me know! - - __ enthought-plan.html - -* `Nested inline markup`_. +.. _bugs: ../../BUGS.html Minimum Requirements for Python Standard Library Candidacy @@ -86,15 +79,6 @@ General settings. These partially solve the problem, allowing or disabling **all** file accesses, but not limited access. -* Refactor - - - Rename methods & variables according to the `Python coding - conventions <policies.html#python-coding-conventions>`_. - - - The name-to-id conversion and hyperlink resolution code needs to be - checked for correctness and refactored. I'm afraid it's a bit of - a spaghetti mess now. - * Configuration file handling needs discussion: - There should be some error checking on the contents of config @@ -105,30 +89,24 @@ General file supplied with the ``--config`` option. Should it? (If yes, error or warning?) - - Is a system-wide configuration file (in ``/etc/docutils.conf``) a - good idea? +* Internationalization: - - Is a user-specific configuration file (``~/.docutils``) really - necessary? Maybe the name (``.docutils``) needs discussion, too. + - I18n needs refactoring, the language dictionaries are difficult to + maintain. Maybe have a look at gettext or similar tools. -* Language modules: in accented languages it may be useful to have - both accented and unaccented entries in the ``bibliographic_fields`` - mapping for versatility. + - Language modules: in accented languages it may be useful to have + both accented and unaccented entries in the + ``bibliographic_fields`` mapping for versatility. -* Add a "--strict-language" option & setting: no English fallback for - language-dependent features. + - Add a "--strict-language" option & setting: no English fallback + for language-dependent features. -* Add internationalization to _`footer boilerplate text` (resulting - from "--generator", "--source-link", and "--date" etc.), allowing - translations. + - Add internationalization to _`footer boilerplate text` (resulting + from "--generator", "--source-link", and "--date" etc.), allowing + translations. * Add validation? See http://pytrex.sourceforge.net, RELAX NG, pyRXP. -* Ask Python-dev for opinions (GvR for a pronouncement) on special - variables (__author__, __version__, etc.): convenience vs. namespace - pollution. Ask opinions on whether or not Docutils should recognize - & use them. - * In ``docutils.readers.get_reader_class`` (& ``parsers`` & ``writers`` too), should we be importing "standalone" or "docutils.readers.standalone"? (This would avoid importing @@ -323,17 +301,9 @@ General As I said earlier in chapter :chapter:`objects`, the reference count gets increased every time a binding is made. -* Add testing for Docutils' front end tools? - -* Changes to sandbox/davidg/infrastructure/docutils-update? - - - Modify the script to only update the snapshots if files have - actually changed in CVS (saving some SourceForge server cycles). - - - Make passing the test suite a prerequisite to snapshot update, - but only if the process is completely automatic. +* Add support for _`multiple output files`. - - Rewrite in Python? +* Add testing for Docutils' front end tools? * Publisher: "Ordinary setup" shouldn't requre specific ordering; at the very least, there ought to be error checking higher up in the @@ -374,10 +344,6 @@ General * Rationalize Writer settings (HTML/LaTeX/PEP) -- share settings. -* The "docutils.conf" included with Docutils should become complete, - with examples of every setting (many/most commented out). It's - currently sparse, requiring doc lookups. - * Merge docs/user/latex.txt info into tools.txt and config.txt. * Add an "--include file" command-line option (config setting too?), @@ -432,17 +398,6 @@ General could be used by any writer, and applying such classes to all tables in a document with writer options is too broad. -* Make the csv-table directive work with Python 2.1/2.2. (See the - discussion_ on the mailing list.) - - .. _discussion: http://thread.gmane.org/gmane.text.docutils.user/1319 - -* Simplify the docutils.nodes.Element implementation? ``node[x]`` is - convenient but can be considered ambiguous (different results if - ``x`` is a string or an integer). Replace with ``node[int]`` and - ``node.attributes[string]``? See - <http://thread.gmane.org/gmane.text.docutils.devel/2844>. - * Add file-specific settings support to config files, like:: [file index.txt] @@ -572,6 +527,11 @@ General: Miscellaneous ideas: +* Ask Python-dev for opinions (GvR for a pronouncement) on special + variables (__author__, __version__, etc.): convenience vs. namespace + pollution. Ask opinions on whether or not Docutils should recognize + & use them. + * If we can detect that a comment block begins with ``##``, a la JavaDoc, it might be useful to indicate interspersed section headers & explanatory text in a module. For example:: @@ -687,19 +647,13 @@ __ rst/alternatives.html#or-not-to-do on whitespace and punctuation as markup delimiters, which may not be applicable in these languages. - Python 2.4 introduces the function ``unicodedata.east_asian_width``, - so this problem will be resolved later, when Python 2.4 is in a - reasonably stable state and being used more widely. + Especially the table parsers suffer from this problem. -* Clean up the code; refactor as required. + We need to use the ``unicodedata.east_asian_width`` function, + introduced in Python 2.4. * Add motivation sections for constructs in spec. -* Allow very long titles (on two or more lines)? - -* And for the sake of completeness, should definition list terms be - allowed to be very long (two or more lines) also? - * Support generic hyperlink references to _`targets in other documents`? Not in an HTML-centric way, though (it's trivial to say ``http://www.example.com/doc#name``, and useless in non-HTML @@ -747,93 +701,15 @@ __ rst/alternatives.html#or-not-to-do support for "=====" header rows. On 2001-08-17 he replied, saying he'd put it on his to-do list, but "don't hold your breath".) -* Tony says inline markup rule 7 could do with a *little* more - exposition in the spec, to make clear what is going on for people - with head colds. - * Fix the parser's indentation handling to conform with the stricter definition in the spec. (Explicit markup blocks should be strict or forgiving?) -* Tighten up the spec for indentation of "constructs using complex - markers": field lists and option lists? Bodies may begin on the - same line as the marker or on a subsequent line (with blank lines - optional). Require that for bodies beginning on the same line as - the marker, all lines be in strict alignment. Currently, this is - acceptable:: - - :Field-name-of-medium-length: Field body beginning on the same - line as the field name. - - This proposal would make the above example illegal, instead - requiring strict alignment. A field body may either begin on the - same line:: - - :Field-name-of-medium-length: Field body beginning on the same - line as the field name. - - Or it may begin on a subsequent line:: - - :Field-name-of-medium-length: - Field body beginning on a line subsequent to that of the - field name. - - This would be especially relevant in degenerate cases like this:: - - :Number-of-African-swallows-requried-to-carry-a-coconut: - It would be very difficult to align the field body with - the left edge of the first line if it began on the same - line as the field name. - -* Allow for variant styles by interpreting _`indented lists` as if - they weren't indented? For example, currently the list below will - be parsed as a list within a block quote:: - - paragraph - - * list item 1 - * list item 2 - - But a lot of people seem to write that way, and HTML browsers make - it look as if that's the way it should be. The parser could check - the contents of block quotes, and if they contain only a single - list, remove the block quote wrapper. There would be two problems: - - 1. What if we actually *do* want a list inside a block quote? - - 2. What if such a list comes immediately after an indented - construct, such as a literal block? - - Both could be solved using empty comments (problem 2 already exists - for a block quote after a literal block). But that's a hack. - - Perhaps a runtime setting, allowing or disabling this convenience, - would be appropriate. But that raises issues too: - - User A, who writes lists indented (and their config file is set - up to allow it), sends a file to user B, who doesn't (and their - config file disables indented lists). The result of processing - by the two users will be different. - - It may seem minor, but it adds ambiguity to the parser, which is - bad. - - See the `Doc-SIG discussion starting 2001-04-18`__ with Ed Loper's - "Structuring: a summary; and an attempt at EBNF", item 4 (and - follow-ups, here__ and here__). Also `docutils-users, - 2003-02-17`__ and `beginning 2003-08-04`__. - - __ http://mail.python.org/pipermail/doc-sig/2001-April/001776.html - __ http://mail.python.org/pipermail/doc-sig/2001-April/001789.html - __ http://mail.python.org/pipermail/doc-sig/2001-April/001793.html - __ http://sourceforge.net/mailarchive/message.php?msg_id=3838913 - __ http://sf.net/mailarchive/forum.php?thread_id=2957175&forum_id=11444 + .. XXX What does this mean? Can you elaborate, David? * Make the parser modular. Allow syntax constructs to be added or - disabled at run-time. Or is subclassing enough? - -* Continue to report (info, level 1) enumerated lists whose start - value is not ordinal-1? + disabled at run-time. Subclassing is probably not enough because it + makes it difficult to apply multiple extensions. * Generalize the "doctest block" construct (which is overly Python-centric) to other interactive sessions? "Doctest block" @@ -869,10 +745,6 @@ __ rst/alternatives.html#or-not-to-do Some pragma directives could be local-scope unless explicitly specified as global/pragma using ":global:" options. -* Remove leading numbers from section titles for implicit link names? - A section titled "3. Conclusion" could then be referred to by - "``Conclusion_``" (i.e., without the "3."). - * Support whitespace in angle-bracketed standalone URLs according to Appendix E ("Recommendations for Delimiting URI in Context") of `RFC 2396`_. @@ -898,8 +770,18 @@ __ rst/alternatives.html#or-not-to-do Decimal justification? -* Make enumerated list parsing more strict, so that this would parse - as a paragraph with an info message:: + All this shouldn't be done automatically. Only when it's requested + by the user, e.g. with something like this:: + + .. table:: + :auto-indent: + + (Table goes here.) + + Otherwise it will break existing documents. + +* Generate a warning or info message for paragraphs which should have + been lists, like this one:: 1. line one 3. line two @@ -907,53 +789,6 @@ __ rst/alternatives.html#or-not-to-do * Generalize the "target-notes" directive into a command-line option somehow? See docutils-develop 2003-02-13. -* Should ^L (or something else in reST) be defined to mean - force/suggest page breaks in whatever output we have? - - A "break" or "page-break" directive would be easy to add. A new - doctree element would be required though (perhaps "break"). The - final behavior would be up to the Writer. The directive argument - could be one of page/column/recto/verso for added flexibility. - - Currently ^L (Python's ``\f``) characters are treated as whitespace. - They're converted to single spaces, actually, as are vertical tabs - (^K, Python's ``\v``). It would be possible to recognize form feeds - as markup, but it requires some thought and discussion first. Are - there any downsides? Many editing environments do not allow the - insertion of control characters. Will it cause any harm? It would - be useful as a shorthand for the directive. - - It's common practice to use ^L before Emacs "Local Variables" - lists:: - - ^L - .. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: - - These are already present in many PEPs and Docutils project - documents. From the Emacs manual (info): - - A "local variables list" goes near the end of the file, in the - last page. (It is often best to put it on a page by itself.) - - It would be unfortunate if this construct caused a final blank page - to be generated (for those Writers that recognize the page breaks). - We'll have to add a transform that looks for a "break" plus zero or - more comments at the end of a document, and removes them. - -* Could the "break" concept above be extended to inline forms? - E.g. "^L" in the middle of a sentence could cause a line break. - Only recognize it at the end of a line (i.e., ``\f\n``)? - - Or is formfeed inappropriate? Perhaps vertical tab (``\v``), but - even that's a stretch. Can't use carriage returns, since they're - commonly used for line endings. - * Allow a "::"-only paragraph (first line, actually) to introduce a _`literal block without a blank line`? (Idea from Paul Moore.) :: @@ -985,12 +820,6 @@ __ rst/alternatives.html#or-not-to-do Probably not worth the trouble. -* Add ``^superscript^`` inline markup? The only common non-markup - uses of "^" I can think of are as short hand for "superscript" - itself and for describing control characters ("^C to cancel"). The - former supports the proposed syntax, and it could be argued that the - latter ought to be literal text anyhow (e.g. "``^C`` to cancel"). - * Add _`math markup`. We should try for a general solution, that's applicable to any output format. Using a standard, such as MathML_, would be best. TeX (or itex_) would be acceptable as a *front-end* @@ -1027,9 +856,8 @@ __ rst/alternatives.html#or-not-to-do .. _name: ^url -* Add an option to allow arbitrary URI schemes (not just those in - urischemes.py)? This would make text like "signal:noise" into a - URI. + This may be too specific to HTML. It hasn't been requested very + often either. * Add an option to add URI schemes at runtime. @@ -1062,8 +890,8 @@ __ rst/alternatives.html#or-not-to-do LaTeX writer (which might very well happen when using configuration files), the spaces in front of footnote references aren't trimmed. -* Enable _`tables inside XML comments`, where "--" ends comments. I - see three implementation possibilities: +* Enable grid _`tables inside XML comments`, where "--" ends comments. + I see three implementation possibilities: 1. Make the table syntax characters into "table" directive options. This is the most flexible but most difficult, and we probably @@ -1080,6 +908,11 @@ __ rst/alternatives.html#or-not-to-do tables are document-specific. A pragma directive would be another approach, to set the syntax once for a whole document. + In the meantime, the list-table_ directive is a good replacement for + grid tables inside XML comments. + + .. _list-table: ../ref/rst/directives.html#list-table + Directives ---------- @@ -1115,13 +948,12 @@ when used in a document. - Allow the _`:trim:` option for all directives when they occur in a substitution definition, not only the unicode_ directive. - .. _unicode: - http://docutils.sf.net/docs/ref/rst/directives.html#unicode-character-codes + .. _unicode: ../ref/rst/directives.html#unicode-character-codes - _`images.figure`: "title" and "number", to indicate a formal figure? - - _`parts.sectnum`: "local"?, "start", "refnum" + - _`parts.sectnum`: "local"?, "refnum" A "local" option could enable numbering for sections from a certain point down, and sections in the rest of the document are @@ -1129,32 +961,12 @@ when used in a document. be numbered, but not the rest. OTOH, an all-or-nothing approach would probably be enough. - The "start" option will specify the sequence set to use at the - same time as the starting value, for the first part of the section - number (i.e., section, not subsection). For example:: - - .. sectnum: :start: 1 - - .. sectnum: :start: A - - .. sectnum: :start: 5 - - .. sectnum: :start: I - - The first one is the default: start at 1, numbered. The second - one specifies letters, and start at "A". The third specifies - numbers, start at 5. The last example could signal Roman - numerals, although I don't know if they'd be applicable here. - Enumerated lists already do all this; perhaps that code could be - reused. - - Here comes the tricky part. The "sectnum" directive should be - usable multiple times in a single document. For example, in a - long document with "chapter" and "appendix" sections, there could - be a second "sectnum" before the first appendix, changing the - sequence used (from 1,2,3... to A,B,C...). This is where the - "local" concept comes in. This part of the implementation can be - left for later. + The "sectnum" directive should be usable multiple times in a + single document. For example, in a long document with "chapter" + and "appendix" sections, there could be a second "sectnum" before + the first appendix, changing the sequence used (from 1,2,3... to + A,B,C...). This is where the "local" concept comes in. This part + of the implementation can be left for later. A "refnum" option (better name?) would insert reference names (targets) consisting of the reference number. Then a URL could be @@ -1177,6 +989,9 @@ when used in a document. & footers? For example, separate headers & footers for odd, even, and the first page of a document. + This may be too specific to output formats which have a notion of + "pages". + - _`misc.include`: - Option to select a range of lines? @@ -1203,61 +1018,37 @@ when used in a document. It needs thought & discussion though, to come up with a consistent set of destination labels and consistent behavior. + And placing HTML code inside the <head> element of an HTML + document is rather the job of a templating system. + - _`body.sidebar`: Allow internal section structure? Adornment styles would be independent of the main document. + That is really complicated, however, and the document model + greatly benefits from its simplicity. + * Implement directives. Each of the list items below begins with an identifier of the form, "module_name.directive_function_name". The directive name itself could be the same as the directive_function_name, or it could differ. - - _`html.imagemap` (Useful outside of HTML? If not, replace with - image only in non-HTML writers?) + - _`html.imagemap` - - _`parts.endnotes` (or "footnotes"): See `Footnote & Citation Gathering`_. - - - _`parts.citations`: See `Footnote & Citation Gathering`_. - - - _`misc.exec`: Execute Python code & insert the results. Perhaps - dangerous? Call it "python" to allow for other languages? - - - _`misc.system`?: Execute an ``os.system()`` call, and insert the - results (possibly as a literal block). Definitely dangerous! How - to make it safe? Perhaps such processing should be left outside - of the document, in the user's production system (a makefile or a - script or whatever). Or, the directive could be disabled by - default and only enabled with an explicit command-line option or - config file setting. Even then, an interactive prompt may be - useful, such as: - - The file.txt document you are processing contains a "system" - directive requesting that the ``sudo rm -rf /`` command be - executed. Allow it to execute? (y/N) + It has the disadvantage that it's only easily implementable for + HTML, so it's specific to one output format. - - _`misc.eval`: Evaluate an expression & insert the text. At parse - time or at substitution time? Dangerous? Perhaps limit to canned - macros; see text.date_ below. + (For non-HTML writers, the imagemap would have to be replaced with + the image only.) - - _`misc.encoding`: Specify the character encoding of the input - data. But there are problems: - - - When it sees the directive, the parser will already have read - the input data, and encoding determination will already have - been done. - - - If a file with an "encoding" directive is edited and saved with - a different encoding, the directive may cause data corruption. - - - _`misc.language`: Specify the language of a document. There is a - problem similar to the first problem listed for misc.encoding_, - although to a lesser degree. + - _`parts.endnotes` (or "footnotes"): See `Footnote & Citation Gathering`_. - - _`misc.settings`: Set any Docutils runtime setting from within a - document? + - _`parts.citations`: See `Footnote & Citation Gathering`_. - - _`misc.charents`: Equivalent to:: + - _`misc.language`: Specify (= change) the language of a document at + parse time. - .. include:: {includepath}/charents.txt + - _`misc.settings`: Set any(?) Docutils runtime setting from within + a document? Needs much thought and discussion. - .. _conditional directives: @@ -1487,17 +1278,6 @@ which will be transformed into standard hyperlink references, which will be processed by the various Writers. No Writer will need to have any knowledge of the Python-Reader origin of these elements. -* Alan Jaffray suggested (and I agree) that it would be sensible to: - - - have a directive and/or command-line option to specify a default - role for interpreted text (done) - - allow the reST processor to take an argument for the default role - (this will be subsumed by the above via the runtime settings - mechanism) - - issue a warning when processing documents with no default role - which contain interpreted text with no explicitly specified role - (there will always be a default role, so this won't happen) - * Add explicit interpreted text roles for the rest of the implicit inline markup constructs: named-reference, anonymous-reference, footnote-reference, citation-reference, substitution-reference, @@ -1580,17 +1360,17 @@ any knowledge of the Python-Reader origin of these elements. __ ../ref/rst/restructuredtext.html#implicit-hyperlink-targets - - "annotation": The equivalent of the HTML "title" attribute. This - is secondary information that may "pop up" when the pointer hovers - over the main text. A corresponding directive would be required - to associate annotations with the original text (by name, or - positionally as in anonymous targets?). + 4. Using substitutions? :: + + .. |reST| acronym:: reST + :text: reStructuredText + + What do we do for other formats than HTML which do not support + tool tips? Put the full text in parentheses? - "figure", "table", "listing", "chapter", "page", etc: See `object numbering and object references`_ above. - - "term"?: Unfamiliar or specialized terminology. - - "glossary-term": This would establish a link to a glossary. It would require an associated "glossary-entry" directive, whose contents could be a definition list:: @@ -1614,13 +1394,6 @@ Unimplemented Transforms Collect and move footnotes & citations to the end of a document. (Separate transforms.) -* _`Hyperlink Target Gathering` - - It probably comes in two phases, because in a Python context we need - to *resolve* them on a per-docstring basis [do we? --DG], but if the - user is trying to do the callout form of presentation, they would - then want to group them all at the end of the document. - * _`Reference Merging` When merging two or more subdocuments (such as docstrings), @@ -1713,20 +1486,17 @@ Unimplemented Transforms HTML Writer =========== -* Test with modern browsers if it's possible to remove the "name" - attributes, which currently serve only for backwards-compatibility - to browsers which aren't XHTML compliant. For a starting point, see - http://www.python.org/dev/doc/idtest.html. - - If enough browsers support the "id" attribute, remove the "name" - attributes. - * Add more support for <link> elements, especially for navigation bars. -* Make the admonitions more distinctive and varied. + The framework does not have a notion of document relationships, so + probably raw.destination_ should be used. + + We'll have framework support for document relationships when support + for `multiple output files`_ is added. The HTML writer could + automatically generate <link> elements then. -* Make the "class" attributes optional? Implies no stylesheet? + .. _raw.destination: misc.raw_ * Base list compaction on the spacing of source list? Would require parser support. (Idea: fantasai, 16 Dec 2002, doc-sig.) @@ -1734,17 +1504,6 @@ HTML Writer * Add a tool tip ("title" attribute?) to footnote back-links identifying them as such. Text in Docutils language module. -* Insert a comment at the top of HTML files that describes how to deal - with the broken servers w.r.t. encodings? Perhaps something like - this: - - <!-- - If your browser is showing gibberish, the server may be broken. - Try manually setting the character coding to "UTF-8". In - Mozilla/Firefox, do ... In Internet Explorer, do ... - For details, see <URL>. - --> - LaTeX writer ============ @@ -2017,7 +1776,9 @@ Front-End Tools * Disable common options that don't apply? -* Implement the "sectnum" directive as a command-line option also? +* Add ``--section-numbering`` command line option. The "sectnum" + directive should override the ``--no-section-numbering`` command + line option then. * Create a single dynamic_ or unqualified_ front end that can be installed? -- cgit v1.2.1 From b19a84d73effa7aaca88ef62caabc506b5d281c6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 20 Jul 2005 15:12:00 +0000 Subject: fixed link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3772 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 08b994834..6a3354739 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -3035,7 +3035,9 @@ Add the following directives? - "eval": Evaluate an expression & insert the text. At parse time or at substitution time? Dangerous? Perhaps limit to canned - macros; see text.date_ below. + macros; see text.date_. + + .. _text.date: ../todo.html#text-date It's too dangerous (or too complicated in the case of "eval"). We do not want to have such things in the core. -- cgit v1.2.1 From 7478f8e665b355da0641c6dd31f44160dfd63414 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Jul 2005 00:45:52 +0000 Subject: added webware wiki git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3774 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FAQ.txt b/FAQ.txt index d071ab86f..7d321d900 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -383,6 +383,8 @@ Are there any Wikis that use reStructuredText syntax? There are several, with various degrees of completeness. With no implied endorsement or recommendation, and in no particular order: +* `Webware for Python wiki + <http://wiki.webwareforpython.org/thiswiki.html>`__ * `Ian Bicking's experimental code <http://docutils.sf.net/sandbox/ianb/wiki/WikiPage.py>`__ * `MoinMoin <http://moin.sf.net>`__ has some support; `here's a sample -- cgit v1.2.1 From 0494cac038b9de233f3a0e96391bf4611f420423 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Jul 2005 00:46:56 +0000 Subject: added note about East Asian character widths git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3775 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b308b759f..dfddc2fcb 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -652,6 +652,13 @@ __ rst/alternatives.html#or-not-to-do We need to use the ``unicodedata.east_asian_width`` function, introduced in Python 2.4. + From `Unicode Standard Annex #11: East Asian Width + <http://www.unicode.org/reports/tr11/>`_: + + In a broad sense, wide characters include W, F, and A (when in + EA context), while narrow characters include N, Na, H, and A + (when not in EA context). + * Add motivation sections for constructs in spec. * Support generic hyperlink references to _`targets in other -- cgit v1.2.1 From 845b7d6360e28760e3f904f487d815ddfba53f18 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Jul 2005 00:47:21 +0000 Subject: clarified _stylesheet_required git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3776 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index 4ad94c5a7..d63b5b5bf 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -912,8 +912,11 @@ _`_source` Default: stdin (None). No command-line options. _`_stylesheet_required` - Used to disable stylesheet checking in writers that require a - stylesheet for correct rendering. For programmatic use only. + Writers that require stylesheets for correct rendering will check + and warn if valid stylesheet settings are absent. This setting is + used to enable stylesheet checking in writers and applications + that require a stylesheet, and disable checking in writers and + applications that don't. For programmatic use only. Default: required (1). No command-line options. -- cgit v1.2.1 From 1da732b52647b11e5dec0d202bede9ed758dcd3a Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 29 Jul 2005 23:38:08 +0000 Subject: added hyperlinks to files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3777 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/substitutions.txt | 92 +++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/docs/ref/rst/substitutions.txt b/docs/ref/rst/substitutions.txt index d4ff17a42..882239086 100644 --- a/docs/ref/rst/substitutions.txt +++ b/docs/ref/rst/substitutions.txt @@ -73,43 +73,43 @@ Character Entity Sets The following files contain substitution definitions corresponding to XML character entity sets, from the following standards: ISO 8879 & ISO 9573-13 (combined), MathML, and XHTML1. They were generated by -the ``tools/unicode2rstsubs.py`` program from the input file +the ``tools/dev/unicode2rstsubs.py`` program from the input file unicode.xml__, which is maintained as part of the MathML 2 Recommentation XML source. __ http://www.w3.org/2003/entities/xml/ -================== ================================================== -Entity Set File Description -================== ================================================== -isoamsa.txt Added Mathematical Symbols: Arrows -isoamsb.txt Added Mathematical Symbols: Binary Operators -isoamsc.txt Added Mathematical Symbols: Delimiters -isoamsn.txt Added Mathematical Symbols: Negated Relations -isoamso.txt Added Mathematical Symbols: Ordinary -isoamsr.txt Added Mathematical Symbols: Relations -isobox.txt Box and Line Drawing -isocyr1.txt Russian Cyrillic -isocyr2.txt Non-Russian Cyrillic -isodia.txt Diacritical Marks -isogrk1.txt Greek Letters -isogrk2.txt Monotoniko Greek -isogrk3.txt Greek Symbols -isogrk4.txt [1]_ Alternative Greek Symbols -isolat1.txt Added Latin 1 -isolat2.txt Added Latin 2 -isomfrk.txt [1]_ Mathematical Fraktur -isomopf.txt [1]_ Mathematical Openface (Double-struck) -isomscr.txt [1]_ Mathematical Script -isonum.txt Numeric and Special Graphic -isopub.txt Publishing -isotech.txt General Technical -mmlalias.txt MathML aliases for entities from other sets -mmlextra.txt [1]_ Extra names added by MathML -xhtml4-lat1.txt XHTML Latin 1 -xhtml4-special.txt XHTML Special Characters -xhtml4-symbol.txt XHTML Mathematical, Greek and Symbolic Characters -================== ================================================== +=================== ================================================= +Entity Set File Description +=================== ================================================= +isoamsa.txt_ Added Mathematical Symbols: Arrows +isoamsb.txt_ Added Mathematical Symbols: Binary Operators +isoamsc.txt_ Added Mathematical Symbols: Delimiters +isoamsn.txt_ Added Mathematical Symbols: Negated Relations +isoamso.txt_ Added Mathematical Symbols: Ordinary +isoamsr.txt_ Added Mathematical Symbols: Relations +isobox.txt_ Box and Line Drawing +isocyr1.txt_ Russian Cyrillic +isocyr2.txt_ Non-Russian Cyrillic +isodia.txt_ Diacritical Marks +isogrk1.txt_ Greek Letters +isogrk2.txt_ Monotoniko Greek +isogrk3.txt_ Greek Symbols +isogrk4.txt_ [1]_ Alternative Greek Symbols +isolat1.txt_ Added Latin 1 +isolat2.txt_ Added Latin 2 +isomfrk.txt_ [1]_ Mathematical Fraktur +isomopf.txt_ [1]_ Mathematical Openface (Double-struck) +isomscr.txt_ [1]_ Mathematical Script +isonum.txt_ Numeric and Special Graphic +isopub.txt_ Publishing +isotech.txt_ General Technical +mmlalias.txt_ MathML aliases for entities from other sets +mmlextra.txt_ [1]_ Extra names added by MathML +xhtml4-lat1.txt_ XHTML Latin 1 +xhtml4-special.txt_ XHTML Special Characters +xhtml4-symbol.txt_ XHTML Mathematical, Greek and Symbolic Characters +=================== ================================================= .. [1] There are ``*-wide.txt`` variants for each of these character entity set files, containing characters outside of the Unicode @@ -124,6 +124,34 @@ entity ``©``. The equivalent reStructuredText substitution reference (defined in both ``isonum.txt`` and ``xhtml1-lat1.txt``) is ``|copy|``. +.. _isoamsa.txt: ../../../docutils/parsers/rst/include/isoamsa.txt +.. _isoamsb.txt: ../../../docutils/parsers/rst/include/isoamsb.txt +.. _isoamsc.txt: ../../../docutils/parsers/rst/include/isoamsc.txt +.. _isoamsn.txt: ../../../docutils/parsers/rst/include/isoamsn.txt +.. _isoamso.txt: ../../../docutils/parsers/rst/include/isoamso.txt +.. _isoamsr.txt: ../../../docutils/parsers/rst/include/isoamsr.txt +.. _isobox.txt: ../../../docutils/parsers/rst/include/isobox.txt +.. _isocyr1.txt: ../../../docutils/parsers/rst/include/isocyr1.txt +.. _isocyr2.txt: ../../../docutils/parsers/rst/include/isocyr2.txt +.. _isodia.txt: ../../../docutils/parsers/rst/include/isodia.txt +.. _isogrk1.txt: ../../../docutils/parsers/rst/include/isogrk1.txt +.. _isogrk2.txt: ../../../docutils/parsers/rst/include/isogrk2.txt +.. _isogrk3.txt: ../../../docutils/parsers/rst/include/isogrk3.txt +.. _isogrk4.txt: ../../../docutils/parsers/rst/include/isogrk4.txt +.. _isolat1.txt: ../../../docutils/parsers/rst/include/isolat1.txt +.. _isolat2.txt: ../../../docutils/parsers/rst/include/isolat2.txt +.. _isomfrk.txt: ../../../docutils/parsers/rst/include/isomfrk.txt +.. _isomopf.txt: ../../../docutils/parsers/rst/include/isomopf.txt +.. _isomscr.txt: ../../../docutils/parsers/rst/include/isomscr.txt +.. _isonum.txt: ../../../docutils/parsers/rst/include/isonum.txt +.. _isopub.txt: ../../../docutils/parsers/rst/include/isopub.txt +.. _isotech.txt: ../../../docutils/parsers/rst/include/isotech.txt +.. _mmlalias.txt: ../../../docutils/parsers/rst/include/mmlalias.txt +.. _mmlextra.txt: ../../../docutils/parsers/rst/include/mmlextra.txt +.. _xhtml4-lat1.txt: ../../../docutils/parsers/rst/include/xhtml4-lat1.txt +.. _xhtml4-special.txt: ../../../docutils/parsers/rst/include/xhtml4-special.txt +.. _xhtml4-symbol.txt: ../../../docutils/parsers/rst/include/xhtml4-symbol.txt + .. Local Variables: -- cgit v1.2.1 From 679456246112254d9408e9da6ab70787a4eda0bf Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Jul 2005 04:53:02 +0000 Subject: clarified/simplified git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3779 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 2282beac2..41045b84e 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -723,14 +723,16 @@ escaped in order to have the line parsed as an ordinary paragraph:: \A. Einstein was a really smart dude. -Nested enumerated lists must be created with indentation. For -example:: +Examples of nested enumerated lists:: - 1. Item 1. + 1. Item 1 initial text. a) Item 1a. b) Item 1b. + 2. a) Item 2a. + b) Item 2b. + Example syntax diagram:: +-------+----------------------+ -- cgit v1.2.1 From c7f93a0617050e0586600e7a48dfe11780063292 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Jul 2005 04:54:59 +0000 Subject: added directive idea git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3780 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index dfddc2fcb..294602281 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1176,6 +1176,9 @@ when used in a document. See docutils-users 2003-03-03. + - _`body.listing`: Code listing with title (to be numbered + eventually), equivalent of "figure" and "table" directives. + - _`colorize.python`: Colorize Python code. Fine for HTML output, but what about other formats? Revert to a literal block? Do we need some kind of "alternate" mechanism? Perhaps use a "pending" -- cgit v1.2.1 From cb3e29f5cdd66d66d7db59b90e0ae3ddf48e4bb7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Jul 2005 04:55:24 +0000 Subject: added bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3781 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index a51c9ac5f..6eece4a14 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -111,6 +111,12 @@ Known Bugs Also see the `SourceForge Bug Tracker`_. +* The "stylesheet" setting (a URL, to be used verbatim) should be + allowed to be combined with "embed_stylesheet". The stylesheet data + should be read in using urllib. There was an assumption that a + stylesheet to be embedded should exist as a file on the local + system, and only the "stylesheet_path" setting should be used. + * ``utils.relative_path()`` sometimes returns absolute _`paths on Windows` (like ``C:/test/foo.css``) where it could have chosen a relative path. -- cgit v1.2.1 From cca84bc8890a87670569bfe427fb61b04d318bf5 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 30 Jul 2005 04:55:40 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3782 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS.txt b/THANKS.txt index 66f32d952..e42b0001c 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -64,6 +64,7 @@ donations, tasty treats, and related projects: * Ludger Humbert * Jeremy Hylton * Tony Ibbs +* Alan G. Isaac * Alan Jaffray * Joe YS Jaw * Dmitry Jemerov -- cgit v1.2.1 From 9ecfb13519d9089e5040161c76ea157487c0b069 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 31 Jul 2005 16:12:50 +0000 Subject: added a bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3784 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index 6eece4a14..d1d98979a 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -175,6 +175,36 @@ Also see the `SourceForge Bug Tracker`_. all IDs from definitions after the first substitution reference is processed. +* There's a bug with _`inline literals in substitutions`:: + + .. |x| replace:: ``x`` + + x |x| + + Parsing, the inline literal context disappears:: + + <document source="<stdin>"> + <substitution_definition names="x"> + x + <paragraph> + x + x + + Here's a probably related bug:: + + .. |x| replace:: ``.`` + + Parsing this results in:: + + <system_message level="3" line="1" source="<stdin>" type="ERROR"> + <paragraph> + Error in "replace" directive: may contain a single paragraph only. + <system_message level="2" line="1" source="<stdin>" type="WARNING"> + <paragraph> + Substitution definition "x" empty or invalid. + <literal_block xml:space="preserve"> + .. |x| replace:: . + * Footnote label "5" should be "4":: $ rst2pseudoxml.py <<EOF -- cgit v1.2.1 From 139e2c721441f1348abdee17b40ebd9d52ca1814 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 31 Jul 2005 16:19:28 +0000 Subject: whitespace git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3785 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index d1d98979a..47d473c3d 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -187,7 +187,7 @@ Also see the `SourceForge Bug Tracker`_. <substitution_definition names="x"> x <paragraph> - x + x x Here's a probably related bug:: @@ -209,7 +209,7 @@ Also see the `SourceForge Bug Tracker`_. $ rst2pseudoxml.py <<EOF > ref [#abc]_ [#]_ [1]_ [#4]_ - > + > > .. [#abc] footnote > .. [#] two > .. [1] one @@ -272,7 +272,7 @@ Also see the `SourceForge Bug Tracker`_. .. _section: This paragraph is explicitly targeted with the name "section". - + When processed to HTML, the 2 internal hyperlinks (to "contents" & "section") will work fine, but hyperlinks from outside the document using ``href="...#contents"`` and ``href="...#section"`` won't work. -- cgit v1.2.1 From 01f344cfa4ebf63ce930644ca126783542418347 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 4 Aug 2005 03:00:27 +0000 Subject: add "new in Docutils 0.3.8" notice to auto-enumerated lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3786 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 41045b84e..23f6469b4 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -673,7 +673,8 @@ The following enumeration sequences are recognized: In addition, the auto-enumerator, "#", may be used to automatically enumerate a list. Auto-enumerated lists may begin with explicit enumeration, which sets the sequence. Fully auto-enumerated lists use -arabic numerals and begin with 1. +arabic numerals and begin with 1. (Auto-enumerated lists are new in +Docutils 0.3.8.) The following formatting types are recognized: @@ -1165,7 +1166,7 @@ Syntax diagram:: Line Blocks ----------- -Doctree elements: line_block, line. New in Docutils 0.3.5. +Doctree elements: line_block, line. (New in Docutils 0.3.5.) Line blocks are useful for address blocks, verse (poetry, song lyrics), and unadorned lists, where the structure of lines is -- cgit v1.2.1 From 45eb6921c60524610114b518a6f6bb5d72b42e00 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 7 Aug 2005 07:44:03 +0000 Subject: Added missing generic filter function. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3787 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 3c670a224..64444f3a8 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -26,6 +26,20 @@ ;; arg easily with C-- C-= (easy to type), as well as ordinary prefix arg with ;; C-u C-=. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Generic Filter function. + +(if (not (fboundp 'filter)) + (defun filter (pred list) + "Returns a list of all the elements fulfilling the pred requirement (that +is for which (pred elem) is true)" + (if list + (let ((head (car list)) + (tail (filter pred (cdr list)))) + (if (funcall pred head) + (cons head tail) + tail))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Generic text functions that are more convenient than the defaults. -- cgit v1.2.1 From 995a73c5bf8b437660c2504491a1b82ec8d16297 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 7 Aug 2005 08:27:19 +0000 Subject: Added a fix to the underlining function that makes it less disturbing when you position the cursor on the underline. Also, fixed the tests. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3788 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 52 +++++++++++++---------- tools/editors/emacs/tests/tests-adjust-section.el | 4 +- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 64444f3a8..b5f08a641 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -390,34 +390,36 @@ This is useful for filling list item paragraphs." (interactive) - ;; check if we're on an underline under a title line, and move the cursor up - ;; if it is so. - (if (and (or (rest-line-single-char-p 1) - (looking-at "^\\s-*$")) - (save-excursion - (forward-line -1) - (beginning-of-line) - (looking-at "^.+$"))) - (forward-line -1)) - - (let ( - ;; find current sectioning character - (curchar (rest-current-section-char)) - ;; find current sectioning style - (init-style (rest-initial-sectioning-style)) - ;; find current indentation of title line - (curindent (save-excursion - (back-to-indentation) - (current-column))) - - ;; ending column + (let* ( + ;; check if we're on an underline under a title line, and move the + ;; cursor up if it is so. + (moved + (if (and (or (rest-line-single-char-p 1) + (looking-at "^\\s-*$")) + (save-excursion + (forward-line -1) + (beginning-of-line) + (looking-at "^.+$"))) + (progn (forward-line -1) t) + )) + + ;; find current sectioning character + (curchar (rest-current-section-char)) + ;; find current sectioning style + (init-style (rest-initial-sectioning-style)) + ;; find current indentation of title line + (curindent (save-excursion + (back-to-indentation) + (current-column))) + + ;; ending column (endcol (- (save-excursion (end-of-line) (current-column)) (save-excursion (back-to-indentation) (current-column)))) - ) + ) ;; if there is no current style found... (if (eq init-style nil) @@ -500,7 +502,11 @@ This is useful for filling list item paragraphs." (if nextchar (rest-update-section nextchar init-style curindent)) ))) - ))) + ) + + (if moved + (progn (forward-line 1) (end-of-line))) + )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index 43215fb98..5af65d56a 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -196,8 +196,8 @@ Some Title " (t)) )) - - "A list of regression tests for the section update method.") + +;; "A list of regression tests for the section update method." -- cgit v1.2.1 From d854c9bf42f3c21b876ad51e3c691def7e072840 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 10 Aug 2005 02:49:06 +0000 Subject: fixed enumerated list bug (SF#1254145) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3789 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 17 +++++++++-------- test/test_parsers/test_rst/test_enumerated_lists.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 4156fd682..175334fd2 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1289,14 +1289,15 @@ class Body(RSTState): self.state_machine.previous_line() if not next_line[:1].strip(): # blank or indented return 1 - next_enumerator, auto_enumerator = self.make_enumerator( - ordinal + 1, sequence, format) - try: - if ( next_line.startswith(next_enumerator) or - next_line.startswith(auto_enumerator) ): - return 1 - except TypeError: - pass + result = self.make_enumerator(ordinal + 1, sequence, format) + if result: + next_enumerator, auto_enumerator = result + try: + if ( next_line.startswith(next_enumerator) or + next_line.startswith(auto_enumerator) ): + return 1 + except TypeError: + pass return None def make_enumerator(self, ordinal, sequence, format): diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index b0be498b4..6824efdbb 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -811,6 +811,16 @@ ii. Item two. #. Item two. 3. Item three. """], +["""\ +z. +x +""", +"""\ +<document source="test data"> + <paragraph> + z. + x +"""], ] -- cgit v1.2.1 From be1cb33dbb9cf978173fa58e20ab86f14641d6b3 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 12 Aug 2005 22:18:09 +0000 Subject: minor update git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3790 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index a16d0ec24..3feae2f30 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -237,8 +237,10 @@ applicable), with particular emphasis as follows: mess up anything else, go right ahead and check it in directly. * For larger changes, use your best judgement. If you're unsure of - the impact, or feel that you require advice or approval, patches or - `the sandbox`_ are the way to go. + the impact, or feel that you require advice or approval, branches, + patches, or `the sandbox`_ are the way to go. + +* You must be prepared to fix any code you have committed. Docutils will pursue an open and trusting policy for as long as possible, and deal with any aberrations if (and hopefully not when) -- cgit v1.2.1 From 6f10c58e06e1c25ff6582280bb641f51213dc956 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 12 Aug 2005 22:20:39 +0000 Subject: updated from Docutils default.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3791 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/pep.css | 139 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 15 deletions(-) diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css index a82045bc9..a687ee8c8 100644 --- a/tools/stylesheets/pep.css +++ b/tools/stylesheets/pep.css @@ -8,11 +8,17 @@ Default cascading style sheet for the PEP HTML output of Docutils. */ +/* "! important" is used here to override other ``margin-top`` and + ``margin-bottom`` styles that are later in the stylesheet or + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ .first { - margin-top: 0 } + margin-top: 0 ! important } -.last { - margin-bottom: 0 } +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } .navigation { width: 100% ; @@ -53,12 +59,15 @@ a.toc-backref { text-decoration: none ; color: black } +blockquote.epigraph { + margin: 2em 5em ; } + body { margin: 0px ; margin-bottom: 1em ; padding: 0px } -dd { +dl.docutils dd { margin-bottom: 0.5em } div.section { @@ -78,12 +87,18 @@ div.abstract p.topic-title { font-weight: bold ; text-align: center } -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { @@ -91,21 +106,58 @@ div.warning p.admonition-title { font-weight: bold ; font-family: sans-serif } -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { font-weight: bold ; - font-family: sans-serif } + font-style: normal } div.figure { margin-left: 2em } div.footer, div.header { + clear: both; font-size: smaller } div.footer { margin-left: 1em ; margin-right: 1em } +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + div.system-messages { margin: 5em } @@ -123,6 +175,10 @@ div.system-message p.system-message-title { div.topic { margin: 2em } +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + h1 { font-family: sans-serif ; font-size: large } @@ -149,9 +205,18 @@ h6 { font-style: italic ; font-size: x-small } -.section hr { +hr.docutils { width: 75% } +img.align-left { + clear: left } + +img.align-right { + clear: right } + +img.borderless { + border: 0 } + ol.simple, ul.simple { margin-bottom: 1em } @@ -170,6 +235,10 @@ ol.lowerroman { ol.upperroman { list-style: upper-roman } +p.attribution { + text-align: right ; + margin-left: 50% } + p.caption { font-style: italic } @@ -180,10 +249,31 @@ p.credits { p.label { white-space: nowrap } +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + p.topic-title { font-family: sans-serif ; font-weight: bold } +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + pre.line-block { font-family: serif ; font-size: 100% } @@ -204,6 +294,9 @@ span.classifier-delimiter { span.interpreted { font-family: sans-serif } +span.option { + white-space: nowrap } + span.option-argument { font-style: italic } @@ -213,11 +306,25 @@ span.pre { span.problematic { color: red } -table { +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid thin gray } + +table.docinfo { + margin: 2em 4em } + +table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } -td, th { +table.footnote { + border-left: solid thin black } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } @@ -228,12 +335,14 @@ td.num { th.field-name { font-weight: bold ; text-align: left ; - white-space: nowrap } + white-space: nowrap ; + padding-left: 0 } -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } -tt { +tt.docutils { background-color: #eeeeee } ul.auto-toc { -- cgit v1.2.1 From b80a48f879114d8b4fb34f8a589193305eeb0452 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 13:53:33 +0000 Subject: added to-do list entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3792 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 294602281..37b173758 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -630,7 +630,9 @@ __ rst/alternatives.html#or-not-to-do (http://article.gmane.org/gmane.text.docutils.cvs/3824). * Complain about bad URI characters - (http://article.gmane.org/gmane.text.docutils.user/2046). + (http://article.gmane.org/gmane.text.docutils.user/2046) and + disallow internal whitespace + (http://article.gmane.org/gmane.text.docutils.user/2214). * Create ``info``-level system messages for unnecessarily backslash-escaped characters (as in ``"\something"``, rendered as -- cgit v1.2.1 From 6847f556f5896ce76aaffdbbd41b8aa7e276cce8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 14:16:17 +0000 Subject: added link to xml2rst git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3793 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/user/links.txt b/docs/user/links.txt index 3ea6035e9..c319392ac 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -31,6 +31,10 @@ the box. * For Blogs (Weblogs), please see the `FAQ entry about Blogs`_. +* xml2rst_, an XSLT stylesheet written by Stefan Merten, converts XML + dumps of the document tree (e.g. created with rst2xml.py) back to + reStructuredText. + * rst2ht_, by Oliver Rutherfurd, converts reStructuredText to an .ht template, for use with ht2html_. @@ -102,6 +106,7 @@ code base. .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax +.. _xml2rst: http://www.merten-home.de/FreeSoftware/xml2rst/index.html .. _rst2ht: http://www.rutherfurd.net/articles/rst-ht2html.html .. _ht2html: http://ht2html.sourceforge.net/ .. _htmlnav: http://docutils.sf.net/sandbox/gschwant/htmlnav/ -- cgit v1.2.1 From 51ed43cb7a9a5cc7c27959ad30d8d360237075e1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 14:19:27 +0000 Subject: changed title to "Link List" so that it is found when googling for 'docutils link list' git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3794 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index c319392ac..563db0fa0 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -1,6 +1,6 @@ -================= - Docutils_ Links -================= +===================== + Docutils_ Link List +===================== :Author: Felix Wiemann :Contact: Felix.Wiemann@ososo.de -- cgit v1.2.1 From 3752c889a0d0bff13b619d9e3c09024a5fd2dbf2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 14:52:05 +0000 Subject: minor improvements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3795 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 3701b41a9..da3d19d23 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -70,6 +70,8 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" + default_transforms = () + def __init__(self): writers.Writer.__init__(self) self.translator_class = LaTeXTranslator @@ -203,7 +205,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dparent}{} % variable') a(r'\providecommand{\Dattr}[5]{#5}') a(r'\providecommand{\Dattrlen}{} % variable') - a(r'\providecommand{\Dtitleastext}{x}') + a(r'\providecommand{\Dtitleastext}{x} % variable') a(r'\providecommand{\Dsinglebackref}{} % variable') a(r'\providecommand{\Dmultiplebackrefs}{} % variable') a('\n\n') @@ -706,12 +708,10 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): (isinstance(node, nodes.Invisible) or isinstance(node, nodes.footnote) or isinstance(node, nodes.citation) or - # We never know what's inside raw nodes, and often - # they *are* invisible. So let's have the user take - # care of them. + # Assume raw nodes to be invisible. isinstance(node, nodes.raw) or - # Horizontally aligned image or figure. - node.get('align', None) in ('left', 'center', 'right'))) + # Floating image or figure. + node.get('align', None) in ('left', 'right'))) def is_visible(self, node): return not self.is_invisible(node) -- cgit v1.2.1 From a308d49c7f8d62f9090183d03be546621efdd854 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 15:10:42 +0000 Subject: added target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3796 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/rst/alternatives.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index 6a3354739..e8730b650 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -1699,7 +1699,7 @@ Issues: - If we took the bones out, it wouldn't be crunchy, now would it? -* A syntax for stubs in ASCII-art tables is easy to imagine:: +* A syntax for _`stubs in grid tables` is easy to imagine:: +------------------------++------------+----------+ | Header row, column 1 || Header 2 | Header 3 | -- cgit v1.2.1 From c5052e88cd35d4376c64c96beee621e3d539cbad Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 15:19:50 +0000 Subject: added target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3797 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 37b173758..4edfe70bd 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -930,10 +930,12 @@ Directives below are often referred to as "module.directive", the directive function. The "module." is not part of the directive name when used in a document. -* Make the directive interface object-oriented +* Make the _`directive interface` object-oriented (http://article.gmane.org/gmane.text.docutils.user/1871). -* Unify table implementations and unify options of table directives +* .. _unify tables: + + Unify table implementations and unify options of table directives (http://article.gmane.org/gmane.text.docutils.user/1857). * Allow directives to be added at run-time? -- cgit v1.2.1 From cf82ee9210cd535244ba63ecfad632fb32cad9c0 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 16:37:53 +0000 Subject: updated Chinese translations, closing SF patch #1243780; thanks Joe YS Jaw git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3798 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/zh_tw.py | 52 ++++++----- docutils/parsers/rst/languages/zh_tw.py | 150 ++++++++++++++++---------------- 2 files changed, 103 insertions(+), 99 deletions(-) diff --git a/docutils/languages/zh_tw.py b/docutils/languages/zh_tw.py index 2035725c0..c648dbcde 100644 --- a/docutils/languages/zh_tw.py +++ b/docutils/languages/zh_tw.py @@ -1,3 +1,4 @@ +# -*- coding: UTF-8 -*- # Author: Joe YS Jaw # Contact: joeysj@users.sourceforge.net # Revision: $Revision$ @@ -17,28 +18,28 @@ __docformat__ = 'reStructuredText' labels = { # fixed: language-dependent - 'author': u'\u4f5c\u8005', # 'Author', - 'authors': u'\u4f5c\u8005\u7fa4', # 'Authors', - 'organization': u'\u7d44\u7e54', # 'Organization', - 'address': u'\u5730\u5740', # 'Address', - 'contact': u'\u9023\u7d61', # 'Contact', - 'version': u'\u7248\u672c', # 'Version', - 'revision': u'\u4fee\u8a02', # 'Revision', - 'status': u'\u72c0\u614b', # 'Status', - 'date': u'\u65e5\u671f', # 'Date', - 'copyright': u'\u7248\u6b0a', # 'Copyright', - 'dedication': u'\u984c\u737b', # 'Dedication', - 'abstract': u'\u6458\u8981', # 'Abstract', - 'attention': u'\u6ce8\u610f\uff01', # 'Attention!', - 'caution': u'\u5c0f\u5fc3\uff01', # 'Caution!', - 'danger': u'\uff01\u5371\u96aa\uff01', # '!DANGER!', - 'error': u'\u932f\u8aa4', # 'Error', - 'hint': u'\u63d0\u793a', # 'Hint', - 'important': u'\u91cd\u8981', # 'Important', - 'note': u'\u8a3b\u89e3', # 'Note', - 'tip': u'\u79d8\u8a23', # 'Tip', - 'warning': u'\u8b66\u544a', # 'Warning', - 'contents': u'\u76ee\u9304' # 'Contents' + 'author': u'\u4f5c\u8005', # '作者' <-- Chinese word + 'authors': u'\u4f5c\u8005\u7fa4', # '作者群', + 'organization': u'\u7d44\u7e54', # '組織', + 'address': u'\u5730\u5740', # '地址', + 'contact': u'\u9023\u7d61', # '連絡', + 'version': u'\u7248\u672c', # '版本', + 'revision': u'\u4fee\u8a02', # '修訂', + 'status': u'\u72c0\u614b', # '狀態', + 'date': u'\u65e5\u671f', # '日期', + 'copyright': u'\u7248\u6b0a', # '版權', + 'dedication': u'\u984c\u737b', # '題獻', + 'abstract': u'\u6458\u8981', # '摘要', + 'attention': u'\u6ce8\u610f\uff01', # '注意!', + 'caution': u'\u5c0f\u5fc3\uff01', # '小心!', + 'danger': u'\uff01\u5371\u96aa\uff01', # '!危險!', + 'error': u'\u932f\u8aa4', # '錯誤', + 'hint': u'\u63d0\u793a', # '提示', + 'important': u'\u91cd\u8981', # '注意!', + 'note': u'\u8a3b\u91cb', # '註釋', + 'tip': u'\u79d8\u8a23', # '秘訣', + 'warning': u'\u8b66\u544a', # '警告', + 'contents': u'\u76ee\u9304' # '目錄' } """Mapping of node class name to label text.""" @@ -58,7 +59,10 @@ bibliographic_fields = { 'abstract': 'abstract'} """Traditional Chinese to canonical name mapping for bibliographic fields.""" -author_separators = [u'\uff1b', u'\uff0c', u'\u3001', - ';', ','] +author_separators = [';', ',', + u'\uff1b', # ';' + u'\uff0c', # ',' + u'\u3001', # '、' + ] """List of separator strings for the 'Authors' bibliographic field. Tried in order.""" diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 664aaf6ea..7e66a56a5 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -19,86 +19,86 @@ __docformat__ = 'reStructuredText' directives = { # language-dependent: fixed - 'attention (translation required)': 'attention', - 'caution (translation required)': 'caution', - 'danger (translation required)': 'danger', - 'error (translation required)': 'error', - 'hint (translation required)': 'hint', - 'important (translation required)': 'important', - 'note (translation required)': 'note', - 'tip (translation required)': 'tip', - 'warning (translation required)': 'warning', - 'admonition (translation required)': 'admonition', - 'sidebar (translation required)': 'sidebar', - 'topic (translation required)': 'topic', - 'line-block (translation required)': 'line-block', - 'parsed-literal (translation required)': 'parsed-literal', - 'rubric (translation required)': 'rubric', - 'epigraph (translation required)': 'epigraph', - 'highlights (translation required)': 'highlights', - 'pull-quote (translation required)': 'pull-quote', - 'compound (translation required)': 'compound', - #'questions (translation required)': 'questions', - 'table (translation required)': 'table', - 'csv-table (translation required)': 'csv-table', - 'list-table (translation required)': 'list-table', - #'qa (translation required)': 'questions', - #'faq (translation required)': 'questions', - 'meta (translation required)': 'meta', - #'imagemap (translation required)': 'imagemap', - 'image (translation required)': 'image', - 'figure (translation required)': 'figure', - 'include (translation required)': 'include', - 'raw (translation required)': 'raw', - 'replace (translation required)': 'replace', - 'unicode (translation required)': 'unicode', - 'class (translation required)': 'class', - 'role (translation required)': 'role', - u'default-role (translation required)': 'default-role', - u'title (translation required)': 'title', - 'contents (translation required)': 'contents', - 'sectnum (translation required)': 'sectnum', - 'section-numbering (translation required)': 'sectnum', - u'header (translation required)': 'header', - u'footer (translation required)': 'footer', - #'footnotes (translation required)': 'footnotes', - #'citations (translation required)': 'citations', - 'target-notes (translation required)': 'target-notes', + 'attention': 'attention', + 'caution': 'caution', + 'danger': 'danger', + 'error': 'error', + 'hint': 'hint', + 'important': 'important', + 'note': 'note', + 'tip': 'tip', + 'warning': 'warning', + 'admonition': 'admonition', + 'sidebar': 'sidebar', + 'topic': 'topic', + 'line-block': 'line-block', + 'parsed-literal': 'parsed-literal', + 'rubric': 'rubric', + 'epigraph': 'epigraph', + 'highlights': 'highlights', + 'pull-quote': 'pull-quote', + 'compound': 'compound', + #'questions': 'questions', + 'table': 'table', + 'csv-table': 'csv-table', + 'list-table': 'list-table', + #'qa': 'questions', + #'faq': 'questions', + 'meta': 'meta', + #'imagemap': 'imagemap', + 'image': 'image', + 'figure': 'figure', + 'include': 'include', + 'raw': 'raw', + 'replace': 'replace', + 'unicode': 'unicode', + 'class': 'class', + 'role': 'role', + u'default-role': 'default-role', + u'title': 'title', + 'contents': 'contents', + 'sectnum': 'sectnum', + 'section-numbering': 'sectnum', + u'header': 'header', + u'footer': 'footer', + #'footnotes': 'footnotes', + #'citations': 'citations', + 'target-notes': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """Traditional Chinese name to registered (in directives/__init__.py) directive name mapping.""" roles = { # language-dependent: fixed - 'abbreviation (translation required)': 'abbreviation', - 'ab (translation required)': 'abbreviation', - 'acronym (translation required)': 'acronym', - 'ac (translation required)': 'acronym', - 'index (translation required)': 'index', - 'i (translation required)': 'index', - 'subscript (translation required)': 'subscript', - 'sub (translation required)': 'subscript', - 'superscript (translation required)': 'superscript', - 'sup (translation required)': 'superscript', - 'title-reference (translation required)': 'title-reference', - 'title (translation required)': 'title-reference', - 't (translation required)': 'title-reference', - 'pep-reference (translation required)': 'pep-reference', - 'pep (translation required)': 'pep-reference', - 'rfc-reference (translation required)': 'rfc-reference', - 'rfc (translation required)': 'rfc-reference', - 'emphasis (translation required)': 'emphasis', - 'strong (translation required)': 'strong', - 'literal (translation required)': 'literal', - 'named-reference (translation required)': 'named-reference', - 'anonymous-reference (translation required)': 'anonymous-reference', - 'footnote-reference (translation required)': 'footnote-reference', - 'citation-reference (translation required)': 'citation-reference', - 'substitution-reference (translation required)': 'substitution-reference', - 'target (translation required)': 'target', - 'uri-reference (translation required)': 'uri-reference', - 'uri (translation required)': 'uri-reference', - 'url (translation required)': 'uri-reference', - 'raw (translation required)': 'raw',} + 'abbreviation': 'abbreviation', + 'ab': 'abbreviation', + 'acronym': 'acronym', + 'ac': 'acronym', + 'index': 'index', + 'i': 'index', + 'subscript': 'subscript', + 'sub': 'subscript', + 'superscript': 'superscript', + 'sup': 'superscript', + 'title-reference': 'title-reference', + 'title': 'title-reference', + 't': 'title-reference', + 'pep-reference': 'pep-reference', + 'pep': 'pep-reference', + 'rfc-reference': 'rfc-reference', + 'rfc': 'rfc-reference', + 'emphasis': 'emphasis', + 'strong': 'strong', + 'literal': 'literal', + 'named-reference': 'named-reference', + 'anonymous-reference': 'anonymous-reference', + 'footnote-reference': 'footnote-reference', + 'citation-reference': 'citation-reference', + 'substitution-reference': 'substitution-reference', + 'target': 'target', + 'uri-reference': 'uri-reference', + 'uri': 'uri-reference', + 'url': 'uri-reference', + 'raw': 'raw',} """Mapping of Traditional Chinese role names to canonical role names for interpreted text.""" -- cgit v1.2.1 From e6ab814ea613b6555962fb91b2f768a1a65e6149 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 16:55:34 +0000 Subject: improved help git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3799 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index da3d19d23..a50ec1fe9 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -30,7 +30,10 @@ class Writer(writers.Writer): settings_spec = ( 'LaTeX-Specific Options', - 'Note that this LaTeX writer is still EXPERIMENTAL.', + 'Note that this LaTeX writer is still EXPERIMENTAL. ' + 'You must specify the location of the tools/stylesheets/latex.tex ' + 'stylesheet file contained in the Docutils distribution tarball to ' + 'make the LaTeX output work.', (('Specify a stylesheet file. The path is used verbatim to include ' 'the file. Overrides --stylesheet-path.', ['--stylesheet'], @@ -40,7 +43,7 @@ class Writer(writers.Writer): 'directory. Overrides --stylesheet.', ['--stylesheet-path'], {'metavar': '<file>', 'overrides': 'stylesheet'}), - ('Specify a uesr stylesheet file. See --stylesheet.', + ('Specify a user stylesheet file. See --stylesheet.', ['--user-stylesheet'], {'default': '', 'metavar': '<file>', 'overrides': 'user_stylesheet_path'}), -- cgit v1.2.1 From ad22732219501fc1d846564dfd6cc01ddafc4d19 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 17:08:27 +0000 Subject: fixed bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3800 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index a50ec1fe9..4d00e6906 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -65,7 +65,7 @@ class Writer(writers.Writer): 'traceback': 1 } - relative_path_settings = ('stylesheet_path',) + relative_path_settings = ('stylesheet_path', 'user_stylesheet_path') config_section = 'newlatex2e writer' config_section_dependencies = ('writers',) -- cgit v1.2.1 From c5b2358f005d4ed25cda7f3f23a87f56a480f129 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 17:34:37 +0000 Subject: re-added "(translation required)" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3801 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/zh_tw.py | 150 ++++++++++++++++---------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 7e66a56a5..664aaf6ea 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -19,86 +19,86 @@ __docformat__ = 'reStructuredText' directives = { # language-dependent: fixed - 'attention': 'attention', - 'caution': 'caution', - 'danger': 'danger', - 'error': 'error', - 'hint': 'hint', - 'important': 'important', - 'note': 'note', - 'tip': 'tip', - 'warning': 'warning', - 'admonition': 'admonition', - 'sidebar': 'sidebar', - 'topic': 'topic', - 'line-block': 'line-block', - 'parsed-literal': 'parsed-literal', - 'rubric': 'rubric', - 'epigraph': 'epigraph', - 'highlights': 'highlights', - 'pull-quote': 'pull-quote', - 'compound': 'compound', - #'questions': 'questions', - 'table': 'table', - 'csv-table': 'csv-table', - 'list-table': 'list-table', - #'qa': 'questions', - #'faq': 'questions', - 'meta': 'meta', - #'imagemap': 'imagemap', - 'image': 'image', - 'figure': 'figure', - 'include': 'include', - 'raw': 'raw', - 'replace': 'replace', - 'unicode': 'unicode', - 'class': 'class', - 'role': 'role', - u'default-role': 'default-role', - u'title': 'title', - 'contents': 'contents', - 'sectnum': 'sectnum', - 'section-numbering': 'sectnum', - u'header': 'header', - u'footer': 'footer', - #'footnotes': 'footnotes', - #'citations': 'citations', - 'target-notes': 'target-notes', + 'attention (translation required)': 'attention', + 'caution (translation required)': 'caution', + 'danger (translation required)': 'danger', + 'error (translation required)': 'error', + 'hint (translation required)': 'hint', + 'important (translation required)': 'important', + 'note (translation required)': 'note', + 'tip (translation required)': 'tip', + 'warning (translation required)': 'warning', + 'admonition (translation required)': 'admonition', + 'sidebar (translation required)': 'sidebar', + 'topic (translation required)': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', + 'rubric (translation required)': 'rubric', + 'epigraph (translation required)': 'epigraph', + 'highlights (translation required)': 'highlights', + 'pull-quote (translation required)': 'pull-quote', + 'compound (translation required)': 'compound', + #'questions (translation required)': 'questions', + 'table (translation required)': 'table', + 'csv-table (translation required)': 'csv-table', + 'list-table (translation required)': 'list-table', + #'qa (translation required)': 'questions', + #'faq (translation required)': 'questions', + 'meta (translation required)': 'meta', + #'imagemap (translation required)': 'imagemap', + 'image (translation required)': 'image', + 'figure (translation required)': 'figure', + 'include (translation required)': 'include', + 'raw (translation required)': 'raw', + 'replace (translation required)': 'replace', + 'unicode (translation required)': 'unicode', + 'class (translation required)': 'class', + 'role (translation required)': 'role', + u'default-role (translation required)': 'default-role', + u'title (translation required)': 'title', + 'contents (translation required)': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + u'header (translation required)': 'header', + u'footer (translation required)': 'footer', + #'footnotes (translation required)': 'footnotes', + #'citations (translation required)': 'citations', + 'target-notes (translation required)': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """Traditional Chinese name to registered (in directives/__init__.py) directive name mapping.""" roles = { # language-dependent: fixed - 'abbreviation': 'abbreviation', - 'ab': 'abbreviation', - 'acronym': 'acronym', - 'ac': 'acronym', - 'index': 'index', - 'i': 'index', - 'subscript': 'subscript', - 'sub': 'subscript', - 'superscript': 'superscript', - 'sup': 'superscript', - 'title-reference': 'title-reference', - 'title': 'title-reference', - 't': 'title-reference', - 'pep-reference': 'pep-reference', - 'pep': 'pep-reference', - 'rfc-reference': 'rfc-reference', - 'rfc': 'rfc-reference', - 'emphasis': 'emphasis', - 'strong': 'strong', - 'literal': 'literal', - 'named-reference': 'named-reference', - 'anonymous-reference': 'anonymous-reference', - 'footnote-reference': 'footnote-reference', - 'citation-reference': 'citation-reference', - 'substitution-reference': 'substitution-reference', - 'target': 'target', - 'uri-reference': 'uri-reference', - 'uri': 'uri-reference', - 'url': 'uri-reference', - 'raw': 'raw',} + 'abbreviation (translation required)': 'abbreviation', + 'ab (translation required)': 'abbreviation', + 'acronym (translation required)': 'acronym', + 'ac (translation required)': 'acronym', + 'index (translation required)': 'index', + 'i (translation required)': 'index', + 'subscript (translation required)': 'subscript', + 'sub (translation required)': 'subscript', + 'superscript (translation required)': 'superscript', + 'sup (translation required)': 'superscript', + 'title-reference (translation required)': 'title-reference', + 'title (translation required)': 'title-reference', + 't (translation required)': 'title-reference', + 'pep-reference (translation required)': 'pep-reference', + 'pep (translation required)': 'pep-reference', + 'rfc-reference (translation required)': 'rfc-reference', + 'rfc (translation required)': 'rfc-reference', + 'emphasis (translation required)': 'emphasis', + 'strong (translation required)': 'strong', + 'literal (translation required)': 'literal', + 'named-reference (translation required)': 'named-reference', + 'anonymous-reference (translation required)': 'anonymous-reference', + 'footnote-reference (translation required)': 'footnote-reference', + 'citation-reference (translation required)': 'citation-reference', + 'substitution-reference (translation required)': 'substitution-reference', + 'target (translation required)': 'target', + 'uri-reference (translation required)': 'uri-reference', + 'uri (translation required)': 'uri-reference', + 'url (translation required)': 'uri-reference', + 'raw (translation required)': 'raw',} """Mapping of Traditional Chinese role names to canonical role names for interpreted text.""" -- cgit v1.2.1 From 321c9e6f1c883f2441b65c9d6692f160735c9b9c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 17:39:12 +0000 Subject: added "(translation required)" for untranslated bibliographic fields git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3802 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/zh_tw.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docutils/languages/zh_tw.py b/docutils/languages/zh_tw.py index c648dbcde..00cffb586 100644 --- a/docutils/languages/zh_tw.py +++ b/docutils/languages/zh_tw.py @@ -45,18 +45,18 @@ labels = { bibliographic_fields = { # language-dependent: fixed - 'author': 'author', - 'authors': 'authors', - 'organization': 'organization', - 'address': 'address', - 'contact': 'contact', - 'version': 'version', - 'revision': 'revision', - 'status': 'status', - 'date': 'date', - 'copyright': 'copyright', - 'dedication': 'dedication', - 'abstract': 'abstract'} + 'author (translation required)': 'author', + 'authors (translation required)': 'authors', + 'organization (translation required)': 'organization', + 'address (translation required)': 'address', + 'contact (translation required)': 'contact', + 'version (translation required)': 'version', + 'revision (translation required)': 'revision', + 'status (translation required)': 'status', + 'date (translation required)': 'date', + 'copyright (translation required)': 'copyright', + 'dedication (translation required)': 'dedication', + 'abstract (translation required)': 'abstract'} """Traditional Chinese to canonical name mapping for bibliographic fields.""" author_separators = [';', ',', -- cgit v1.2.1 From faf70308e43beacc515f5ab14afab0dd1c4af888 Mon Sep 17 00:00:00 2001 From: lele <lele@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 19:24:03 +0000 Subject: Italian translation of newest directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3803 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/languages/it.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index e28f3ec00..de5e32d8b 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -53,15 +53,15 @@ directives = { 'unicode': 'unicode', 'classe': 'class', 'ruolo': 'role', - u'default-role (translation required)': 'default-role', - 'title (translation required)': 'title', + 'ruolo-predefinito': 'default-role', + 'titolo': 'title', 'indice': 'contents', 'contenuti': 'contents', 'seznum': 'sectnum', 'sezioni-autonumerate': 'sectnum', 'annota-riferimenti-esterni': 'target-notes', - u'header (translation required)': 'header', - u'footer (translation required)': 'footer', + 'intestazione': 'header', + 'piede-pagina': 'footer', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -- cgit v1.2.1 From f8ffb27c69811c3e0b936505e4ab978ddd03dbdc Mon Sep 17 00:00:00 2001 From: lele <lele@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 19:25:39 +0000 Subject: Fixed a typo in the Docutils release that introduced units git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3804 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 23f6469b4..264b9aabe 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2787,7 +2787,7 @@ characters (see `Escaping Mechanism`_ above). Units ===== -(New in Docutils 3.4.10.) +(New in Docutils 0.3.10.) All measures consist of a positive floating point number in standard (non-scientific) notation and a unit, possibly separated by one or -- cgit v1.2.1 From 572dab40eb2e04bea643f9d03f0900d91c4c6577 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 20:24:03 +0000 Subject: two more typos git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3805 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index b5941c8de..2908d4959 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -202,7 +202,7 @@ The following options are recognized: specified, they are combined. For example, a height of 200 and a scale of 50 is equivalent to a height of 100 with no scale. - New in Docutils 3.4.10: It is also possible to specify a `length + New in Docutils 0.3.10: It is also possible to specify a `length value`_. ``width`` : integer @@ -210,7 +210,7 @@ The following options are recognized: the image horizontally. As with "height" above, when the "scale" option is also specified, they are combined. - New in Docutils 3.4.10: It is also possible to specify a length_ + New in Docutils 0.3.10: It is also possible to specify a length_ or `percentage value`_ (which is relative to the current line width). -- cgit v1.2.1 From f0828fe76f43889b5bb74db2dd54b6df2c0cd5c7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 21:59:15 +0000 Subject: improved bug so that it can be copied and pasted easier git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3806 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 47d473c3d..06d3ca3af 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -205,16 +205,18 @@ Also see the `SourceForge Bug Tracker`_. <literal_block xml:space="preserve"> .. |x| replace:: . -* Footnote label "5" should be "4":: - - $ rst2pseudoxml.py <<EOF - > ref [#abc]_ [#]_ [1]_ [#4]_ - > - > .. [#abc] footnote - > .. [#] two - > .. [1] one - > .. [#4] four - > EOF +* Footnote label "5" should be "4" when processing the following + input:: + + ref [#abc]_ [#]_ [1]_ [#4]_ + + .. [#abc] footnote + .. [#] two + .. [1] one + .. [#4] four + + Output:: + <document source="<stdin>"> <paragraph> ref -- cgit v1.2.1 From 3cb6c0f587d0b5ebe3f55b206d80ed03a684dd34 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 14 Aug 2005 23:18:36 +0000 Subject: removed bug with indirect substitutions; seems to be fixed git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3807 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 12 ------------ test/test_transforms/test_substitutions.py | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 06d3ca3af..40562fca7 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -146,18 +146,6 @@ Also see the `SourceForge Bug Tracker`_. Quite a few nodes are getting a "None" source attribute as well. In particular, see the bodies of definition lists. -* David Abrahams pointed out that _`doubly-indirect substitutions` - have a bug, but only when there's multiple references:: - - |substitute| my coke for gin - |substitute| you for my mum - at least I'll get my washing done - - .. |substitute| replace:: |replace| - .. |replace| replace:: swap - - This is tricky. Substitutions have to propagate back completely. - * .. _substitutions and references: Another bug from David Abrahams (run with ``rst2html.py --traceback``):: diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 33a33b754..67aa3dfed 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -76,6 +76,31 @@ u"""\ \u00C9 . """], +[u"""\ +Indirect substitution definitions with multiple references: + +|substitute| my coke for gin +|substitute| you for my mum +at least I'll get my washing done + +.. |substitute| replace:: |replace| +.. |replace| replace:: swap +""", +u"""\ +<document source="test data"> + <paragraph> + Indirect substitution definitions with multiple references: + <paragraph> + swap + my coke for gin + swap + you for my mum + at least I'll get my washing done + <substitution_definition names="substitute"> + swap + <substitution_definition names="replace"> + swap +"""], ]) totest['unicode'] = ((Substitutions,), [ -- cgit v1.2.1 From c2a46503c0ea15806345b53815d95d917eb57e4e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 15 Aug 2005 18:21:54 +0000 Subject: added note about project data at BerliOS and SF git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3808 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index dceb88f5d..730e54e42 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -20,6 +20,12 @@ Subversion is exhaustively documented in the `Subversion Book`_ .. _Subversion: http://subversion.tigris.org/ .. _Subversion Book: http://svnbook.red-bean.com/ +.. Note:: + + While the repository resides at BerliOS, all other project data + (web site, snapshots, releases, mailing lists, trackers) is hosted + at SourceForge. + Accessing the Repository ======================== -- cgit v1.2.1 From 74e448e6230eaaf792f6fe2b0c936cb9bdfeaf41 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 15 Aug 2005 19:45:02 +0000 Subject: restored a bug (removed in r3807) which lingers; added a commented-out test case for said bug; removed a bogus bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3809 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 38 ++++++------------------- test/test_transforms/test_substitutions.py | 45 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 40562fca7..72f44264a 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -146,6 +146,14 @@ Also see the `SourceForge Bug Tracker`_. Quite a few nodes are getting a "None" source attribute as well. In particular, see the bodies of definition lists. +* There's a bug with _`doubly-indirect substitutions` but only when + there's multiple references and in certain cases. See the + commented-out test case in test_transforms/test_substitutions.py + (line 104 on, in revision 3808) which fails. + + This is tricky. Substitution definitions have to propagate back + completely, through multiple levels of references. + * .. _substitutions and references: Another bug from David Abrahams (run with ``rst2html.py --traceback``):: @@ -163,36 +171,6 @@ Also see the `SourceForge Bug Tracker`_. all IDs from definitions after the first substitution reference is processed. -* There's a bug with _`inline literals in substitutions`:: - - .. |x| replace:: ``x`` - - x |x| - - Parsing, the inline literal context disappears:: - - <document source="<stdin>"> - <substitution_definition names="x"> - x - <paragraph> - x - x - - Here's a probably related bug:: - - .. |x| replace:: ``.`` - - Parsing this results in:: - - <system_message level="3" line="1" source="<stdin>" type="ERROR"> - <paragraph> - Error in "replace" directive: may contain a single paragraph only. - <system_message level="2" line="1" source="<stdin>" type="WARNING"> - <paragraph> - Substitution definition "x" empty or invalid. - <literal_block xml:space="preserve"> - .. |x| replace:: . - * Footnote label "5" should be "4" when processing the following input:: diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 67aa3dfed..19534a486 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -101,6 +101,51 @@ u"""\ <substitution_definition names="replace"> swap """], +#["""\ +#.. |l| unicode:: U+00AB .. left chevron +#.. |r| unicode:: U+00BB .. right chevron +#.. |.| replace:: |l|\ ``.``\ |r| +# +#.. Delete either of the following lines, and there is no error. +# +#Regular expression |.| will match any character +# +#.. Note:: Note that |.| matches *exactly* one character +#""", +#u"""\ +#<document source="test data"> +# <substitution_definition names="l"> +# \xab +# <substitution_definition names="r"> +# \xbb +# <substitution_definition names="."> +# <substitution_reference refname="l"> +# l +# <literal> +# . +# <substitution_reference refname="r"> +# r +# <comment xml:space="preserve"> +# Delete either of the following lines, and there is no error. +# <paragraph> +# Regular expression \n\ +# \xab +# <literal> +# . +# \xbb +# will match any character +# <note> +# <paragraph> +# Note that \n\ +# \xab +# <literal> +# . +# \xbb +# matches \n\ +# <emphasis> +# exactly +# one character +#"""], ]) totest['unicode'] = ((Substitutions,), [ -- cgit v1.2.1 From 67c57d6128cf805d676bd3ff38a3a8f8a7da274b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 15 Aug 2005 20:00:05 +0000 Subject: made Null writer "support" all formats git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3810 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/null.py | 4 ++++ test/test_writers/test_null_misc.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100755 test/test_writers/test_null_misc.py diff --git a/docutils/writers/null.py b/docutils/writers/null.py index cf3566480..fb611dd88 100644 --- a/docutils/writers/null.py +++ b/docutils/writers/null.py @@ -21,3 +21,7 @@ class Writer(writers.Writer): def translate(self): pass + + def supports(self, format): + """This writer supports all format-specific elements.""" + return 1 diff --git a/test/test_writers/test_null_misc.py b/test/test_writers/test_null_misc.py new file mode 100755 index 000000000..bac41384f --- /dev/null +++ b/test/test_writers/test_null_misc.py @@ -0,0 +1,25 @@ +#! /usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Miscellaneous Null writer tests. +""" + +from __init__ import DocutilsTestSupport +from docutils.writers import null + + +class SupportsTestCase(DocutilsTestSupport.StandardTestCase): + + def test_xmlcharrefreplace(self): + self.assert_(null.Writer().supports('anyformat')) + + +if __name__ == '__main__': + import unittest + unittest.main() -- cgit v1.2.1 From 12230a35702461fd90db1254371ad0050b74977e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 15 Aug 2005 20:10:27 +0000 Subject: committed too early; sorry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3811 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/null.py | 4 ---- test/test_writers/test_null_misc.py | 25 ------------------------- 2 files changed, 29 deletions(-) delete mode 100755 test/test_writers/test_null_misc.py diff --git a/docutils/writers/null.py b/docutils/writers/null.py index fb611dd88..cf3566480 100644 --- a/docutils/writers/null.py +++ b/docutils/writers/null.py @@ -21,7 +21,3 @@ class Writer(writers.Writer): def translate(self): pass - - def supports(self, format): - """This writer supports all format-specific elements.""" - return 1 diff --git a/test/test_writers/test_null_misc.py b/test/test_writers/test_null_misc.py deleted file mode 100755 index bac41384f..000000000 --- a/test/test_writers/test_null_misc.py +++ /dev/null @@ -1,25 +0,0 @@ -#! /usr/bin/env python - -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Miscellaneous Null writer tests. -""" - -from __init__ import DocutilsTestSupport -from docutils.writers import null - - -class SupportsTestCase(DocutilsTestSupport.StandardTestCase): - - def test_xmlcharrefreplace(self): - self.assert_(null.Writer().supports('anyformat')) - - -if __name__ == '__main__': - import unittest - unittest.main() -- cgit v1.2.1 From e03c5f0ae2f26b8eed7b441a3275e453c6426abb Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 15 Aug 2005 21:17:12 +0000 Subject: added to-do list entry about block quotes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3812 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4edfe70bd..c9df96008 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -625,6 +625,17 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* Allow multiple block quotes, only separated by attributions + (http://article.gmane.org/gmane.text.docutils.devel/2985), e.g.:: + + quote 1 + + ---Attrib 1 + + quote 2 + + ---Attrib 2 + * Change the specification so that more punctuation is allowed before/after inline markup start/end string (http://article.gmane.org/gmane.text.docutils.cvs/3824). -- cgit v1.2.1 From 03f113d5425662822ddb565d627b9c6b39e25aab Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 13:32:03 +0000 Subject: removed superfluous error message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3813 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/__init__.py | 4 +--- test/test_parsers/test_rst/test_directives/test_unknown.py | 9 --------- test/test_parsers/test_rst/test_substitutions.py | 3 --- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index dadd08e65..0bfb6abd6 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -181,9 +181,7 @@ def directive(directive_name, language_module, document): try: modulename, functionname = _directive_registry[canonicalname] except KeyError: - messages.append(document.reporter.error( - 'Directive "%s" not registered (canonical name "%s").' - % (directive_name, canonicalname), line=document.current_line)) + # Error handling done by caller. return None, messages if _modules.has_key(modulename): module = _modules[modulename] diff --git a/test/test_parsers/test_rst/test_directives/test_unknown.py b/test/test_parsers/test_rst/test_directives/test_unknown.py index 8340a224b..3c859faa3 100755 --- a/test/test_parsers/test_rst/test_directives/test_unknown.py +++ b/test/test_parsers/test_rst/test_directives/test_unknown.py @@ -34,9 +34,6 @@ totest['unknown'] = [ <paragraph> No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". Trying "reStructuredText-unknown-directive" as canonical directive name. - <system_message level="3" line="1" source="test data" type="ERROR"> - <paragraph> - Directive "reStructuredText-unknown-directive" not registered (canonical name "restructuredtext-unknown-directive"). <system_message level="3" line="1" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". @@ -46,9 +43,6 @@ totest['unknown'] = [ <paragraph> No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". Trying "reStructuredText-unknown-directive" as canonical directive name. - <system_message level="3" line="3" source="test data" type="ERROR"> - <paragraph> - Directive "reStructuredText-unknown-directive" not registered (canonical name "restructuredtext-unknown-directive"). <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". @@ -58,9 +52,6 @@ totest['unknown'] = [ <paragraph> No directive entry for "reStructuredText-unknown-directive" in module "docutils.parsers.rst.languages.en". Trying "reStructuredText-unknown-directive" as canonical directive name. - <system_message level="3" line="5" source="test data" type="ERROR"> - <paragraph> - Directive "reStructuredText-unknown-directive" not registered (canonical name "restructuredtext-unknown-directive"). <system_message level="3" line="5" source="test data" type="ERROR"> <paragraph> Unknown directive type "reStructuredText-unknown-directive". diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 773702533..d2a5207c9 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -223,9 +223,6 @@ No blank line after. <paragraph> No directive entry for "directive" in module "docutils.parsers.rst.languages.en". Trying "directive" as canonical directive name. - <system_message level="3" line="8" source="test data" type="ERROR"> - <paragraph> - Directive "directive" not registered (canonical name "directive"). <system_message level="3" line="8" source="test data" type="ERROR"> <paragraph> Unknown directive type "directive". -- cgit v1.2.1 From b2b685c6119a8e74207a6adaf0761eddb8476ae2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 17:47:06 +0000 Subject: updated link git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3817 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FAQ.txt b/FAQ.txt index 7d321d900..285c6bbd2 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -386,7 +386,7 @@ implied endorsement or recommendation, and in no particular order: * `Webware for Python wiki <http://wiki.webwareforpython.org/thiswiki.html>`__ * `Ian Bicking's experimental code - <http://docutils.sf.net/sandbox/ianb/wiki/WikiPage.py>`__ + <http://docutils.sf.net/sandbox/ianb/wiki/Wiki.py>`__ * `MoinMoin <http://moin.sf.net>`__ has some support; `here's a sample <http://twistedmatrix.com/users/jh.twistd/moin/moin.cgi/RestSample>`__ * Zope-based `Zwiki <http://zwiki.org/>`__ -- cgit v1.2.1 From ee2563b54ff734521c0b61611dd433395cf3b853 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 18:03:26 +0000 Subject: updated two more links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3818 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 285c6bbd2..c1db00035 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -387,8 +387,8 @@ implied endorsement or recommendation, and in no particular order: <http://wiki.webwareforpython.org/thiswiki.html>`__ * `Ian Bicking's experimental code <http://docutils.sf.net/sandbox/ianb/wiki/Wiki.py>`__ -* `MoinMoin <http://moin.sf.net>`__ has some support; `here's a sample - <http://twistedmatrix.com/users/jh.twistd/moin/moin.cgi/RestSample>`__ +* `MoinMoin <http://moinmoin.wikiwikiweb.de/>`__ has some support; + `here's a sample <http://moinmoin.wikiwikiweb.de/RestSample>`__ * Zope-based `Zwiki <http://zwiki.org/>`__ * Zope3-based Zwiki (in the Zope 3 source tree as ``zope.products.zwiki``) * `StikiWiki <http://mithrandr.moria.org/code/stikiwiki/>`__ -- cgit v1.2.1 From 9ff6bdb0b70260e90973b1bf4f733ca7cc59dab6 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 18:05:17 +0000 Subject: updated name git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3819 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.txt b/docs/index.txt index bb468e8d7..75429f87a 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -82,7 +82,7 @@ Docutils-general: * `Docutils Configuration Files <user/config.html>`__ * `Docutils LaTeX Writer <user/latex.html>`__ * `Docutils Mailing Lists <user/mailing-lists.html>`__ -* `Docutils Links <user/links.html>`__ +* `Docutils Link List <user/links.html>`__ `reStructuredText <http://docutils.sourceforge.net/rst.html>`_: -- cgit v1.2.1 From ef661342c659d1cc901b6dd5c21e763c333abead Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 18:06:34 +0000 Subject: moved ...2rest tools together git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3820 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 563db0fa0..37ccbb856 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -35,15 +35,15 @@ the box. dumps of the document tree (e.g. created with rst2xml.py) back to reStructuredText. +* xhtml2rest_, written by Antonios Christofides, is a simple utility + to convert XHTML to reStructuredText. + * rst2ht_, by Oliver Rutherfurd, converts reStructuredText to an .ht template, for use with ht2html_. * htmlnav_, by Gunnar Schwant, is an HTML writer which supports navigation bars. -* xhtml2rest_, written by Antonios Christofides, is a simple utility - to convert XHTML to reStructuredText. - * rst2chm_, written by Oliver Rutherfurd, generates Microsoft HTML Help files from reStructuredText files. -- cgit v1.2.1 From 28663f797ced7a935e8c662a097a34f0f30be428 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 17 Aug 2005 18:11:50 +0000 Subject: added reference to link list in round-tripping FAQ entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3821 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index c1db00035..c3504e74a 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -361,20 +361,25 @@ If anyone knows of other/better solutions, please `let us know`_. Are there any tools for HTML/XML-to-reStructuredText? (Round-tripping) ----------------------------------------------------------------------- -People have tossed the idea around, but little if any actual work has -ever been done. There's no reason why reStructuredText should not be -round-trippable to/from XML; any technicalities which prevent -round-tripping would be considered bugs. Whitespace would not be -identical, but paragraphs shouldn't suffer. The tricky parts would be -the smaller details, like links and IDs and other bookkeeping. +People have tossed the idea around, and some implementations of +reStructuredText-generating tools can be found in the `Docutils Link +List`_. + +There's no reason why reStructuredText should not be round-trippable +to/from XML; any technicalities which prevent round-tripping would be +considered bugs. Whitespace would not be identical, but paragraphs +shouldn't suffer. The tricky parts would be the smaller details, like +links and IDs and other bookkeeping. For HTML, true round-tripping may not be possible. Even adding lots of extra "class" attributes may not be enough. A "simple HTML" to RST filter is possible -- for some definition of "simple HTML" -- but HTML is used as dumb formatting so much that such a filter may not be -particularly useful. No general-purpose filter exists. An 80/20 -approach should work though: build a tool that does 80% of the work -automatically, leaving the other 20% for manual tweaks. +particularly useful. An 80/20 approach should work though: build a +tool that does 80% of the work automatically, leaving the other 20% +for manual tweaks. + +.. _Docutils Link List: docs/user/links.html Are there any Wikis that use reStructuredText syntax? -- cgit v1.2.1 From 15f953a780c227ca084a01b0a87edc15ec88fca0 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 18 Aug 2005 11:20:39 +0000 Subject: clarify colons in explicit target names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3823 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 264b9aabe..6bbdd9361 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1851,7 +1851,7 @@ indirect. .. _split: `A Hyperlink`_ -If a reference name contains a colon followed by whitespace, either: +If the reference name contains any colons, either: - the phrase must be enclosed in backquotes:: -- cgit v1.2.1 From 7234954bc7bd0a5bceacf6a67641c876438ef67e Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 18 Aug 2005 11:21:13 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3824 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c9df96008..5c61da4ac 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -72,6 +72,9 @@ for inclusion in the Python standard library. General ======= +* Move some general-interest sandboxes out of individuals' + directories, into subprojects? + * Add option for file (and URL) access restriction to make Docutils usable in Wikis and similar applications. -- cgit v1.2.1 From 2f3fd059cdc4944f1faedea164de5bd2aa85cea4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 23 Aug 2005 23:43:40 +0000 Subject: added target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3827 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 5c61da4ac..06d1e3d8e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -371,7 +371,9 @@ General & XMLs. Aahz implemented something like this in sandbox/aahz/Effective/EffMap.py. -* William Dode suggested that table cells be assigned "class" +* .. _classes for table cells: + + William Dode suggested that table cells be assigned "class" attributes by columns, so that stylesheets can affect text alignment. Unfortunately, there doesn't seem to be a way (in HTML at least) to leverage the "colspec" elements (HTML "col" tags) by -- cgit v1.2.1 From 090741b70591dc6209c48d4147167b6d88c578c7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 24 Aug 2005 00:05:38 +0000 Subject: fixed bug with "image" directive "target" option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3828 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docutils/parsers/rst/directives/images.py | 7 ++++--- test/test_parsers/test_rst/test_directives/test_images.py | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6601bb25a..29fb21421 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -47,6 +47,7 @@ Changes Since 0.3.9 * docutils/parsers/rst/states.py: - Fixed bug with escaped colons indicating a literal block. + - Fixed bug with enumerated lists (SF#1254145). * docutils/parsers/rst/directives/misc.py: @@ -56,6 +57,7 @@ Changes Since 0.3.9 * docutils/parsers/rst/directives/images.py: - Added support for image width and height units. + - Fixed bug with image "target" options. * docutils/parsers/rst/include/: Directory added to project; contains standard data files for the "include" directive. Initial contents: diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index ef77c2bef..1c9c50e26 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -14,7 +14,7 @@ __docformat__ = 'reStructuredText' import sys from docutils import nodes, utils from docutils.parsers.rst import directives, states -from docutils.nodes import fully_normalize_name +from docutils.nodes import fully_normalize_name, whitespace_normalize_name from docutils.parsers.rst.roles import set_classes try: @@ -60,8 +60,9 @@ def image(name, arguments, options, content, lineno, if target_type == 'refuri': reference_node = nodes.reference(refuri=data) elif target_type == 'refname': - reference_node = nodes.reference(refname=data, - name=fully_normalize_name(options['target'])) + reference_node = nodes.reference( + refname=fully_normalize_name(data), + name=whitespace_normalize_name(data)) state.document.note_refname(reference_node) else: # malformed target messages.append(data) # data is a system message diff --git a/test/test_parsers/test_rst/test_directives/test_images.py b/test/test_parsers/test_rst/test_directives/test_images.py index 4e4c429f6..50f555ba1 100755 --- a/test/test_parsers/test_rst/test_directives/test_images.py +++ b/test/test_parsers/test_rst/test_directives/test_images.py @@ -295,7 +295,7 @@ totest['images'] = [ """, """\ <document source="test data"> - <reference name="indirect_" refname="indirect"> + <reference name="indirect" refname="indirect"> <image uri="picture.png"> """], ["""\ @@ -311,7 +311,7 @@ totest['images'] = [ <document source="test data"> <reference refuri="a/multi/line/uri"> <image uri="picture.png"> - <reference name="`a multi line internal reference`_" refname="a multi line internal reference"> + <reference name="a multi line internal reference" refname="a multi line internal reference"> <image uri="picture.png"> """], ["""\ @@ -401,7 +401,7 @@ u"""\ """, """\ <document source="test data"> - <reference name="uppercase_" refname="Uppercase"> + <reference name="Uppercase" refname="uppercase"> <image uri="test.png"> <target ids="uppercase" names="uppercase" refuri="http://docutils.sourceforge.net/"> """], -- cgit v1.2.1 From e7a14a1597305c6b282cfb59569395c0eef4b7bd Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 24 Aug 2005 00:23:46 +0000 Subject: also fixed by rev. 3828 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3829 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_pseudoxml.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index c098ff0e0..c2af4aaa9 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1120,7 +1120,7 @@ Images <paragraph> An image directive (also clickable -- a hyperlink reference): - <reference name="directives_" refid="directives"> + <reference name="directives" refid="directives"> <image classes="class1 class2" uri="../../../docs/user/rst/images/title.png"> <paragraph> Image with multiple IDs: -- cgit v1.2.1 From 5c90ddc006b36818e727b4a42196a708b2a78a25 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 24 Aug 2005 21:33:21 +0000 Subject: made _stylesheet_required setting default to 0, activating it in the rst2html.py front-end tool git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3830 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 8 ++++---- docs/user/config.txt | 17 ++++++++--------- docutils/core.py | 6 ------ docutils/frontend.py | 3 +-- docutils/writers/html4css1.py | 3 ++- test/DocutilsTestSupport.py | 1 - test/functional/tests/_default.py | 1 - test/test_dependencies.py | 1 - test/test_writers/test_html4css1_misc.py | 3 +-- tools/rst2html.py | 3 ++- 10 files changed, 18 insertions(+), 28 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 29fb21421..2614f5817 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -28,10 +28,6 @@ Changes Since 0.3.9 - Added ``publish_doctree`` and ``publish_from_doctree`` convenience functions, for document tree extraction and reprocessing. -* docutils/frontend.py: - - - Added ``_stylesheet_required`` internal setting. - * docutils/io.py: - Added ``DocTreeInput`` class, for reprocessing existing documents. @@ -100,6 +96,7 @@ Changes Since 0.3.9 - Made ``--embed-stylesheet`` the default rather than ``--link-stylesheet``. - Added writer-specific transform to check the stylesheet setting. + - Added ``_stylesheet_required`` internal setting, defaulting to 0. * docutils/writers/docutils_xml.py: @@ -125,6 +122,9 @@ Changes Since 0.3.9 * test/coverage.sh: Added to project; test coverage script. +* tools/rst2html.py: Made stylesheet requirement explicit (via + ``_stylesheet_required`` setting). + * tools/rstpep2html.py: Renamed from pep.py. * tools/dev/create_unimap.py: Added to project; script to create the diff --git a/docs/user/config.txt b/docs/user/config.txt index d63b5b5bf..0a7ce5ec3 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -651,6 +651,14 @@ stylesheet_path __ `stylesheet_path [latex2e writer]`_ +_`_stylesheet_required` + Warn if valid stylesheet settings are absent. For programmatic + use only. + + Default: not required (0), except when using the ``rst2html.py`` + front-end tool. No command-line options; pass ``--stylesheet=`` + (i.e., with no argument) to disable the stylesheet explicitly. + .. _xml_declaration [html4css1 writer]: xml_declaration @@ -911,15 +919,6 @@ _`_source` Default: stdin (None). No command-line options. -_`_stylesheet_required` - Writers that require stylesheets for correct rendering will check - and warn if valid stylesheet settings are absent. This setting is - used to enable stylesheet checking in writers and applications - that require a stylesheet, and disable checking in writers and - applications that don't. For programmatic use only. - - Default: required (1). No command-line options. - .. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html .. [#pwd] Path relative to the working directory of the process at diff --git a/docutils/core.py b/docutils/core.py index b666006f3..6c7c6c599 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -135,12 +135,6 @@ class Publisher: defaults = (settings_overrides or {}).copy() # Propagate exceptions by default when used programmatically: defaults.setdefault('traceback', 1) - # Do not complain on missing stylesheet when used - # programmatically. A stylesheet is often not necessary - # because the application uses only snippets of the - # output, and requiring a stylesheet would break existing - # applications which use Docutils programmatically. - defaults.setdefault('_stylesheet_required', 0) self.get_settings(settings_spec=settings_spec, config_section=config_section, **defaults) diff --git a/docutils/frontend.py b/docutils/frontend.py index 62037b5f7..b0e0048cd 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -461,8 +461,7 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): settings_defaults = {'_disable_config': None, '_source': None, - '_destination': None, - '_stylesheet_required': 1,} + '_destination': None,} """Defaults for settings that don't have command-line option equivalents.""" relative_path_settings = ('warning_stream',) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index c92b97130..26efb9359 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -111,7 +111,8 @@ class Writer(writers.Writer): ['--cloak-email-addresses'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) - settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} + settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace', + '_stylesheet_required': 0} relative_path_settings = ('stylesheet_path',) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 0466590fd..ba4a14f81 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -638,7 +638,6 @@ class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): """ settings_default_overrides = {'_disable_config': 1, - '_stylesheet_required': 0, 'strict_visitor': 1} writer_name = '' # set in subclasses or constructor diff --git a/test/functional/tests/_default.py b/test/functional/tests/_default.py index 4c72c04c8..2835c5b2e 100644 --- a/test/functional/tests/_default.py +++ b/test/functional/tests/_default.py @@ -5,4 +5,3 @@ settings_overrides['halt_level'] = 5 settings_overrides['warning_stream'] = '' settings_overrides['input_encoding'] = 'utf-8' settings_overrides['embed_stylesheet'] = 0 -settings_overrides['_stylesheet_required'] = 0 diff --git a/test/test_dependencies.py b/test/test_dependencies.py index e1ccc24ef..c9f00518d 100755 --- a/test/test_dependencies.py +++ b/test/test_dependencies.py @@ -30,7 +30,6 @@ class RecordDependenciesTests(unittest.TestCase): settings.setdefault('settings_overrides', {}) settings['settings_overrides'] = settings['settings_overrides'].copy() settings['settings_overrides']['_disable_config'] = 1 - settings['settings_overrides']['_stylesheet_required'] = 0 if not settings['settings_overrides'].has_key('record_dependencies'): settings['settings_overrides']['record_dependencies'] = \ docutils.utils.DependencyList(recordfile) diff --git a/test/test_writers/test_html4css1_misc.py b/test/test_writers/test_html4css1_misc.py index 940f99482..ab728be13 100755 --- a/test/test_writers/test_html4css1_misc.py +++ b/test/test_writers/test_html4css1_misc.py @@ -23,8 +23,7 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): settings_overrides={ 'output_encoding': 'latin1', 'stylesheet': '', - '_disable_config': 1, - '_stylesheet_required': 0,} + '_disable_config': 1,} result = core.publish_string( 'äöü€', writer_name='html4css1', settings_overrides=settings_overrides) diff --git a/tools/rst2html.py b/tools/rst2html.py index 35e5558aa..7fa3aebc4 100755 --- a/tools/rst2html.py +++ b/tools/rst2html.py @@ -22,4 +22,5 @@ from docutils.core import publish_cmdline, default_description description = ('Generates (X)HTML documents from standalone reStructuredText ' 'sources. ' + default_description) -publish_cmdline(writer_name='html', description=description) +publish_cmdline(writer_name='html', description=description, + settings_overrides={'_stylesheet_required': 1}) -- cgit v1.2.1 From 904258b0f9b4eb56b69dabff59ba73bf34488091 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 24 Aug 2005 21:40:39 +0000 Subject: fixed image target test in test_transforms/test_hyperlinks.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3831 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms/test_hyperlinks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 85dfe9a87..8d7d6a029 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -682,11 +682,11 @@ __ http://example.org <target ids="external" names="external" refuri="http://uri"> <target ids="indirect" names="indirect" refuri="http://uri"> <target refid="internal"> - <reference ids="internal" name="external_" names="internal" refuri="http://uri"> + <reference ids="internal" name="external" names="internal" refuri="http://uri"> <image uri="picture.png"> - <reference name="indirect_" refuri="http://uri"> + <reference name="indirect" refuri="http://uri"> <image uri="picture.png"> - <reference name="internal_" refid="internal"> + <reference name="internal" refid="internal"> <image uri="picture.png"> """], ["""\ -- cgit v1.2.1 From 166a3c55fa3628d3f16237bd4360b687f5d1cef4 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 25 Aug 2005 17:15:22 +0000 Subject: Moved "id" attribute from container (section etc.) to the <a> tag in the title, to be on the same tag as "name". (!!! To be reverted in Docutils 0.5.) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3832 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 + THANKS.txt | 2 + docutils/writers/html4css1.py | 37 +++-- test/functional/expected/pep_html.html | 16 +-- .../expected/standalone_rst_html4css1.html | 154 ++++++++++----------- test/test_writers/test_html4css1.py | 48 +++---- 6 files changed, 141 insertions(+), 119 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 2614f5817..ca042bfea 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -97,6 +97,9 @@ Changes Since 0.3.9 ``--link-stylesheet``. - Added writer-specific transform to check the stylesheet setting. - Added ``_stylesheet_required`` internal setting, defaulting to 0. + - Moved "id" attribute from container (section etc.) to title's <a> + tag, to be on the same tag as "name". + (!!! To be reverted in Docutils 0.5.) * docutils/writers/docutils_xml.py: diff --git a/THANKS.txt b/THANKS.txt index e42b0001c..9c1315603 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -105,6 +105,7 @@ donations, tasty treats, and related projects: * Brett g Porter * David Priest * Jens Quade +* Edward K. Ream * Andy Robinson * Tavis Rudd * Tracy Ruggles @@ -136,6 +137,7 @@ donations, tasty treats, and related projects: * Wu Wei * Edward Welbourne * Felix Wiemann +* Anthony Williams * Ka-Ping Yee * Moshe Zadka diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 26efb9359..b86c19fe6 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -310,6 +310,7 @@ class HTMLTranslator(nodes.NodeVisitor): tagname = tagname.lower() prefix = [] atts = {} + ids = [] for (name, value) in attributes.items(): atts[name.lower()] = value classes = node.get('classes', []) @@ -318,9 +319,13 @@ class HTMLTranslator(nodes.NodeVisitor): if classes: atts['class'] = ' '.join(classes) assert not atts.has_key('id') - if node.get('ids'): - atts['id'] = node['ids'][0] - for id in node['ids'][1:]: + ids.extend(node.get('ids', [])) + if atts.has_key('ids'): + ids.extend(atts['ids']) + del atts['ids'] + if ids: + atts['id'] = ids[0] + for id in ids[1:]: if infix: # Empty tag. prefix.append('<span id="%s"></span>' % id) @@ -328,6 +333,7 @@ class HTMLTranslator(nodes.NodeVisitor): # Non-empty tag. We place the auxiliary <span> # tag *inside* the element. suffix += '<span id="%s"></span>' % id + # !!! next 2 lines to be removed in Docutils 0.5: if atts.has_key('id') and tagname in self.named_tags: atts['name'] = atts['id'] # for compatibility with old browsers attlist = atts.items() @@ -353,6 +359,12 @@ class HTMLTranslator(nodes.NodeVisitor): """Construct and return an XML-compatible empty tag.""" return self.starttag(node, tagname, suffix, infix=' /', **attributes) + # !!! to be removed in Docutils 0.5 (change calls to use "starttag"): + def start_tag_with_title(self, node, tagname, **atts): + """ID and NAME attributes will be handled in the title.""" + node = {'classes': node.get('classes', [])} + return self.starttag(node, tagname, **atts) + def set_first_last(self, node): children = [n for n in node if not isinstance(n, nodes.Invisible)] if children: @@ -392,8 +404,8 @@ class HTMLTranslator(nodes.NodeVisitor): self.depart_docinfo_item() def visit_admonition(self, node, name=''): - self.body.append(self.starttag(node, 'div', - CLASS=(name or 'admonition'))) + self.body.append(self.start_tag_with_title( + node, 'div', CLASS=(name or 'admonition'))) if name: node.insert(0, nodes.title(name, self.language.labels[name])) self.set_first_last(node) @@ -1174,14 +1186,16 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_section(self, node): self.section_level += 1 - self.body.append(self.starttag(node, 'div', CLASS='section')) + self.body.append( + self.start_tag_with_title(node, 'div', CLASS='section')) def depart_section(self, node): self.section_level -= 1 self.body.append('</div>\n') def visit_sidebar(self, node): - self.body.append(self.starttag(node, 'div', CLASS='sidebar')) + self.body.append( + self.start_tag_with_title(node, 'div', CLASS='sidebar')) self.set_first_last(node) self.in_sidebar = 1 @@ -1379,17 +1393,20 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( self.starttag(node, 'h%s' % h_level, '', **atts)) atts = {} + # !!! next 2 lines to be removed in Docutils 0.5: if node.parent['ids']: - atts['name'] = node.parent['ids'][0] + atts['ids'] = node.parent['ids'] if node.hasattr('refid'): atts['class'] = 'toc-backref' atts['href'] = '#' + node['refid'] self.body.append(self.starttag({}, 'a', '', **atts)) self.context.append('</a></h%s>\n' % (h_level)) + # !!! conditional to be removed in Docutils 0.5: if check_id: if node.parent['ids']: + atts={'ids': node.parent['ids']} self.body.append( - self.starttag({}, 'a', '', name=node.parent['ids'][0])) + self.starttag({}, 'a', '', **atts)) self.context.append('</a>' + close_tag) else: self.context.append(close_tag) @@ -1410,7 +1427,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('</cite>') def visit_topic(self, node): - self.body.append(self.starttag(node, 'div', CLASS='topic')) + self.body.append(self.start_tag_with_title(node, 'div', CLASS='topic')) self.topic_classes = node['classes'] def depart_topic(self, node): diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index e12b15c0e..d48b8fb99 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -53,25 +53,25 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! </tbody> </table> <hr /> -<div class="contents topic" id="contents"> -<p class="topic-title first"><a name="contents">Contents</a></p> +<div class="contents topic"> +<p class="topic-title first"><a id="contents" name="contents">Contents</a></p> <ul class="simple"> <li><a class="reference" href="#abstract" id="id5" name="id5">Abstract</a></li> <li><a class="reference" href="#copyright" id="id6" name="id6">Copyright</a></li> <li><a class="reference" href="#references-and-footnotes" id="id7" name="id7">References and Footnotes</a></li> </ul> </div> -<div class="section" id="abstract"> -<h1><a class="toc-backref" href="#id5" name="abstract">Abstract</a></h1> +<div class="section"> +<h1><a class="toc-backref" href="#id5" id="abstract" name="abstract">Abstract</a></h1> <p>This is just a test <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a>. See the <a class="reference" href="http://www.python.org/peps/">PEP repository</a> <a class="footnote-reference" href="#id3" id="id4" name="id4">[2]</a> for the real thing.</p> </div> -<div class="section" id="copyright"> -<h1><a class="toc-backref" href="#id6" name="copyright">Copyright</a></h1> +<div class="section"> +<h1><a class="toc-backref" href="#id6" id="copyright" name="copyright">Copyright</a></h1> <p>This document has been placed in the public domain.</p> </div> -<div class="section" id="references-and-footnotes"> -<h1><a class="toc-backref" href="#id7" name="references-and-footnotes">References and Footnotes</a></h1> +<div class="section"> +<h1><a class="toc-backref" href="#id7" id="references-and-footnotes" name="references-and-footnotes">References and Footnotes</a></h1> <table class="docutils footnote" frame="void" id="id2" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 7e4c91546..86dfed7cb 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -85,8 +85,8 @@ transforms to after the document title, subtitle, and docinfo. --> <!-- Above is the document title, and below is the subtitle. They are transformed from section titles after parsing. --> <!-- bibliographic fields (which also require a transform): --> -<div class="contents topic" id="table-of-contents"> -<p class="topic-title first"><a name="table-of-contents">Table of Contents</a></p> +<div class="contents topic"> +<p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of Contents</a></p> <ul class="auto-toc simple"> <li><a class="reference" href="#structural-elements" id="id33" name="id33">1   Structural Elements</a><ul class="auto-toc"> <li><a class="reference" href="#section-title" id="id34" name="id34">1.1   Section Title</a></li> @@ -137,31 +137,31 @@ They are transformed from section titles after parsing. --> <li><a class="reference" href="#error-handling" id="id69" name="id69">3   Error Handling</a></li> </ul> </div> -<div class="section" id="structural-elements"> -<h1><a class="toc-backref" href="#id33" name="structural-elements">1   Structural Elements</a></h1> -<div class="section" id="section-title"> -<h2 class="with-subtitle"><a class="toc-backref" href="#id34" name="section-title">1.1   Section Title</a></h2> +<div class="section"> +<h1><a class="toc-backref" href="#id33" id="structural-elements" name="structural-elements">1   Structural Elements</a></h1> +<div class="section"> +<h2 class="with-subtitle"><a class="toc-backref" href="#id34" id="section-title" name="section-title">1.1   Section Title</a></h2> <h2 class="section-subtitle" id="section-subtitle"><span class="section-subtitle">Section Subtitle</span></h2> <p>That's it, the text just above this line.</p> </div> -<div class="section" id="empty-section"> -<h2><a class="toc-backref" href="#id35" name="empty-section">1.2   Empty Section</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id35" id="empty-section" name="empty-section">1.2   Empty Section</a></h2> </div> -<div class="section" id="transitions"> -<h2><a class="toc-backref" href="#id36" name="transitions">1.3   Transitions</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id36" id="transitions" name="transitions">1.3   Transitions</a></h2> <p>Here's a transition:</p> <hr class="docutils" /> <p>It divides the section. Transitions may also occur between sections:</p> </div> </div> <hr class="docutils" /> -<div class="section" id="body-elements"> -<h1><a class="toc-backref" href="#id37" name="body-elements">2   Body Elements</a></h1> -<div class="section" id="paragraphs"> -<h2><a class="toc-backref" href="#id38" name="paragraphs">2.1   Paragraphs</a></h2> +<div class="section"> +<h1><a class="toc-backref" href="#id37" id="body-elements" name="body-elements">2   Body Elements</a></h1> +<div class="section"> +<h2><a class="toc-backref" href="#id38" id="paragraphs" name="paragraphs">2.1   Paragraphs</a></h2> <p>A paragraph.</p> -<div class="section" id="inline-markup"> -<h3><a class="toc-backref" href="#id39" name="inline-markup">2.1.1   Inline Markup</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id39" id="inline-markup" name="inline-markup">2.1.1   Inline Markup</a></h3> <p>Paragraphs contain text and may contain inline markup: <em>emphasis</em>, <strong>strong emphasis</strong>, <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literals</span></tt>, standalone hyperlinks (<a class="reference" href="http://www.python.org">http://www.python.org</a>), external hyperlinks (<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id21" id="id22" name="id22">[5]</a>), internal @@ -191,8 +191,8 @@ and explicit roles for <em>standard</em> <strong>inline</strong> live link to PEP 258 here.</p> </div> </div> -<div class="section" id="bullet-lists"> -<h2><a class="toc-backref" href="#id40" name="bullet-lists">2.2   Bullet Lists</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id40" id="bullet-lists" name="bullet-lists">2.2   Bullet Lists</a></h2> <ul> <li><p class="first">A bullet list</p> <ul class="simple"> @@ -216,8 +216,8 @@ live link to PEP 258 here.</p> </li> </ul> </div> -<div class="section" id="enumerated-lists"> -<h2><a class="toc-backref" href="#id41" name="enumerated-lists">2.3   Enumerated Lists</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id41" id="enumerated-lists" name="enumerated-lists">2.3   Enumerated Lists</a></h2> <ol class="arabic"> <li><p class="first">Arabic numerals.</p> <ol class="loweralpha simple"> @@ -249,8 +249,8 @@ live link to PEP 258 here.</p> </li> </ol> </div> -<div class="section" id="definition-lists"> -<h2><a class="toc-backref" href="#id42" name="definition-lists">2.4   Definition Lists</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id42" id="definition-lists" name="definition-lists">2.4   Definition Lists</a></h2> <dl class="docutils"> <dt>Term</dt> <dd>Definition</dd> @@ -264,8 +264,8 @@ live link to PEP 258 here.</p> <dd>Definition</dd> </dl> </div> -<div class="section" id="field-lists"> -<h2><a class="toc-backref" href="#id43" name="field-lists">2.5   Field Lists</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id43" id="field-lists" name="field-lists">2.5   Field Lists</a></h2> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> @@ -287,8 +287,8 @@ doesn't get stripped away.)</p> </tbody> </table> </div> -<div class="section" id="option-lists"> -<h2><a class="toc-backref" href="#id44" name="option-lists">2.6   Option Lists</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id44" id="option-lists" name="option-lists">2.6   Option Lists</a></h2> <p>For listing command-line options:</p> <table class="docutils option-list" frame="void" rules="none"> <col class="option" /> @@ -333,8 +333,8 @@ regardless of where it starts.</p> <p>There must be at least two spaces between the option and the description.</p> </div> -<div class="section" id="literal-blocks"> -<h2><a class="toc-backref" href="#id45" name="literal-blocks">2.7   Literal Blocks</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id45" id="literal-blocks" name="literal-blocks">2.7   Literal Blocks</a></h2> <p>Literal blocks are indicated with a double-colon ("::") at the end of the preceding paragraph (over there <tt class="docutils literal"><span class="pre">--></span></tt>). They can be indented:</p> <pre class="literal-block"> @@ -350,8 +350,8 @@ if literal_block: > Why didn't I think of that? </pre> </div> -<div class="section" id="line-blocks"> -<h2><a class="toc-backref" href="#id46" name="line-blocks">2.8   Line Blocks</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id46" id="line-blocks" name="line-blocks">2.8   Line Blocks</a></h2> <p>This section tests line blocks. Line blocks are body elements which consist of lines and other line blocks. Nested line blocks cause indentation.</p> @@ -409,8 +409,8 @@ the left edge of the text above it.</div> </div> </blockquote> </div> -<div class="section" id="block-quotes"> -<h2><a class="toc-backref" href="#id47" name="block-quotes">2.9   Block Quotes</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id47" id="block-quotes" name="block-quotes">2.9   Block Quotes</a></h2> <p>Block quotes consist of indented body elements:</p> <blockquote> <p>My theory by A. Elk. Brackets Miss, brackets. This theory goes @@ -421,8 +421,8 @@ own it, and what it is too.</p> <p class="attribution">—Anne Elk (Miss)</p> </blockquote> </div> -<div class="section" id="doctest-blocks"> -<h2><a class="toc-backref" href="#id48" name="doctest-blocks">2.10   Doctest Blocks</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id48" id="doctest-blocks" name="doctest-blocks">2.10   Doctest Blocks</a></h2> <pre class="doctest-block"> >>> print 'Python-specific usage examples; begun with ">>>"' Python-specific usage examples; begun with ">>>" @@ -430,8 +430,8 @@ Python-specific usage examples; begun with ">>>" (cut and pasted from interactive Python sessions) </pre> </div> -<div class="section" id="footnotes"> -<h2><a class="toc-backref" href="#id49" name="footnotes">2.11   Footnotes</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id49" id="footnotes" name="footnotes">2.11   Footnotes</a></h2> <table class="docutils footnote" frame="void" id="id6" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -482,8 +482,8 @@ nonexistent footnote: <a href="#id25" name="id26"><span class="problematic" id=" </tbody> </table> </div> -<div class="section" id="citations"> -<h2><a class="toc-backref" href="#id50" name="citations">2.12   Citations</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id50" id="citations" name="citations">2.12   Citations</a></h2> <table class="docutils citation" frame="void" id="cit2002" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -494,8 +494,8 @@ rendered separately and differently from footnotes.</td></tr> <p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id27" name="id28"><span class="problematic" id="id28">[nonexistent]_</span></a> citation.</p> </div> -<div class="section" id="targets"> -<span id="another-target"></span><h2><a class="toc-backref" href="#id51" name="targets">2.13   Targets</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id51" id="targets" name="targets"><span id="another-target"></span>2.13   Targets</a></h2> <p id="example">This paragraph is pointed to by the explicit "example" target. A reference can be found under <a class="reference" href="#inline-markup">Inline Markup</a>, above. <a class="reference" href="#inline-hyperlink-targets">Inline hyperlink targets</a> are also possible.</p> @@ -507,22 +507,22 @@ hyperlink targets</a> are also possible.</p> refer to the <a class="reference" href="#targets">Targets</a> section.</p> <p>Here's a <a href="#id29" name="id30"><span class="problematic" id="id30">`hyperlink reference without a target`_</span></a>, which generates an error.</p> -<div class="section" id="duplicate-target-names"> -<h3><a class="toc-backref" href="#id52" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id52" id="duplicate-target-names" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> <p>Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages.</p> </div> -<div class="section" id="id18"> -<h3><a class="toc-backref" href="#id53" name="id18">2.13.2   Duplicate Target Names</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id53" id="id18" name="id18">2.13.2   Duplicate Target Names</a></h3> <p>Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: <a href="#id31" name="id32"><span class="problematic" id="id32">`Duplicate Target Names`_</span></a>), an error is generated.</p> </div> </div> -<div class="section" id="directives"> -<h2><a class="toc-backref" href="#id54" name="directives">2.14   Directives</a></h2> -<div class="contents local topic" id="contents"> +<div class="section"> +<h2><a class="toc-backref" href="#id54" id="directives" name="directives">2.14   Directives</a></h2> +<div class="contents local topic"> <ul class="auto-toc simple"> <li><a class="reference" href="#document-parts" id="id70" name="id70">2.14.1   Document Parts</a></li> <li><a class="reference" href="#images" id="id71" name="id71">2.14.2   Images</a></li> @@ -536,14 +536,14 @@ this: <a href="#id31" name="id32"><span class="problematic" id="id32">`Duplicate <p>These are just a sample of the many reStructuredText Directives. For others, please see <a class="reference" href="http://docutils.sourceforge.net/docs/ref/rst/directives.html">http://docutils.sourceforge.net/docs/ref/rst/directives.html</a>.</p> -<div class="section" id="document-parts"> -<h3><a class="toc-backref" href="#id70" name="document-parts">2.14.1   Document Parts</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id70" id="document-parts" name="document-parts">2.14.1   Document Parts</a></h3> <p>An example of the "contents" directive can be seen above this section (a local, untitled table of <a class="reference" href="#contents">contents</a>) and at the beginning of the document (a document-wide <a class="reference" href="#table-of-contents">table of contents</a>).</p> </div> -<div class="section" id="images"> -<h3><a class="toc-backref" href="#id71" name="images">2.14.2   Images</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id71" id="images" name="images">2.14.2   Images</a></h3> <p>An image directive (also clickable -- a hyperlink reference):</p> <a class="reference image-reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a> <p>Image with multiple IDs:</p> @@ -604,8 +604,8 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>An image 3 cm high:</p> <img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="height: 3cm;" /> </div> -<div class="section" id="admonitions"> -<h3><a class="toc-backref" href="#id72" name="admonitions">2.14.3   Admonitions</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id72" id="admonitions" name="admonitions">2.14.3   Admonitions</a></h3> <div class="attention"> <p class="first admonition-title">Attention!</p> <p class="last">Directives at large.</p> @@ -653,8 +653,8 @@ Reader discretion is strongly advised.</p> <p class="last">You can make up your own admonition too.</p> </div> </div> -<div class="section" id="topics-sidebars-and-rubrics"> -<h3><a class="toc-backref" href="#id73" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id73" id="topics-sidebars-and-rubrics" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> <div class="sidebar"> <p class="first sidebar-title">Sidebar Title</p> <p class="sidebar-subtitle">Optional Subtitle</p> @@ -670,8 +670,8 @@ background color.</p> </div> <p class="rubric">This is a rubric</p> </div> -<div class="section" id="target-footnotes"> -<h3><a class="toc-backref" href="#id74" name="target-footnotes">2.14.5   Target Footnotes</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id74" id="target-footnotes" name="target-footnotes">2.14.5   Target Footnotes</a></h3> <table class="docutils footnote" frame="void" id="id21" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> @@ -679,12 +679,12 @@ background color.</p> </tbody> </table> </div> -<div class="section" id="replacement-text"> -<h3><a class="toc-backref" href="#id75" name="replacement-text">2.14.6   Replacement Text</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id75" id="replacement-text" name="replacement-text">2.14.6   Replacement Text</a></h3> <p>I recommend you try <a class="reference" href="http://www.python.org/">Python, <em>the</em> best language around</a> <a class="footnote-reference" href="#id21" id="id24" name="id24">[5]</a>.</p> </div> -<div class="section" id="compound-paragraph"> -<h3><a class="toc-backref" href="#id76" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> +<div class="section"> +<h3><a class="toc-backref" href="#id76" id="compound-paragraph" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> <div class="some-class compound"> <p class="compound-first">Compound 1, paragraph 1.</p> <p class="compound-middle">Compound 1, paragraph 2.</p> @@ -751,13 +751,13 @@ paragraph.</td> </div> </div> </div> -<div class="section" id="substitution-definitions"> -<h2><a class="toc-backref" href="#id62" name="substitution-definitions">2.15   Substitution Definitions</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id62" id="substitution-definitions" name="substitution-definitions">2.15   Substitution Definitions</a></h2> <p>An inline image (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" />) example:</p> <p>(Substitution definitions are not visible in the HTML source.)</p> </div> -<div class="section" id="comments"> -<h2><a class="toc-backref" href="#id63" name="comments">2.16   Comments</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id63" id="comments" name="comments">2.16   Comments</a></h2> <p>Here's one:</p> <!-- Comments begin with two dots and a space. Anything may follow, except for the syntax of footnotes, hyperlink @@ -766,14 +766,14 @@ targets, directives, or substitution definitions. Double-dashes - - "- -" - - must be escaped somehow in HTML output. --> <p>(View the HTML source to see the comment.)</p> </div> -<div class="section" id="raw-text"> -<h2><a class="toc-backref" href="#id64" name="raw-text">2.17   Raw text</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id64" id="raw-text" name="raw-text">2.17   Raw text</a></h2> <p>This does not necessarily look nice, because there may be missing white space.</p> <p>It's just there to freeze the behavior.</p> A test.Second test.<div class="myclass">Another test with myclass set.</div><p>This is the <span class="myrawroleclass">fourth test</span> with myrawroleclass set.</p> Fifth test in HTML.<br />Line two.</div> -<div class="section" id="colspanning-tables"> -<h2><a class="toc-backref" href="#id65" name="colspanning-tables">2.18   Colspanning tables</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id65" id="colspanning-tables" name="colspanning-tables">2.18   Colspanning tables</a></h2> <p>This table has a cell spanning two columns:</p> <table border="1" class="docutils"> <colgroup> @@ -810,8 +810,8 @@ Fifth test in HTML.<br />Line two.</div> </tbody> </table> </div> -<div class="section" id="rowspanning-tables"> -<h2><a class="toc-backref" href="#id66" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id66" id="rowspanning-tables" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> <p>Here's a table with cells spanning several rows:</p> <table border="1" class="docutils"> <colgroup> @@ -843,8 +843,8 @@ cell.</td> </tbody> </table> </div> -<div class="section" id="complex-tables"> -<h2><a class="toc-backref" href="#id67" name="complex-tables">2.20   Complex tables</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id67" id="complex-tables" name="complex-tables">2.20   Complex tables</a></h2> <p>Here's a complex table, which should test all features.</p> <table border="1" class="docutils"> <colgroup> @@ -892,8 +892,8 @@ empty: <tt class="docutils literal"><span class="pre">--></span></tt></td> </tbody> </table> </div> -<div class="section" id="list-tables"> -<h2><a class="toc-backref" href="#id68" name="list-tables">2.21   List Tables</a></h2> +<div class="section"> +<h2><a class="toc-backref" href="#id68" id="list-tables" name="list-tables">2.21   List Tables</a></h2> <p>Here's a list table exercising all features:</p> <table border="1" class="test docutils"> <caption>list table with integral header</caption> @@ -926,8 +926,8 @@ crunchy, now would it?</td> </table> </div> </div> -<div class="section" id="error-handling"> -<h1><a class="toc-backref" href="#id69" name="error-handling">3   Error Handling</a></h1> +<div class="section"> +<h1><a class="toc-backref" href="#id69" id="error-handling" name="error-handling">3   Error Handling</a></h1> <p>Any errors caught during processing will generate system messages.</p> <p>There should be five messages in the following, auto-generated section, "Docutils System Messages":</p> diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 6ce0c15cd..fa072f9a1 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -120,11 +120,11 @@ And even more stuff """, """\ {'fragment': '''<p>Some stuff</p> -<div class="section" id="section"> -<h1><a name="section">Section</a></h1> +<div class="section"> +<h1><a id="section" name="section">Section</a></h1> <p>Some more stuff</p> -<div class="section" id="another-section"> -<h2><a name="another-section">Another Section</a></h2> +<div class="section"> +<h2><a id="another-section" name="another-section">Another Section</a></h2> <p>And even more stuff</p> </div> </div>\\n''', @@ -132,11 +132,11 @@ And even more stuff <h1 class="title">Title</h1> <h2 class="subtitle" id="subtitle">Subtitle</h2> <p>Some stuff</p> -<div class="section" id="section"> -<h1><a name="section">Section</a></h1> +<div class="section"> +<h1><a id="section" name="section">Section</a></h1> <p>Some more stuff</p> -<div class="section" id="another-section"> -<h2><a name="another-section">Another Section</a></h2> +<div class="section"> +<h2><a id="another-section" name="another-section">Another Section</a></h2> <p>And even more stuff</p> </div> </div> @@ -265,32 +265,32 @@ Another Section And even more stuff """, """\ -{'fragment': '''<div class="section" id="title"> -<h1><a name="title">Title</a></h1> -<div class="section" id="not-a-subtitle"> -<h2><a name="not-a-subtitle">Not A Subtitle</a></h2> +{'fragment': '''<div class="section"> +<h1><a id="title" name="title">Title</a></h1> +<div class="section"> +<h2><a id="not-a-subtitle" name="not-a-subtitle">Not A Subtitle</a></h2> <p>Some stuff</p> -<div class="section" id="section"> -<h3><a name="section">Section</a></h3> +<div class="section"> +<h3><a id="section" name="section">Section</a></h3> <p>Some more stuff</p> -<div class="section" id="another-section"> -<h4><a name="another-section">Another Section</a></h4> +<div class="section"> +<h4><a id="another-section" name="another-section">Another Section</a></h4> <p>And even more stuff</p> </div> </div> </div> </div>\\n''', 'html_body': '''<div class="document"> -<div class="section" id="title"> -<h1><a name="title">Title</a></h1> -<div class="section" id="not-a-subtitle"> -<h2><a name="not-a-subtitle">Not A Subtitle</a></h2> +<div class="section"> +<h1><a id="title" name="title">Title</a></h1> +<div class="section"> +<h2><a id="not-a-subtitle" name="not-a-subtitle">Not A Subtitle</a></h2> <p>Some stuff</p> -<div class="section" id="section"> -<h3><a name="section">Section</a></h3> +<div class="section"> +<h3><a id="section" name="section">Section</a></h3> <p>Some more stuff</p> -<div class="section" id="another-section"> -<h4><a name="another-section">Another Section</a></h4> +<div class="section"> +<h4><a id="another-section" name="another-section">Another Section</a></h4> <p>And even more stuff</p> </div> </div> -- cgit v1.2.1 From b67ead9a20e534e7bb5fac07d62a8738ea8e5f46 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 03:14:19 +0000 Subject: catch unescaped colon at end of hyperlink targets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3833 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 1 + test/test_parsers/test_rst/test_targets.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 175334fd2..06077cfca 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1723,6 +1723,7 @@ class Body(RSTState): %(non_whitespace_escape_before)s (?P=quote) # close quote if open quote used ) + (?<![^\x00]:) # no unescaped colon at end %(non_whitespace_escape_before)s [ ]? # optional space : # end of reference name diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index 9d846c142..ad3d3dd25 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -298,6 +298,23 @@ Explicit internal target. Duplicate explicit target name: "target". <target dupnames="target" ids="id4" refuri="Explicit_external_target"> """], +["""\ +.. _unescaped colon at end:: no good + +.. _escaped colon\:: OK + +.. _`unescaped colon, quoted:`: OK +""", +"""\ +<document source="test data"> + <comment xml:space="preserve"> + _unescaped colon at end:: no good + <system_message level="2" line="1" source="test data" type="WARNING"> + <paragraph> + malformed hyperlink target. + <target ids="escaped-colon" names="escaped colon:" refuri="OK"> + <target ids="unescaped-colon-quoted" names="unescaped colon, quoted:" refuri="OK"> +"""], ] totest['anonymous_targets'] = [ -- cgit v1.2.1 From 59693acd6fa7b6336dc7b56c8c4fe094aef2c93b Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 13:10:47 +0000 Subject: catch another case of malformed hyperlink target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3834 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 2 +- test/test_parsers/test_rst/test_targets.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 06077cfca..d72a96e0c 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1723,7 +1723,7 @@ class Body(RSTState): %(non_whitespace_escape_before)s (?P=quote) # close quote if open quote used ) - (?<![^\x00]:) # no unescaped colon at end + (?<!(?<!\x00):) # no unescaped colon at end %(non_whitespace_escape_before)s [ ]? # optional space : # end of reference name diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index ad3d3dd25..ef7f8ec76 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -301,6 +301,8 @@ Explicit internal target. ["""\ .. _unescaped colon at end:: no good +.. _:: no good either + .. _escaped colon\:: OK .. _`unescaped colon, quoted:`: OK @@ -312,6 +314,11 @@ Explicit internal target. <system_message level="2" line="1" source="test data" type="WARNING"> <paragraph> malformed hyperlink target. + <comment xml:space="preserve"> + _:: no good either + <system_message level="2" line="3" source="test data" type="WARNING"> + <paragraph> + malformed hyperlink target. <target ids="escaped-colon" names="escaped colon:" refuri="OK"> <target ids="unescaped-colon-quoted" names="unescaped colon, quoted:" refuri="OK"> """], -- cgit v1.2.1 From f680b4c26ef854c01f13b0f9cfc92e39037abf78 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 14:29:20 +0000 Subject: added entry on serving XHTML as "Content-type: text/html" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3835 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 32 ++++++++++++++++++++++++++++++++ THANKS.txt | 3 +++ 2 files changed, 35 insertions(+) diff --git a/FAQ.txt b/FAQ.txt index c3504e74a..80895e633 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -902,6 +902,38 @@ returns a dictionary containing an 'html_body_' entry. docs/api/publisher.html#html-body +Why is the Docutils XHTML served as "Content-type: text/html"? +-------------------------------------------------------------- + +Full question: + + Docutils' HTML output looks like XHTML and is advertised as such:: + + <?xml version="1.0" encoding="utf-8" ?> + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xht ml1/DTD/xhtml1-transitional.dtd"> + + But this is followed by:: + + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + + Shouldn't this be "application/xhtml+xml" instead of "text/html"? + +In a perfect web, the Docutils XHTML output would be 100% strict +XHTML. But it's not a perfect web, and a major source of imperfection +is Internet Explorer. Despite it's drawbacks, IE still represents the +majority of web browsers, and cannot be ignored. + +Short answer: if we didn't serve XHTML as "text/html" (which is a +perfectly valid thing to do), it couldn't be viewed in Internet +Explorer. + +Long answer: see the `"Criticisms of Internet Explorer" Wikipedia +entry <http://en.wikipedia.org/wiki/Criticisms_of_Internet_Explorer#XHTML>`__. + +(Thanks to Martin F. Krafft, Robert Kern and Michael Foord.) + + Python Source Reader ==================== diff --git a/THANKS.txt b/THANKS.txt index 9c1315603..cf9208556 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -45,6 +45,7 @@ donations, tasty treats, and related projects: * Benja Fallenstein * fantasai * Stefane Fermigier +* Michael Foord * Jim Fulton * Peter Funk * Lele Gaifax @@ -70,10 +71,12 @@ donations, tasty treats, and related projects: * Dmitry Jemerov * Richard Jones * Andreas Jung +* Robert Kern * Garth Kidd * Philipp Knüsel * Axel Kollmorgen * Jeff Kowalczyk +* Martin F. Krafft * Dave Kuhlman * Lloyd Kvam * Kirill Lapshin -- cgit v1.2.1 From c7418d6456149d9c8b6997d2fc9c00d0d6f3153d Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 15:37:59 +0000 Subject: added HTML (CSS) stylesheet howto git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3836 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/html-stylesheets.txt | 73 +++++++++++++++++++++++++++++++++++++++++ docs/index.txt | 2 ++ 2 files changed, 75 insertions(+) create mode 100644 docs/howto/html-stylesheets.txt diff --git a/docs/howto/html-stylesheets.txt b/docs/howto/html-stylesheets.txt new file mode 100644 index 000000000..74fccaa45 --- /dev/null +++ b/docs/howto/html-stylesheets.txt @@ -0,0 +1,73 @@ +============================================== + Writing HTML (CSS) Stylesheets for Docutils_ +============================================== + +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + +.. _Docutils: http://docutils.sourceforge.net/ + + +The look of Docutils' HTML output is customizable via a CSS +stylesheet. The default stylesheet is called ``default.css`` and can +be found in the ``tools/stylesheets/`` directory of the Docutils +distribution tarball. + +To customize the stylesheet, place a new file (e.g. called +``docutils.css``) in the same directory as ``default.css`` and use the +following template:: + + /* + :Author: Your Name + :Contact: Your Email Address + :Copyright: This stylesheet has been placed in the public domain. + + Stylesheet for use with Docutils. [Optionally place a more + detailed description here.] + */ + + @import url(default.css); + + /* Your customizations go here. For example: */ + + h1, h2, h3, h4, h5, h6, p.topic-title { + font-family: sans-serif } + +For help on the CSS syntax, please see `the WDG's guide to Cascading +Style Sheets`__ and, in particular, their `list of CSS1 properties`__. + +__ http://www.htmlhelp.com/reference/css/ +__ http://www.htmlhelp.com/reference/css/all-properties.html + +It is important that you do not edit a copy of ``default.css`` +directly because ``default.css`` is frequently updated with each new +release of Docutils. + +Also make sure that you import ``default.css`` (using "``@import +url(default.css);``") because the definitions contained in the default +stylesheet are required for correct rendering (margins, alignment, +etc.). + +If you think your stylesheet is fancy and you would like to let others +benefit from your efforts, you are encouraged to post the stylesheet +to the Docutils-users_ mailing list. We can upload it to the Docutils +repository if you would like us to do so. + +If you decide to share you stylesheet with other users of Docutils, +please keep website-specific customizations not applicable to +Docutils' HTML code in a separate stylesheet. + +.. _Docutils-users: ../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/docs/index.txt b/docs/index.txt index 75429f87a..ab77b94a2 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -181,6 +181,8 @@ __ http://www.python.org/peps/pep-0287.html ``howto/``: Instructions for Developers ======================================= +* `Writing HTML (CSS) Stylesheets for Docutils + <howto/html-stylesheets.html>`__ * `Docutils Internationalization <howto/i18n.html>`__ * `Creating reStructuredText Directives <howto/rst-directives.html>`__ * `Creating reStructuredText Interpreted Text Roles -- cgit v1.2.1 From 970f082ec7e1d6c9bcd0785185dfba33a46d9115 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 15:49:37 +0000 Subject: updated section about stylesheets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3837 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 28433005e..7986e51a5 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -114,31 +114,18 @@ of processing, and links to the Docutils projects, add some options:: Stylesheets ``````````` -``rst2html.py`` inserts into the generated HTML a link to a cascading -stylesheet, defaulting to "``default.css``" (override with a -"``--stylesheet``" or "``--stylesheet-path``" command-line option or -with configuration file settings). The -"``tools/stylesheets/default.css``" stylesheet is provided for basic -use. To experiment with styles, rather than editing the default -stylesheet (which will be updated as the project evolves), it is -recommended to use an "``@import``" statement to create a "wrapper" -stylesheet. For example, a "``my.css``" stylesheet could contain the -following:: - - @import url(default.css); - - h1, h2, h3, h4, h5, h6, p.topic-title { - font-family: sans-serif } - -Generate HTML with the following command:: - - rst2html.py -stg --stylesheet my.css test.txt test.html - -When viewed in a browser, the new "wrapper" stylesheet will change the -typeface family of titles to "sans serif", typically Helvetica or -Arial. Other styles will not be affected. Styles in wrapper -stylesheets override styles in imported stylesheets, enabling -incremental experimentation. +``rst2html.py`` inserts into the generated HTML a cascading stylesheet +(or a link to a stylesheet, when passing the "``--link-stylesheet``" +option). You must specify the location of the stylesheet (normally +``tools/stylesheets/default.css`` in the Docutils distribution +tarball) with a "``--stylesheet``" or "``--stylesheet-path``" +command-line option unless a configuration file +(e.g. ``/etc/docutils.conf`` or ``~/.docutils.conf``) does so for you. +The "``tools/stylesheets/default.css``" stylesheet is provided for +basic use. To experiment with styles, please see the `guide to +writing HTML (CSS) stylesheets for Docutils`__. + +__ ../howto/html-stylesheets.html rstpep2html.py -- cgit v1.2.1 From 7f6fa5828f837c9fc241ca94536937ee3578b3ed Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 16:15:37 +0000 Subject: minor improvements git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3838 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/html-stylesheets.txt | 4 ++-- tools/stylesheets/default.css | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/howto/html-stylesheets.txt b/docs/howto/html-stylesheets.txt index 74fccaa45..1ae265e5e 100644 --- a/docs/howto/html-stylesheets.txt +++ b/docs/howto/html-stylesheets.txt @@ -17,8 +17,8 @@ be found in the ``tools/stylesheets/`` directory of the Docutils distribution tarball. To customize the stylesheet, place a new file (e.g. called -``docutils.css``) in the same directory as ``default.css`` and use the -following template:: +``my-docutils.css``) in the same directory as ``default.css`` and use +the following template:: /* :Author: Your Name diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css index abfcbce7a..a418a7a00 100644 --- a/tools/stylesheets/default.css +++ b/tools/stylesheets/default.css @@ -2,10 +2,13 @@ :Author: David Goodger :Contact: goodger@users.sourceforge.net :Date: $Date$ -:Version: $Revision$ +:Revision: $Revision$ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. */ /* "! important" is used here to override other ``margin-top`` and -- cgit v1.2.1 From 1895e2e02f536430272a0189237d4ec7a64f3cd3 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 26 Aug 2005 18:07:38 +0000 Subject: added to-do list entry about :parent: option of "class" directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3839 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 06d1e3d8e..aae1b0d83 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1019,6 +1019,11 @@ when used in a document. This may be too specific to output formats which have a notion of "pages". + - _`misc.class`: + + - Add a ``:parent:`` option for setting the parent's class + (http://article.gmane.org/gmane.text.docutils.devel/3165). + - _`misc.include`: - Option to select a range of lines? -- cgit v1.2.1 From 86b1366574934851dffcc5e622f0724882e90f6c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 27 Aug 2005 13:43:58 +0000 Subject: LaTeX writer: protect closing sqaure brackets as well git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3840 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 3 +-- test/functional/expected/standalone_rst_latex.tex | 6 +++--- test/test_writers/test_latex2e.py | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 02ebffc67..4bbe9db08 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -867,8 +867,7 @@ class LaTeXTranslator(nodes.NodeVisitor): closings = "" openings = "" text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) - # lines starting with "[" give errors. - text = text.replace('[', '{[}') + text = text.replace('[', '{[}').replace(']', '{]}') if self.insert_none_breaking_blanks: text = text.replace(' ', '~') if self.latex_encoding != 'utf8': diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 06e00ab67..fcdaea338 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -753,7 +753,7 @@ This footnote shows the next symbol in the sequence. \end{figure} \begin{figure}[b]\hypertarget{id13}$^{4}$ Here's an unreferenced footnote, with a reference to a -nonexistent footnote:{\color{red}\bfseries{}{[}5]{\_}}. +nonexistent footnote:{\color{red}\bfseries{}{[}5{]}{\_}}. \end{figure} @@ -767,7 +767,7 @@ Citations are text-labeled footnotes. They may be rendered separately and differently from footnotes. \end{figure} -Here's a reference to the above, [\hyperlink{cit2002}{CIT2002}], and a {\color{red}\bfseries{}{[}nonexistent]{\_}} +Here's a reference to the above, [\hyperlink{cit2002}{CIT2002}], and a {\color{red}\bfseries{}{[}nonexistent{]}{\_}} citation. @@ -1343,7 +1343,7 @@ These are all ASCII characters except a-zA-Z0-9 and space: \texttt{!!!"{}"{}"{\#}{\#}{\#}{\$}{\$}{\$}{\%}{\%}{\%}{\&}{\&}{\&}'{}'{}'((()))***+++,{},{},-{}-{}-...///:::} -\texttt{;;;<{}<{}<===>{}>{}>???@@@{[}{[}{[}{\textbackslash}{\textbackslash}{\textbackslash}]]]{\textasciicircum}{\textasciicircum}{\textasciicircum}{\_}{\_}{\_}`{}`{}`{\{}{\{}{\{}|||{\}}{\}}{\}}{\textasciitilde}{\textasciitilde}{\textasciitilde}} +\texttt{;;;<{}<{}<===>{}>{}>???@@@{[}{[}{[}{\textbackslash}{\textbackslash}{\textbackslash}{]}{]}{]}{\textasciicircum}{\textasciicircum}{\textasciicircum}{\_}{\_}{\_}`{}`{}`{\{}{\{}{\{}|||{\}}{\}}{\}}{\textasciitilde}{\textasciitilde}{\textasciitilde}} \texttt{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} diff --git a/test/test_writers/test_latex2e.py b/test/test_writers/test_latex2e.py index e0e7cc16f..04448883a 100755 --- a/test/test_writers/test_latex2e.py +++ b/test/test_writers/test_latex2e.py @@ -332,7 +332,7 @@ something~before~to~get~a~end~of~line.~\\\\ {[}~\\\\ ~\\\\ the~empty~line~gets~tested~too~\\\\ -] +{]} }\\end{quote} \\end{document} -- cgit v1.2.1 From 19aec1e70c4828d113ff64a12e24afe93df40b6c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 28 Aug 2005 22:38:40 +0000 Subject: replaced hack with clean handling of unreferenced anonymous targets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3841 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/references.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index a7e038809..7e75402ae 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -128,11 +128,6 @@ class AnonymousHyperlinks(Transform): prbid = self.document.set_id(prb) msg.add_backref(prbid) ref.parent.replace(ref, prb) - for target in self.document.anonymous_targets: - # Assume that all anonymous targets have been - # referenced to avoid generating lots of - # system_messages. - target.referenced = 1 return for ref, target in zip(self.document.anonymous_refs, self.document.anonymous_targets): @@ -791,6 +786,12 @@ class DanglingReferences(Transform): # 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']: -- cgit v1.2.1 From fd75267451af302fc989b5e1f892dd4585311763 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 29 Aug 2005 22:34:31 +0000 Subject: HTML writer: - Added vertical space between fields of field lists. - Added ``--compact-field-lists`` option to remove vertical space in simple field lists. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3842 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 ++ docs/user/config.txt | 9 ++++ docutils/writers/html4css1.py | 52 +++++++++++++++++++--- .../expected/standalone_rst_html4css1.html | 7 +-- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ca042bfea..dc473bfb6 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -100,6 +100,9 @@ Changes Since 0.3.9 - Moved "id" attribute from container (section etc.) to title's <a> 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. * docutils/writers/docutils_xml.py: diff --git a/docs/user/config.txt b/docs/user/config.txt index 0a7ce5ec3..ea3916bfc 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -584,6 +584,15 @@ _`compact_lists` Default: enabled (1). Options: ``--compact-lists, --no-compact-lists``. +_`compact_field_lists` + + Remove extra vertical whitespace between items of field lists that + are "simple" (i.e., all field bodies each contain at most one + paragraph). + + Default: enabled (1). Options: ``--compact-field-lists, + --no-compact-field-lists``. + _`embed_stylesheet` Embed the stylesheet in the output HTML file. The stylesheet file must be accessible during processing. diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index b86c19fe6..574731c16 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -100,6 +100,14 @@ class Writer(writers.Writer): ('Disable compact simple bullet and enumerated lists.', ['--no-compact-lists'], {'dest': 'compact_lists', 'action': 'store_false'}), + ('Remove extra vertical whitespace between items of simple field ' + 'lists. Default: enabled.', + ['--compact-field-lists'], + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compact simple field lists.', + ['--no-compact-field-lists'], + {'dest': 'compact_field_lists', 'action': 'store_false'}), ('Omit the XML declaration. Use with caution.', ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', @@ -249,6 +257,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.colspecs = [] self.compact_p = 1 self.compact_simple = None + self.compact_field_list = None self.in_docinfo = None self.in_sidebar = None self.title = [] @@ -365,11 +374,21 @@ class HTMLTranslator(nodes.NodeVisitor): node = {'classes': node.get('classes', [])} return self.starttag(node, tagname, **atts) - def set_first_last(self, node): + def set_class_on_child(self, node, class_, index=0): + """ + Set class `class_` on the visible child no. index of `node`. + Do nothing if node has fewer children than `index`. + """ children = [n for n in node if not isinstance(n, nodes.Invisible)] - if children: - children[0]['classes'].append('first') - children[-1]['classes'].append('last') + try: + child = children[index] + except IndexError: + return + child['classes'].append(class_) + + def set_first_last(self, node): + self.set_class_on_child(node, 'first', 0) + self.set_class_on_child(node, 'last', -1) def visit_Text(self, node): text = node.astext() @@ -741,12 +760,33 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_body(self, node): self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) - self.set_first_last(node) + self.set_class_on_child(node, 'first', 0) + field = node.parent + if (self.compact_field_list or + isinstance(field.parent, nodes.docinfo) or + field.parent.index(field) == len(field.parent) - 1): + # If we are in a compact list, the docinfo, or if this is + # the last field of the field list, do not add vertical + # space after last element. + self.set_class_on_child(node, 'last', -1) def depart_field_body(self, node): self.body.append('</td>\n') def visit_field_list(self, node): + self.context.append((self.compact_field_list, self.compact_p)) + self.compact_p = None + if self.settings.compact_field_lists: + self.compact_field_list = 1 + for field in node: + field_body = field[-1] + assert isinstance(field_body, nodes.field_body) + children = [n for n in field_body + if not isinstance(n, nodes.Invisible)] + if not (len(children) == 1 and + isinstance(children[0], nodes.paragraph)): + self.compact_field_list = 0 + break self.body.append(self.starttag(node, 'table', frame='void', rules='none', CLASS='docutils field-list')) @@ -756,6 +796,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_field_list(self, node): self.body.append('</tbody>\n</table>\n') + self.compact_field_list, self.compact_p = self.context.pop() def visit_field_name(self, node): atts = {} @@ -1102,6 +1143,7 @@ class HTMLTranslator(nodes.NodeVisitor): # Attribute which needs to survive. return 0 if (self.compact_simple or + self.compact_field_list or self.compact_p and (len(node.parent) == 1 or len(node.parent) == 2 and isinstance(node.parent[0], nodes.label))): diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 86dfed7cb..2093ab1bb 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -270,12 +270,13 @@ live link to PEP 258 here.</p> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">what:</th><td class="field-body">Field lists map field names to field bodies, like database +<tr class="field"><th class="field-name">what:</th><td class="field-body"><p class="first">Field lists map field names to field bodies, like database records. They are often part of an extension syntax. They are -an unambiguous variant of RFC 2822 fields.</td> +an unambiguous variant of RFC 2822 fields.</p> +</td> </tr> <tr class="field"><th class="field-name">how arg1 arg2:</th><td class="field-body"><p class="first">The field marker is a colon, the field name, and a colon.</p> -<p class="last">The field body may contain one or more body elements, indented +<p>The field body may contain one or more body elements, indented relative to the field marker.</p> </td> </tr> -- cgit v1.2.1 From a1b0314ca1358c6730e1795a4fff9746fbc096a4 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 29 Aug 2005 22:42:16 +0000 Subject: allow field bodies of simple field lists to be empty; mmmh, the test source doesn't look particularly nice -- it contains redundancy; I think a lot of cleanup is required in both the test and the HTML writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3843 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 3 ++- test/test_writers/test_html4css1.py | 47 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 574731c16..41938b46f 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -783,7 +783,8 @@ class HTMLTranslator(nodes.NodeVisitor): assert isinstance(field_body, nodes.field_body) children = [n for n in field_body if not isinstance(n, nodes.Invisible)] - if not (len(children) == 1 and + if not (len(children) == 0 or + len(children) == 1 and isinstance(children[0], nodes.paragraph)): self.compact_field_list = 0 break diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index fa072f9a1..3e08d32c4 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -316,6 +316,53 @@ And even more stuff </div>\\n''', 'html_head': '''...<title>\\n'''} """], +["""\ +Not a docinfo. + +:This: .. _target: + + is +:a: +:simple: +:field: list +""", +"""\ +{'fragment': '''

    Not a docinfo.

    + +++ + + + + + + + + + +
    This:

    is

    +
    a:
    simple:
    field:list
    \\n''', + 'html_body': '''
    +

    Not a docinfo.

    + +++ + + + + + + + + + +
    This:

    is

    +
    a:
    simple:
    field:list
    +
    \\n''', + 'html_head': '''...\\n'''} +"""], ]) -- cgit v1.2.1 From b95d84cfc83f7934e18ab1a35fd8176104a5e249 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 2 Sep 2005 20:40:36 +0000 Subject: replaced "infix" parameter of starttag method with "empty" parameter; improved comments git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3844 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 41938b46f..876cbe140 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -311,7 +311,7 @@ class HTMLTranslator(nodes.NodeVisitor): """Cleanse, HTML encode, and return attribute value text.""" return self.encode(whitespace.sub(' ', text)) - def starttag(self, node, tagname, suffix='\n', infix='', **attributes): + def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): """ Construct and return a start tag given a node (id & class attributes are extracted), tag name, and optional attributes. @@ -335,12 +335,17 @@ class HTMLTranslator(nodes.NodeVisitor): if ids: atts['id'] = ids[0] for id in ids[1:]: - if infix: - # Empty tag. + # Add empty "span" elements for additional IDs. Note + # that we cannot use empty "a" elements because there + # may be targets inside of references, but nested "a" + # elements aren't allowed in XHTML (even if they do + # not all have a "href" attribute). + if empty: + # Empty tag. Insert target right in front of element. prefix.append('' % id) else: - # Non-empty tag. We place the auxiliary - # tag *inside* the element. + # Non-empty tag. Place the auxiliary tag + # *inside* the element, as the first child. suffix += '' % id # !!! next 2 lines to be removed in Docutils 0.5: if atts.has_key('id') and tagname in self.named_tags: @@ -362,11 +367,15 @@ class HTMLTranslator(nodes.NodeVisitor): except TypeError: # for Python 2.1 compatibility: uval = unicode(str(value)) parts.append('%s="%s"' % (name.lower(), self.attval(uval))) + if empty: + infix = ' /' + else: + infix = '' return ''.join(prefix) + '<%s%s>' % (' '.join(parts), infix) + suffix def emptytag(self, node, tagname, suffix='\n', **attributes): """Construct and return an XML-compatible empty tag.""" - return self.starttag(node, tagname, suffix, infix=' /', **attributes) + return self.starttag(node, tagname, suffix, empty=1, **attributes) # !!! to be removed in Docutils 0.5 (change calls to use "starttag"): def start_tag_with_title(self, node, tagname, **atts): -- cgit v1.2.1 From 8ef551960b648500dd88e1f8109792d4503ef235 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Sep 2005 02:59:53 +0000 Subject: removed 1-argument use of ``setdefault``, slated to be removed from Python git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3845 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/images.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docutils/parsers/rst/directives/images.py b/docutils/parsers/rst/directives/images.py index 1c9c50e26..8dc94af96 100644 --- a/docutils/parsers/rst/directives/images.py +++ b/docutils/parsers/rst/directives/images.py @@ -89,12 +89,15 @@ def figure_align(argument): def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - figwidth = options.setdefault('figwidth') - figclasses = options.setdefault('figclass') - align = options.setdefault('align') - del options['figwidth'] - del options['figclass'] - del options['align'] + figwidth = options.get('figwidth') + if figwidth: + del options['figwidth'] + figclasses = options.get('figclass') + if figclasses: + del options['figclass'] + align = options.get('align') + if align: + del options['align'] (image_node,) = image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine) if isinstance(image_node, nodes.system_message): -- cgit v1.2.1 From bbd8182dacb5220dfd8f6a7197fcdc96679fff25 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Sep 2005 03:02:06 +0000 Subject: elaborated entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3846 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/FAQ.txt b/FAQ.txt index 80895e633..68462a6e3 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -931,7 +931,16 @@ Explorer. Long answer: see the `"Criticisms of Internet Explorer" Wikipedia entry `__. -(Thanks to Martin F. Krafft, Robert Kern and Michael Foord.) +However, there's also `Sending XHTML as text/html Considered +Harmful`__. What to do, what to do? We're damned no matter what we +do. So we'll continue to do the practical instead of the pure: +support the browsers that are actually out there, and not fight for +strict standards compliance. + +__ http://hixie.ch/advocacy/xhtml + +(Thanks to Martin F. Krafft, Robert Kern, Michael Foord, and Alan +G. Isaac.) Python Source Reader -- cgit v1.2.1 From b1115e0e1e4f8f31723af15ddf0b8a2650c7a45d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 3 Sep 2005 23:14:29 +0000 Subject: some more search engine optimization git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3848 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/user/links.txt b/docs/user/links.txt index 37ccbb856..d2127d3dc 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -8,6 +8,8 @@ :Date: $Date$ :Copyright: This document has been placed in the public domain. +.. title:: Docutils Links + .. contents:: This document contains links users of Docutils and reStructuredText -- cgit v1.2.1 From 322f1d74b093ec0bb7584967dedba83238c20c95 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 5 Sep 2005 20:44:51 +0000 Subject: updated text about call-out form of hyperlinks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3853 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/rst/quickref.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/user/rst/quickref.html b/docs/user/rst/quickref.html index fdb9a8adb..604cfe6bc 100644 --- a/docs/user/rst/quickref.html +++ b/docs/user/rst/quickref.html @@ -1092,7 +1092,10 @@ A transition marker is a horizontal line documents (think of the indirect hyperlink being "folded in" like ingredients into a cake), and "call-out" is more suitable for printed documents, where the link needs to be presented explicitly, for - example as a footnote. + example as a footnote. You can force usage of the call-out form by + using the + "target-notes" + directive.

    reStructuredText also provides for embedded URIs (details), -- cgit v1.2.1 From 7f1304df3b44693bac96a903352618b5bec8b740 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 8 Sep 2005 04:49:59 +0000 Subject: clarified stylesheet requirement git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3857 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 6 +++--- docs/user/tools.txt | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 68462a6e3..1d34962ec 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -710,7 +710,7 @@ What kind of HTML does it produce? ---------------------------------- It produces XHTML compatible with the `XHTML 1.0`_ specification. A -cascading style sheet (provided as "tools/stylesheets/default.css") is +cascading stylesheet (provided as "tools/stylesheets/default.css") is required for proper viewing with a modern graphical browser. Correct rendering of the HTML produced depends on the CSS support of the browser. @@ -795,8 +795,8 @@ single document title. HTML is being used for dumb formatting for nothing but final display. A stylesheet *is required*, and one is provided: -tools/stylesheets/default.css. Of course, you're welcome to roll your -own. The default stylesheet provides rules to format ``

    `` and ``

    `` differently from ordinary ``

    `` and ``

    ``:: diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 7986e51a5..9a2ddbcc4 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -99,16 +99,20 @@ rst2html.py The ``rst2html.py`` front end reads standalone reStructuredText source files and produces HTML 4 (XHTML 1) output compatible with modern -browsers. For example, to process a reStructuredText file -"``test.txt``" into HTML:: +browsers that support cascading stylesheets (CSS). A stylesheet is +required for proper rendering; an example is provided in +``tools/stylesheets/default.css`` (see Stylesheets_ below). - rst2html.py test.txt test.html +For example, to process a reStructuredText file "``test.txt``" into +HTML:: + + rst2html.py --stylesheet=mystyles.css test.txt test.html Now open the "``test.html``" file in your favorite browser to see the results. To get a footer with a link to the source file, date & time of processing, and links to the Docutils projects, add some options:: - rst2html.py -stg test.txt test.html + rst2html.py --stylesheet=mystyles.css -stg test.txt test.html Stylesheets -- cgit v1.2.1 From 1f4936a3415c16d38c76e3d39fc285c0428ffed8 Mon Sep 17 00:00:00 2001 From: blais Date: Fri, 9 Sep 2005 15:17:31 +0000 Subject: New support for section title underlining in Emacs. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3860 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 1454 ++++++++++++++------- tools/editors/emacs/tests/Makefile | 4 + tools/editors/emacs/tests/README | 27 + tools/editors/emacs/tests/tests-adjust-section.el | 774 +++++++++-- tools/editors/emacs/tests/tests-basic.el | 762 +++++++++++ tools/editors/emacs/tests/tests-runner.el | 122 ++ 6 files changed, 2553 insertions(+), 590 deletions(-) create mode 100644 tools/editors/emacs/tests/Makefile create mode 100644 tools/editors/emacs/tests/README create mode 100644 tools/editors/emacs/tests/tests-basic.el create mode 100644 tools/editors/emacs/tests/tests-runner.el diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index b5f08a641..0c13a82a2 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -9,22 +9,34 @@ ;; Installation instructions ;; ------------------------- ;; -;; Add this line to your .emacs file:: +;; Add this line to your .emacs file and bind the versatile sectioning commands +;; in text mode, like this:: ;; ;; (require 'restructuredtext) +;; (add-hook 'text-mode-hook 'rest-text-mode-hook) ;; -;; You should bind the versatile sectioning command to some key in the text-mode -;; hook. Something like this:: +;; The keys it defines are: ;; -;; (defun user-rst-mode-hook () -;; (local-set-key [(control ?=)] 'rest-adjust-section-title) -;; ) -;; (add-hook 'text-mode-hook 'user-rst-mode-hook) +;; C-= : updates or rotates the section title around point or +;; promotes/demotes the decorations within the region (see full details +;; below). +;; +;; Note that C-= is a good binding, since it allows you to specify a +;; negative arg easily with C-- C-= (easy to type), as well as ordinary +;; prefix arg with C-u C-=. +;; +;; C-x C-= : displays the hierarchy of title decorations from this file. +;; +;; C-M-{, C-M-} : navigate between section titles. +;; +;; Other specialized and more generic functions are also available (see source +;; code). The most important function provided by this file for section title +;; adjustments is rest-adjust. +;; +;; TODO: +;; - Add an option to forego using the file structure in order to make +;; suggestion, and to always use the preferred decorations to do that. ;; -;; Other specialized and more generic functions are also available. -;; Note that C-= is a good binding, since it allows you to specify a negative -;; arg easily with C-- C-= (easy to type), as well as ordinary prefix arg with -;; C-u C-=. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Generic Filter function. @@ -40,100 +52,113 @@ is for which (pred elem) is true)" (cons head tail) tail))))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Generic text functions that are more convenient than the defaults. -;; - -(defun replace-lines (fromchar tochar) - "Replace flush-left lines, consisting of multiple FROMCHAR characters, -with equal-length lines of TOCHAR." - (interactive "\ -cSearch for flush-left lines of char: -cand replace with char: ") - (save-excursion - (let* ((fromstr (string fromchar)) - (searchre (concat "^" (regexp-quote fromstr) "+ *$")) - (found 0)) - (condition-case err - (while t - (search-forward-regexp searchre) - (setq found (1+ found)) - (search-backward fromstr) ;; point will be *before* last char - (setq p (1+ (point))) - (beginning-of-line) - (setq l (- p (point))) - (kill-line) - (insert-char tochar l)) - (search-failed - (message (format "%d lines replaced." found))))))) - -(defun join-paragraph () - "Join lines in current paragraph into one line, removing end-of-lines." - (interactive) - (let ((fill-column 65000)) ; some big number - (call-interactively 'fill-paragraph))) - -(defun force-fill-paragraph () - "Fill paragraph at point, first joining the paragraph's lines into one. -This is useful for filling list item paragraphs." - (interactive) - (join-paragraph) - (fill-paragraph nil)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The following functions implement a smart automatic title sectioning feature. ;; The idea is that with the cursor sitting on a section title, we try to get as -;; much information from context and do the best thing. This function can be -;; invoked many time and/or with prefix argument to rotate between the various -;; options. +;; much information from context and try to do the best thing automatically. +;; This function can be invoked many times and/or with prefix argument to rotate +;; between the various sectioning decorations. ;; -;; There are two styles of sectioning: +;; Definitions: the two forms of sectioning define semantically separate section +;; levels. A sectioning DECORATION consists in: ;; -;; 1. simple-underline, e.g. |Some Title -;; |---------- +;; - a CHARACTER ;; -;; 2. overline-and-underline, e.g. |------------ -;; | Some Title -;; |------------ +;; - a STYLE which can be either of 'simple' or 'over-and-under'. +;; +;; - an INDENT (meaningful for the over-and-under style only) which determines +;; how many characters and over-and-under style is hanging outside of the +;; title at the beginning and ending. +;; +;; Here are two examples of decorations (| represents the window border, column +;; 0): +;; +;; | +;; 1. char: '-' e |Some Title +;; style: simple |---------- +;; | +;; 2. char: '=' |============== +;; style: over-and-under | Some Title +;; indent: 2 |============== +;; | ;; ;; Some notes: ;; -;; - the underlining character that is used depends on context. The file is +;; - The underlining character that is used depends on context. The file is ;; scanned to find other sections and an appropriate character is selected. -;; If the function is invoked on a section that is complete, the character -;; is rotated among the existing ones. +;; If the function is invoked on a section that is complete, the character is +;; rotated among the existing section decorations. +;; +;; Note that when rotating the characters, if we come to the end of the +;; hierarchy of decorations, the variable rest-preferred-decorations is +;; consulted to propose a new underline decoration, and if continued, we cycle +;; the decorations all over again. Set this variable to nil if you want to +;; limit the underlining character propositions to the existing decorations in +;; the file. ;; -;; Note that when rotating the underlining characters, if we come to the end -;; of the hierarchy of characters, the variable rest-preferred-characters -;; is consulted to propose a new underline char, and if continued, we cycle -;; the underline characters all over again. Set this variable to nil if -;; you want to limit the underlining character propositions to the existing -;; underlines in the file. +;; - A prefix argument can be used to alternate the style. ;; -;; - prefix argument is used to alternate the sectioning style. +;; - An underline/overline that is not extended to the column at which it should +;; be hanging is dubbed INCOMPLETE. For example:: ;; -;; Examples: +;; |Some Title +;; |------- +;; +;; Examples of default invocation: ;; ;; |Some Title ---> |Some Title -;; | |---------- +;; | |---------- ;; ;; |Some Title ---> |Some Title -;; |----- |---------- +;; |----- |---------- ;; ;; | |------------ ;; | Some Title ---> | Some Title -;; | |------------ +;; | |------------ ;; -;; In overline-and-underline style, a variable is available to select how much -;; space to leave before and after the title (it can be zero) when alternating -;; the style. Note that if the title already has some whitespace in front of -;; it, we don't adjust it to the variable setting, we use the whitespace that is -;; already there for adjustment. +;; In over-and-under style, when alternating the style, a variable is available +;; to select how much default indent to use (it can be zero). Note that if the +;; current section decoration already has an indent, we don't adjust it to the +;; default, we rather use the current indent that is already there for +;; adjustment (unless we cycle, in which case we use the indent that has been +;; found previously). + +(defun rest-text-mode-hook () + "Default text mode hook for rest." + (local-set-key [(control ?=)] 'rest-adjust) + (local-set-key [(control x)(control ?=)] 'rest-display-sections-hierarchy) + (local-set-key [(control meta ?{)] 'rest-backward-section) + (local-set-key [(control meta ?})] 'rest-forward-section) + ) + +(defcustom rest-preferred-decorations '( (?= over-and-under 1) + (?= simple 0) + (?- simple 0) + (?~ simple 0) + (?+ simple 0) + (?` simple 0) + (?# simple 0) + (?@ simple 0) ) + "Preferred ordering of section title decorations. This + sequence is consulted to offer a new decoration suggestion when + we rotate the underlines at the end of the existing hierarchy + of characters, or when there is no existing section title in + the file.") + + +(defcustom rest-default-indent 1 + "Number of characters to indent the section title when toggling + decoration styles. This is used when switching from a simple + decoration style to a over-and-under decoration style.") + -(defun rest-line-single-char-p (&optional accept-special) +(defcustom rest-section-text-regexp "^[ \t]*\\S-*[a-zA-Z0-9]\\S-*" + "Regular expression for valid section title text.") + + +(defun rest-line-homogeneous-p (&optional accept-special) "Predicate return the unique char if the current line is composed only of a single repeated non-whitespace character. This returns the char even if there is whitespace at @@ -146,128 +171,95 @@ This is useful for filling list item paragraphs." (save-excursion (back-to-indentation) (if (not (looking-at "\n")) - (let ((c (thing-at-point 'char))) - (if (and (looking-at (format "[%s]+\\s-*$" c)) - (or accept-special - (and - ;; common patterns - (not (looking-at "::\\s-*$")) - (not (looking-at "\\.\\.\\.\\s-*$")) - ;; discard one char line - (not (looking-at ".\\s-*$")) - ))) - (string-to-char c)) - )) + (let ((c (thing-at-point 'char))) + (if (and (looking-at (format "[%s]+[ \t]*$" c)) + (or accept-special + (and + ;; Common patterns. + (not (looking-at "::[ \t]*$")) + (not (looking-at "\\.\\.\\.[ \t]*$")) + ;; Discard one char line + (not (looking-at ".[ \t]*$")) + ))) + (string-to-char c)) + )) )) -(defun rest-find-last-section-char () - "Looks backward for the last section char found in the file." - (let (c) - (save-excursion - (while (and (not c) (not (bobp))) - (forward-line -1) - (setq c (rest-line-single-char-p)) - )) - c)) +(defun rest-compare-decorations (deco1 deco2) + "Compare decorations. Returns true if both are equal, +according to restructured text semantics (only the character and +the style are compared, the indentation does not matter." + (and (eq (car deco1) (car deco2)) + (eq (cadr deco1) (cadr deco2)))) + + +(defun rest-get-decoration-match (hier deco) + "Returns the index (level) of the decoration in the given hierarchy. +This basically just searches for the item using the appropriate +comparison and returns the index. We return nil if the item is +not found." + (let ((cur hier)) + (while (and cur (not (rest-compare-decorations (car cur) deco))) + (setq cur (cdr cur))) + cur)) -(defun rest-current-section-char (&optional point) - "Gets the section char around the current point." - (save-excursion - (if point (goto-char point)) - (let ((offlist '(0 1 -2)) - loff - rval - c) - (while offlist - (forward-line (car offlist)) - (setq c (rest-line-single-char-p 1)) - (if c - (progn (setq offlist nil - rval c)) - (setq offlist (cdr offlist))) - ) - rval - ))) - -(defun rest-initial-sectioning-style (&optional point) - "Looks around point and attempts to determine the sectioning - style, between simple-underline and overline-and-underline. If - there aren't any existing over/underlines, return nil." - (save-excursion - (if point (goto-char point)) - (let (ou) - (save-excursion - (setq ou (mapcar - (lambda (x) - (forward-line x) - (rest-line-single-char-p)) - '(-1 2)))) - (beginning-of-line) - (cond - ((equal ou '(nil nil)) nil) - ((car ou) 'over-and-under) ;; we only need check the overline - (t 'simple) - ) - ))) - -(defun rest-all-section-chars (&optional ignore-lines) - "Finds all the section chars in the entire file and orders them - hierarchically, removing duplicates. Basically, returns a list - of the section underlining characters. - - Optional parameters IGNORE-AROUND can be a list of lines to - ignore." - - (let (chars - c - (curline 1)) - (save-excursion - (beginning-of-buffer) - (while (< (point) (buffer-end 1)) - (if (not (memq curline ignore-lines)) - (progn - (setq c (rest-line-single-char-p)) - (if c - (progn - (add-to-list 'chars c t) - ))) ) - (forward-line 1) (setq curline (+ curline 1)) - )) - chars)) - -(defun rest-suggest-new-char (allchars) - "Given the last char that has been seen, suggest a new, - different character, different from all that have been seen." - (let ((potentials (copy-sequence rest-preferred-characters))) - (dolist (x allchars) - (setq potentials (delq x potentials)) - ) - (car potentials) - )) -(defun rest-update-section (underlinechar style &optional indent) - "Unconditionally updates the overline/underline of a section - title using the given character CHAR, with STYLE 'simple or - 'over-and-under, in which case with title whitespace separation - on each side with INDENT whitespaces. If the style is 'simple, - whitespace before the title is removed. +(defun rest-suggest-new-decoration (alldecos &optional prev) + "Suggest a new, different decoration, different from all that +have been seen. - If there are existing overline and/or underline, they are - removed before adding the requested adornments." + ALLDECOS is the set of all decorations, including the line + numbers. PREV is the optional previous decoration, in order to + suggest a better match." + + ;; For all the preferred decorations... + (let* ( + ;; If 'prev' is given, reorder the list to start searching after the match. + (fplist + (cdr (rest-get-decoration-match rest-preferred-decorations prev))) + + ;; List of candidates to search. + (curpotential (append fplist rest-preferred-decorations))) + (while + ;; For all the decorations... + (let ((cur alldecos) + found) + (while (and cur (not found)) + (if (rest-compare-decorations (car cur) (car curpotential)) + ;; Found it! + (setq found (car curpotential)) + (setq cur (cdr cur)))) + found) + + (setq curpotential (cdr curpotential))) + + (copy-list (car curpotential)) )) + + +(defun rest-update-section (char style &optional indent) + "Unconditionally updates the style of a section decoration + using the given character CHAR, with STYLE 'simple or + 'over-and-under, and with indent INDENT. If the STYLE is + 'simple, whitespace before the title is removed (indent is + always assume to be 0). + + If there are existing overline and/or underline from the + existing decoration, they are removed before adding the + requested decoration." (interactive) (let (marker - len - ec - (c ?-)) + len + ec + (c ?-)) (end-of-line) (setq marker (point-marker)) ;; Fixup whitespace at the beginning and end of the line (if (or (null indent) (eq style 'simple)) - (setq indent 0)) + (setq indent 0)) (beginning-of-line) (delete-horizontal-space) (insert (make-string indent ? )) @@ -280,234 +272,807 @@ This is useful for filling list item paragraphs." ;; Remove previous line if it consists only of a single repeated character (save-excursion - (forward-line -1) - (and (rest-line-single-char-p 1) - (kill-line 1))) - - ;; Remove following line if it consists only of a single repeated character + (forward-line -1) + (and (rest-line-homogeneous-p 1) + ;; Avoid removing the underline of a title right above us. + (save-excursion (forward-line -1) + (not (looking-at rest-section-text-regexp))) + (kill-line 1))) + + ;; Remove following line if it consists only of a single repeated + ;; character (save-excursion - (forward-line +1) - (and (rest-line-single-char-p 1) - (kill-line 1)) - ;; Add a newline if we're at the end of the buffer, for the subsequence - ;; inserting of the underline - (if (= (point) (buffer-end 1)) - (newline 1))) + (forward-line +1) + (and (rest-line-homogeneous-p 1) + (kill-line 1)) + ;; Add a newline if we're at the end of the buffer, for the subsequence + ;; inserting of the underline + (if (= (point) (buffer-end 1)) + (newline 1))) ;; Insert overline (if (eq style 'over-and-under) - (save-excursion - (beginning-of-line) - (open-line 1) - (insert (make-string len underlinechar)))) + (save-excursion + (beginning-of-line) + (open-line 1) + (insert (make-string len char)))) ;; Insert underline (forward-line +1) (open-line 1) - (insert (make-string len underlinechar)) + (insert (make-string len char)) (forward-line +1) (goto-char marker) )) -(defvar rest-preferred-characters '(?= ?- ?~ ?+ ?` ?# ?@) - "Preferred ordering of underline characters. This sequence is - consulted to offer a new underline character when we rotate the - underlines at the end of the existing hierarchy of characters.") -(defvar rest-default-under-and-over-indent 1 - "Number of characters to indent the section title when toggling - sectioning styles. This is used when switching from a simple - section style to a over-and-under style.") - -(defun rest-adjust-section-title () - "Adjust/rotate the section underlining for the section around - point. - - This function is the main entry point of this module and is a - bit of a swiss knife. It is meant as the single function to - invoke to adjust the underlines (and possibly overlines) of a - section title in restructuredtext. The next action it takes - depends on context around the point, and it is meant to be - invoked possibly more than once. Basically, this function deals - with: - - - underlining a title if it does not have an underline; - - adjusting the length of the underline characters to fit a - modified title; - - rotating the underlines/overlines in the set of already - existing underline chars used in the file; - - switching between simple underline and over-and-under style - sectioning (or box style). - - Here are the gory details: - - - If the current line has no underline character around it, - search backwards for a previously used underlining character, - and underline the current line as a section title (also see - prefix argument below). - - If no pre-existing underlining character is found in the on - the line, we use the last seen underline char or consult the - first element of rest-preferred-characters if this is the - first title in the entire file. - - - If the current line does have an underline or overline, and - if - - - the underline do not extend to exactly the end of the - title line, this changes the length of the under(over)lines - to fit exactly the section title; - - - the underline length is already adjusted to the end of the - title line, we search the file for the underline chars, and - we rotate the current title's underline character with that - list (going down the hierarchy that is present in the - file); - - If there is a prefix argument, switch the style between the - initial sectioning style and the other sectioning style. The - two styles are overline-and-underline and simple-underline. +(defun rest-normalize-cursor-position () + "If the cursor is on a decoration line or an empty line , place + it on the section title line (at the end). Returns the line + offset by which the cursor was moved. This works both over or + under a line." + (if (save-excursion (beginning-of-line) + (or (rest-line-homogeneous-p 1) + (looking-at "^[ \t]*$"))) + (progn + (beginning-of-line) + (cond + ((save-excursion (forward-line -1) + (beginning-of-line) + (and (looking-at rest-section-text-regexp) + (not (rest-line-homogeneous-p 1)))) + (progn (forward-line -1) -1)) + ((save-excursion (forward-line +1) + (beginning-of-line) + (and (looking-at rest-section-text-regexp) + (not (rest-line-homogeneous-p 1)))) + (progn (forward-line +1) +1)) + (t 0))) + 0 )) + + +(defun rest-find-all-decorations () + "Finds all the decorations in the file, and returns a list of + (line, decoration) pairs. Each decoration consists in a (char, + style, indent) triple. + + This function does not detect the hierarchy of decorations, it + just finds all of them in a file. You can then invoke another + function to remove redundancies and inconsistencies." + + (let (positions + (curline 1)) + ;; Iterate over all the section titles/decorations in the file. + (save-excursion + (beginning-of-buffer) + (while (< (point) (buffer-end 1)) + (if (rest-line-homogeneous-p) + (progn + (setq curline (+ curline (rest-normalize-cursor-position))) + + ;; Here we have found a potential site for a decoration, + ;; characterize it. + (let ((deco (rest-get-decoration))) + (if (cadr deco) ;; Style is existing. + ;; Found a real decoration site. + (progn + (push (cons curline deco) positions) + ;; Push beyond the underline. + (forward-line 1) + (setq curline (+ curline 1)) + ))) + )) + (forward-line 1) + (setq curline (+ curline 1)) + )) + (reverse positions))) + + +(defun rest-infer-hierarchy (decorations) + "Build a hierarchy of decorations using the list of given decorations. + + This function expects a list of (char, style, indent) + decoration specifications, in order that they appear in a file, + and will infer a hierarchy of section levels by removing + decorations that have already been seen in a forward traversal of the + decorations, comparing just the character and style. + + Similarly returns a list of (char, style, indent), where each + list element should be unique." + + (let ((hierarchy-alist (list))) + (dolist (x decorations) + (let ((char (car x)) + (style (cadr x)) + (indent (caddr x))) + (if (not (assoc (cons char style) hierarchy-alist)) + (progn + (setq hierarchy-alist + (append hierarchy-alist + (list (cons (cons char style) x)))) + )) + )) + (mapcar 'cdr hierarchy-alist) + )) + + +(defun rest-get-hierarchy (&optional alldecos ignore) + "Returns a list of decorations that represents the hierarchy of + section titles in the file. + + If the line number in IGNORE is specified, the decoration found + on that line (if there is one) is not taken into account when + building the hierarchy." + (let ((all (or alldecos (rest-find-all-decorations)))) + (setq all (assq-delete-all ignore all)) + (rest-infer-hierarchy (mapcar 'cdr all)))) + + +(defun rest-get-decoration (&optional point) + "Looks around point and finds the characteristics of the + decoration that is found there. We assume that the cursor is + already placed on the title line (and not on the overline or + underline). + + This function returns a (char, style, indent) triple. If the + characters of overline and underline are different, we return + the underline character. The indent is always calculated. A + decoration can be said to exist if the style is not nil. + + A point can be specified to go to the given location before + extracting the decoration." + + (let (char style indent) + (save-excursion + (if point (goto-char point)) + (beginning-of-line) + (if (looking-at rest-section-text-regexp) + (let* ((over (save-excursion + (forward-line -1) + (rest-line-homogeneous-p))) + + (under (save-excursion + (forward-line +1) + (rest-line-homogeneous-p))) + ) + + ;; Check that the line above the overline is not part of a title + ;; above it. + (if (and over + (save-excursion + (and (equal (forward-line -2) 0) + (looking-at rest-section-text-regexp)))) + (setq over nil)) + + (cond + ;; No decoration found, leave all return values nil. + ((and (eq over nil) (eq under nil))) + + ;; Overline only, leave all return values nil. + ;; + ;; Note: we don't return the overline character, but it could perhaps + ;; in some cases be used to do something. + ((and over (eq under nil))) + + ;; Underline only. + ((and under (eq over nil)) + (setq char under + style 'simple)) + + ;; Both overline and underline. + (t + (setq char under + style 'over-and-under)) + ) + ) + ) + ;; Find indentation. + (setq indent (save-excursion (back-to-indentation) (current-column))) + ) + ;; Return values. + (list char style indent))) + + +(defun rest-get-decorations-around (&optional alldecos) + "Given the list of all decorations (with positions), +find the decorations before and after the given point. +A list of the previous and next decorations is returned." + (let* ((all (or alldecos (rest-find-all-decorations))) + (curline (line-number-at-pos)) + prev next + (cur all)) + + ;; Search for the decorations around the current line. + (while (and cur (< (caar cur) curline)) + (setq prev cur + cur (cdr cur))) + ;; 'cur' is the following decoration. + + (if (and cur (caar cur)) + (setq next (if (= curline (caar cur)) (cdr cur) cur))) + + (mapcar 'cdar (list prev next)) + )) + + +(defun rest-decoration-complete-p (deco &optional point) + "Return true if the decoration DECO around POINT is complete." + ;; Note: we assume that the detection of the overline as being the underline + ;; of a preceding title has already been detected, and has been eliminated + ;; from the decoration that is given to us. + + ;; There is some sectioning already present, so check if the current + ;; sectioning is complete and correct. + (let* ((char (car deco)) + (style (cadr deco)) + (indent (caddr deco)) + (endcol (save-excursion (end-of-line) (current-column))) + ) + (if char + (let ((exps (concat "^" + (regexp-quote (make-string (+ endcol indent) char)) + "$"))) + (and + (save-excursion (forward-line +1) + (beginning-of-line) + (looking-at exps)) + (or (not (eq style 'over-and-under)) + (save-excursion (forward-line -1) + (beginning-of-line) + (looking-at exps)))) + )) + )) + + +(defun rest-get-next-decoration + (curdeco hier &optional suggestion reverse-direction) + "Get the next decoration for CURDECO, in given hierarchy HIER, +and suggesting for new decoration SUGGESTION." + + (let* ( + (char (car curdeco)) + (style (cadr curdeco)) + + ;; Build a new list of decorations for the rotation. + (rotdecos + (append hier + ;; Suggest a new decoration. + (list suggestion + ;; If nothing to suggest, use first decoration. + (car hier)))) ) + (or + ;; Search for next decoration. + (cadr + (let ((cur (if reverse-direction rotdecos + (reverse rotdecos))) + found) + (while (and cur + (not (and (eq char (caar cur)) + (eq style (cadar cur))))) + (setq cur (cdr cur))) + cur)) + + ;; If not found, take the first of all decorations. + suggestion + ))) + + +(defun rest-adjust () + "Adjust/rotate the section decoration for the section title +around point or promote/demote the decorations inside the region, +depending on if the region is active. This function is meant to +be invoked possibly multiple times, and can vary its behaviour +with a positive prefix argument (toggle style), or with a +negative prefix argument (alternate behaviour). + +This function is the main focus of this module and is a bit of a +swiss knife. It is meant as the single most essential function +to be bound to invoke to adjust the decorations of a section +title in restructuredtext. It tries to deal with all the +possible cases gracefully and to do `the right thing' in all +cases. + +See the documentations of rest-adjust-decoration and +rest-promote-region for full details. + +Prefix Arguments +================ + +The method can take either (but not both) of + +a. a (non-negative) prefix argument, which means to toggle the + decoration style. Invoke with C-u prefix for example; + +b. a negative numerical argument, which generally inverts the + direction of search in the file or hierarchy. Invoke with C-- + prefix for example. + +" + (interactive) + + (let* ( ;; Parse the positive and negative prefix arguments. + (reverse-direction + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0))) + (toggle-style + (and current-prefix-arg (not reverse-direction)))) + + (if mark-active + ;; Adjust decorations within region. + (rest-promote-region current-prefix-arg) + ;; Adjust decoration around point. + (rest-adjust-decoration toggle-style reverse-direction)) + )) + + +(defun rest-adjust-decoration (&optional toggle-style reverse-direction) +"Adjust/rotate the section decoration for the section title around point. + +This function is meant to be invoked possibly multiple times, and +can vary its behaviour with a true TOGGLE-STYLE argument, or with +a REVERSE-DIRECTION argument. + +General Behaviour +================= + +The next action it takes depends on context around the point, and +it is meant to be invoked possibly more than once to rotate among +the various possibilities. Basically, this function deals with: + +- adding a decoration if the title does not have one; + +- adjusting the length of the underline characters to fit a + modified title; + +- rotating the decoration in the set of already existing + sectioning decorations used in the file; + +- switching between simple and over-and-under styles. + +You should normally not have to read all the following, just +invoke the method and it will do the most obvious thing that you +would expect. + + +Decoration Definitions +====================== + +The decorations consist in + +1. a CHARACTER + +2. a STYLE which can be either of 'simple' or 'over-and-under'. + +3. an INDENT (meaningful for the over-and-under style only) + which determines how many characters and over-and-under + style is hanging outside of the title at the beginning and + ending. + +See source code for mode details. + + +Detailed Behaviour Description +============================== + +Here are the gory details of the algorithm (it seems quite +complicated, but really, it does the most obvious thing in all +the particular cases): + +Before applying the decoration change, the cursor is placed on +the closest line that could contain a section title. + +Case 1: No Decoration +--------------------- + +If the current line has no decoration around it, + +- search backwards for the last previous decoration, and apply + the decoration one level lower to the current line. If there + is no defined level below this previous decoration, we suggest + the most appropriate of the rest-preferred-decorations. + + If REVERSE-DIRECTION is true, we simply use the previous + decoration found directly. + +- if there is no decoration found in the given direction, we use + the first of rest-preferred-decorations. + +The prefix argument forces a toggle of the prescribed decoration +style. + +Case 2: Incomplete Decoration +----------------------------- + +If the current line does have an existing decoration, but the +decoration is incomplete, that is, the underline/overline does +not extend to exactly the end of the title line (it is either too +short or too long), we simply extend the length of the +underlines/overlines to fit exactly the section title. + +If the prefix argument is given, we toggle the style of the +decoration as well. + +REVERSE-DIRECTION has no effect in this case. + +Case 3: Complete Existing Decoration +------------------------------------ + +If the decoration is complete (i.e. the underline (overline) +length is already adjusted to the end of the title line), we +search/parse the file to establish the hierarchy of all the +decorations (making sure not to include the decoration around +point), and we rotate the current title's decoration from within +that list (by default, going *down* the hierarchy that is present +in the file, i.e. to a lower section level). This is meant to be +used potentially multiple times, until the desired decoration is +found around the title. + +If we hit the boundary of the hierarchy, exactly one choice from +the list of preferred decorations is suggested/chosen, the first +of those decoration that has not been seen in the file yet (and +not including the decoration around point), and the next +invocation rolls over to the other end of the hierarchy (i.e. it +cycles). This allows you to avoid having to set which character +to use by always using the + +If REVERSE-DIRECTION is true, the effect is to change the +direction of rotation in the hierarchy of decorations, thus +instead going *up* the hierarchy. + +However, if there is a non-negative prefix argument, we do not +rotate the decoration, but instead simply toggle the style of the +current decoration (this should be the most common way to toggle +the style of an existing complete decoration). + + +Point Location +============== + +The invocation of this function can be carried out anywhere +within the section title line, on an existing underline or +overline, as well as on an empty line following a section title. +This is meant to be as convenient as possible. + + +Indented Sections +================= + +Indented section titles such as :: + + My Title + -------- + +are illegal in restructuredtext and thus not recognized by the +parser. This code will thus not work in a way that would support +indented sections (it would be ambiguous anyway). + + +Joint Sections +============== + +Section titles that are right next to each other may not be +treated well. More work might be needed to support those, and +special conditions on the completeness of existing decorations +might be required to make it non-ambiguous. + +For now we assume that the decorations are disjoint, that is, +there is at least a single line between the titles/decoration +lines. + + +Suggested Binding +================= + +We suggest that you bind this function on C-=. It is close to +C-- so a negative argument can be easily specified with a flick +of the right hand fingers and the binding is unused in text-mode." + (interactive) + + ;; If we were invoked directly, parse the prefix arguments into the + ;; arguments of the function. + (if current-prefix-arg + (setq reverse-direction + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0)) + + toggle-style + (and current-prefix-arg (not reverse-direction)))) + + (let* (;; Check if we're on an underline around a section title, and move the + ;; cursor to the title if this is the case. + (moved (rest-normalize-cursor-position)) + + ;; Find the decoration and completeness around point. + (curdeco (rest-get-decoration)) + (char (car curdeco)) + (style (cadr curdeco)) + (indent (caddr curdeco)) + + ;; New values to be computed. + char-new style-new indent-new + ) + + ;; We've moved the cursor... if we're not looking at some text, we have + ;; nothing to do. + (if (save-excursion (beginning-of-line) + (looking-at rest-section-text-regexp)) + (progn + (cond + ;;--------------------------------------------------------------------- + ;; Case 1: No Decoration + ((and (eq char nil) (eq style nil)) + + (let* ((alldecos (rest-find-all-decorations)) + + (around (rest-get-decorations-around alldecos)) + (prev (car around)) + cur + + (hier (rest-get-hierarchy alldecos)) + ) + + ;; Advance one level down. + (setq cur + (if prev + (if (not reverse-direction) + (or (cadr (rest-get-decoration-match hier prev)) + (rest-suggest-new-decoration hier prev)) + prev) + (copy-list (car rest-preferred-decorations)) + )) + + ;; Invert the style if requested. + (if toggle-style + (setcar (cdr cur) (if (eq (cadr cur) 'simple) + 'over-and-under 'simple)) ) + + (setq char-new (car cur) + style-new (cadr cur) + indent-new (caddr cur)) + )) + + ;;--------------------------------------------------------------------- + ;; Case 2: Incomplete Decoration + ((not (rest-decoration-complete-p curdeco)) + + ;; Invert the style if requested. + (if toggle-style + (setq style (if (eq style 'simple) 'over-and-under 'simple))) + + (setq char-new char + style-new style + indent-new indent)) + + ;;--------------------------------------------------------------------- + ;; Case 3: Complete Existing Decoration + (t + (if toggle-style + + ;; Simply switch the style of the current decoration. + (setq char-new char + style-new (if (eq style 'simple) 'over-and-under 'simple) + indent-new rest-default-indent) + + ;; Else, we rotate, ignoring the decoration around the current + ;; line... + (let* ((alldecos (rest-find-all-decorations)) + + (hier (rest-get-hierarchy alldecos (line-number-at-pos))) + + ;; Suggestion, in case we need to come up with something + ;; new + (suggestion (rest-suggest-new-decoration + hier + (car (rest-get-decorations-around alldecos)))) + + (nextdeco (rest-get-next-decoration + curdeco hier suggestion reverse-direction)) + + ) + + ;; Indent, if present, always overrides the prescribed indent. + (setq char-new (car nextdeco) + style-new (cadr nextdeco) + indent-new (caddr nextdeco)) + + ))) + ) + + ;; Override indent with present indent! + (setq indent-new (if (> indent 0) indent indent-new)) + + (if (and char-new style-new) + (rest-update-section char-new style-new indent-new)) + )) + + + ;; Correct the position of the cursor to more accurately reflect where it + ;; was located when the function was invoked. + (if (not (= moved 0)) + (progn (forward-line (- moved)) + (end-of-line))) + + )) + +;; Maintain an alias for compatibility. +(defalias 'rest-adjust-section-title 'rest-adjust) + + +(defun rest-promote-region (&optional demote) + "Promote the section titles within the region. + +With argument DEMOTE or a prefix argument, demote the +section titles instead. The algorithm used at the boundaries of +the hierarchy is similar to that used by rest-adjust-decoration." + (interactive) + + (let* ((demote (or current-prefix-arg demote)) + (alldecos (rest-find-all-decorations)) + (cur alldecos) + + (hier (rest-get-hierarchy alldecos)) + (suggestion (rest-suggest-new-decoration hier)) + + (region-begin-line (line-number-at-pos (region-beginning))) + (region-end-line (line-number-at-pos (region-end))) + + marker-list + ) + + ;; Skip the markers that come before the region beginning + (while (and cur (< (caar cur) region-begin-line)) + (setq cur (cdr cur))) - If however, you are on a complete section title and you - specify a negative argument, the effect of the prefix - argument is to change the direction of rotation of the - underline characters. Thus using a prefix argument and a - negative prefix argument achieves a different result in the - case of rotation. - - Note that the initial style of underlining (simple underline - or box-style) depends on if there is whitespace at the start - of the line. If there are already underlines/overlines, - those are used to select the style, otherwise if there is - whitespace at the front of the title overline-and-underline - style is chosen, and otherwise simple underline. - - Also, note that this should work on the section title line as - well as on a complete or incomplete underline for a - title (first thing we check for that case and move the cursor - up a line if needed)." + ;; Create a list of markers for all the decorations which are found within + ;; the region. + (save-excursion + (let (m line) + (while (and cur (< (setq line (caar cur)) region-end-line)) + (setq m (make-marker)) + (goto-line line) + (push (list (set-marker m (point)) (cdar cur)) marker-list) + (setq cur (cdr cur)) )) + + ;; Apply modifications. + (let (nextdeco) + (dolist (p marker-list) + ;; Go to the decoration to promote. + (goto-char (car p)) + + ;; Rotate the next decoration. + (setq nextdeco (rest-get-next-decoration + (cadr p) hier suggestion demote)) + + ;; Update the decoration. + (apply 'rest-update-section nextdeco) + + ;; Clear marker to avoid slowing down the editing after we're done. + (set-marker (car p) nil) + )) + (setq deactivate-mark nil) + ))) + + +(defun rest-display-sections-hierarchy (&optional decorations) + "Display the current file's section title decorations hierarchy. + This function expects a list of (char, style, indent) triples." (interactive) - (let* ( - ;; check if we're on an underline under a title line, and move the - ;; cursor up if it is so. - (moved - (if (and (or (rest-line-single-char-p 1) - (looking-at "^\\s-*$")) - (save-excursion - (forward-line -1) - (beginning-of-line) - (looking-at "^.+$"))) - (progn (forward-line -1) t) - )) - - ;; find current sectioning character - (curchar (rest-current-section-char)) - ;; find current sectioning style - (init-style (rest-initial-sectioning-style)) - ;; find current indentation of title line - (curindent (save-excursion - (back-to-indentation) - (current-column))) - - ;; ending column - (endcol (- (save-excursion - (end-of-line) - (current-column)) - (save-excursion - (back-to-indentation) - (current-column)))) + (if (not decorations) + (setq decorations (rest-get-hierarchy))) + (with-output-to-temp-buffer "*rest section hierarchy*" + (let ((level 1)) + (with-current-buffer standard-output + (dolist (x decorations) + (insert (format "\nSection Level %d" level)) + (apply 'rest-update-section x) + (end-of-buffer) + (insert "\n") + (incf level) + )) + ))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Section movement commands. +;; + +(defun rest-forward-section (&optional offset) + "Skip to the next restructured text section title. + OFFSET specifies how many titles to skip. Use a negative OFFSET to move + backwards in the file (default is to use 1)." + (interactive) + (let* (;; Default value for offset. + (offset (or offset 1)) + + ;; Get all the decorations in the file, with their line numbers. + (alldecos (rest-find-all-decorations)) + + ;; Get the current line. + (curline (line-number-at-pos)) + + (cur alldecos) + (idx 0) + line ) - ;; if there is no current style found... - (if (eq init-style nil) - ;; select based on the whitespace at the beginning of the line - (save-excursion - (beginning-of-line) - (setq init-style - (if (looking-at "^\\s-+") 'over-and-under 'simple)))) - - ;; if we're switching characters, we're going to simply change the - ;; sectioning style. this branch is also taken if there is no current - ;; sectioning around the title. - (if (or (and current-prefix-arg - (not (< (prefix-numeric-value current-prefix-arg) 0))) - (eq curchar nil)) - - ;; we're switching characters or there is currently no sectioning - (progn - (setq curchar - (or curchar - (rest-find-last-section-char) - (car (rest-all-section-chars)) - (car rest-preferred-characters) - ?=)) - - ;; if there is a current indent, reuse it, otherwise use default - (if (= curindent 0) - (setq curindent rest-default-under-and-over-indent)) - - (rest-update-section - curchar - (if (and current-prefix-arg - (not (< (prefix-numeric-value current-prefix-arg) 0))) - (if (eq init-style 'over-and-under) 'simple 'over-and-under) - init-style) - curindent) - ) - - ;; else we're not switching characters, and there is some sectioning - ;; already present, so check if the current sectioning is complete and - ;; correct. - (let ((exps (concat "^" - (regexp-quote (make-string - (+ endcol curindent) curchar)) - "$"))) - (if (or - (not (save-excursion (forward-line +1) - (beginning-of-line) - (looking-at exps))) - (and (eq init-style 'over-and-under) - (not (save-excursion (forward-line -1) - (beginning-of-line) - (looking-at exps))))) - - ;; the current sectioning needs to be fixed/updated! - (rest-update-section curchar init-style curindent) - - ;; the current sectioning is complete, rotate characters - (let* ( (curline (+ (count-lines (point-min) (point)) - (if (bolp) 1 0))) - (allchars (rest-all-section-chars - (list (- curline 1) curline (+ curline 1)))) - - (rotchars - (append allchars - (filter 'identity - (list - ;; suggest a new char - (rest-suggest-new-char allchars) - ;; rotate to first char - (car allchars))))) - (nextchar - (or (cadr (memq curchar - (if (< (prefix-numeric-value - current-prefix-arg) 0) - (reverse rotchars) rotchars))) - (car allchars)) ) ) - - - (if nextchar - (rest-update-section nextchar init-style curindent)) - ))) - ) + ;; Find the index of the "next" decoration w.r.t. to the current line. + (while (and cur (< (caar cur) curline)) + (setq cur (cdr cur)) + (incf idx)) + ;; 'cur' is the decoration on or following the current line. + + (if (and (> offset 0) cur (= (caar cur) curline)) + (incf idx)) - (if moved - (progn (forward-line 1) (end-of-line))) + ;; Find the final index. + (setq idx (+ idx (if (> offset 0) (- offset 1) offset))) + (setq cur (nth idx alldecos)) + + ;; If the index is positive, goto the line, otherwise go to the buffer + ;; boundaries. + (if (and cur (>= idx 0)) + (goto-line (car cur)) + (if (> offset 0) (end-of-buffer) (beginning-of-buffer))) )) +(defun rest-backward-section () + "Like rest-forward-section, except move back one title." + (interactive) + (rest-forward-section -1)) + + + + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Generic text functions that are more convenient than the defaults. +;; + +(defun replace-lines (fromchar tochar) + "Replace flush-left lines, consisting of multiple FROMCHAR characters, +with equal-length lines of TOCHAR." + (interactive "\ +cSearch for flush-left lines of char: +cand replace with char: ") + (save-excursion + (let* ((fromstr (string fromchar)) + (searchre (concat "^" (regexp-quote fromstr) "+ *$")) + (found 0)) + (condition-case err + (while t + (search-forward-regexp searchre) + (setq found (1+ found)) + (search-backward fromstr) ;; point will be *before* last char + (setq p (1+ (point))) + (beginning-of-line) + (setq l (- p (point))) + (kill-line) + (insert-char tochar l)) + (search-failed + (message (format "%d lines replaced." found))))))) + +(defun join-paragraph () + "Join lines in current paragraph into one line, removing end-of-lines." + (interactive) + (let ((fill-column 65000)) ; some big number + (call-interactively 'fill-paragraph))) + +(defun force-fill-paragraph () + "Fill paragraph at point, first joining the paragraph's lines into one. +This is useful for filling list item paragraphs." + (interactive) + (join-paragraph) + (fill-paragraph nil)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -531,91 +1096,34 @@ As an added convenience, if the command is repeated immediately, the alternative column is used (fill-column vs. end of previous/next line)." (interactive) (let* ((curcol (current-column)) - (curline (+ (count-lines (point-min) (point)) - (if (eq curcol 0) 1 0))) - (lbp (line-beginning-position 0)) - (prevcol (if (and (= curline 1) (not current-prefix-arg)) - fill-column - (save-excursion - (forward-line (if current-prefix-arg 1 -1)) - (end-of-line) - (skip-chars-backward " \t" lbp) - (let ((cc (current-column))) - (if (= cc 0) fill-column cc))))) - (rightmost-column - (cond (tofill fill-column) - ((equal last-command 'repeat-last-character) - (if (= curcol fill-column) prevcol fill-column)) - (t (save-excursion - (if (= prevcol 0) fill-column prevcol))) - )) ) + (curline (+ (count-lines (point-min) (point)) + (if (eq curcol 0) 1 0))) + (lbp (line-beginning-position 0)) + (prevcol (if (and (= curline 1) (not current-prefix-arg)) + fill-column + (save-excursion + (forward-line (if current-prefix-arg 1 -1)) + (end-of-line) + (skip-chars-backward " \t" lbp) + (let ((cc (current-column))) + (if (= cc 0) fill-column cc))))) + (rightmost-column + (cond (tofill fill-column) + ((equal last-command 'repeat-last-character) + (if (= curcol fill-column) prevcol fill-column)) + (t (save-excursion + (if (= prevcol 0) fill-column prevcol))) + )) ) (end-of-line) (if (> (current-column) rightmost-column) - ;; shave characters off the end - (delete-region (- (point) - (- (current-column) rightmost-column)) - (point)) + ;; shave characters off the end + (delete-region (- (point) + (- (current-column) rightmost-column)) + (point)) ;; fill with last characters (insert-char (preceding-char) - (- rightmost-column (current-column)))) + (- rightmost-column (current-column)))) )) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Section movement commands. -;; - -;; Note: this is not quite correct, the definition is any non alpha-numeric -;; character. -(defun rest-title-char-p (c) - "Returns true if the given character is a valid title char." - (and (string-match "[-=`:\\.'\"~^_*+#<>!$%&(),/;?@\\\|]" - (char-to-string c)) t)) - -(defun rest-forward-section () - "Skip to the next restructured text section title." - (interactive) - (let* ( (newpoint - (save-excursion - (forward-char) ;; in case we're right on a title - (while - (not - (and (re-search-forward "^[A-Za-z0-9].*[ \t]*$" nil t) - (reST-title-char-p (char-after (+ (point) 1))) - (looking-at (format "\n%c\\{%d,\\}[ \t]*$" - (char-after (+ (point) 1)) - (current-column)))))) - (beginning-of-line) - (point))) ) - (if newpoint (goto-char newpoint)) )) - -(defun rest-backward-section () - "Skip to the previous restructured text section title." - (interactive) - (let* ( (newpoint - (save-excursion - ;;(forward-char) ;; in case we're right on a title - (while - (not - (and (or (backward-char) t) - (re-search-backward "^[A-Za-z0-9].*[ \t]*$" nil t) - (or (end-of-line) t) - (reST-title-char-p (char-after (+ (point) 1))) - (looking-at (format "\n%c\\{%d,\\}[ \t]*$" - (char-after (+ (point) 1)) - (current-column)))))) - (beginning-of-line) - (point))) ) - (if newpoint (goto-char newpoint)) )) - - -;;------------------------------------------------------------------------------ -;; For backwards compatibility. Remove at some point. -(defalias 'reST-title-char-p 'rest-title-char-p) -(defalias 'reST-forward-title 'rest-forward-section) -(defalias 'reST-backward-title 'rest-backward-section) - - (provide 'restructuredtext) diff --git a/tools/editors/emacs/tests/Makefile b/tools/editors/emacs/tests/Makefile new file mode 100644 index 000000000..02fd22712 --- /dev/null +++ b/tools/editors/emacs/tests/Makefile @@ -0,0 +1,4 @@ + +runtests: + emacs --script tests-basic.el + emacs --script tests-adjust-section.el diff --git a/tools/editors/emacs/tests/README b/tools/editors/emacs/tests/README new file mode 100644 index 000000000..a1f4b0e4a --- /dev/null +++ b/tools/editors/emacs/tests/README @@ -0,0 +1,27 @@ +========================================== + Tests for automatic section adjustment +========================================== + +:Author: Martin Blais +:Date: 2005-09-03 + + +Running the tests +================= + +To run the test suite, you can either evaluate the relevant progn from within +emacs, or you can run them from the command-line like this, e.g.:: + + emacs --script tests-basic.el + +See the Makefile for more details. + +Status +====== + +We are planning to write many more tests and eventually to rewrite the +interactive section adjustment because it contains a few bugs (it nonetheless +pretty much works well otherwise). Some of those bugs have been added and are +currently failing if you run the tests. + +(See the FIXME statements for where to continue.) diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index 5af65d56a..d544fda98 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -3,238 +3,778 @@ ;; Copyright: This module has been placed in the public domain. ;; ;; Regression tests for rest-adjust-section-title. +;; +;; Run this with:: +;; +;; emacs --script tests-adjust-section.el ;; -(setq rest-adjust-section-tests +;; Define tests. +(setq rest-adjust-decoration-tests '( - (simple +;;------------------------------------------------------------------------------ +(nodec-first-simple-1 " Some Title@ " " +============ + Some Title +============ + +" +) + +;;------------------------------------------------------------------------------ +(nodec-first-simple-2 +" Some Title -========== +@ +" +" +============ + Some Title +============ -") +" +) - (simple-cursor-in-line +;;------------------------------------------------------------------------------ +(nodec-first-simple-3 " Some Tit@le " " -Some Title -========== +============ + Some Title +============ -") +" +) - (simple-cursor-beginning +;;------------------------------------------------------------------------------ +(nodec-first-simple-4 " @Some Title " " -Some Title -========== +============ + Some Title +============ ") - (simple-at-end-of-buffer + +;;------------------------------------------------------------------------------ +(nodec-first-simple-others +" +Some Title@ + +Other Title +----------- + +Other Title2 +~~~~~~~~~~~~ + +" +" +============ + Some Title +============ + +Other Title +----------- + +Other Title2 +~~~~~~~~~~~~ + +" +) + + +;;------------------------------------------------------------------------------ +(nodec-first-toggle +" +Some Title@ + " -Some Title@" " Some Title ========== -") - (cursor-on-empty-line-under " -Some Title -@ +(t)) + +;;------------------------------------------------------------------------------ +(nodec-first-forced +" + Some Title@ + +" +" +================ + Some Title +================ + +" +) + +;;------------------------------------------------------------------------------ +(nodec-first-forced-2 +" + Some Title@ + " " Some Title ========== -") +" +(t)) +;;------------------------------------------------------------------------------ +(nodec-simple +" +Previous Title +-------------- + +Some Title@ + +" +" +Previous Title +-------------- +Some Title +~~~~~~~~~~ + +" +) - (partial +;;------------------------------------------------------------------------------ +(nodec-simple-neg " +Previous Title +-------------- + Some Title@ ---- + +Next Title +~~~~~~~~~~ + " " +Previous Title +-------------- + Some Title ----------- +~~~~~~~~~~ -") +Next Title +~~~~~~~~~~ - (cursor-on-underline " -Some Title ----@ +) + +;;------------------------------------------------------------------------------ +(nodec-simple-toggle +" +Previous Title +-------------- + +Some Title@ + " " +Previous Title +-------------- + +~~~~~~~~~~ Some Title ----------- +~~~~~~~~~~ -") +" +(t)) - (cursor-on-underline-one-char +;;------------------------------------------------------------------------------ +(nodec-simple-force-toggle " -Some Title -~@ +Previous Title +-------------- + + Some Title@ + " " +Previous Title +-------------- + +~~~~~~~~~~~~~~ + Some Title +~~~~~~~~~~~~~~ + +" +(t)) + + +;;------------------------------------------------------------------------------ +(nodec-simple-forced +" +Previous Title +-------------- + + Some Title@ + +" +" +Previous Title +-------------- + Some Title ~~~~~~~~~~ -") +" +) - (with-previous-text +;;------------------------------------------------------------------------------ +(nodec-neg " -Some Title -********** +Previous Title +-------------- -Subtitle@ +Some Title@ +Next Title +~~~~~~~~~~ " " +Previous Title +-------------- + Some Title -********** +---------- -Subtitle -******** +Next Title +~~~~~~~~~~ +" +(-1)) -") +;;------------------------------------------------------------------------------ +(incomplete-simple-1 +" +Previous Title@ +---------- +" +" +Previous Title +-------------- - (with-suggested-new-text " -Some Title -========== +) -Subtitle +;;------------------------------------------------------------------------------ +(incomplete-simple-2 +" +Previous Title +----------@ +" +" +Previous Title +-------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-simple-3 +" +Previous Title +-@ +" +" +================ + Previous Title +================ + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-simple-too-long +" +Previous Title +------------------@ +" +" +Previous Title +-------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-simple-uo +" +---------------- + Previous Title +----------@ +" +" +---------------- + Previous Title +---------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-partial-overline +" +----------@ + Previous Title +---------------- +" +" +---------------- + Previous Title +---------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-both +" +---------- + Previous Title@ +----- +" +" +---------------- + Previous Title +---------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-toggle +" +Previous Title +----------@ +" +" +-------------- +Previous Title +-------------- + +" +(t)) + +;;------------------------------------------------------------------------------ +(incomplete-toggle-2 +" +---------------- + Previous Title@ +-------- +" +" +Previous Title +-------------- + +" +(t)) + +;;------------------------------------------------------------------------------ +(incomplete-toggle-overline +" +--------@ + Previous Title +---------------- +" +" +Previous Title +-------------- + +" +(t)) + +;;------------------------------------------------------------------------------ +(incomplete-top +"--------@ + Previous Title +---------------- +" +"---------------- + Previous Title +---------------- + +" +) + +;;------------------------------------------------------------------------------ +(incomplete-top-2 +"======= +Document Title@ +============== +" +"============== +Document Title +============== + +" +) + +;;------------------------------------------------------------------------------ +(complete-simple +" +================ + Document Title +================ + +SubTitle +-------- + +My Title@ -------- -Subtitle2@ +After Title +~~~~~~~~~~~ " " -Some Title +================ + Document Title +================ + +SubTitle +-------- + +========== + My Title ========== -Subtitle +After Title +~~~~~~~~~~~ + +" +) + +;;------------------------------------------------------------------------------ +(complete-simple-neg +" +================ + Document Title +================ + +SubTitle +-------- + +My Title@ +-------- + +After Title +~~~~~~~~~~~ + +" +" +================ + Document Title +================ + +SubTitle -------- -Subtitle2 -~~~~~~~~~ +My Title +~~~~~~~~ + +After Title +~~~~~~~~~~~ " -(nil nil)) +(-1)) - (with-previous-text-rotating +;;------------------------------------------------------------------------------ +(complete-simple-suggestion-down " -Some Title -========== +================ + Document Title +================ -Subtitle +SubTitle +======== + +My Title@ +======== + +" +" +================ + Document Title +================ + +SubTitle +======== + +My Title +-------- + +" +(-1)) + +;;------------------------------------------------------------------------------ +(complete-simple-boundary-down +" +================ + Document Title +================ + +SubTitle +======== + +My Title@ -------- -Subtitle2@ +" +" +================ + Document Title +================ + +SubTitle +======== + +========== + My Title +========== " +(-1)) + +;;------------------------------------------------------------------------------ +(complete-simple-suggestion-up " -Some Title +================ + Document Title +================ + +SubTitle +======== + +========== + My Title@ ========== -Subtitle +" +" +================ + Document Title +================ + +SubTitle +======== + +My Title -------- -Subtitle2 -========= +" +) +;;------------------------------------------------------------------------------ +(complete-simple-boundary-up ;; Note: boundary-up does not exist. " -(nil nil nil)) +================ + Document Title +================ + +SubTitle +======== - (start-indented +My Title@ +-------- " - Some Title@ +" +================ + Document Title +================ + +SubTitle +======== + +My Title +======== + +" +) + +;;------------------------------------------------------------------------------ +(complete-toggle-1 +" +SubTitle@ +~~~~~~~~ + +" +" +~~~~~~~~~~ + SubTitle +~~~~~~~~~~ + +" +(t)) + +;;------------------------------------------------------------------------------ +(complete-toggle-2 +" +~~~~~~~~~~ + SubTitle@ +~~~~~~~~~~ + +" +" +SubTitle +~~~~~~~~ + +" +(t)) + +;;------------------------------------------------------------------------------ +(at-file-beginning +" +Document Title@ " " ================ - Some Title + Document Title@ ================ -") +" +) + - (switch-from-nothing +;;------------------------------------------------------------------------------ +(at-file-ending " -Some Title@ +Document Title@ " " -============ - Some Title -============ -" (t)) +================ + Document Title@ +================ - (switch-from-over-and-under " -============ - Some Title@ -============ +) + +;;------------------------------------------------------------------------------ +(at-file-ending-2 " + +Document Title@" " -Some Title -========== -" (t)) +================ + Document Title@ +================ +" +) + +;;------------------------------------------------------------------------------ +(conjoint +" +Document Title +============== +Subtitle@ + +" +" +Document Title +============== +Subtitle@ +-------- + +" +) + +;;------------------------------------------------------------------------------ +(same-conjoint-2 +"============== +Document Title@ +============== +Subtitle +======== + +" +"Document Title@ +============== +Subtitle +======== + +" +) + +;;------------------------------------------------------------------------------ +(same-conjoint-2b +" +============== +Document Title@ +============== +Subtitle +======== + +" +" +Document Title@ +============== +Subtitle +======== + +" +) + + +;;------------------------------------------------------------------------------ +(same-conjoint-2 +" +============== +Document Title +============== +=============== +Document Title2@ +=============== + +" +" +============== +Document Title +============== +Document Title2 +=============== + +" +) )) -;; "A list of regression tests for the section update method." - - - -(defun regression-test-compare-expect-buffer (testlist fun) - "Run the regression tests for the section adjusting method." - - (let ((buf (get-buffer-create "restructuredtext-regression-tests")) - (specchar "@") - ) - (dolist (curtest testlist) - ;; print current text - (message (format "========= %s" (prin1-to-string (car curtest)))) - - ;; prepare a buffer with the starting text, and move the cursor where - ;; the special character is located - (switch-to-buffer buf) - (erase-buffer) - (insert (cadr curtest)) - (search-backward specchar) - (delete-char 1) - - ;; run the section title update command n times - (dolist (x (or (cadddr curtest) (list nil))) - (let ((current-prefix-arg x)) - (funcall fun))) - - ;; compare the buffer output with the expected text - (or (string= - (buffer-string) - (caddr curtest)) - (progn - (error "Test %s failed." (car curtest)))) - ) - )) - -;; evaluate this to run the tests, either interactively or in batch -(regression-test-compare-expect-buffer - rest-adjust-section-tests - (lambda () - (call-interactively 'rest-adjust-section-title))) + +;; Main program. Evaluate this to run the tests. +;; (setq debug-on-error t) + +;; Import the module from the file in the parent directory directly. +(add-to-list 'load-path ".") +(load "tests-runner.el") +(add-to-list 'load-path "..") +(load "restructuredtext.el") + +(progn + (regression-test-compare-expect-buffer + "Test interactive adjustment of sections." + rest-adjust-decoration-tests + (lambda () + (call-interactively 'rest-adjust)) + nil)) + diff --git a/tools/editors/emacs/tests/tests-basic.el b/tools/editors/emacs/tests/tests-basic.el new file mode 100644 index 000000000..73054742f --- /dev/null +++ b/tools/editors/emacs/tests/tests-basic.el @@ -0,0 +1,762 @@ +;; Authors: Martin Blais +;; Date: $Date: 2005/04/01 23:19:41 $ +;; Copyright: This module has been placed in the public domain. +;; +;; Regression tests for rest-adjust-section-title. +;; +;; Run this with:: +;; +;; emacs --script tests-adjust-section.el +;; + +;; Import the module from the file in the parent directory directly. +(add-to-list 'load-path ".") +(load "tests-runner.el") +(add-to-list 'load-path "..") +(load "restructuredtext.el") + +;; (setq debug-on-error t) + + +(setq rest-line-homogeneous-p-tests + '( +;;------------------------------------------------------------------------------ +(simple "Blablabla bla@" nil) +(true "-----------@" ?-) +(indented " -----------@" ?-) +(letter " aaaa@aaa" ?a) +(true2 "uuuuuuuuuuuuuuuuu@" ?u) +(misleading "--=---------@" nil) +(notstrip " uuuuuuuuuuuuuuuuu@" ?u) +(notstrip2 " uuuuuuuuuuuuuuuuu @" ?u) +(position "-------@----" ?-) +(one-char "-@" nil) +)) + +(progn + (regression-test-compare-expect-values + "Tests for predicate for one char line." + rest-line-homogeneous-p-tests 'rest-line-homogeneous-p nil)) + + + + +(setq rest-normalize-cursor-position-tests + '( +;;------------------------------------------------------------------------------ +(under +" + +Du bon vin tous les jours. +@ +" +" + +@Du bon vin tous les jours. + +" +) + +;;------------------------------------------------------------------------------ +(over +" +@ +Du bon vin tous les jours. + +" +" + +@Du bon vin tous les jours. + +" +) + +;;------------------------------------------------------------------------------ +(underline +" + +Du bon vin tous les jours. +------@----- +" +" + +@Du bon vin tous les jours. +----------- +" +) + +;;------------------------------------------------------------------------------ +(overline +" +------@----- +Du bon vin tous les jours. + +" +" +----------- +@Du bon vin tous les jours. + +" +) + +;;------------------------------------------------------------------------------ +(both +" +@----------- +Du bon vin tous les jours. +----------- + +" +" +----------- +@Du bon vin tous les jours. +----------- + +" +) + +;;------------------------------------------------------------------------------ +(joint +" +Du bon vin tous les jours. +@----------- +Du bon vin tous les jours. +----------- + +" +" +@Du bon vin tous les jours. +----------- +Du bon vin tous les jours. +----------- + +" +) + +;;------------------------------------------------------------------------------ +(separator +" + +@----------- + +" +" + +@----------- + +" +) + +;;------------------------------------------------------------------------------ +(between +" +Line 1 +@ +Line 2 + +" +" +@Line 1 + +Line 2 + +" +) + +;;------------------------------------------------------------------------------ +(between-2 +" +===================================== + Project Idea: Panorama Stitcher +==================================== + +:Author: Martin Blais +@ +Another Title +============= +" +" +===================================== + Project Idea: Panorama Stitcher +==================================== + +@:Author: Martin Blais + +Another Title +============= +" +) + +)) + + +(progn + (regression-test-compare-expect-buffer + "Test preparation of cursor position." + rest-normalize-cursor-position-tests 'rest-normalize-cursor-position nil)) + + + + + + + +(setq rest-get-decoration-tests + '( +;;------------------------------------------------------------------------------ +(nodec-1 +" + +@Du bon vin tous les jours + +" +(nil nil 0)) + +;;------------------------------------------------------------------------------ +(nodec-2 +" + +@ +Du bon vin tous les jours + +" +(nil nil 0)) + +;;------------------------------------------------------------------------------ +(nodec-indent +" + +@ Du bon vin tous les jours + +" +(nil nil 2)) + +;;------------------------------------------------------------------------------ +(underline +" + +@Du bon vin tous les jours +========================= + +" +(?= simple 0)) + +;;------------------------------------------------------------------------------ +(underline-incomplete +" + +@Du bon vin tous les jours +==================== + +" +(?= simple 0)) + +;;------------------------------------------------------------------------------ +(underline-indent +" + +@ Du bon vin tous les jours +==================== + +" +(?= simple 5)) + +;;------------------------------------------------------------------------------ +(underline-one-char +" + +@Du bon vin tous les jours +- +" +(nil nil 0)) + +;;------------------------------------------------------------------------------ +(underline-two-char +" + +@Du bon vin tous les jours +-- +" +(?- simple 0)) + +;;------------------------------------------------------------------------------ +(over-and-under +" +~~~~~~~~~~~~~~~~~~~~~~~~~ +@Du bon vin tous les jours +~~~~~~~~~~~~~~~~~~~~~~~~~ + +" +(?~ over-and-under 0)) + +;;------------------------------------------------------------------------------ +(over-and-under-top +"~~~~~~~~~~~~~~~~~~~~~~~~~ +@Du bon vin tous les jours +~~~~~~~~~~~~~~~~~~~~~~~~~ + +" +(?~ over-and-under 0)) + +;;------------------------------------------------------------------------------ +(over-and-under-indent +" +~~~~~~~~~~~~~~~~~~~~~~~~~ +@ Du bon vin tous les jours +~~~~~~~~~~~~~~~~~~~~~~~~~ + +" +(?~ over-and-under 3)) + +;;------------------------------------------------------------------------------ +(over-and-under-incomplete +" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@Du bon vin tous les jours +~~~~~~~~~~~~~~~~~~~ + +" +(?~ over-and-under 0)) + +;;------------------------------------------------------------------------------ +(over-and-under-different-chars +" +--------------------------- +@Du bon vin tous les jours +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +" +(?~ over-and-under 0)) + + +;;------------------------------------------------------------------------------ +(not-beginning +" + +Du bon vin to@us les jours +========================= + +" +(?= simple 0)) + +;;------------------------------------------------------------------------------ +(over-over-and-under +" +@ +========================= +Du bon vin tous les jours +========================= +" +(nil nil 0)) + +;;------------------------------------------------------------------------------ +(joint-1 +" +========================= +Du bon vin tous les jours +========================= +Du bon vin@ + +" +(nil nil 0)) + +;;------------------------------------------------------------------------------ +(joint-2 +" +========================= +Du bon vin tous les jours +========================= +Du bon vin@ +---------- + +" +(45 simple 0)) + +;;------------------------------------------------------------------------------ +(joint-3 +" +========================= +Du bon vin tous les jours +========================= +---------- +Du bon vin@ +---------- + +" +(45 over-and-under 0)) + +;;------------------------------------------------------------------------------ +(joint-4 +" +========================= +Du bon vin tous les jours +========================= +-------------- + Du bon vin@ +-------------- + +" +(45 over-and-under 2)) + +)) + + +(progn + (regression-test-compare-expect-values + "Test getting the decoration." + rest-get-decoration-tests 'rest-get-decoration nil)) + + + + + + + + + + + + + + +(setq text-1 +"=============================== + Project Idea: My Document +=============================== + +:Author: Martin Blais + +Introduction +============ + +This is the introduction. + +Notes +----- + +Some notes. + +Main Points +=========== + +Yep. + +Super Point +----------- + +~~~~~~~~~~~ +@ Sub Point +~~~~~~~~~~~ + +Isn't this fabulous? + +Conclusion +========== + +That's it, really. + +") + + +(setq text-2 +" + +Previous +-------- + +Current@ +~~~~~~~ + +Next +++++ + +") + +;; ~~~~~~~~~~~~~~~~~~ +;; Buggy Decoration +;; ~~~~~~ +;; +;; ~~~~~~~~~~~~ +;; Decoration +;; +;; +;; ========== + +(setq rest-find-all-decorations-tests + `( + ;;------------------------------------------------------------------------------ + (basic-1 ,text-1 + ((2 61 over-and-under 3) + (7 61 simple 0) + (12 45 simple 0) + (17 61 simple 0) + (22 45 simple 0) + (26 126 over-and-under 1) + (31 61 simple 0)) + ) + + (basic-2 ,text-2 + ((3 45 simple 0) + (6 126 simple 0) + (9 43 simple 0)) + ) + + )) + + +(progn + (regression-test-compare-expect-values + "Test finding all the decorations in a file." + rest-find-all-decorations-tests 'rest-find-all-decorations nil)) + + + + +(setq rest-get-hierarchy-tests + `( + ;;------------------------------------------------------------------------------ + (basic-1 ,text-1 + ((61 over-and-under 3) + (61 simple 0) + (45 simple 0) + (126 over-and-under 1)) + ) + )) + +(progn + (regression-test-compare-expect-values + "Test finding the hierarchy of sections in a file." + rest-get-hierarchy-tests 'rest-get-hierarchy nil)) + + + + +(setq rest-get-hierarchy-ignore-tests + `( + ;;------------------------------------------------------------------------------ + (basic-1 ,text-1 + ((61 over-and-under 3) + (61 simple 0) + (45 simple 0)) + ) + )) + +(progn + (regression-test-compare-expect-values + "Test finding the hierarchy of sections in a file, ignoring lines." + rest-get-hierarchy-ignore-tests + (lambda () (rest-get-hierarchy nil (line-number-at-pos))) nil)) + + + + + + + +(setq rest-decoration-complete-p-tests + '( +;;------------------------------------------------------------------------------ +(nodec +" + +@Vaudou + +" nil ((?= simple 0))) + +;;------------------------------------------------------------------------------ +(complete-simple +" +@Vaudou +====== +" t ((?= simple 0))) + +;;------------------------------------------------------------------------------ +(complete-over-and-under +" +====== +@Vaudou +====== +" t ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(complete-over-and-under-indent +" +========== +@ Vaudou +========== +" t ((?= over-and-under 2))) + +;;------------------------------------------------------------------------------ +(incomplete-simple-short +" +@Vaudou +===== +" nil ((?= simple 0))) + +;;------------------------------------------------------------------------------ +(incomplete-simple-long +" +@Vaudou +======= +" nil ((?= simple 0))) + +;;------------------------------------------------------------------------------ +(incomplete-simple-mixed +" +@Vaudou +===-== +" nil ((?= simple 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-1 +" +====== +@Vaudou +===== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-2 +" +===== +@Vaudou +====== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-mixed-1 +" +====== +@Vaudou +===-== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-mixed-2 +" +===-== +@Vaudou +====== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-only +" +====== +@Vaudou + +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-mixed +" +====== +@Vaudou +------ +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-1 +" +========== + @Vaudou +========= +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-2 +" +========= + @Vaudou +========== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-mixed-1 +" +========== + @Vaudou +===-====== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-and-under-mixed-2 +" +===-====== + @Vaudou +========== +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-over-only +" +========== + @Vaudou + +" nil ((?= over-and-under 0))) + +;;------------------------------------------------------------------------------ +(incomplete-mixed-2 +" +========== + @Vaudou +---------- +" nil ((?= over-and-under 0))) + +)) + +(progn + (regression-test-compare-expect-values + "Tests for completeness predicate." + rest-decoration-complete-p-tests 'rest-decoration-complete-p nil)) + + + + + + + + + + + + + +(setq rest-get-decorations-around-tests + '( +;;------------------------------------------------------------------------------ +(simple +" + +Previous +-------- + +@Current + +Next +++++ + +" ((?- simple 0) (?+ simple 0))) + +;;------------------------------------------------------------------------------ +(simple-2 +" + +Previous +-------- + +Current@ +~~~~~~~ + +Next +++++ + +" ((?- simple 0) (?+ simple 0))) + +)) + +(progn + (regression-test-compare-expect-values + "Tests getting the decorations around a point." + rest-get-decorations-around-tests 'rest-get-decorations-around nil)) + diff --git a/tools/editors/emacs/tests/tests-runner.el b/tools/editors/emacs/tests/tests-runner.el new file mode 100644 index 000000000..2304ae54a --- /dev/null +++ b/tools/editors/emacs/tests/tests-runner.el @@ -0,0 +1,122 @@ +;; Authors: Martin Blais +;; Date: $Date: 2005/04/01 23:19:41 $ +;; Copyright: This module has been placed in the public domain. +;; +;; Simple generic test runner for test scripts. +;; +;; Run this with:: +;; +;; emacs --script .el +;; + +(require 'cl) + +(defvar regression-point-char "@" + "Special character used to mark the position of point in input + text and expected text.") + +(defun regression-test-loop (suitename testfun testlist fun &optional continue) + "Loop over a series of tests in a buffer and run the 'testfun' +function." + + (message (format "\n\n Test Suite: %s\n\n" suitename)) + + (let ((buf (get-buffer-create "regression-tests")) + errtxt + ) + (dolist (curtest testlist) + + ;; Print current text. + (message (format "========= %s" (prin1-to-string (car curtest)))) + + ;; Prepare a buffer with the starting text, and move the cursor where + ;; the special character is located. + (switch-to-buffer buf) + (erase-buffer) + (insert (cadr curtest)) + + (if (not (search-backward regression-point-char nil t)) + (error (concat "Error: Badly formed test input, missing " + "the cursor position marker."))) + + (delete-char 1) + + (setq errtxt (funcall testfun + (car curtest) + (caddr curtest) + (cadddr curtest))) + + (if errtxt + (if continue + (progn (message errtxt) + (message "(Continuing...)")) + (error errtxt))) + )) + (message "Done.")) + + +(defun regression-compare-buffers (testname expected testargs) + "Compare the buffer and expected text and return actual +contents if they do not match." + + ;; Run the section title update command n times. + (dolist (x (or testargs (list nil))) + (let ((current-prefix-arg x)) + (funcall fun))) + + ;; Compare the buffer output with the expected text. + (let* (;; Get the actual buffer contents. + (actual (buffer-string)) + ;; Get the expected location of point + (exppoint (string-match regression-point-char expected)) + + (expected-clean (if exppoint + (concat (substring expected 0 exppoint) + (substring expected (+ 1 exppoint))) + expected)) + + ;; Adjust position of point vs. string index. + (exppoint (and exppoint (+ exppoint 1))) + + ) + + (if (not (string= expected-clean actual)) + ;; Error! Test failed. + (format "Error: Test %s failed: \nexpected\n%s\ngot\n%s" + testname + (prin1-to-string expected-clean) + (prin1-to-string actual)) + (if (and exppoint (not (equal exppoint (point)))) + ;; Error! Test failed, final position of cursor is not the same. + (format "Error: Test %s failed: cursor badly placed." testname)) + ))) + +(defun regression-test-compare-expect-buffer + (suitename testlist fun &optional continue) + "Run the regression tests for the expected buffer contents." + (regression-test-loop + suitename 'regression-compare-buffers testlist fun continue)) + + +(defun regression-compare-values (testname expected testargs) + "Compare the buffer and expected text and return actual +contents if they do not match." + + (let (actual) + ;; Run the section title update command n times. + (setq actual (apply fun testargs)) + + ;; Compare the buffer output with the expected text. + (if (not (equal actual expected)) + ;; Error! Test failed. + (format "Error: Test %s failed: expected '%s' got '%s'." + testname + (prin1-to-string expected) + (prin1-to-string actual)) + ))) + +(defun regression-test-compare-expect-values + (suitename testlist fun &optional continue) + "Run the regression tests for expected values comparison." + (regression-test-loop + suitename 'regression-compare-values testlist fun continue)) -- cgit v1.2.1 From 7f6a756ab8409fd086904e9941eb3c52a5d27e88 Mon Sep 17 00:00:00 2001 From: blais Date: Fri, 9 Sep 2005 15:29:59 +0000 Subject: Backported to emacs-21. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3861 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 22 +++++++++++++++++++++- tools/editors/emacs/tests/Makefile | 5 +++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 0c13a82a2..6f88fcc44 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -33,6 +33,11 @@ ;; code). The most important function provided by this file for section title ;; adjustments is rest-adjust. ;; +;; You should consider customizing the following variables: +;; +;; - rest-default-indent +;; - rest-preferred-decorations +;; ;; TODO: ;; - Add an option to forego using the file structure in order to make ;; suggestion, and to always use the preferred decorations to do that. @@ -53,6 +58,21 @@ is for which (pred elem) is true)" tail))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; From emacs-22 + +(if (not (fboundp 'line-number-at-pos)) + (defun line-number-at-pos (&optional pos) + "Return (narrowed) buffer line number at position POS. + If POS is nil, use current buffer location." + (let ((opoint (or pos (point))) start) + (save-excursion + (goto-char (point-min)) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines start (point)))))) ) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The following functions implement a smart automatic title sectioning feature. @@ -154,7 +174,7 @@ is for which (pred elem) is true)" decoration style to a over-and-under decoration style.") -(defcustom rest-section-text-regexp "^[ \t]*\\S-*[a-zA-Z0-9]\\S-*" +(defvar rest-section-text-regexp "^[ \t]*\\S-*[a-zA-Z0-9]\\S-*" "Regular expression for valid section title text.") diff --git a/tools/editors/emacs/tests/Makefile b/tools/editors/emacs/tests/Makefile index 02fd22712..ea024e3fd 100644 --- a/tools/editors/emacs/tests/Makefile +++ b/tools/editors/emacs/tests/Makefile @@ -1,4 +1,9 @@ runtests: + emacs-21 --batch -l tests-basic.el + emacs-21 --batch -l tests-adjust-section.el + +runtests-emacs-cvs: emacs --script tests-basic.el emacs --script tests-adjust-section.el + -- cgit v1.2.1 From ed79f56f61e529788d15f3e44f8b426d39cd1823 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 9 Sep 2005 19:31:06 +0000 Subject: added bug with expose_internals git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3863 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index 72f44264a..defe9ef09 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -251,6 +251,25 @@ Also see the `SourceForge Bug Tracker`_. Hyperlink targets with duplicate names should be assigned new IDs unrelated to the target names (i.e., "id"-prefix serial IDs). +* _`expose_internals` is (partially) broken:: + + $ echo x | rst2pseudoxml.py --expose-internal-attribute rawsource + Traceback (most recent call last): + File "/home/felix/bin/rst2pseudoxml.py", line 25, in ? + publish_cmdline(description=description) + File "/home/felix/.python/lib/docutils/core.py", line 341, in publish_cmdline + config_section=config_section, enable_exit_status=enable_exit_status) + File "/home/felix/.python/lib/docutils/core.py", line 217, in publish + self.apply_transforms() + File "/home/felix/.python/lib/docutils/core.py", line 186, in apply_transforms + self.document.transformer.apply_transforms() + File "/home/felix/.python/lib/docutils/transforms/__init__.py", line 192, in apply_transforms + transform.apply(**kwargs) + File "/home/felix/.python/lib/docutils/transforms/universal.py", line 98, in apply + node['internal:' + att] = value + AttributeError: Text instance has no attribute '__setitem__' + + .. Local Variables: -- cgit v1.2.1 From b38f1ece385244850516545ef17072b1d99c7372 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 10 Sep 2005 19:03:32 +0000 Subject: give Martin top billing; almost all of the code is his git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3864 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 6f88fcc44..9d43734ef 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -1,5 +1,5 @@ -;; Authors: David Goodger , -;; Martin Blais +;; Authors: Martin Blais , +;; David Goodger ;; Date: $Date$ ;; Copyright: This module has been placed in the public domain. ;; -- cgit v1.2.1 From 4bab3b641ddd264e0b3b3dad289c088758ed4cf2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 20:29:10 +0000 Subject: renamed Element.attr_defaults to list_attributes; added Element.update() method git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3865 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 32 ++++++++++++++++++++++---------- test/test_nodes.py | 13 +++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 8ff275129..af1ba59f5 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -333,9 +333,9 @@ class Element(Node): This is equivalent to ``element.extend([node1, node2])``. """ - attr_defaults = {'ids': [], 'classes': [], 'names': [], - 'dupnames': [], 'backrefs': []} - """Default attributes.""" + list_attributes = ('ids', 'classes', 'names', 'dupnames', 'backrefs') + """List attributes, automatically initialized to empty lists for + all nodes.""" tagname = None """The element generic identifier. If None, it is set as an instance @@ -356,10 +356,9 @@ class Element(Node): self.attributes = {} """Dictionary of attribute {name: value}.""" - # Copy default values. - for att, value in self.attr_defaults.items(): - # Default values are always lists (at the moment). - self.attributes[att] = value[:] + # Initialize list attributes. + for att in self.list_attributes: + self.attributes[att] = [] for att, value in attributes.items(): self.attributes[att.lower()] = value @@ -540,11 +539,24 @@ class Element(Node): return self.children.index(item) def is_not_default(self, key): - try: - return self[key] != self.attr_defaults[key] - except KeyError: + if self[key] == [] and key in self.list_attributes: + return 0 + else: return 1 + def update(self, dict): + """ + Update attributes from node or dictionary `dict`, extending + (instead of overwriting) list attributes. + """ + if isinstance(dict, Node): + dict = dict.attributes + for att, value in dict.items(): + if att in self.list_attributes: + self[att].extend(value) + else: + self[att] = value + def clear(self): self.children = [] diff --git a/test/test_nodes.py b/test/test_nodes.py index 3889a19be..1427c6146 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -105,6 +105,19 @@ class ElementTests(unittest.TestCase): {'ids': ['someid']}) self.assert_(element.is_not_default('ids')) + def test_update(self): + element1 = nodes.Element() + element2 = nodes.Element() + element1['ids'] = ['foo', 'bar'] + element1['test'] = ['this is not a known list attribute'] + element2['ids'] = ['baz', 'qux'] + element2['test'] = ['overwrite'] + element1.update(element2) + # 'ids' are appended. + self.assertEquals(element1['ids'], ['foo', 'bar', 'baz', 'qux']) + # 'test' is overwritten. + self.assertEquals(element1['test'], ['overwrite']) + class MiscTests(unittest.TestCase): -- cgit v1.2.1 From 963bd1c5e6b84ae881a1046be9f95fc8b18547d3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 20:54:18 +0000 Subject: added Element.substitute() git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3866 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 11 +++++++++++ test/test_nodes.py | 47 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index af1ba59f5..b7ee898c0 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -569,6 +569,17 @@ class Element(Node): elif new is not None: self[index:index+1] = new + def substitute(self, new): + """ + Substitute `new` for `self` node, where `new` is a node or + list of nodes. + """ + if isinstance(new, Node): + new.update(self) + else: + new[0].update(self) + self.parent.replace(self, new) + def first_child_matching_class(self, childclass, start=0, end=sys.maxint): """ Return the index of the first child whose class exactly matches. diff --git a/test/test_nodes.py b/test/test_nodes.py index 1427c6146..deda8455d 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -106,18 +106,51 @@ class ElementTests(unittest.TestCase): self.assert_(element.is_not_default('ids')) def test_update(self): - element1 = nodes.Element() - element2 = nodes.Element() - element1['ids'] = ['foo', 'bar'] - element1['test'] = ['this is not a known list attribute'] - element2['ids'] = ['baz', 'qux'] - element2['test'] = ['overwrite'] + element1 = nodes.Element(ids=['foo', 'bar'], test=['a', 'list']) + element2 = nodes.Element(ids=['baz', 'qux'], test=['overwrite']) element1.update(element2) - # 'ids' are appended. + # 'ids' are appended because 'ids' is a known list attribute. self.assertEquals(element1['ids'], ['foo', 'bar', 'baz', 'qux']) # 'test' is overwritten. self.assertEquals(element1['test'], ['overwrite']) + def test_substitute(self): + parent = nodes.Element(ids=['parent']) + child1 = nodes.Element(ids=['child1']) + grandchild = nodes.Element(ids=['grandchild']) + child1 += grandchild + child2 = nodes.Element(ids=['child2']) + twins = [nodes.Element(ids=['twin%s' % i]) for i in (1, 2)] + child2 += twins + child3 = nodes.Element(ids=['child3']) + parent += [child1, child2, child3] + self.assertEquals(parent.pformat(), """\ + + + + + + + +""") + # Replace child1 with the grandchild. + child1.substitute(child1[0]) + self.assertEquals(parent[0], grandchild) + # Assert that 'ids' have been updated. + self.assertEquals(grandchild['ids'], ['grandchild', 'child1']) + # Replace child2 with its children. + child2.substitute(child2[:]) + self.assertEquals(parent[1:3], twins) + # Assert that 'ids' have been propagated to first child. + self.assertEquals(twins[0]['ids'], ['twin1', 'child2']) + self.assertEquals(twins[1]['ids'], ['twin2']) + # Replace child3 with new child. + newchild = nodes.Element(ids=['newchild']) + child3.substitute(newchild) + self.assertEquals(parent[3], newchild) + self.assertEquals(len(parent), 4) + self.assertEquals(newchild['ids'], ['newchild', 'child3']) + class MiscTests(unittest.TestCase): -- cgit v1.2.1 From 8f5edb1d33cbff7e8ce9fe12991f4eab25418681 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 21:14:49 +0000 Subject: added bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3867 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index defe9ef09..f4c89a71e 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -269,6 +269,11 @@ Also see the `SourceForge Bug Tracker`_. node['internal:' + att] = value AttributeError: Text instance has no attribute '__setitem__' +* The "contents" ID of the local table of contents in + ``test/functional/expected/standalone_rst_pseudoxml.txt`` is lost in + the HTML output at + ``test/functional/expected/standalone_rst_html4css1.html``. + .. -- cgit v1.2.1 From 1fb082996542f35c18179afdff35ddba32d698f6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 21:22:16 +0000 Subject: renamed update to update_basic_atts; added history entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3868 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docutils/nodes.py | 17 +++++++---------- test/test_nodes.py | 14 +++++++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index dc473bfb6..475560a1b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -178,6 +178,8 @@ Release 0.3.9 (2005-05-26) - 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: diff --git a/docutils/nodes.py b/docutils/nodes.py index b7ee898c0..b38333321 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -544,18 +544,15 @@ class Element(Node): else: return 1 - def update(self, dict): + def update_basic_atts(self, dict): """ - Update attributes from node or dictionary `dict`, extending - (instead of overwriting) list attributes. + Update basic attributes ('ids', 'names', 'classes', + 'dupnames', but not 'source') from node or dictionary `dict`. """ if isinstance(dict, Node): dict = dict.attributes - for att, value in dict.items(): - if att in self.list_attributes: - self[att].extend(value) - else: - self[att] = value + for att in ('ids', 'classes', 'names', 'dupnames'): + self[att].extend(dict.get(att, [])) def clear(self): self.children = [] @@ -575,9 +572,9 @@ class Element(Node): list of nodes. """ if isinstance(new, Node): - new.update(self) + new.update_basic_atts(self) else: - new[0].update(self) + new[0].update_basic_atts(self) self.parent.replace(self, new) def first_child_matching_class(self, childclass, start=0, end=sys.maxint): diff --git a/test/test_nodes.py b/test/test_nodes.py index deda8455d..effdce2db 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -105,14 +105,14 @@ class ElementTests(unittest.TestCase): {'ids': ['someid']}) self.assert_(element.is_not_default('ids')) - def test_update(self): - element1 = nodes.Element(ids=['foo', 'bar'], test=['a', 'list']) - element2 = nodes.Element(ids=['baz', 'qux'], test=['overwrite']) - element1.update(element2) - # 'ids' are appended because 'ids' is a known list attribute. + def test_update_basic_atts(self): + element1 = nodes.Element(ids=['foo', 'bar'], test=['test1']) + element2 = nodes.Element(ids=['baz', 'qux'], test=['test2']) + element1.update_basic_atts(element2) + # 'ids' are appended because 'ids' is a basic attribute. self.assertEquals(element1['ids'], ['foo', 'bar', 'baz', 'qux']) - # 'test' is overwritten. - self.assertEquals(element1['test'], ['overwrite']) + # 'test' is not overwritten because it is not a basic attribute. + self.assertEquals(element1['test'], ['test1']) def test_substitute(self): parent = nodes.Element(ids=['parent']) -- cgit v1.2.1 From c0c6ea6df4b5fa31abd0d36c73a258b274eccc81 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 21:53:02 +0000 Subject: cover two more cases: update() is passed an empty new list; substitute() is trying to substitute a node for itself git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3869 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 21 +++++++++++++++++---- test/test_nodes.py | 10 ++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index b38333321..4684bfd68 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -552,7 +552,9 @@ class Element(Node): if isinstance(dict, Node): dict = dict.attributes for att in ('ids', 'classes', 'names', 'dupnames'): - self[att].extend(dict.get(att, [])) + for value in dict.get(att, []): + if not value in self[att]: + self[att].append(value) def clear(self): self.children = [] @@ -571,10 +573,21 @@ class Element(Node): Substitute `new` for `self` node, where `new` is a node or list of nodes. """ - if isinstance(new, Node): - new.update_basic_atts(self) + update = new + if not isinstance(new, Node): + # `new` is a list; update first child. + try: + update = new[0] + except IndexError: + update = None + if isinstance(update, Element): + update.update_basic_atts(self) else: - new[0].update_basic_atts(self) + # `update` is a Text node or `new` is an empty list. + # Assert that we aren't losing any attributes. + for att in ('ids', 'names', 'classes', 'dupnames'): + assert not self[att], \ + 'Losing "%s" attribute: %s' % (att, self[att]) self.parent.replace(self, new) def first_child_matching_class(self, childclass, start=0, end=sys.maxint): diff --git a/test/test_nodes.py b/test/test_nodes.py index effdce2db..520abd17a 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -123,7 +123,8 @@ class ElementTests(unittest.TestCase): twins = [nodes.Element(ids=['twin%s' % i]) for i in (1, 2)] child2 += twins child3 = nodes.Element(ids=['child3']) - parent += [child1, child2, child3] + child4 = nodes.Element(ids=['child4']) + parent += [child1, child2, child3, child4] self.assertEquals(parent.pformat(), """\ @@ -132,6 +133,7 @@ class ElementTests(unittest.TestCase): + """) # Replace child1 with the grandchild. child1.substitute(child1[0]) @@ -148,8 +150,12 @@ class ElementTests(unittest.TestCase): newchild = nodes.Element(ids=['newchild']) child3.substitute(newchild) self.assertEquals(parent[3], newchild) - self.assertEquals(len(parent), 4) self.assertEquals(newchild['ids'], ['newchild', 'child3']) + # Crazy but possible case: Substitute child4 for itself. + child4.substitute(child4) + # Make sure the 'child4' ID hasn't been duplicated. + self.assertEquals(child4['ids'], ['child4']) + self.assertEquals(len(parent), 5) class MiscTests(unittest.TestCase): -- cgit v1.2.1 From 469baf29f163924dca499b0591ca6f2addba6b35 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 21:53:49 +0000 Subject: replaced node.parent.replace(node, new) constructs with node.substitute(new) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3870 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/components.py | 2 +- docutils/transforms/misc.py | 2 +- docutils/transforms/parts.py | 2 +- docutils/transforms/peps.py | 6 +++--- docutils/transforms/references.py | 16 ++++++++-------- test/functional/expected/standalone_rst_html4css1.html | 4 ++-- test/functional/expected/standalone_rst_pseudoxml.txt | 4 ++-- test/test_transforms/test_footnotes.py | 4 ++-- test/test_transforms/test_hyperlinks.py | 4 ++-- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index 8f4a267e1..a31f09fb5 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -49,6 +49,6 @@ class Filter(Transform): format = pending.details['format'] component = self.document.transformer.components[component_type] if component.supports(format): - pending.parent.replace(pending, pending.details['nodes']) + pending.substitute(pending.details['nodes']) else: pending.parent.remove(pending) diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index fd8ba6b25..18446944d 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -66,7 +66,7 @@ class ClassAttribute(Transform): % pending.details['directive'], nodes.literal_block(pending.rawsource, pending.rawsource), line=pending.line) - pending.parent.replace(pending, error) + pending.substitute(error) class Transitions(Transform): diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index ff6a0e550..b28c44c71 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -97,7 +97,7 @@ class Contents(Transform): self.backlinks = self.document.settings.toc_backlinks contents = self.build_contents(startnode) if len(contents): - self.startnode.parent.replace(self.startnode, contents) + self.startnode.substitute(contents) else: self.startnode.parent.parent.remove(self.startnode.parent) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 201ce314b..96c265207 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -107,11 +107,11 @@ class Headers(Transform): if name == 'author': for node in para: if isinstance(node, nodes.reference): - node.parent.replace(node, mask_email(node)) + node.substitute(mask_email(node)) elif name == 'discussions-to': for node in para: if isinstance(node, nodes.reference): - node.parent.replace(node, mask_email(node, pep)) + node.substitute(mask_email(node, pep)) elif name in ('replaces', 'replaced-by', 'requires'): newbody = [] space = nodes.Text(' ') @@ -241,7 +241,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): pass def visit_reference(self, node): - node.parent.replace(node, mask_email(node)) + node.substitute(mask_email(node)) def visit_field_list(self, node): if 'rfc2822' in node['classes']: diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 7e75402ae..92ab1b529 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -127,7 +127,7 @@ class AnonymousHyperlinks(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.parent.replace(ref, prb) + ref.substitute(prb) return for ref, target in zip(self.document.anonymous_refs, self.document.anonymous_targets): @@ -281,7 +281,7 @@ class IndirectHyperlinks(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.parent.replace(ref, prb) + ref.substitute(prb) target.resolved = 1 def resolve_indirect_references(self, target): @@ -540,7 +540,7 @@ class Footnotes(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.parent.replace(ref, prb) + ref.substitute(prb) break ref += nodes.Text(label) id = self.document.nameids[label] @@ -580,7 +580,7 @@ class Footnotes(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.parent.replace(ref, prb) + ref.substitute(prb) break footnote = self.document.symbol_footnotes[i] assert len(footnote['ids']) == 1 @@ -674,7 +674,7 @@ class Substitutions(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.parent.replace(ref, prb) + ref.substitute(prb) else: subdef = defs[key] parent = ref.parent @@ -691,7 +691,7 @@ class Substitutions(Transform): and isinstance(parent[index + 1], nodes.Text)): parent.replace(parent[index + 1], parent[index + 1].lstrip()) - parent.replace(ref, subdef.children) + ref.substitute(subdef.children) self.document.substitution_refs = None # release replaced references @@ -732,7 +732,7 @@ class TargetNotes(Transform): if not notes.has_key(target['refuri']): notes[target['refuri']] = footnote nodelist.append(footnote) - self.startnode.parent.replace(self.startnode, nodelist) + self.startnode.substitute(nodelist) def make_target_footnote(self, target, refs, notes): refuri = target['refuri'] @@ -838,7 +838,7 @@ class DanglingReferencesVisitor(nodes.SparseNodeVisitor): node.rawsource, node.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - node.parent.replace(node, prb) + node.substitute(prb) else: del node['refname'] node['refid'] = id diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 2093ab1bb..da34c5fee 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -479,7 +479,7 @@ Here's a reference to the next footnote: [4]Here's an unreferenced footnote, with a reference to a -nonexistent footnote: [5]_. +nonexistent footnote: [5]_.

    @@ -492,7 +492,7 @@ nonexistent footnote: [CIT2002], and a [nonexistent]_ +

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index c2af4aaa9..1e16812f1 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -948,7 +948,7 @@ Here's an unreferenced footnote, with a reference to a nonexistent footnote: - + [5]_ .
    @@ -967,7 +967,7 @@ CIT2002 , and a - + [nonexistent]_ citation. diff --git a/test/test_transforms/test_footnotes.py b/test/test_transforms/test_footnotes.py index f0a1a2ed0..86cbd2110 100755 --- a/test/test_transforms/test_footnotes.py +++ b/test/test_transforms/test_footnotes.py @@ -182,7 +182,7 @@ Mixed anonymous and labelled auto-numbered footnotes: 3 should be 3, \n\ - + [#]_ is one too many, @@ -327,7 +327,7 @@ and labelled auto-numbered footnotes: 6 should be 6, \n\ - + [#]_ is one too many, diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 8d7d6a029..d060043cd 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -145,7 +145,7 @@ circular_ indirect reference circular_ indirect reference - + .. _indirect: circular_ @@ -787,7 +787,7 @@ Duplicate manual footnote labels, with reference ([1]_): Duplicate manual footnote labels, with reference ( - + [1]_ ): -- cgit v1.2.1 From 77b4d3fc857f026b735bd906979900c63f314be6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 22:01:23 +0000 Subject: clarified test text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3871 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_html4css1.html | 5 +++-- test/functional/expected/standalone_rst_latex.tex | 5 +++-- test/functional/expected/standalone_rst_pseudoxml.txt | 5 +++-- test/functional/input/data/standard.txt | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index da34c5fee..4aa0e097d 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -712,8 +712,9 @@ This one starts with a literal block.

    Compound 4, a paragraph.

    -

    Now something really perverted -- a nested compound block. In -LaTeX, the following paragraphs should all be first-line indented:

    +

    Now something really perverted -- a nested compound block. This is +just to test that it works at all; the results don't have to be +meaningful.

    Compound 5, block 1 (a paragraph).

    diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index fcdaea338..aa03b5dc0 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -1140,8 +1140,9 @@ This~one~starts~with~a~literal~block. }\end{quote} Compound 4, a paragraph. -Now something \emph{really} perverted -{}- a nested compound block. In -LaTeX, the following paragraphs should all be first-line indented: +Now something \emph{really} perverted -{}- a nested compound block. This is +just to test that it works at all; the results don't have to be +meaningful. Compound 5, block 1 (a paragraph). diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 1e16812f1..cab207a70 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1351,8 +1351,9 @@ Now something really - perverted -- a nested compound block. In - LaTeX, the following paragraphs should all be first-line indented: + perverted -- a nested compound block. This is + just to test that it works at all; the results don't have to be + meaningful. Compound 5, block 1 (a paragraph). diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 140be35c7..85016529f 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -612,8 +612,9 @@ Another compound statement: Compound 4, a paragraph. -Now something *really* perverted -- a nested compound block. In -LaTeX, the following paragraphs should all be first-line indented: +Now something *really* perverted -- a nested compound block. This is +just to test that it works at all; the results don't have to be +meaningful. .. compound:: -- cgit v1.2.1 From 8252a44b36b80dc64f70b92666b525f5b44f2d4c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 22:23:43 +0000 Subject: added writer_aux module containing Compound transform, which flattens the compound paragraph structure git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3872 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/writer_aux.py | 52 ++++++++++++++++++++++++++++++ test/test_transforms/test_writer_aux.py | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 docutils/transforms/writer_aux.py create mode 100755 test/test_transforms/test_writer_aux.py diff --git a/docutils/transforms/writer_aux.py b/docutils/transforms/writer_aux.py new file mode 100644 index 000000000..99e961243 --- /dev/null +++ b/docutils/transforms/writer_aux.py @@ -0,0 +1,52 @@ +# Authors: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# 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 +from docutils.transforms import Transform + + +class Compound(Transform): + + """ + Flatten all compound paragraphs. For example, transform :: + + + + + + + into :: + + + + + """ + + default_priority = 810 + + def apply(self): + for compound in self.document.traverse(nodes.compound): + first_child = 1 + for child in compound: + if first_child: + if not isinstance(child, nodes.Invisible): + first_child = 0 + else: + child['classes'].append('continued') + # Substitute children for compound. + compound.substitute(compound[:]) diff --git a/test/test_transforms/test_writer_aux.py b/test/test_transforms/test_writer_aux.py new file mode 100755 index 000000000..34b723241 --- /dev/null +++ b/test/test_transforms/test_writer_aux.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python + +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Test module for writer_aux transforms. +""" + +from docutils.transforms import writer_aux +from __init__ import DocutilsTestSupport +from docutils.parsers.rst import Parser + +def suite(): + parser = Parser() + s = DocutilsTestSupport.TransformTestSuite(parser) + s.generateTests(totest) + return s + + +totest = {} + +totest['compound'] = ((writer_aux.Compound,), [ +["""\ +.. class:: compound + +.. compound:: + + .. class:: paragraph1 + + Paragraph 1. + + .. class:: paragraph2 + + Paragraph 2. + + Block quote. +""", +"""\ + + + Paragraph 1. + + Paragraph 2. + + + Block quote. +"""], +]) + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 25decd0059501f1581c3079896a21626fcdb8174 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 22:26:19 +0000 Subject: updated docs: history and tranform list git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3873 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 ++++ docs/ref/transforms.txt | 2 ++ docutils/writers/newlatex2e.py | 53 ++++++++++++++++++++++++++++-------------- tools/stylesheets/latex.tex | 7 ++++-- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 475560a1b..4af33a6e3 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -86,6 +86,11 @@ Changes Since 0.3.9 - Removed universal.FinalChecks transform (logic has been moved to several new transforms). +* docutils/transforms/writer_aux.py: Added to project; auxiliary + transforms for writers. + + - Added ``Compound`` transform, which flattens compound paragraphs. + * docutils/writers/html4css1.py: - Added support for image width and height units. diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index cd9cf3fe8..05185d6ef 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -71,6 +71,8 @@ peps.PEPZero peps.Headers (t/p) 760 components.Filter "meta" (d/p) 780 +writer_aux.Compound newlatex2e (w) 810 + universal.Decorations Transformer 820 misc.Transitions standalone (r), pep (r) 830 diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 4d00e6906..afe7b7599 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -21,6 +21,7 @@ from types import ListType import docutils from docutils import nodes, writers, utils +from docutils.transforms import writer_aux class Writer(writers.Writer): @@ -73,7 +74,7 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" - default_transforms = () + default_transforms = (writer_aux.Compound,) def __init__(self): writers.Writer.__init__(self) @@ -211,6 +212,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dtitleastext}{x} % variable') a(r'\providecommand{\Dsinglebackref}{} % variable') a(r'\providecommand{\Dmultiplebackrefs}{} % variable') + a(r'\providecommand{\Dparagraphindented}{false} % variable') a('\n\n') # Get comprehensive Unicode map. @@ -354,6 +356,29 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def depart_Text(self, node): pass + def is_indented(self, paragraph): + """Return true if `paragraph` should be first-line-indented.""" + assert isinstance(paragraph, nodes.paragraph) + siblings = [n for n in paragraph.parent if + self.is_visible(n) and not isinstance(n, nodes.Titular)] + index = siblings.index(paragraph) + # Special handling for children of compound paragraphs: + if isinstance(paragraph.parent, nodes.compound): + # Indent only the first paragraph in a `compound` node. + if index > 0: + return 0 + else: + return self.is_indented(node.parent) + # Indent all but the first paragraphs. + return index > 1 + + def visit_compound(self, node): + impossible + + def before_paragraph(self, node): + self.append(r'\renewcommand{\Dparagraphindented}{%s}' + % (self.is_indented(node) and 'true' or 'false')) + def before_title(self, node): self.append(r'\renewcommand{\Dtitleastext}{%s}' % self.encode(node.astext())) @@ -714,15 +739,13 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): # Assume raw nodes to be invisible. isinstance(node, nodes.raw) or # Floating image or figure. - node.get('align', None) in ('left', 'right'))) + node.get('align') in ('left', 'right'))) def is_visible(self, node): return not self.is_invisible(node) def needs_space(self, node): - """ - Two nodes for which `needs_space` is true need auxiliary space. - """ + """Two nodes for which `needs_space` is true need auxiliary space.""" # Return true if node is a visible block-level element. return ((isinstance(node, nodes.Body) or isinstance(node, nodes.topic)) and @@ -731,7 +754,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): def always_needs_space(self, node): """ - Always add space around nodes for which `always_needs_space` + Always add space around nodes for which `always_needs_space()` is true, regardless of whether the other node needs space as well. (E.g. transition next to section.) """ @@ -752,16 +775,12 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): ascend=0, siblings=1, descend=0, condition=self.is_visible) # Insert space if necessary. - if (self.always_needs_space(node) or - self.always_needs_space(next_node) or - self.needs_space(node) and self.needs_space(next_node)): - if isinstance(next_node, nodes.paragraph): - if isinstance(node, nodes.paragraph): - # Space between paragraphs. - self.append(r'\Dparagraphspace') - else: - # Space in front of a paragraph. - self.append(r'\Dauxiliaryparspace') + if (self.needs_space(node) and self.needs_space(next_node) or + self.always_needs_space(node) or + self.always_needs_space(next_node)): + if isinstance(node, nodes.paragraph) and isinstance(next_node, nodes.paragraph): + # Space between paragraphs. + self.append(r'\Dparagraphspace') else: - # Space in front of something else than a paragraph. + # One of the elements is not a paragraph. self.append(r'\Dauxiliaryspace') diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index aee91b56f..da8af083f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -100,7 +100,7 @@ \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% \par\noindent% } -\providecommand{\Dauxiliaryparspace}{% +\providecommand{\Dauxiliaryparspace}{% XXX REMOVEME \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% \par% } @@ -247,7 +247,10 @@ }}}}% } -\providecommand{\DNparagraph}[1]{#1} +\providecommand{\DNparagraph}[1]{% + \ifthenelse{\equal{\Dparagraphindented}{true}}{\indent}{\noindent}% + #1% +} \providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} \providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} \providecommand{\Dtopictitle}[1]{% -- cgit v1.2.1 From 0fd701f2bbb030913b466c209733dccc733a1aa8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 11 Sep 2005 22:32:23 +0000 Subject: polished new LaTeX writer; sorry, the last check-in accidentally contained the two newlatex files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3874 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 12 ++---------- tools/stylesheets/latex.tex | 4 ---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index afe7b7599..3ea14eaca 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -362,19 +362,11 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): siblings = [n for n in paragraph.parent if self.is_visible(n) and not isinstance(n, nodes.Titular)] index = siblings.index(paragraph) - # Special handling for children of compound paragraphs: - if isinstance(paragraph.parent, nodes.compound): - # Indent only the first paragraph in a `compound` node. - if index > 0: - return 0 - else: - return self.is_indented(node.parent) + if 'continued' in paragraph['classes']: + return 0 # Indent all but the first paragraphs. return index > 1 - def visit_compound(self, node): - impossible - def before_paragraph(self, node): self.append(r'\renewcommand{\Dparagraphindented}{%s}' % (self.is_indented(node) and 'true' or 'false')) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index da8af083f..515c34099 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -100,10 +100,6 @@ \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% \par\noindent% } -\providecommand{\Dauxiliaryparspace}{% XXX REMOVEME - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \par% -} \providecommand{\Dparagraphspace}{\par} \providecommand{\Dneedvspace}{true} -- cgit v1.2.1 From b07ac8b595e3217c26ee6eb04ff648511a99dc0e Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 12 Sep 2005 21:22:07 +0000 Subject: more tests, more handling for edge cases, some polishing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3875 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 9 +-- test/functional/input/data/latex.txt | 114 +++++++++++++++++++++++++++++------ tools/stylesheets/latex.tex | 50 ++++++++++++--- 3 files changed, 142 insertions(+), 31 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 3ea14eaca..aaafa0424 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -362,10 +362,11 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): siblings = [n for n in paragraph.parent if self.is_visible(n) and not isinstance(n, nodes.Titular)] index = siblings.index(paragraph) - if 'continued' in paragraph['classes']: + if ('continued' in paragraph['classes'] or + index > 0 and isinstance(siblings[index-1], nodes.transition)): return 0 # Indent all but the first paragraphs. - return index > 1 + return index > 0 def before_paragraph(self, node): self.append(r'\renewcommand{\Dparagraphindented}{%s}' @@ -492,7 +493,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): self.process_backlinks(node, 'citation') def before_table(self, node): - # A tables contains exactly one tgroup. See before_tgroup. + # A table contains exactly one tgroup. See before_tgroup. pass def before_tgroup(self, node): @@ -507,7 +508,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): for w in widths: # 0.93 is probably wrong in many cases. XXX Find a # solution which works *always*. - tablespec += r'p{%s\linewidth}|' % (0.93 * w / + tablespec += r'p{%s\textwidth}|' % (0.93 * w / max(total_width, 60)) self.append(r'\Dmaketable{%s}{' % tablespec) self.context.append('}') diff --git a/test/functional/input/data/latex.txt b/test/functional/input/data/latex.txt index ee9c02a4d..20d59db1e 100644 --- a/test/functional/input/data/latex.txt +++ b/test/functional/input/data/latex.txt @@ -83,28 +83,108 @@ Nested Elements :Field list: | Line | Block -:Another field: * Bullet - * list +:Field 2: * Bullet + * list +:Another (longer) field: * Bullet + * list +:Yet another long field: + * .. comment + + Bullet + + .. comment + + * .. comment + + list + + .. comment + +:Field: * This + + is + + a + + * bullet + + list + +:Field: * | This is + | a bullet + * | list with + | line blocks +:Last field: Last field. * * * * * * * * Deeply nested list. 1. 2. 3. 4. 5. 6. 7. 8. Deeply nested list. -+---------------+ -| | Line block | -| | -| * Bullet list | -| | -| :: | -| | -| Literal | -| block | -+---------------+ -| :Field 1: | -| Text. | -| :Field 2: | -| More text. | -+---------------+ ++-----------------+ +| | Line block | +| | +| * Bullet list | +| | +| :: | +| | +| Literal | +| block | ++-----------------+ +| :Field 1: | +| Text. | +| :Field 2: | +| More text. | ++-----------------+ +| +-------+-----+ | +| | A |* foo| | +| | nested| | | +| | table.|* bar| | +| +-------+-----+ | ++-----------------+ +| This is a | +| paragraph. | +| | +| +-------+-----+ | +| | A |* foo| | +| | nested| | | +| | table.|* bar| | +| +-------+-----+ | +| | +| Another longer | +| paragraph. | ++-----------------+ +| * A list. | +| * A list. | +| | +| +-------+-----+ | +| | A |* foo| | +| | nested| | | +| | table.|* bar| | +| +-------+-----+ | +| | +| * Another list. | +| * Another list. | ++-----------------+ +| Foo | +| | +| Bar | ++-----------------+ +| * Foo | +| | +| * Bar | ++-----------------+ +| * This is a | +| paragraph. | +| | +| This is a | +| paragraph. | +| | +| * This is a | +| paragraph. | +| | +| This is a | +| paragraph. | ++-----------------+ Images diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index 515c34099..eb19ddb8e 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -428,7 +428,7 @@ \Dprovidelength{\Dlistspacing}{0.8\baselineskip} \providecommand{\Dsetlistrightmargin}{% - \ifthenelse{\lengthtest{\linewidth>10em}}{% + \ifthenelse{\lengthtest{\linewidth>12em}}{% % Equal margins. \setlength{\rightmargin}{\leftmargin}% }{% @@ -842,11 +842,23 @@ % 1. Table spec (like "|p|p|"). % 2. Table contents. {% - \renewcommand{\Dinsidetabular}{true}% - \begin{longtable}{#1}% - \hline% - #2% - \end{longtable}% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Inside longtable; we cannot have nested longtables. + % The following \vspace *adds* vertical space. I have no idea + % how to do this in a cleaner way. + %\mbox{}\par\vspace{-0.5em}% + \begin{tabular}{#1}% + \hline% + #2% + \end{tabular}% + %\par\noindent\vspace{-0.5em}% + }{% + \renewcommand{\Dinsidetabular}{true}% + \begin{longtable}{#1}% + \hline% + #2% + \end{longtable}% + }% }% } \providecommand{\DNthead}[1]{% @@ -857,20 +869,38 @@ #1\tabularnewline% \hline% } +\providecommand{\Dinsidemulticolumn}{false} +\providecommand{\Dcompensatingmulticol}[3]{% + \multicolumn{#1}{#2}{% + {% + \renewcommand{\Dinsidemulticolumn}{true}% + % Compensate for weird missing vertical space at top of paragraph. + \raisebox{-2.5pt}{#3}% + }% + }% +} \providecommand{\Dcolspan}[2]{% % Take care of the morecols attribute (but incremented by 1). - &\multicolumn{#1}{l|}{#2}% + &% + \Dcompensatingmulticol{#1}{l|}{#2}% } \providecommand{\Dcolspanleft}[2]{% % Like \Dmorecols, but called for the leftmost entries in a table % row. - \multicolumn{#1}{|l|}{#2}% + \Dcompensatingmulticol{#1}{|l|}{#2}% } \providecommand{\Dsubsequententry}[1]{% % } -% \DNentry is not used because we set the ampersand ("&") in the -% \DAcolspan... macros. +\providecommand{\DNentry}[1]{% + % The following sequence adds minimal vertical space above the top + % lines of the first cell paragraph, so that vertical space is + % balanced at the top and bottom of table cells. + \ifthenelse{\equal{\Dinsidemulticolumn}{false}}{% + \vspace{-1em}\vspace{-\parskip}\par% + }{}% + #1% +} \providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} \providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} -- cgit v1.2.1 From 245f008322533935ac8e50a8b42d2f303e8c2f68 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 13 Sep 2005 17:23:28 +0000 Subject: added reference to current thread about adaptable file extensions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3876 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index aae1b0d83..18689dd8b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -715,11 +715,13 @@ __ rst/alternatives.html#or-not-to-do This may not be just a parser issue; it may need framework support. Mailing list threads: `Images in both HTML and LaTeX`__ (especially - `this summary of Felix's objections`__), `more-universal links?`__ + `this summary of Felix's objections`__), `more-universal links?`__, + `Output-format-sensitive link targets?`__ __ http://thread.gmane.org/gmane.text.docutils.user/1239 __ http://article.gmane.org/gmane.text.docutils.user/1278 __ http://thread.gmane.org/gmane.text.docutils.user/1915 + __ http://thread.gmane.org/gmane.text.docutils.user/2438 * Implement the header row separator modification to table.el. (Wrote to Takaaki Ota & the table.el mailing list on 2001-08-12, suggesting -- cgit v1.2.1 From 37341b9e7726b33a7c3899587e0c98ae50734e5b Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 15 Sep 2005 14:16:04 +0000 Subject: fixed bug with expose_internals setting and Text nodes (exposed by the "rawsource" internal attribute) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3877 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 19 ------------------- docutils/transforms/universal.py | 5 ++++- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index f4c89a71e..8e2473df6 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -251,30 +251,11 @@ Also see the `SourceForge Bug Tracker`_. Hyperlink targets with duplicate names should be assigned new IDs unrelated to the target names (i.e., "id"-prefix serial IDs). -* _`expose_internals` is (partially) broken:: - - $ echo x | rst2pseudoxml.py --expose-internal-attribute rawsource - Traceback (most recent call last): - File "/home/felix/bin/rst2pseudoxml.py", line 25, in ? - publish_cmdline(description=description) - File "/home/felix/.python/lib/docutils/core.py", line 341, in publish_cmdline - config_section=config_section, enable_exit_status=enable_exit_status) - File "/home/felix/.python/lib/docutils/core.py", line 217, in publish - self.apply_transforms() - File "/home/felix/.python/lib/docutils/core.py", line 186, in apply_transforms - self.document.transformer.apply_transforms() - File "/home/felix/.python/lib/docutils/transforms/__init__.py", line 192, in apply_transforms - transform.apply(**kwargs) - File "/home/felix/.python/lib/docutils/transforms/universal.py", line 98, in apply - node['internal:' + att] = value - AttributeError: Text instance has no attribute '__setitem__' - * The "contents" ID of the local table of contents in ``test/functional/expected/standalone_rst_pseudoxml.txt`` is lost in the HTML output at ``test/functional/expected/standalone_rst_html4css1.html``. - .. Local Variables: diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py index 2766ed41b..a6a0462cb 100644 --- a/docutils/transforms/universal.py +++ b/docutils/transforms/universal.py @@ -88,10 +88,13 @@ class ExposeInternals(Transform): """ 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(): + 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: -- cgit v1.2.1 From 6d0b86cbbac0c9d61343db1fdb490b5a204a7981 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 15 Sep 2005 14:16:22 +0000 Subject: created docutils/writers/support directory for supporting modules and data files; moved unicode_latex.py there git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3878 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 4 +- docutils/writers/support/__init__.py | 1 + docutils/writers/support/unicode_latex.py | 2371 +++++++++++++++++++++++++++++ docutils/writers/unicode_latex.py | 2371 ----------------------------- 4 files changed, 2374 insertions(+), 2373 deletions(-) create mode 100644 docutils/writers/support/__init__.py create mode 100644 docutils/writers/support/unicode_latex.py delete mode 100644 docutils/writers/unicode_latex.py diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index aaafa0424..c934ff972 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -21,6 +21,7 @@ from types import ListType import docutils from docutils import nodes, writers, utils +from docutils.writers.support import unicode_latex from docutils.transforms import writer_aux @@ -215,8 +216,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dparagraphindented}{false} % variable') a('\n\n') - # Get comprehensive Unicode map. - from unicode_latex import unicode_map + unicode_map = unicode_latex.unicode_map # comprehensive Unicode map # Fix problems with unimap.py. unicode_map.update({ # We have AE or T1 encoding, so "``" etc. work. The macros diff --git a/docutils/writers/support/__init__.py b/docutils/writers/support/__init__.py new file mode 100644 index 000000000..87197468a --- /dev/null +++ b/docutils/writers/support/__init__.py @@ -0,0 +1 @@ +# This file is needed for Python to treat this directory as a package. diff --git a/docutils/writers/support/unicode_latex.py b/docutils/writers/support/unicode_latex.py new file mode 100644 index 000000000..2998178f4 --- /dev/null +++ b/docutils/writers/support/unicode_latex.py @@ -0,0 +1,2371 @@ +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This file has been placed in the public domain. + +# This is a mapping of Unicode characters to LaTeX equivalents. +# The information has been extracted from +# , written by +# David Carlisle and Sebastian Rahtz. +# +# The extraction has been done by the "create_unimap.py" script +# located at . + +unicode_map = {u'\xa0': '$~$', +u'\xa1': '{\\textexclamdown}', +u'\xa2': '{\\textcent}', +u'\xa3': '{\\textsterling}', +u'\xa4': '{\\textcurrency}', +u'\xa5': '{\\textyen}', +u'\xa6': '{\\textbrokenbar}', +u'\xa7': '{\\textsection}', +u'\xa8': '{\\textasciidieresis}', +u'\xa9': '{\\textcopyright}', +u'\xaa': '{\\textordfeminine}', +u'\xab': '{\\guillemotleft}', +u'\xac': '$\\lnot$', +u'\xad': '$\\-$', +u'\xae': '{\\textregistered}', +u'\xaf': '{\\textasciimacron}', +u'\xb0': '{\\textdegree}', +u'\xb1': '$\\pm$', +u'\xb2': '${^2}$', +u'\xb3': '${^3}$', +u'\xb4': '{\\textasciiacute}', +u'\xb5': '$\\mathrm{\\mu}$', +u'\xb6': '{\\textparagraph}', +u'\xb7': '$\\cdot$', +u'\xb8': '{\\c{}}', +u'\xb9': '${^1}$', +u'\xba': '{\\textordmasculine}', +u'\xbb': '{\\guillemotright}', +u'\xbc': '{\\textonequarter}', +u'\xbd': '{\\textonehalf}', +u'\xbe': '{\\textthreequarters}', +u'\xbf': '{\\textquestiondown}', +u'\xc0': '{\\`{A}}', +u'\xc1': "{\\'{A}}", +u'\xc2': '{\\^{A}}', +u'\xc3': '{\\~{A}}', +u'\xc4': '{\\"{A}}', +u'\xc5': '{\\AA}', +u'\xc6': '{\\AE}', +u'\xc7': '{\\c{C}}', +u'\xc8': '{\\`{E}}', +u'\xc9': "{\\'{E}}", +u'\xca': '{\\^{E}}', +u'\xcb': '{\\"{E}}', +u'\xcc': '{\\`{I}}', +u'\xcd': "{\\'{I}}", +u'\xce': '{\\^{I}}', +u'\xcf': '{\\"{I}}', +u'\xd0': '{\\DH}', +u'\xd1': '{\\~{N}}', +u'\xd2': '{\\`{O}}', +u'\xd3': "{\\'{O}}", +u'\xd4': '{\\^{O}}', +u'\xd5': '{\\~{O}}', +u'\xd6': '{\\"{O}}', +u'\xd7': '{\\texttimes}', +u'\xd8': '{\\O}', +u'\xd9': '{\\`{U}}', +u'\xda': "{\\'{U}}", +u'\xdb': '{\\^{U}}', +u'\xdc': '{\\"{U}}', +u'\xdd': "{\\'{Y}}", +u'\xde': '{\\TH}', +u'\xdf': '{\\ss}', +u'\xe0': '{\\`{a}}', +u'\xe1': "{\\'{a}}", +u'\xe2': '{\\^{a}}', +u'\xe3': '{\\~{a}}', +u'\xe4': '{\\"{a}}', +u'\xe5': '{\\aa}', +u'\xe6': '{\\ae}', +u'\xe7': '{\\c{c}}', +u'\xe8': '{\\`{e}}', +u'\xe9': "{\\'{e}}", +u'\xea': '{\\^{e}}', +u'\xeb': '{\\"{e}}', +u'\xec': '{\\`{\\i}}', +u'\xed': "{\\'{\\i}}", +u'\xee': '{\\^{\\i}}', +u'\xef': '{\\"{\\i}}', +u'\xf0': '{\\dh}', +u'\xf1': '{\\~{n}}', +u'\xf2': '{\\`{o}}', +u'\xf3': "{\\'{o}}", +u'\xf4': '{\\^{o}}', +u'\xf5': '{\\~{o}}', +u'\xf6': '{\\"{o}}', +u'\xf7': '$\\div$', +u'\xf8': '{\\o}', +u'\xf9': '{\\`{u}}', +u'\xfa': "{\\'{u}}", +u'\xfb': '{\\^{u}}', +u'\xfc': '{\\"{u}}', +u'\xfd': "{\\'{y}}", +u'\xfe': '{\\th}', +u'\xff': '{\\"{y}}', +u'\u0100': '{\\={A}}', +u'\u0101': '{\\={a}}', +u'\u0102': '{\\u{A}}', +u'\u0103': '{\\u{a}}', +u'\u0104': '{\\k{A}}', +u'\u0105': '{\\k{a}}', +u'\u0106': "{\\'{C}}", +u'\u0107': "{\\'{c}}", +u'\u0108': '{\\^{C}}', +u'\u0109': '{\\^{c}}', +u'\u010a': '{\\.{C}}', +u'\u010b': '{\\.{c}}', +u'\u010c': '{\\v{C}}', +u'\u010d': '{\\v{c}}', +u'\u010e': '{\\v{D}}', +u'\u010f': '{\\v{d}}', +u'\u0110': '{\\DJ}', +u'\u0111': '{\\dj}', +u'\u0112': '{\\={E}}', +u'\u0113': '{\\={e}}', +u'\u0114': '{\\u{E}}', +u'\u0115': '{\\u{e}}', +u'\u0116': '{\\.{E}}', +u'\u0117': '{\\.{e}}', +u'\u0118': '{\\k{E}}', +u'\u0119': '{\\k{e}}', +u'\u011a': '{\\v{E}}', +u'\u011b': '{\\v{e}}', +u'\u011c': '{\\^{G}}', +u'\u011d': '{\\^{g}}', +u'\u011e': '{\\u{G}}', +u'\u011f': '{\\u{g}}', +u'\u0120': '{\\.{G}}', +u'\u0121': '{\\.{g}}', +u'\u0122': '{\\c{G}}', +u'\u0123': '{\\c{g}}', +u'\u0124': '{\\^{H}}', +u'\u0125': '{\\^{h}}', +u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', +u'\u0127': '$\\Elzxh$', +u'\u0128': '{\\~{I}}', +u'\u0129': '{\\~{\\i}}', +u'\u012a': '{\\={I}}', +u'\u012b': '{\\={\\i}}', +u'\u012c': '{\\u{I}}', +u'\u012d': '{\\u{\\i}}', +u'\u012e': '{\\k{I}}', +u'\u012f': '{\\k{i}}', +u'\u0130': '{\\.{I}}', +u'\u0131': '{\\i}', +u'\u0132': '{IJ}', +u'\u0133': '{ij}', +u'\u0134': '{\\^{J}}', +u'\u0135': '{\\^{\\j}}', +u'\u0136': '{\\c{K}}', +u'\u0137': '{\\c{k}}', +u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', +u'\u0139': "{\\'{L}}", +u'\u013a': "{\\'{l}}", +u'\u013b': '{\\c{L}}', +u'\u013c': '{\\c{l}}', +u'\u013d': '{\\v{L}}', +u'\u013e': '{\\v{l}}', +u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', +u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', +u'\u0141': '{\\L}', +u'\u0142': '{\\l}', +u'\u0143': "{\\'{N}}", +u'\u0144': "{\\'{n}}", +u'\u0145': '{\\c{N}}', +u'\u0146': '{\\c{n}}', +u'\u0147': '{\\v{N}}', +u'\u0148': '{\\v{n}}', +u'\u0149': "{'n}", +u'\u014a': '{\\NG}', +u'\u014b': '{\\ng}', +u'\u014c': '{\\={O}}', +u'\u014d': '{\\={o}}', +u'\u014e': '{\\u{O}}', +u'\u014f': '{\\u{o}}', +u'\u0150': '{\\H{O}}', +u'\u0151': '{\\H{o}}', +u'\u0152': '{\\OE}', +u'\u0153': '{\\oe}', +u'\u0154': "{\\'{R}}", +u'\u0155': "{\\'{r}}", +u'\u0156': '{\\c{R}}', +u'\u0157': '{\\c{r}}', +u'\u0158': '{\\v{R}}', +u'\u0159': '{\\v{r}}', +u'\u015a': "{\\'{S}}", +u'\u015b': "{\\'{s}}", +u'\u015c': '{\\^{S}}', +u'\u015d': '{\\^{s}}', +u'\u015e': '{\\c{S}}', +u'\u015f': '{\\c{s}}', +u'\u0160': '{\\v{S}}', +u'\u0161': '{\\v{s}}', +u'\u0162': '{\\c{T}}', +u'\u0163': '{\\c{t}}', +u'\u0164': '{\\v{T}}', +u'\u0165': '{\\v{t}}', +u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', +u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', +u'\u0168': '{\\~{U}}', +u'\u0169': '{\\~{u}}', +u'\u016a': '{\\={U}}', +u'\u016b': '{\\={u}}', +u'\u016c': '{\\u{U}}', +u'\u016d': '{\\u{u}}', +u'\u016e': '{\\r{U}}', +u'\u016f': '{\\r{u}}', +u'\u0170': '{\\H{U}}', +u'\u0171': '{\\H{u}}', +u'\u0172': '{\\k{U}}', +u'\u0173': '{\\k{u}}', +u'\u0174': '{\\^{W}}', +u'\u0175': '{\\^{w}}', +u'\u0176': '{\\^{Y}}', +u'\u0177': '{\\^{y}}', +u'\u0178': '{\\"{Y}}', +u'\u0179': "{\\'{Z}}", +u'\u017a': "{\\'{z}}", +u'\u017b': '{\\.{Z}}', +u'\u017c': '{\\.{z}}', +u'\u017d': '{\\v{Z}}', +u'\u017e': '{\\v{z}}', +u'\u0192': '$f$', +u'\u0195': '{\\texthvlig}', +u'\u019e': '{\\textnrleg}', +u'\u01aa': '$\\eth$', +u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', +u'\u01c2': '{\\textdoublepipe}', +u'\u01f5': "{\\'{g}}", +u'\u0250': '$\\Elztrna$', +u'\u0252': '$\\Elztrnsa$', +u'\u0254': '$\\Elzopeno$', +u'\u0256': '$\\Elzrtld$', +u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', +u'\u0259': '$\\Elzschwa$', +u'\u025b': '$\\varepsilon$', +u'\u0261': '{g}', +u'\u0263': '$\\Elzpgamma$', +u'\u0264': '$\\Elzpbgam$', +u'\u0265': '$\\Elztrnh$', +u'\u026c': '$\\Elzbtdl$', +u'\u026d': '$\\Elzrtll$', +u'\u026f': '$\\Elztrnm$', +u'\u0270': '$\\Elztrnmlr$', +u'\u0271': '$\\Elzltlmr$', +u'\u0272': '{\\Elzltln}', +u'\u0273': '$\\Elzrtln$', +u'\u0277': '$\\Elzclomeg$', +u'\u0278': '{\\textphi}', +u'\u0279': '$\\Elztrnr$', +u'\u027a': '$\\Elztrnrl$', +u'\u027b': '$\\Elzrttrnr$', +u'\u027c': '$\\Elzrl$', +u'\u027d': '$\\Elzrtlr$', +u'\u027e': '$\\Elzfhr$', +u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', +u'\u0282': '$\\Elzrtls$', +u'\u0283': '$\\Elzesh$', +u'\u0287': '$\\Elztrnt$', +u'\u0288': '$\\Elzrtlt$', +u'\u028a': '$\\Elzpupsil$', +u'\u028b': '$\\Elzpscrv$', +u'\u028c': '$\\Elzinvv$', +u'\u028d': '$\\Elzinvw$', +u'\u028e': '$\\Elztrny$', +u'\u0290': '$\\Elzrtlz$', +u'\u0292': '$\\Elzyogh$', +u'\u0294': '$\\Elzglst$', +u'\u0295': '$\\Elzreglst$', +u'\u0296': '$\\Elzinglst$', +u'\u029e': '{\\textturnk}', +u'\u02a4': '$\\Elzdyogh$', +u'\u02a7': '$\\Elztesh$', +u'\u02bc': "{'}", +u'\u02c7': '{\\textasciicaron}', +u'\u02c8': '$\\Elzverts$', +u'\u02cc': '$\\Elzverti$', +u'\u02d0': '$\\Elzlmrk$', +u'\u02d1': '$\\Elzhlmrk$', +u'\u02d2': '$\\Elzsbrhr$', +u'\u02d3': '$\\Elzsblhr$', +u'\u02d4': '$\\Elzrais$', +u'\u02d5': '$\\Elzlow$', +u'\u02d8': '{\\textasciibreve}', +u'\u02d9': '{\\textperiodcentered}', +u'\u02da': '{\\r{}}', +u'\u02db': '{\\k{}}', +u'\u02dc': '{\\texttildelow}', +u'\u02dd': '{\\H{}}', +u'\u02e5': '{\\tone{55}}', +u'\u02e6': '{\\tone{44}}', +u'\u02e7': '{\\tone{33}}', +u'\u02e8': '{\\tone{22}}', +u'\u02e9': '{\\tone{11}}', +u'\u0300': '{\\`}', +u'\u0301': "{\\'}", +u'\u0302': '{\\^}', +u'\u0303': '{\\~}', +u'\u0304': '{\\=}', +u'\u0306': '{\\u}', +u'\u0307': '{\\.}', +u'\u0308': '{\\"}', +u'\u030a': '{\\r}', +u'\u030b': '{\\H}', +u'\u030c': '{\\v}', +u'\u030f': '{\\cyrchar\\C}', +u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', +u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', +u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', +u'\u0321': '$\\Elzpalh$', +u'\u0322': '{\\Elzrh}', +u'\u0327': '{\\c}', +u'\u0328': '{\\k}', +u'\u032a': '$\\Elzsbbrg$', +u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', +u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', +u'\u0335': '{\\Elzxl}', +u'\u0336': '{\\Elzbar}', +u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', +u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', +u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', +u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', +u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', +u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', +u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', +u'\u0386': "{\\'{A}}", +u'\u0388': "{\\'{E}}", +u'\u0389': "{\\'{H}}", +u'\u038a': "{\\'{}{I}}", +u'\u038c': "{\\'{}O}", +u'\u038e': "$\\mathrm{'Y}$", +u'\u038f': "$\\mathrm{'\\Omega}$", +u'\u0390': '$\\acute{\\ddot{\\iota}}$', +u'\u0391': '$\\Alpha$', +u'\u0392': '$\\Beta$', +u'\u0393': '$\\Gamma$', +u'\u0394': '$\\Delta$', +u'\u0395': '$\\Epsilon$', +u'\u0396': '$\\Zeta$', +u'\u0397': '$\\Eta$', +u'\u0398': '$\\Theta$', +u'\u0399': '$\\Iota$', +u'\u039a': '$\\Kappa$', +u'\u039b': '$\\Lambda$', +u'\u039c': '$M$', +u'\u039d': '$N$', +u'\u039e': '$\\Xi$', +u'\u039f': '$O$', +u'\u03a0': '$\\Pi$', +u'\u03a1': '$\\Rho$', +u'\u03a3': '$\\Sigma$', +u'\u03a4': '$\\Tau$', +u'\u03a5': '$\\Upsilon$', +u'\u03a6': '$\\Phi$', +u'\u03a7': '$\\Chi$', +u'\u03a8': '$\\Psi$', +u'\u03a9': '$\\Omega$', +u'\u03aa': '$\\mathrm{\\ddot{I}}$', +u'\u03ab': '$\\mathrm{\\ddot{Y}}$', +u'\u03ac': "{\\'{$\\alpha$}}", +u'\u03ad': '$\\acute{\\epsilon}$', +u'\u03ae': '$\\acute{\\eta}$', +u'\u03af': '$\\acute{\\iota}$', +u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', +u'\u03b1': '$\\alpha$', +u'\u03b2': '$\\beta$', +u'\u03b3': '$\\gamma$', +u'\u03b4': '$\\delta$', +u'\u03b5': '$\\epsilon$', +u'\u03b6': '$\\zeta$', +u'\u03b7': '$\\eta$', +u'\u03b8': '{\\texttheta}', +u'\u03b9': '$\\iota$', +u'\u03ba': '$\\kappa$', +u'\u03bb': '$\\lambda$', +u'\u03bc': '$\\mu$', +u'\u03bd': '$\\nu$', +u'\u03be': '$\\xi$', +u'\u03bf': '$o$', +u'\u03c0': '$\\pi$', +u'\u03c1': '$\\rho$', +u'\u03c2': '$\\varsigma$', +u'\u03c3': '$\\sigma$', +u'\u03c4': '$\\tau$', +u'\u03c5': '$\\upsilon$', +u'\u03c6': '$\\varphi$', +u'\u03c7': '$\\chi$', +u'\u03c8': '$\\psi$', +u'\u03c9': '$\\omega$', +u'\u03ca': '$\\ddot{\\iota}$', +u'\u03cb': '$\\ddot{\\upsilon}$', +u'\u03cc': "{\\'{o}}", +u'\u03cd': '$\\acute{\\upsilon}$', +u'\u03ce': '$\\acute{\\omega}$', +u'\u03d0': '{\\Pisymbol{ppi022}{87}}', +u'\u03d1': '{\\textvartheta}', +u'\u03d2': '$\\Upsilon$', +u'\u03d5': '$\\phi$', +u'\u03d6': '$\\varpi$', +u'\u03da': '$\\Stigma$', +u'\u03dc': '$\\Digamma$', +u'\u03dd': '$\\digamma$', +u'\u03de': '$\\Koppa$', +u'\u03e0': '$\\Sampi$', +u'\u03f0': '$\\varkappa$', +u'\u03f1': '$\\varrho$', +u'\u03f4': '{\\textTheta}', +u'\u03f6': '$\\backepsilon$', +u'\u0401': '{\\cyrchar\\CYRYO}', +u'\u0402': '{\\cyrchar\\CYRDJE}', +u'\u0403': "{\\cyrchar{\\'\\CYRG}}", +u'\u0404': '{\\cyrchar\\CYRIE}', +u'\u0405': '{\\cyrchar\\CYRDZE}', +u'\u0406': '{\\cyrchar\\CYRII}', +u'\u0407': '{\\cyrchar\\CYRYI}', +u'\u0408': '{\\cyrchar\\CYRJE}', +u'\u0409': '{\\cyrchar\\CYRLJE}', +u'\u040a': '{\\cyrchar\\CYRNJE}', +u'\u040b': '{\\cyrchar\\CYRTSHE}', +u'\u040c': "{\\cyrchar{\\'\\CYRK}}", +u'\u040e': '{\\cyrchar\\CYRUSHRT}', +u'\u040f': '{\\cyrchar\\CYRDZHE}', +u'\u0410': '{\\cyrchar\\CYRA}', +u'\u0411': '{\\cyrchar\\CYRB}', +u'\u0412': '{\\cyrchar\\CYRV}', +u'\u0413': '{\\cyrchar\\CYRG}', +u'\u0414': '{\\cyrchar\\CYRD}', +u'\u0415': '{\\cyrchar\\CYRE}', +u'\u0416': '{\\cyrchar\\CYRZH}', +u'\u0417': '{\\cyrchar\\CYRZ}', +u'\u0418': '{\\cyrchar\\CYRI}', +u'\u0419': '{\\cyrchar\\CYRISHRT}', +u'\u041a': '{\\cyrchar\\CYRK}', +u'\u041b': '{\\cyrchar\\CYRL}', +u'\u041c': '{\\cyrchar\\CYRM}', +u'\u041d': '{\\cyrchar\\CYRN}', +u'\u041e': '{\\cyrchar\\CYRO}', +u'\u041f': '{\\cyrchar\\CYRP}', +u'\u0420': '{\\cyrchar\\CYRR}', +u'\u0421': '{\\cyrchar\\CYRS}', +u'\u0422': '{\\cyrchar\\CYRT}', +u'\u0423': '{\\cyrchar\\CYRU}', +u'\u0424': '{\\cyrchar\\CYRF}', +u'\u0425': '{\\cyrchar\\CYRH}', +u'\u0426': '{\\cyrchar\\CYRC}', +u'\u0427': '{\\cyrchar\\CYRCH}', +u'\u0428': '{\\cyrchar\\CYRSH}', +u'\u0429': '{\\cyrchar\\CYRSHCH}', +u'\u042a': '{\\cyrchar\\CYRHRDSN}', +u'\u042b': '{\\cyrchar\\CYRERY}', +u'\u042c': '{\\cyrchar\\CYRSFTSN}', +u'\u042d': '{\\cyrchar\\CYREREV}', +u'\u042e': '{\\cyrchar\\CYRYU}', +u'\u042f': '{\\cyrchar\\CYRYA}', +u'\u0430': '{\\cyrchar\\cyra}', +u'\u0431': '{\\cyrchar\\cyrb}', +u'\u0432': '{\\cyrchar\\cyrv}', +u'\u0433': '{\\cyrchar\\cyrg}', +u'\u0434': '{\\cyrchar\\cyrd}', +u'\u0435': '{\\cyrchar\\cyre}', +u'\u0436': '{\\cyrchar\\cyrzh}', +u'\u0437': '{\\cyrchar\\cyrz}', +u'\u0438': '{\\cyrchar\\cyri}', +u'\u0439': '{\\cyrchar\\cyrishrt}', +u'\u043a': '{\\cyrchar\\cyrk}', +u'\u043b': '{\\cyrchar\\cyrl}', +u'\u043c': '{\\cyrchar\\cyrm}', +u'\u043d': '{\\cyrchar\\cyrn}', +u'\u043e': '{\\cyrchar\\cyro}', +u'\u043f': '{\\cyrchar\\cyrp}', +u'\u0440': '{\\cyrchar\\cyrr}', +u'\u0441': '{\\cyrchar\\cyrs}', +u'\u0442': '{\\cyrchar\\cyrt}', +u'\u0443': '{\\cyrchar\\cyru}', +u'\u0444': '{\\cyrchar\\cyrf}', +u'\u0445': '{\\cyrchar\\cyrh}', +u'\u0446': '{\\cyrchar\\cyrc}', +u'\u0447': '{\\cyrchar\\cyrch}', +u'\u0448': '{\\cyrchar\\cyrsh}', +u'\u0449': '{\\cyrchar\\cyrshch}', +u'\u044a': '{\\cyrchar\\cyrhrdsn}', +u'\u044b': '{\\cyrchar\\cyrery}', +u'\u044c': '{\\cyrchar\\cyrsftsn}', +u'\u044d': '{\\cyrchar\\cyrerev}', +u'\u044e': '{\\cyrchar\\cyryu}', +u'\u044f': '{\\cyrchar\\cyrya}', +u'\u0451': '{\\cyrchar\\cyryo}', +u'\u0452': '{\\cyrchar\\cyrdje}', +u'\u0453': "{\\cyrchar{\\'\\cyrg}}", +u'\u0454': '{\\cyrchar\\cyrie}', +u'\u0455': '{\\cyrchar\\cyrdze}', +u'\u0456': '{\\cyrchar\\cyrii}', +u'\u0457': '{\\cyrchar\\cyryi}', +u'\u0458': '{\\cyrchar\\cyrje}', +u'\u0459': '{\\cyrchar\\cyrlje}', +u'\u045a': '{\\cyrchar\\cyrnje}', +u'\u045b': '{\\cyrchar\\cyrtshe}', +u'\u045c': "{\\cyrchar{\\'\\cyrk}}", +u'\u045e': '{\\cyrchar\\cyrushrt}', +u'\u045f': '{\\cyrchar\\cyrdzhe}', +u'\u0460': '{\\cyrchar\\CYROMEGA}', +u'\u0461': '{\\cyrchar\\cyromega}', +u'\u0462': '{\\cyrchar\\CYRYAT}', +u'\u0464': '{\\cyrchar\\CYRIOTE}', +u'\u0465': '{\\cyrchar\\cyriote}', +u'\u0466': '{\\cyrchar\\CYRLYUS}', +u'\u0467': '{\\cyrchar\\cyrlyus}', +u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', +u'\u0469': '{\\cyrchar\\cyriotlyus}', +u'\u046a': '{\\cyrchar\\CYRBYUS}', +u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', +u'\u046d': '{\\cyrchar\\cyriotbyus}', +u'\u046e': '{\\cyrchar\\CYRKSI}', +u'\u046f': '{\\cyrchar\\cyrksi}', +u'\u0470': '{\\cyrchar\\CYRPSI}', +u'\u0471': '{\\cyrchar\\cyrpsi}', +u'\u0472': '{\\cyrchar\\CYRFITA}', +u'\u0474': '{\\cyrchar\\CYRIZH}', +u'\u0478': '{\\cyrchar\\CYRUK}', +u'\u0479': '{\\cyrchar\\cyruk}', +u'\u047a': '{\\cyrchar\\CYROMEGARND}', +u'\u047b': '{\\cyrchar\\cyromegarnd}', +u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', +u'\u047d': '{\\cyrchar\\cyromegatitlo}', +u'\u047e': '{\\cyrchar\\CYROT}', +u'\u047f': '{\\cyrchar\\cyrot}', +u'\u0480': '{\\cyrchar\\CYRKOPPA}', +u'\u0481': '{\\cyrchar\\cyrkoppa}', +u'\u0482': '{\\cyrchar\\cyrthousands}', +u'\u0488': '{\\cyrchar\\cyrhundredthousands}', +u'\u0489': '{\\cyrchar\\cyrmillions}', +u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', +u'\u048d': '{\\cyrchar\\cyrsemisftsn}', +u'\u048e': '{\\cyrchar\\CYRRTICK}', +u'\u048f': '{\\cyrchar\\cyrrtick}', +u'\u0490': '{\\cyrchar\\CYRGUP}', +u'\u0491': '{\\cyrchar\\cyrgup}', +u'\u0492': '{\\cyrchar\\CYRGHCRS}', +u'\u0493': '{\\cyrchar\\cyrghcrs}', +u'\u0494': '{\\cyrchar\\CYRGHK}', +u'\u0495': '{\\cyrchar\\cyrghk}', +u'\u0496': '{\\cyrchar\\CYRZHDSC}', +u'\u0497': '{\\cyrchar\\cyrzhdsc}', +u'\u0498': '{\\cyrchar\\CYRZDSC}', +u'\u0499': '{\\cyrchar\\cyrzdsc}', +u'\u049a': '{\\cyrchar\\CYRKDSC}', +u'\u049b': '{\\cyrchar\\cyrkdsc}', +u'\u049c': '{\\cyrchar\\CYRKVCRS}', +u'\u049d': '{\\cyrchar\\cyrkvcrs}', +u'\u049e': '{\\cyrchar\\CYRKHCRS}', +u'\u049f': '{\\cyrchar\\cyrkhcrs}', +u'\u04a0': '{\\cyrchar\\CYRKBEAK}', +u'\u04a1': '{\\cyrchar\\cyrkbeak}', +u'\u04a2': '{\\cyrchar\\CYRNDSC}', +u'\u04a3': '{\\cyrchar\\cyrndsc}', +u'\u04a4': '{\\cyrchar\\CYRNG}', +u'\u04a5': '{\\cyrchar\\cyrng}', +u'\u04a6': '{\\cyrchar\\CYRPHK}', +u'\u04a7': '{\\cyrchar\\cyrphk}', +u'\u04a8': '{\\cyrchar\\CYRABHHA}', +u'\u04a9': '{\\cyrchar\\cyrabhha}', +u'\u04aa': '{\\cyrchar\\CYRSDSC}', +u'\u04ab': '{\\cyrchar\\cyrsdsc}', +u'\u04ac': '{\\cyrchar\\CYRTDSC}', +u'\u04ad': '{\\cyrchar\\cyrtdsc}', +u'\u04ae': '{\\cyrchar\\CYRY}', +u'\u04af': '{\\cyrchar\\cyry}', +u'\u04b0': '{\\cyrchar\\CYRYHCRS}', +u'\u04b1': '{\\cyrchar\\cyryhcrs}', +u'\u04b2': '{\\cyrchar\\CYRHDSC}', +u'\u04b3': '{\\cyrchar\\cyrhdsc}', +u'\u04b4': '{\\cyrchar\\CYRTETSE}', +u'\u04b5': '{\\cyrchar\\cyrtetse}', +u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', +u'\u04b7': '{\\cyrchar\\cyrchrdsc}', +u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', +u'\u04b9': '{\\cyrchar\\cyrchvcrs}', +u'\u04ba': '{\\cyrchar\\CYRSHHA}', +u'\u04bb': '{\\cyrchar\\cyrshha}', +u'\u04bc': '{\\cyrchar\\CYRABHCH}', +u'\u04bd': '{\\cyrchar\\cyrabhch}', +u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', +u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', +u'\u04c0': '{\\cyrchar\\CYRpalochka}', +u'\u04c3': '{\\cyrchar\\CYRKHK}', +u'\u04c4': '{\\cyrchar\\cyrkhk}', +u'\u04c7': '{\\cyrchar\\CYRNHK}', +u'\u04c8': '{\\cyrchar\\cyrnhk}', +u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', +u'\u04cc': '{\\cyrchar\\cyrchldsc}', +u'\u04d4': '{\\cyrchar\\CYRAE}', +u'\u04d5': '{\\cyrchar\\cyrae}', +u'\u04d8': '{\\cyrchar\\CYRSCHWA}', +u'\u04d9': '{\\cyrchar\\cyrschwa}', +u'\u04e0': '{\\cyrchar\\CYRABHDZE}', +u'\u04e1': '{\\cyrchar\\cyrabhdze}', +u'\u04e8': '{\\cyrchar\\CYROTLD}', +u'\u04e9': '{\\cyrchar\\cyrotld}', +u'\u2002': '{\\hspace{0.6em}}', +u'\u2003': '{\\hspace{1em}}', +u'\u2004': '{\\hspace{0.33em}}', +u'\u2005': '{\\hspace{0.25em}}', +u'\u2006': '{\\hspace{0.166em}}', +u'\u2007': '{\\hphantom{0}}', +u'\u2008': '{\\hphantom{,}}', +u'\u2009': '{\\hspace{0.167em}}', +u'\u200a': '$\\mkern1mu$', +u'\u2010': '{-}', +u'\u2013': '{\\textendash}', +u'\u2014': '{\\textemdash}', +u'\u2015': '{\\rule{1em}{1pt}}', +u'\u2016': '$\\Vert$', +u'\u2018': '{`}', +u'\u2019': "{'}", +u'\u201a': '{,}', +u'\u201b': '$\\Elzreapos$', +u'\u201c': '{\\textquotedblleft}', +u'\u201d': '{\\textquotedblright}', +u'\u201e': '{,,}', +u'\u2020': '{\\textdagger}', +u'\u2021': '{\\textdaggerdbl}', +u'\u2022': '{\\textbullet}', +u'\u2024': '{.}', +u'\u2025': '{..}', +u'\u2026': '{\\ldots}', +u'\u2030': '{\\textperthousand}', +u'\u2031': '{\\textpertenthousand}', +u'\u2032': "${'}$", +u'\u2033': "${''}$", +u'\u2034': "${'''}$", +u'\u2035': '$\\backprime$', +u'\u2039': '{\\guilsinglleft}', +u'\u203a': '{\\guilsinglright}', +u'\u2057': "$''''$", +u'\u205f': '{\\mkern4mu}', +u'\u2060': '{\\nolinebreak}', +u'\u20a7': '{\\ensuremath{\\Elzpes}}', +u'\u20ac': '{\\mbox{\\texteuro}}', +u'\u20db': '$\\dddot$', +u'\u20dc': '$\\ddddot$', +u'\u2102': '$\\mathbb{C}$', +u'\u210a': '{\\mathscr{g}}', +u'\u210b': '$\\mathscr{H}$', +u'\u210c': '$\\mathfrak{H}$', +u'\u210d': '$\\mathbb{H}$', +u'\u210f': '$\\hslash$', +u'\u2110': '$\\mathscr{I}$', +u'\u2111': '$\\mathfrak{I}$', +u'\u2112': '$\\mathscr{L}$', +u'\u2113': '$\\mathscr{l}$', +u'\u2115': '$\\mathbb{N}$', +u'\u2116': '{\\cyrchar\\textnumero}', +u'\u2118': '$\\wp$', +u'\u2119': '$\\mathbb{P}$', +u'\u211a': '$\\mathbb{Q}$', +u'\u211b': '$\\mathscr{R}$', +u'\u211c': '$\\mathfrak{R}$', +u'\u211d': '$\\mathbb{R}$', +u'\u211e': '$\\Elzxrat$', +u'\u2122': '{\\texttrademark}', +u'\u2124': '$\\mathbb{Z}$', +u'\u2126': '$\\Omega$', +u'\u2127': '$\\mho$', +u'\u2128': '$\\mathfrak{Z}$', +u'\u2129': '$\\ElsevierGlyph{2129}$', +u'\u212b': '{\\AA}', +u'\u212c': '$\\mathscr{B}$', +u'\u212d': '$\\mathfrak{C}$', +u'\u212f': '$\\mathscr{e}$', +u'\u2130': '$\\mathscr{E}$', +u'\u2131': '$\\mathscr{F}$', +u'\u2133': '$\\mathscr{M}$', +u'\u2134': '$\\mathscr{o}$', +u'\u2135': '$\\aleph$', +u'\u2136': '$\\beth$', +u'\u2137': '$\\gimel$', +u'\u2138': '$\\daleth$', +u'\u2153': '$\\textfrac{1}{3}$', +u'\u2154': '$\\textfrac{2}{3}$', +u'\u2155': '$\\textfrac{1}{5}$', +u'\u2156': '$\\textfrac{2}{5}$', +u'\u2157': '$\\textfrac{3}{5}$', +u'\u2158': '$\\textfrac{4}{5}$', +u'\u2159': '$\\textfrac{1}{6}$', +u'\u215a': '$\\textfrac{5}{6}$', +u'\u215b': '$\\textfrac{1}{8}$', +u'\u215c': '$\\textfrac{3}{8}$', +u'\u215d': '$\\textfrac{5}{8}$', +u'\u215e': '$\\textfrac{7}{8}$', +u'\u2190': '$\\leftarrow$', +u'\u2191': '$\\uparrow$', +u'\u2192': '$\\rightarrow$', +u'\u2193': '$\\downarrow$', +u'\u2194': '$\\leftrightarrow$', +u'\u2195': '$\\updownarrow$', +u'\u2196': '$\\nwarrow$', +u'\u2197': '$\\nearrow$', +u'\u2198': '$\\searrow$', +u'\u2199': '$\\swarrow$', +u'\u219a': '$\\nleftarrow$', +u'\u219b': '$\\nrightarrow$', +u'\u219c': '$\\arrowwaveright$', +u'\u219d': '$\\arrowwaveright$', +u'\u219e': '$\\twoheadleftarrow$', +u'\u21a0': '$\\twoheadrightarrow$', +u'\u21a2': '$\\leftarrowtail$', +u'\u21a3': '$\\rightarrowtail$', +u'\u21a6': '$\\mapsto$', +u'\u21a9': '$\\hookleftarrow$', +u'\u21aa': '$\\hookrightarrow$', +u'\u21ab': '$\\looparrowleft$', +u'\u21ac': '$\\looparrowright$', +u'\u21ad': '$\\leftrightsquigarrow$', +u'\u21ae': '$\\nleftrightarrow$', +u'\u21b0': '$\\Lsh$', +u'\u21b1': '$\\Rsh$', +u'\u21b3': '$\\ElsevierGlyph{21B3}$', +u'\u21b6': '$\\curvearrowleft$', +u'\u21b7': '$\\curvearrowright$', +u'\u21ba': '$\\circlearrowleft$', +u'\u21bb': '$\\circlearrowright$', +u'\u21bc': '$\\leftharpoonup$', +u'\u21bd': '$\\leftharpoondown$', +u'\u21be': '$\\upharpoonright$', +u'\u21bf': '$\\upharpoonleft$', +u'\u21c0': '$\\rightharpoonup$', +u'\u21c1': '$\\rightharpoondown$', +u'\u21c2': '$\\downharpoonright$', +u'\u21c3': '$\\downharpoonleft$', +u'\u21c4': '$\\rightleftarrows$', +u'\u21c5': '$\\dblarrowupdown$', +u'\u21c6': '$\\leftrightarrows$', +u'\u21c7': '$\\leftleftarrows$', +u'\u21c8': '$\\upuparrows$', +u'\u21c9': '$\\rightrightarrows$', +u'\u21ca': '$\\downdownarrows$', +u'\u21cb': '$\\leftrightharpoons$', +u'\u21cc': '$\\rightleftharpoons$', +u'\u21cd': '$\\nLeftarrow$', +u'\u21ce': '$\\nLeftrightarrow$', +u'\u21cf': '$\\nRightarrow$', +u'\u21d0': '$\\Leftarrow$', +u'\u21d1': '$\\Uparrow$', +u'\u21d2': '$\\Rightarrow$', +u'\u21d3': '$\\Downarrow$', +u'\u21d4': '$\\Leftrightarrow$', +u'\u21d5': '$\\Updownarrow$', +u'\u21da': '$\\Lleftarrow$', +u'\u21db': '$\\Rrightarrow$', +u'\u21dd': '$\\rightsquigarrow$', +u'\u21f5': '$\\DownArrowUpArrow$', +u'\u2200': '$\\forall$', +u'\u2201': '$\\complement$', +u'\u2202': '$\\partial$', +u'\u2203': '$\\exists$', +u'\u2204': '$\\nexists$', +u'\u2205': '$\\varnothing$', +u'\u2207': '$\\nabla$', +u'\u2208': '$\\in$', +u'\u2209': '$\\not\\in$', +u'\u220b': '$\\ni$', +u'\u220c': '$\\not\\ni$', +u'\u220f': '$\\prod$', +u'\u2210': '$\\coprod$', +u'\u2211': '$\\sum$', +u'\u2212': '{-}', +u'\u2213': '$\\mp$', +u'\u2214': '$\\dotplus$', +u'\u2216': '$\\setminus$', +u'\u2217': '${_\\ast}$', +u'\u2218': '$\\circ$', +u'\u2219': '$\\bullet$', +u'\u221a': '$\\surd$', +u'\u221d': '$\\propto$', +u'\u221e': '$\\infty$', +u'\u221f': '$\\rightangle$', +u'\u2220': '$\\angle$', +u'\u2221': '$\\measuredangle$', +u'\u2222': '$\\sphericalangle$', +u'\u2223': '$\\mid$', +u'\u2224': '$\\nmid$', +u'\u2225': '$\\parallel$', +u'\u2226': '$\\nparallel$', +u'\u2227': '$\\wedge$', +u'\u2228': '$\\vee$', +u'\u2229': '$\\cap$', +u'\u222a': '$\\cup$', +u'\u222b': '$\\int$', +u'\u222c': '$\\int\\!\\int$', +u'\u222d': '$\\int\\!\\int\\!\\int$', +u'\u222e': '$\\oint$', +u'\u222f': '$\\surfintegral$', +u'\u2230': '$\\volintegral$', +u'\u2231': '$\\clwintegral$', +u'\u2232': '$\\ElsevierGlyph{2232}$', +u'\u2233': '$\\ElsevierGlyph{2233}$', +u'\u2234': '$\\therefore$', +u'\u2235': '$\\because$', +u'\u2237': '$\\Colon$', +u'\u2238': '$\\ElsevierGlyph{2238}$', +u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', +u'\u223b': '$\\homothetic$', +u'\u223c': '$\\sim$', +u'\u223d': '$\\backsim$', +u'\u223e': '$\\lazysinv$', +u'\u2240': '$\\wr$', +u'\u2241': '$\\not\\sim$', +u'\u2242': '$\\ElsevierGlyph{2242}$', +u'\u2243': '$\\simeq$', +u'\u2244': '$\\not\\simeq$', +u'\u2245': '$\\cong$', +u'\u2246': '$\\approxnotequal$', +u'\u2247': '$\\not\\cong$', +u'\u2248': '$\\approx$', +u'\u2249': '$\\not\\approx$', +u'\u224a': '$\\approxeq$', +u'\u224b': '$\\tildetrpl$', +u'\u224c': '$\\allequal$', +u'\u224d': '$\\asymp$', +u'\u224e': '$\\Bumpeq$', +u'\u224f': '$\\bumpeq$', +u'\u2250': '$\\doteq$', +u'\u2251': '$\\doteqdot$', +u'\u2252': '$\\fallingdotseq$', +u'\u2253': '$\\risingdotseq$', +u'\u2254': '{:=}', +u'\u2255': '$=:$', +u'\u2256': '$\\eqcirc$', +u'\u2257': '$\\circeq$', +u'\u2259': '$\\estimates$', +u'\u225a': '$\\ElsevierGlyph{225A}$', +u'\u225b': '$\\starequal$', +u'\u225c': '$\\triangleq$', +u'\u225f': '$\\ElsevierGlyph{225F}$', +u'\u2260': '$\\not =$', +u'\u2261': '$\\equiv$', +u'\u2262': '$\\not\\equiv$', +u'\u2264': '$\\leq$', +u'\u2265': '$\\geq$', +u'\u2266': '$\\leqq$', +u'\u2267': '$\\geqq$', +u'\u2268': '$\\lneqq$', +u'\u2269': '$\\gneqq$', +u'\u226a': '$\\ll$', +u'\u226b': '$\\gg$', +u'\u226c': '$\\between$', +u'\u226d': '$\\not\\kern-0.3em\\times$', +u'\u226e': '$\\not<$', +u'\u226f': '$\\not>$', +u'\u2270': '$\\not\\leq$', +u'\u2271': '$\\not\\geq$', +u'\u2272': '$\\lessequivlnt$', +u'\u2273': '$\\greaterequivlnt$', +u'\u2274': '$\\ElsevierGlyph{2274}$', +u'\u2275': '$\\ElsevierGlyph{2275}$', +u'\u2276': '$\\lessgtr$', +u'\u2277': '$\\gtrless$', +u'\u2278': '$\\notlessgreater$', +u'\u2279': '$\\notgreaterless$', +u'\u227a': '$\\prec$', +u'\u227b': '$\\succ$', +u'\u227c': '$\\preccurlyeq$', +u'\u227d': '$\\succcurlyeq$', +u'\u227e': '$\\precapprox$', +u'\u227f': '$\\succapprox$', +u'\u2280': '$\\not\\prec$', +u'\u2281': '$\\not\\succ$', +u'\u2282': '$\\subset$', +u'\u2283': '$\\supset$', +u'\u2284': '$\\not\\subset$', +u'\u2285': '$\\not\\supset$', +u'\u2286': '$\\subseteq$', +u'\u2287': '$\\supseteq$', +u'\u2288': '$\\not\\subseteq$', +u'\u2289': '$\\not\\supseteq$', +u'\u228a': '$\\subsetneq$', +u'\u228b': '$\\supsetneq$', +u'\u228e': '$\\uplus$', +u'\u228f': '$\\sqsubset$', +u'\u2290': '$\\sqsupset$', +u'\u2291': '$\\sqsubseteq$', +u'\u2292': '$\\sqsupseteq$', +u'\u2293': '$\\sqcap$', +u'\u2294': '$\\sqcup$', +u'\u2295': '$\\oplus$', +u'\u2296': '$\\ominus$', +u'\u2297': '$\\otimes$', +u'\u2298': '$\\oslash$', +u'\u2299': '$\\odot$', +u'\u229a': '$\\circledcirc$', +u'\u229b': '$\\circledast$', +u'\u229d': '$\\circleddash$', +u'\u229e': '$\\boxplus$', +u'\u229f': '$\\boxminus$', +u'\u22a0': '$\\boxtimes$', +u'\u22a1': '$\\boxdot$', +u'\u22a2': '$\\vdash$', +u'\u22a3': '$\\dashv$', +u'\u22a4': '$\\top$', +u'\u22a5': '$\\perp$', +u'\u22a7': '$\\truestate$', +u'\u22a8': '$\\forcesextra$', +u'\u22a9': '$\\Vdash$', +u'\u22aa': '$\\Vvdash$', +u'\u22ab': '$\\VDash$', +u'\u22ac': '$\\nvdash$', +u'\u22ad': '$\\nvDash$', +u'\u22ae': '$\\nVdash$', +u'\u22af': '$\\nVDash$', +u'\u22b2': '$\\vartriangleleft$', +u'\u22b3': '$\\vartriangleright$', +u'\u22b4': '$\\trianglelefteq$', +u'\u22b5': '$\\trianglerighteq$', +u'\u22b6': '$\\original$', +u'\u22b7': '$\\image$', +u'\u22b8': '$\\multimap$', +u'\u22b9': '$\\hermitconjmatrix$', +u'\u22ba': '$\\intercal$', +u'\u22bb': '$\\veebar$', +u'\u22be': '$\\rightanglearc$', +u'\u22c0': '$\\ElsevierGlyph{22C0}$', +u'\u22c1': '$\\ElsevierGlyph{22C1}$', +u'\u22c2': '$\\bigcap$', +u'\u22c3': '$\\bigcup$', +u'\u22c4': '$\\diamond$', +u'\u22c5': '$\\cdot$', +u'\u22c6': '$\\star$', +u'\u22c7': '$\\divideontimes$', +u'\u22c8': '$\\bowtie$', +u'\u22c9': '$\\ltimes$', +u'\u22ca': '$\\rtimes$', +u'\u22cb': '$\\leftthreetimes$', +u'\u22cc': '$\\rightthreetimes$', +u'\u22cd': '$\\backsimeq$', +u'\u22ce': '$\\curlyvee$', +u'\u22cf': '$\\curlywedge$', +u'\u22d0': '$\\Subset$', +u'\u22d1': '$\\Supset$', +u'\u22d2': '$\\Cap$', +u'\u22d3': '$\\Cup$', +u'\u22d4': '$\\pitchfork$', +u'\u22d6': '$\\lessdot$', +u'\u22d7': '$\\gtrdot$', +u'\u22d8': '$\\verymuchless$', +u'\u22d9': '$\\verymuchgreater$', +u'\u22da': '$\\lesseqgtr$', +u'\u22db': '$\\gtreqless$', +u'\u22de': '$\\curlyeqprec$', +u'\u22df': '$\\curlyeqsucc$', +u'\u22e2': '$\\not\\sqsubseteq$', +u'\u22e3': '$\\not\\sqsupseteq$', +u'\u22e5': '$\\Elzsqspne$', +u'\u22e6': '$\\lnsim$', +u'\u22e7': '$\\gnsim$', +u'\u22e8': '$\\precedesnotsimilar$', +u'\u22e9': '$\\succnsim$', +u'\u22ea': '$\\ntriangleleft$', +u'\u22eb': '$\\ntriangleright$', +u'\u22ec': '$\\ntrianglelefteq$', +u'\u22ed': '$\\ntrianglerighteq$', +u'\u22ee': '$\\vdots$', +u'\u22ef': '$\\cdots$', +u'\u22f0': '$\\upslopeellipsis$', +u'\u22f1': '$\\downslopeellipsis$', +u'\u2305': '{\\barwedge}', +u'\u2306': '$\\perspcorrespond$', +u'\u2308': '$\\lceil$', +u'\u2309': '$\\rceil$', +u'\u230a': '$\\lfloor$', +u'\u230b': '$\\rfloor$', +u'\u2315': '$\\recorder$', +u'\u2316': '$\\mathchar"2208$', +u'\u231c': '$\\ulcorner$', +u'\u231d': '$\\urcorner$', +u'\u231e': '$\\llcorner$', +u'\u231f': '$\\lrcorner$', +u'\u2322': '$\\frown$', +u'\u2323': '$\\smile$', +u'\u2329': '$\\langle$', +u'\u232a': '$\\rangle$', +u'\u233d': '$\\ElsevierGlyph{E838}$', +u'\u23a3': '$\\Elzdlcorn$', +u'\u23b0': '$\\lmoustache$', +u'\u23b1': '$\\rmoustache$', +u'\u2423': '{\\textvisiblespace}', +u'\u2460': '{\\ding{172}}', +u'\u2461': '{\\ding{173}}', +u'\u2462': '{\\ding{174}}', +u'\u2463': '{\\ding{175}}', +u'\u2464': '{\\ding{176}}', +u'\u2465': '{\\ding{177}}', +u'\u2466': '{\\ding{178}}', +u'\u2467': '{\\ding{179}}', +u'\u2468': '{\\ding{180}}', +u'\u2469': '{\\ding{181}}', +u'\u24c8': '$\\circledS$', +u'\u2506': '$\\Elzdshfnc$', +u'\u2519': '$\\Elzsqfnw$', +u'\u2571': '$\\diagup$', +u'\u25a0': '{\\ding{110}}', +u'\u25a1': '$\\square$', +u'\u25aa': '$\\blacksquare$', +u'\u25ad': '$\\fbox{~~}$', +u'\u25af': '$\\Elzvrecto$', +u'\u25b1': '$\\ElsevierGlyph{E381}$', +u'\u25b2': '{\\ding{115}}', +u'\u25b3': '$\\bigtriangleup$', +u'\u25b4': '$\\blacktriangle$', +u'\u25b5': '$\\vartriangle$', +u'\u25b8': '$\\blacktriangleright$', +u'\u25b9': '$\\triangleright$', +u'\u25bc': '{\\ding{116}}', +u'\u25bd': '$\\bigtriangledown$', +u'\u25be': '$\\blacktriangledown$', +u'\u25bf': '$\\triangledown$', +u'\u25c2': '$\\blacktriangleleft$', +u'\u25c3': '$\\triangleleft$', +u'\u25c6': '{\\ding{117}}', +u'\u25ca': '$\\lozenge$', +u'\u25cb': '$\\bigcirc$', +u'\u25cf': '{\\ding{108}}', +u'\u25d0': '$\\Elzcirfl$', +u'\u25d1': '$\\Elzcirfr$', +u'\u25d2': '$\\Elzcirfb$', +u'\u25d7': '{\\ding{119}}', +u'\u25d8': '$\\Elzrvbull$', +u'\u25e7': '$\\Elzsqfl$', +u'\u25e8': '$\\Elzsqfr$', +u'\u25ea': '$\\Elzsqfse$', +u'\u25ef': '$\\bigcirc$', +u'\u2605': '{\\ding{72}}', +u'\u2606': '{\\ding{73}}', +u'\u260e': '{\\ding{37}}', +u'\u261b': '{\\ding{42}}', +u'\u261e': '{\\ding{43}}', +u'\u263e': '{\\rightmoon}', +u'\u263f': '{\\mercury}', +u'\u2640': '{\\venus}', +u'\u2642': '{\\male}', +u'\u2643': '{\\jupiter}', +u'\u2644': '{\\saturn}', +u'\u2645': '{\\uranus}', +u'\u2646': '{\\neptune}', +u'\u2647': '{\\pluto}', +u'\u2648': '{\\aries}', +u'\u2649': '{\\taurus}', +u'\u264a': '{\\gemini}', +u'\u264b': '{\\cancer}', +u'\u264c': '{\\leo}', +u'\u264d': '{\\virgo}', +u'\u264e': '{\\libra}', +u'\u264f': '{\\scorpio}', +u'\u2650': '{\\sagittarius}', +u'\u2651': '{\\capricornus}', +u'\u2652': '{\\aquarius}', +u'\u2653': '{\\pisces}', +u'\u2660': '{\\ding{171}}', +u'\u2662': '$\\diamond$', +u'\u2663': '{\\ding{168}}', +u'\u2665': '{\\ding{170}}', +u'\u2666': '{\\ding{169}}', +u'\u2669': '{\\quarternote}', +u'\u266a': '{\\eighthnote}', +u'\u266d': '$\\flat$', +u'\u266e': '$\\natural$', +u'\u266f': '$\\sharp$', +u'\u2701': '{\\ding{33}}', +u'\u2702': '{\\ding{34}}', +u'\u2703': '{\\ding{35}}', +u'\u2704': '{\\ding{36}}', +u'\u2706': '{\\ding{38}}', +u'\u2707': '{\\ding{39}}', +u'\u2708': '{\\ding{40}}', +u'\u2709': '{\\ding{41}}', +u'\u270c': '{\\ding{44}}', +u'\u270d': '{\\ding{45}}', +u'\u270e': '{\\ding{46}}', +u'\u270f': '{\\ding{47}}', +u'\u2710': '{\\ding{48}}', +u'\u2711': '{\\ding{49}}', +u'\u2712': '{\\ding{50}}', +u'\u2713': '{\\ding{51}}', +u'\u2714': '{\\ding{52}}', +u'\u2715': '{\\ding{53}}', +u'\u2716': '{\\ding{54}}', +u'\u2717': '{\\ding{55}}', +u'\u2718': '{\\ding{56}}', +u'\u2719': '{\\ding{57}}', +u'\u271a': '{\\ding{58}}', +u'\u271b': '{\\ding{59}}', +u'\u271c': '{\\ding{60}}', +u'\u271d': '{\\ding{61}}', +u'\u271e': '{\\ding{62}}', +u'\u271f': '{\\ding{63}}', +u'\u2720': '{\\ding{64}}', +u'\u2721': '{\\ding{65}}', +u'\u2722': '{\\ding{66}}', +u'\u2723': '{\\ding{67}}', +u'\u2724': '{\\ding{68}}', +u'\u2725': '{\\ding{69}}', +u'\u2726': '{\\ding{70}}', +u'\u2727': '{\\ding{71}}', +u'\u2729': '{\\ding{73}}', +u'\u272a': '{\\ding{74}}', +u'\u272b': '{\\ding{75}}', +u'\u272c': '{\\ding{76}}', +u'\u272d': '{\\ding{77}}', +u'\u272e': '{\\ding{78}}', +u'\u272f': '{\\ding{79}}', +u'\u2730': '{\\ding{80}}', +u'\u2731': '{\\ding{81}}', +u'\u2732': '{\\ding{82}}', +u'\u2733': '{\\ding{83}}', +u'\u2734': '{\\ding{84}}', +u'\u2735': '{\\ding{85}}', +u'\u2736': '{\\ding{86}}', +u'\u2737': '{\\ding{87}}', +u'\u2738': '{\\ding{88}}', +u'\u2739': '{\\ding{89}}', +u'\u273a': '{\\ding{90}}', +u'\u273b': '{\\ding{91}}', +u'\u273c': '{\\ding{92}}', +u'\u273d': '{\\ding{93}}', +u'\u273e': '{\\ding{94}}', +u'\u273f': '{\\ding{95}}', +u'\u2740': '{\\ding{96}}', +u'\u2741': '{\\ding{97}}', +u'\u2742': '{\\ding{98}}', +u'\u2743': '{\\ding{99}}', +u'\u2744': '{\\ding{100}}', +u'\u2745': '{\\ding{101}}', +u'\u2746': '{\\ding{102}}', +u'\u2747': '{\\ding{103}}', +u'\u2748': '{\\ding{104}}', +u'\u2749': '{\\ding{105}}', +u'\u274a': '{\\ding{106}}', +u'\u274b': '{\\ding{107}}', +u'\u274d': '{\\ding{109}}', +u'\u274f': '{\\ding{111}}', +u'\u2750': '{\\ding{112}}', +u'\u2751': '{\\ding{113}}', +u'\u2752': '{\\ding{114}}', +u'\u2756': '{\\ding{118}}', +u'\u2758': '{\\ding{120}}', +u'\u2759': '{\\ding{121}}', +u'\u275a': '{\\ding{122}}', +u'\u275b': '{\\ding{123}}', +u'\u275c': '{\\ding{124}}', +u'\u275d': '{\\ding{125}}', +u'\u275e': '{\\ding{126}}', +u'\u2761': '{\\ding{161}}', +u'\u2762': '{\\ding{162}}', +u'\u2763': '{\\ding{163}}', +u'\u2764': '{\\ding{164}}', +u'\u2765': '{\\ding{165}}', +u'\u2766': '{\\ding{166}}', +u'\u2767': '{\\ding{167}}', +u'\u2776': '{\\ding{182}}', +u'\u2777': '{\\ding{183}}', +u'\u2778': '{\\ding{184}}', +u'\u2779': '{\\ding{185}}', +u'\u277a': '{\\ding{186}}', +u'\u277b': '{\\ding{187}}', +u'\u277c': '{\\ding{188}}', +u'\u277d': '{\\ding{189}}', +u'\u277e': '{\\ding{190}}', +u'\u277f': '{\\ding{191}}', +u'\u2780': '{\\ding{192}}', +u'\u2781': '{\\ding{193}}', +u'\u2782': '{\\ding{194}}', +u'\u2783': '{\\ding{195}}', +u'\u2784': '{\\ding{196}}', +u'\u2785': '{\\ding{197}}', +u'\u2786': '{\\ding{198}}', +u'\u2787': '{\\ding{199}}', +u'\u2788': '{\\ding{200}}', +u'\u2789': '{\\ding{201}}', +u'\u278a': '{\\ding{202}}', +u'\u278b': '{\\ding{203}}', +u'\u278c': '{\\ding{204}}', +u'\u278d': '{\\ding{205}}', +u'\u278e': '{\\ding{206}}', +u'\u278f': '{\\ding{207}}', +u'\u2790': '{\\ding{208}}', +u'\u2791': '{\\ding{209}}', +u'\u2792': '{\\ding{210}}', +u'\u2793': '{\\ding{211}}', +u'\u2794': '{\\ding{212}}', +u'\u2798': '{\\ding{216}}', +u'\u2799': '{\\ding{217}}', +u'\u279a': '{\\ding{218}}', +u'\u279b': '{\\ding{219}}', +u'\u279c': '{\\ding{220}}', +u'\u279d': '{\\ding{221}}', +u'\u279e': '{\\ding{222}}', +u'\u279f': '{\\ding{223}}', +u'\u27a0': '{\\ding{224}}', +u'\u27a1': '{\\ding{225}}', +u'\u27a2': '{\\ding{226}}', +u'\u27a3': '{\\ding{227}}', +u'\u27a4': '{\\ding{228}}', +u'\u27a5': '{\\ding{229}}', +u'\u27a6': '{\\ding{230}}', +u'\u27a7': '{\\ding{231}}', +u'\u27a8': '{\\ding{232}}', +u'\u27a9': '{\\ding{233}}', +u'\u27aa': '{\\ding{234}}', +u'\u27ab': '{\\ding{235}}', +u'\u27ac': '{\\ding{236}}', +u'\u27ad': '{\\ding{237}}', +u'\u27ae': '{\\ding{238}}', +u'\u27af': '{\\ding{239}}', +u'\u27b1': '{\\ding{241}}', +u'\u27b2': '{\\ding{242}}', +u'\u27b3': '{\\ding{243}}', +u'\u27b4': '{\\ding{244}}', +u'\u27b5': '{\\ding{245}}', +u'\u27b6': '{\\ding{246}}', +u'\u27b7': '{\\ding{247}}', +u'\u27b8': '{\\ding{248}}', +u'\u27b9': '{\\ding{249}}', +u'\u27ba': '{\\ding{250}}', +u'\u27bb': '{\\ding{251}}', +u'\u27bc': '{\\ding{252}}', +u'\u27bd': '{\\ding{253}}', +u'\u27be': '{\\ding{254}}', +u'\u27f5': '$\\longleftarrow$', +u'\u27f6': '$\\longrightarrow$', +u'\u27f7': '$\\longleftrightarrow$', +u'\u27f8': '$\\Longleftarrow$', +u'\u27f9': '$\\Longrightarrow$', +u'\u27fa': '$\\Longleftrightarrow$', +u'\u27fc': '$\\longmapsto$', +u'\u27ff': '$\\sim\\joinrel\\leadsto$', +u'\u2905': '$\\ElsevierGlyph{E212}$', +u'\u2912': '$\\UpArrowBar$', +u'\u2913': '$\\DownArrowBar$', +u'\u2923': '$\\ElsevierGlyph{E20C}$', +u'\u2924': '$\\ElsevierGlyph{E20D}$', +u'\u2925': '$\\ElsevierGlyph{E20B}$', +u'\u2926': '$\\ElsevierGlyph{E20A}$', +u'\u2927': '$\\ElsevierGlyph{E211}$', +u'\u2928': '$\\ElsevierGlyph{E20E}$', +u'\u2929': '$\\ElsevierGlyph{E20F}$', +u'\u292a': '$\\ElsevierGlyph{E210}$', +u'\u2933': '$\\ElsevierGlyph{E21C}$', +u'\u2936': '$\\ElsevierGlyph{E21A}$', +u'\u2937': '$\\ElsevierGlyph{E219}$', +u'\u2940': '$\\Elolarr$', +u'\u2941': '$\\Elorarr$', +u'\u2942': '$\\ElzRlarr$', +u'\u2944': '$\\ElzrLarr$', +u'\u2947': '$\\Elzrarrx$', +u'\u294e': '$\\LeftRightVector$', +u'\u294f': '$\\RightUpDownVector$', +u'\u2950': '$\\DownLeftRightVector$', +u'\u2951': '$\\LeftUpDownVector$', +u'\u2952': '$\\LeftVectorBar$', +u'\u2953': '$\\RightVectorBar$', +u'\u2954': '$\\RightUpVectorBar$', +u'\u2955': '$\\RightDownVectorBar$', +u'\u2956': '$\\DownLeftVectorBar$', +u'\u2957': '$\\DownRightVectorBar$', +u'\u2958': '$\\LeftUpVectorBar$', +u'\u2959': '$\\LeftDownVectorBar$', +u'\u295a': '$\\LeftTeeVector$', +u'\u295b': '$\\RightTeeVector$', +u'\u295c': '$\\RightUpTeeVector$', +u'\u295d': '$\\RightDownTeeVector$', +u'\u295e': '$\\DownLeftTeeVector$', +u'\u295f': '$\\DownRightTeeVector$', +u'\u2960': '$\\LeftUpTeeVector$', +u'\u2961': '$\\LeftDownTeeVector$', +u'\u296e': '$\\UpEquilibrium$', +u'\u296f': '$\\ReverseUpEquilibrium$', +u'\u2970': '$\\RoundImplies$', +u'\u297c': '$\\ElsevierGlyph{E214}$', +u'\u297d': '$\\ElsevierGlyph{E215}$', +u'\u2980': '$\\Elztfnc$', +u'\u2985': '$\\ElsevierGlyph{3018}$', +u'\u2986': '$\\Elroang$', +u'\u2993': '$<\\kern-0.58em($', +u'\u2994': '$\\ElsevierGlyph{E291}$', +u'\u2999': '$\\Elzddfnc$', +u'\u299c': '$\\Angle$', +u'\u29a0': '$\\Elzlpargt$', +u'\u29b5': '$\\ElsevierGlyph{E260}$', +u'\u29b6': '$\\ElsevierGlyph{E61B}$', +u'\u29ca': '$\\ElzLap$', +u'\u29cb': '$\\Elzdefas$', +u'\u29cf': '$\\LeftTriangleBar$', +u'\u29d0': '$\\RightTriangleBar$', +u'\u29dc': '$\\ElsevierGlyph{E372}$', +u'\u29eb': '$\\blacklozenge$', +u'\u29f4': '$\\RuleDelayed$', +u'\u2a04': '$\\Elxuplus$', +u'\u2a05': '$\\ElzThr$', +u'\u2a06': '$\\Elxsqcup$', +u'\u2a07': '$\\ElzInf$', +u'\u2a08': '$\\ElzSup$', +u'\u2a0d': '$\\ElzCint$', +u'\u2a0f': '$\\clockoint$', +u'\u2a10': '$\\ElsevierGlyph{E395}$', +u'\u2a16': '$\\sqrint$', +u'\u2a25': '$\\ElsevierGlyph{E25A}$', +u'\u2a2a': '$\\ElsevierGlyph{E25B}$', +u'\u2a2d': '$\\ElsevierGlyph{E25C}$', +u'\u2a2e': '$\\ElsevierGlyph{E25D}$', +u'\u2a2f': '$\\ElzTimes$', +u'\u2a34': '$\\ElsevierGlyph{E25E}$', +u'\u2a35': '$\\ElsevierGlyph{E25E}$', +u'\u2a3c': '$\\ElsevierGlyph{E259}$', +u'\u2a3f': '$\\amalg$', +u'\u2a53': '$\\ElzAnd$', +u'\u2a54': '$\\ElzOr$', +u'\u2a55': '$\\ElsevierGlyph{E36E}$', +u'\u2a56': '$\\ElOr$', +u'\u2a5e': '$\\perspcorrespond$', +u'\u2a5f': '$\\Elzminhat$', +u'\u2a63': '$\\ElsevierGlyph{225A}$', +u'\u2a6e': '$\\stackrel{*}{=}$', +u'\u2a75': '$\\Equal$', +u'\u2a7d': '$\\leqslant$', +u'\u2a7e': '$\\geqslant$', +u'\u2a85': '$\\lessapprox$', +u'\u2a86': '$\\gtrapprox$', +u'\u2a87': '$\\lneq$', +u'\u2a88': '$\\gneq$', +u'\u2a89': '$\\lnapprox$', +u'\u2a8a': '$\\gnapprox$', +u'\u2a8b': '$\\lesseqqgtr$', +u'\u2a8c': '$\\gtreqqless$', +u'\u2a95': '$\\eqslantless$', +u'\u2a96': '$\\eqslantgtr$', +u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', +u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', +u'\u2aa1': '$\\NestedLessLess$', +u'\u2aa2': '$\\NestedGreaterGreater$', +u'\u2aaf': '$\\preceq$', +u'\u2ab0': '$\\succeq$', +u'\u2ab5': '$\\precneqq$', +u'\u2ab6': '$\\succneqq$', +u'\u2ab7': '$\\precapprox$', +u'\u2ab8': '$\\succapprox$', +u'\u2ab9': '$\\precnapprox$', +u'\u2aba': '$\\succnapprox$', +u'\u2ac5': '$\\subseteqq$', +u'\u2ac6': '$\\supseteqq$', +u'\u2acb': '$\\subsetneqq$', +u'\u2acc': '$\\supsetneqq$', +u'\u2aeb': '$\\ElsevierGlyph{E30D}$', +u'\u2af6': '$\\Elztdcol$', +u'\u2afd': '${{/}\\!\\!{/}}$', +u'\u300a': '$\\ElsevierGlyph{300A}$', +u'\u300b': '$\\ElsevierGlyph{300B}$', +u'\u3018': '$\\ElsevierGlyph{3018}$', +u'\u3019': '$\\ElsevierGlyph{3019}$', +u'\u301a': '$\\openbracketleft$', +u'\u301b': '$\\openbracketright$', +u'\ufb00': '{ff}', +u'\ufb01': '{fi}', +u'\ufb02': '{fl}', +u'\ufb03': '{ffi}', +u'\ufb04': '{ffl}', +u'\U0001d400': '$\\mathbf{A}$', +u'\U0001d401': '$\\mathbf{B}$', +u'\U0001d402': '$\\mathbf{C}$', +u'\U0001d403': '$\\mathbf{D}$', +u'\U0001d404': '$\\mathbf{E}$', +u'\U0001d405': '$\\mathbf{F}$', +u'\U0001d406': '$\\mathbf{G}$', +u'\U0001d407': '$\\mathbf{H}$', +u'\U0001d408': '$\\mathbf{I}$', +u'\U0001d409': '$\\mathbf{J}$', +u'\U0001d40a': '$\\mathbf{K}$', +u'\U0001d40b': '$\\mathbf{L}$', +u'\U0001d40c': '$\\mathbf{M}$', +u'\U0001d40d': '$\\mathbf{N}$', +u'\U0001d40e': '$\\mathbf{O}$', +u'\U0001d40f': '$\\mathbf{P}$', +u'\U0001d410': '$\\mathbf{Q}$', +u'\U0001d411': '$\\mathbf{R}$', +u'\U0001d412': '$\\mathbf{S}$', +u'\U0001d413': '$\\mathbf{T}$', +u'\U0001d414': '$\\mathbf{U}$', +u'\U0001d415': '$\\mathbf{V}$', +u'\U0001d416': '$\\mathbf{W}$', +u'\U0001d417': '$\\mathbf{X}$', +u'\U0001d418': '$\\mathbf{Y}$', +u'\U0001d419': '$\\mathbf{Z}$', +u'\U0001d41a': '$\\mathbf{a}$', +u'\U0001d41b': '$\\mathbf{b}$', +u'\U0001d41c': '$\\mathbf{c}$', +u'\U0001d41d': '$\\mathbf{d}$', +u'\U0001d41e': '$\\mathbf{e}$', +u'\U0001d41f': '$\\mathbf{f}$', +u'\U0001d420': '$\\mathbf{g}$', +u'\U0001d421': '$\\mathbf{h}$', +u'\U0001d422': '$\\mathbf{i}$', +u'\U0001d423': '$\\mathbf{j}$', +u'\U0001d424': '$\\mathbf{k}$', +u'\U0001d425': '$\\mathbf{l}$', +u'\U0001d426': '$\\mathbf{m}$', +u'\U0001d427': '$\\mathbf{n}$', +u'\U0001d428': '$\\mathbf{o}$', +u'\U0001d429': '$\\mathbf{p}$', +u'\U0001d42a': '$\\mathbf{q}$', +u'\U0001d42b': '$\\mathbf{r}$', +u'\U0001d42c': '$\\mathbf{s}$', +u'\U0001d42d': '$\\mathbf{t}$', +u'\U0001d42e': '$\\mathbf{u}$', +u'\U0001d42f': '$\\mathbf{v}$', +u'\U0001d430': '$\\mathbf{w}$', +u'\U0001d431': '$\\mathbf{x}$', +u'\U0001d432': '$\\mathbf{y}$', +u'\U0001d433': '$\\mathbf{z}$', +u'\U0001d434': '$\\mathsl{A}$', +u'\U0001d435': '$\\mathsl{B}$', +u'\U0001d436': '$\\mathsl{C}$', +u'\U0001d437': '$\\mathsl{D}$', +u'\U0001d438': '$\\mathsl{E}$', +u'\U0001d439': '$\\mathsl{F}$', +u'\U0001d43a': '$\\mathsl{G}$', +u'\U0001d43b': '$\\mathsl{H}$', +u'\U0001d43c': '$\\mathsl{I}$', +u'\U0001d43d': '$\\mathsl{J}$', +u'\U0001d43e': '$\\mathsl{K}$', +u'\U0001d43f': '$\\mathsl{L}$', +u'\U0001d440': '$\\mathsl{M}$', +u'\U0001d441': '$\\mathsl{N}$', +u'\U0001d442': '$\\mathsl{O}$', +u'\U0001d443': '$\\mathsl{P}$', +u'\U0001d444': '$\\mathsl{Q}$', +u'\U0001d445': '$\\mathsl{R}$', +u'\U0001d446': '$\\mathsl{S}$', +u'\U0001d447': '$\\mathsl{T}$', +u'\U0001d448': '$\\mathsl{U}$', +u'\U0001d449': '$\\mathsl{V}$', +u'\U0001d44a': '$\\mathsl{W}$', +u'\U0001d44b': '$\\mathsl{X}$', +u'\U0001d44c': '$\\mathsl{Y}$', +u'\U0001d44d': '$\\mathsl{Z}$', +u'\U0001d44e': '$\\mathsl{a}$', +u'\U0001d44f': '$\\mathsl{b}$', +u'\U0001d450': '$\\mathsl{c}$', +u'\U0001d451': '$\\mathsl{d}$', +u'\U0001d452': '$\\mathsl{e}$', +u'\U0001d453': '$\\mathsl{f}$', +u'\U0001d454': '$\\mathsl{g}$', +u'\U0001d456': '$\\mathsl{i}$', +u'\U0001d457': '$\\mathsl{j}$', +u'\U0001d458': '$\\mathsl{k}$', +u'\U0001d459': '$\\mathsl{l}$', +u'\U0001d45a': '$\\mathsl{m}$', +u'\U0001d45b': '$\\mathsl{n}$', +u'\U0001d45c': '$\\mathsl{o}$', +u'\U0001d45d': '$\\mathsl{p}$', +u'\U0001d45e': '$\\mathsl{q}$', +u'\U0001d45f': '$\\mathsl{r}$', +u'\U0001d460': '$\\mathsl{s}$', +u'\U0001d461': '$\\mathsl{t}$', +u'\U0001d462': '$\\mathsl{u}$', +u'\U0001d463': '$\\mathsl{v}$', +u'\U0001d464': '$\\mathsl{w}$', +u'\U0001d465': '$\\mathsl{x}$', +u'\U0001d466': '$\\mathsl{y}$', +u'\U0001d467': '$\\mathsl{z}$', +u'\U0001d468': '$\\mathbit{A}$', +u'\U0001d469': '$\\mathbit{B}$', +u'\U0001d46a': '$\\mathbit{C}$', +u'\U0001d46b': '$\\mathbit{D}$', +u'\U0001d46c': '$\\mathbit{E}$', +u'\U0001d46d': '$\\mathbit{F}$', +u'\U0001d46e': '$\\mathbit{G}$', +u'\U0001d46f': '$\\mathbit{H}$', +u'\U0001d470': '$\\mathbit{I}$', +u'\U0001d471': '$\\mathbit{J}$', +u'\U0001d472': '$\\mathbit{K}$', +u'\U0001d473': '$\\mathbit{L}$', +u'\U0001d474': '$\\mathbit{M}$', +u'\U0001d475': '$\\mathbit{N}$', +u'\U0001d476': '$\\mathbit{O}$', +u'\U0001d477': '$\\mathbit{P}$', +u'\U0001d478': '$\\mathbit{Q}$', +u'\U0001d479': '$\\mathbit{R}$', +u'\U0001d47a': '$\\mathbit{S}$', +u'\U0001d47b': '$\\mathbit{T}$', +u'\U0001d47c': '$\\mathbit{U}$', +u'\U0001d47d': '$\\mathbit{V}$', +u'\U0001d47e': '$\\mathbit{W}$', +u'\U0001d47f': '$\\mathbit{X}$', +u'\U0001d480': '$\\mathbit{Y}$', +u'\U0001d481': '$\\mathbit{Z}$', +u'\U0001d482': '$\\mathbit{a}$', +u'\U0001d483': '$\\mathbit{b}$', +u'\U0001d484': '$\\mathbit{c}$', +u'\U0001d485': '$\\mathbit{d}$', +u'\U0001d486': '$\\mathbit{e}$', +u'\U0001d487': '$\\mathbit{f}$', +u'\U0001d488': '$\\mathbit{g}$', +u'\U0001d489': '$\\mathbit{h}$', +u'\U0001d48a': '$\\mathbit{i}$', +u'\U0001d48b': '$\\mathbit{j}$', +u'\U0001d48c': '$\\mathbit{k}$', +u'\U0001d48d': '$\\mathbit{l}$', +u'\U0001d48e': '$\\mathbit{m}$', +u'\U0001d48f': '$\\mathbit{n}$', +u'\U0001d490': '$\\mathbit{o}$', +u'\U0001d491': '$\\mathbit{p}$', +u'\U0001d492': '$\\mathbit{q}$', +u'\U0001d493': '$\\mathbit{r}$', +u'\U0001d494': '$\\mathbit{s}$', +u'\U0001d495': '$\\mathbit{t}$', +u'\U0001d496': '$\\mathbit{u}$', +u'\U0001d497': '$\\mathbit{v}$', +u'\U0001d498': '$\\mathbit{w}$', +u'\U0001d499': '$\\mathbit{x}$', +u'\U0001d49a': '$\\mathbit{y}$', +u'\U0001d49b': '$\\mathbit{z}$', +u'\U0001d49c': '$\\mathscr{A}$', +u'\U0001d49e': '$\\mathscr{C}$', +u'\U0001d49f': '$\\mathscr{D}$', +u'\U0001d4a2': '$\\mathscr{G}$', +u'\U0001d4a5': '$\\mathscr{J}$', +u'\U0001d4a6': '$\\mathscr{K}$', +u'\U0001d4a9': '$\\mathscr{N}$', +u'\U0001d4aa': '$\\mathscr{O}$', +u'\U0001d4ab': '$\\mathscr{P}$', +u'\U0001d4ac': '$\\mathscr{Q}$', +u'\U0001d4ae': '$\\mathscr{S}$', +u'\U0001d4af': '$\\mathscr{T}$', +u'\U0001d4b0': '$\\mathscr{U}$', +u'\U0001d4b1': '$\\mathscr{V}$', +u'\U0001d4b2': '$\\mathscr{W}$', +u'\U0001d4b3': '$\\mathscr{X}$', +u'\U0001d4b4': '$\\mathscr{Y}$', +u'\U0001d4b5': '$\\mathscr{Z}$', +u'\U0001d4b6': '$\\mathscr{a}$', +u'\U0001d4b7': '$\\mathscr{b}$', +u'\U0001d4b8': '$\\mathscr{c}$', +u'\U0001d4b9': '$\\mathscr{d}$', +u'\U0001d4bb': '$\\mathscr{f}$', +u'\U0001d4bd': '$\\mathscr{h}$', +u'\U0001d4be': '$\\mathscr{i}$', +u'\U0001d4bf': '$\\mathscr{j}$', +u'\U0001d4c0': '$\\mathscr{k}$', +u'\U0001d4c1': '$\\mathscr{l}$', +u'\U0001d4c2': '$\\mathscr{m}$', +u'\U0001d4c3': '$\\mathscr{n}$', +u'\U0001d4c5': '$\\mathscr{p}$', +u'\U0001d4c6': '$\\mathscr{q}$', +u'\U0001d4c7': '$\\mathscr{r}$', +u'\U0001d4c8': '$\\mathscr{s}$', +u'\U0001d4c9': '$\\mathscr{t}$', +u'\U0001d4ca': '$\\mathscr{u}$', +u'\U0001d4cb': '$\\mathscr{v}$', +u'\U0001d4cc': '$\\mathscr{w}$', +u'\U0001d4cd': '$\\mathscr{x}$', +u'\U0001d4ce': '$\\mathscr{y}$', +u'\U0001d4cf': '$\\mathscr{z}$', +u'\U0001d4d0': '$\\mathmit{A}$', +u'\U0001d4d1': '$\\mathmit{B}$', +u'\U0001d4d2': '$\\mathmit{C}$', +u'\U0001d4d3': '$\\mathmit{D}$', +u'\U0001d4d4': '$\\mathmit{E}$', +u'\U0001d4d5': '$\\mathmit{F}$', +u'\U0001d4d6': '$\\mathmit{G}$', +u'\U0001d4d7': '$\\mathmit{H}$', +u'\U0001d4d8': '$\\mathmit{I}$', +u'\U0001d4d9': '$\\mathmit{J}$', +u'\U0001d4da': '$\\mathmit{K}$', +u'\U0001d4db': '$\\mathmit{L}$', +u'\U0001d4dc': '$\\mathmit{M}$', +u'\U0001d4dd': '$\\mathmit{N}$', +u'\U0001d4de': '$\\mathmit{O}$', +u'\U0001d4df': '$\\mathmit{P}$', +u'\U0001d4e0': '$\\mathmit{Q}$', +u'\U0001d4e1': '$\\mathmit{R}$', +u'\U0001d4e2': '$\\mathmit{S}$', +u'\U0001d4e3': '$\\mathmit{T}$', +u'\U0001d4e4': '$\\mathmit{U}$', +u'\U0001d4e5': '$\\mathmit{V}$', +u'\U0001d4e6': '$\\mathmit{W}$', +u'\U0001d4e7': '$\\mathmit{X}$', +u'\U0001d4e8': '$\\mathmit{Y}$', +u'\U0001d4e9': '$\\mathmit{Z}$', +u'\U0001d4ea': '$\\mathmit{a}$', +u'\U0001d4eb': '$\\mathmit{b}$', +u'\U0001d4ec': '$\\mathmit{c}$', +u'\U0001d4ed': '$\\mathmit{d}$', +u'\U0001d4ee': '$\\mathmit{e}$', +u'\U0001d4ef': '$\\mathmit{f}$', +u'\U0001d4f0': '$\\mathmit{g}$', +u'\U0001d4f1': '$\\mathmit{h}$', +u'\U0001d4f2': '$\\mathmit{i}$', +u'\U0001d4f3': '$\\mathmit{j}$', +u'\U0001d4f4': '$\\mathmit{k}$', +u'\U0001d4f5': '$\\mathmit{l}$', +u'\U0001d4f6': '$\\mathmit{m}$', +u'\U0001d4f7': '$\\mathmit{n}$', +u'\U0001d4f8': '$\\mathmit{o}$', +u'\U0001d4f9': '$\\mathmit{p}$', +u'\U0001d4fa': '$\\mathmit{q}$', +u'\U0001d4fb': '$\\mathmit{r}$', +u'\U0001d4fc': '$\\mathmit{s}$', +u'\U0001d4fd': '$\\mathmit{t}$', +u'\U0001d4fe': '$\\mathmit{u}$', +u'\U0001d4ff': '$\\mathmit{v}$', +u'\U0001d500': '$\\mathmit{w}$', +u'\U0001d501': '$\\mathmit{x}$', +u'\U0001d502': '$\\mathmit{y}$', +u'\U0001d503': '$\\mathmit{z}$', +u'\U0001d504': '$\\mathfrak{A}$', +u'\U0001d505': '$\\mathfrak{B}$', +u'\U0001d507': '$\\mathfrak{D}$', +u'\U0001d508': '$\\mathfrak{E}$', +u'\U0001d509': '$\\mathfrak{F}$', +u'\U0001d50a': '$\\mathfrak{G}$', +u'\U0001d50d': '$\\mathfrak{J}$', +u'\U0001d50e': '$\\mathfrak{K}$', +u'\U0001d50f': '$\\mathfrak{L}$', +u'\U0001d510': '$\\mathfrak{M}$', +u'\U0001d511': '$\\mathfrak{N}$', +u'\U0001d512': '$\\mathfrak{O}$', +u'\U0001d513': '$\\mathfrak{P}$', +u'\U0001d514': '$\\mathfrak{Q}$', +u'\U0001d516': '$\\mathfrak{S}$', +u'\U0001d517': '$\\mathfrak{T}$', +u'\U0001d518': '$\\mathfrak{U}$', +u'\U0001d519': '$\\mathfrak{V}$', +u'\U0001d51a': '$\\mathfrak{W}$', +u'\U0001d51b': '$\\mathfrak{X}$', +u'\U0001d51c': '$\\mathfrak{Y}$', +u'\U0001d51e': '$\\mathfrak{a}$', +u'\U0001d51f': '$\\mathfrak{b}$', +u'\U0001d520': '$\\mathfrak{c}$', +u'\U0001d521': '$\\mathfrak{d}$', +u'\U0001d522': '$\\mathfrak{e}$', +u'\U0001d523': '$\\mathfrak{f}$', +u'\U0001d524': '$\\mathfrak{g}$', +u'\U0001d525': '$\\mathfrak{h}$', +u'\U0001d526': '$\\mathfrak{i}$', +u'\U0001d527': '$\\mathfrak{j}$', +u'\U0001d528': '$\\mathfrak{k}$', +u'\U0001d529': '$\\mathfrak{l}$', +u'\U0001d52a': '$\\mathfrak{m}$', +u'\U0001d52b': '$\\mathfrak{n}$', +u'\U0001d52c': '$\\mathfrak{o}$', +u'\U0001d52d': '$\\mathfrak{p}$', +u'\U0001d52e': '$\\mathfrak{q}$', +u'\U0001d52f': '$\\mathfrak{r}$', +u'\U0001d530': '$\\mathfrak{s}$', +u'\U0001d531': '$\\mathfrak{t}$', +u'\U0001d532': '$\\mathfrak{u}$', +u'\U0001d533': '$\\mathfrak{v}$', +u'\U0001d534': '$\\mathfrak{w}$', +u'\U0001d535': '$\\mathfrak{x}$', +u'\U0001d536': '$\\mathfrak{y}$', +u'\U0001d537': '$\\mathfrak{z}$', +u'\U0001d538': '$\\mathbb{A}$', +u'\U0001d539': '$\\mathbb{B}$', +u'\U0001d53b': '$\\mathbb{D}$', +u'\U0001d53c': '$\\mathbb{E}$', +u'\U0001d53d': '$\\mathbb{F}$', +u'\U0001d53e': '$\\mathbb{G}$', +u'\U0001d540': '$\\mathbb{I}$', +u'\U0001d541': '$\\mathbb{J}$', +u'\U0001d542': '$\\mathbb{K}$', +u'\U0001d543': '$\\mathbb{L}$', +u'\U0001d544': '$\\mathbb{M}$', +u'\U0001d546': '$\\mathbb{O}$', +u'\U0001d54a': '$\\mathbb{S}$', +u'\U0001d54b': '$\\mathbb{T}$', +u'\U0001d54c': '$\\mathbb{U}$', +u'\U0001d54d': '$\\mathbb{V}$', +u'\U0001d54e': '$\\mathbb{W}$', +u'\U0001d54f': '$\\mathbb{X}$', +u'\U0001d550': '$\\mathbb{Y}$', +u'\U0001d552': '$\\mathbb{a}$', +u'\U0001d553': '$\\mathbb{b}$', +u'\U0001d554': '$\\mathbb{c}$', +u'\U0001d555': '$\\mathbb{d}$', +u'\U0001d556': '$\\mathbb{e}$', +u'\U0001d557': '$\\mathbb{f}$', +u'\U0001d558': '$\\mathbb{g}$', +u'\U0001d559': '$\\mathbb{h}$', +u'\U0001d55a': '$\\mathbb{i}$', +u'\U0001d55b': '$\\mathbb{j}$', +u'\U0001d55c': '$\\mathbb{k}$', +u'\U0001d55d': '$\\mathbb{l}$', +u'\U0001d55e': '$\\mathbb{m}$', +u'\U0001d55f': '$\\mathbb{n}$', +u'\U0001d560': '$\\mathbb{o}$', +u'\U0001d561': '$\\mathbb{p}$', +u'\U0001d562': '$\\mathbb{q}$', +u'\U0001d563': '$\\mathbb{r}$', +u'\U0001d564': '$\\mathbb{s}$', +u'\U0001d565': '$\\mathbb{t}$', +u'\U0001d566': '$\\mathbb{u}$', +u'\U0001d567': '$\\mathbb{v}$', +u'\U0001d568': '$\\mathbb{w}$', +u'\U0001d569': '$\\mathbb{x}$', +u'\U0001d56a': '$\\mathbb{y}$', +u'\U0001d56b': '$\\mathbb{z}$', +u'\U0001d56c': '$\\mathslbb{A}$', +u'\U0001d56d': '$\\mathslbb{B}$', +u'\U0001d56e': '$\\mathslbb{C}$', +u'\U0001d56f': '$\\mathslbb{D}$', +u'\U0001d570': '$\\mathslbb{E}$', +u'\U0001d571': '$\\mathslbb{F}$', +u'\U0001d572': '$\\mathslbb{G}$', +u'\U0001d573': '$\\mathslbb{H}$', +u'\U0001d574': '$\\mathslbb{I}$', +u'\U0001d575': '$\\mathslbb{J}$', +u'\U0001d576': '$\\mathslbb{K}$', +u'\U0001d577': '$\\mathslbb{L}$', +u'\U0001d578': '$\\mathslbb{M}$', +u'\U0001d579': '$\\mathslbb{N}$', +u'\U0001d57a': '$\\mathslbb{O}$', +u'\U0001d57b': '$\\mathslbb{P}$', +u'\U0001d57c': '$\\mathslbb{Q}$', +u'\U0001d57d': '$\\mathslbb{R}$', +u'\U0001d57e': '$\\mathslbb{S}$', +u'\U0001d57f': '$\\mathslbb{T}$', +u'\U0001d580': '$\\mathslbb{U}$', +u'\U0001d581': '$\\mathslbb{V}$', +u'\U0001d582': '$\\mathslbb{W}$', +u'\U0001d583': '$\\mathslbb{X}$', +u'\U0001d584': '$\\mathslbb{Y}$', +u'\U0001d585': '$\\mathslbb{Z}$', +u'\U0001d586': '$\\mathslbb{a}$', +u'\U0001d587': '$\\mathslbb{b}$', +u'\U0001d588': '$\\mathslbb{c}$', +u'\U0001d589': '$\\mathslbb{d}$', +u'\U0001d58a': '$\\mathslbb{e}$', +u'\U0001d58b': '$\\mathslbb{f}$', +u'\U0001d58c': '$\\mathslbb{g}$', +u'\U0001d58d': '$\\mathslbb{h}$', +u'\U0001d58e': '$\\mathslbb{i}$', +u'\U0001d58f': '$\\mathslbb{j}$', +u'\U0001d590': '$\\mathslbb{k}$', +u'\U0001d591': '$\\mathslbb{l}$', +u'\U0001d592': '$\\mathslbb{m}$', +u'\U0001d593': '$\\mathslbb{n}$', +u'\U0001d594': '$\\mathslbb{o}$', +u'\U0001d595': '$\\mathslbb{p}$', +u'\U0001d596': '$\\mathslbb{q}$', +u'\U0001d597': '$\\mathslbb{r}$', +u'\U0001d598': '$\\mathslbb{s}$', +u'\U0001d599': '$\\mathslbb{t}$', +u'\U0001d59a': '$\\mathslbb{u}$', +u'\U0001d59b': '$\\mathslbb{v}$', +u'\U0001d59c': '$\\mathslbb{w}$', +u'\U0001d59d': '$\\mathslbb{x}$', +u'\U0001d59e': '$\\mathslbb{y}$', +u'\U0001d59f': '$\\mathslbb{z}$', +u'\U0001d5a0': '$\\mathsf{A}$', +u'\U0001d5a1': '$\\mathsf{B}$', +u'\U0001d5a2': '$\\mathsf{C}$', +u'\U0001d5a3': '$\\mathsf{D}$', +u'\U0001d5a4': '$\\mathsf{E}$', +u'\U0001d5a5': '$\\mathsf{F}$', +u'\U0001d5a6': '$\\mathsf{G}$', +u'\U0001d5a7': '$\\mathsf{H}$', +u'\U0001d5a8': '$\\mathsf{I}$', +u'\U0001d5a9': '$\\mathsf{J}$', +u'\U0001d5aa': '$\\mathsf{K}$', +u'\U0001d5ab': '$\\mathsf{L}$', +u'\U0001d5ac': '$\\mathsf{M}$', +u'\U0001d5ad': '$\\mathsf{N}$', +u'\U0001d5ae': '$\\mathsf{O}$', +u'\U0001d5af': '$\\mathsf{P}$', +u'\U0001d5b0': '$\\mathsf{Q}$', +u'\U0001d5b1': '$\\mathsf{R}$', +u'\U0001d5b2': '$\\mathsf{S}$', +u'\U0001d5b3': '$\\mathsf{T}$', +u'\U0001d5b4': '$\\mathsf{U}$', +u'\U0001d5b5': '$\\mathsf{V}$', +u'\U0001d5b6': '$\\mathsf{W}$', +u'\U0001d5b7': '$\\mathsf{X}$', +u'\U0001d5b8': '$\\mathsf{Y}$', +u'\U0001d5b9': '$\\mathsf{Z}$', +u'\U0001d5ba': '$\\mathsf{a}$', +u'\U0001d5bb': '$\\mathsf{b}$', +u'\U0001d5bc': '$\\mathsf{c}$', +u'\U0001d5bd': '$\\mathsf{d}$', +u'\U0001d5be': '$\\mathsf{e}$', +u'\U0001d5bf': '$\\mathsf{f}$', +u'\U0001d5c0': '$\\mathsf{g}$', +u'\U0001d5c1': '$\\mathsf{h}$', +u'\U0001d5c2': '$\\mathsf{i}$', +u'\U0001d5c3': '$\\mathsf{j}$', +u'\U0001d5c4': '$\\mathsf{k}$', +u'\U0001d5c5': '$\\mathsf{l}$', +u'\U0001d5c6': '$\\mathsf{m}$', +u'\U0001d5c7': '$\\mathsf{n}$', +u'\U0001d5c8': '$\\mathsf{o}$', +u'\U0001d5c9': '$\\mathsf{p}$', +u'\U0001d5ca': '$\\mathsf{q}$', +u'\U0001d5cb': '$\\mathsf{r}$', +u'\U0001d5cc': '$\\mathsf{s}$', +u'\U0001d5cd': '$\\mathsf{t}$', +u'\U0001d5ce': '$\\mathsf{u}$', +u'\U0001d5cf': '$\\mathsf{v}$', +u'\U0001d5d0': '$\\mathsf{w}$', +u'\U0001d5d1': '$\\mathsf{x}$', +u'\U0001d5d2': '$\\mathsf{y}$', +u'\U0001d5d3': '$\\mathsf{z}$', +u'\U0001d5d4': '$\\mathsfbf{A}$', +u'\U0001d5d5': '$\\mathsfbf{B}$', +u'\U0001d5d6': '$\\mathsfbf{C}$', +u'\U0001d5d7': '$\\mathsfbf{D}$', +u'\U0001d5d8': '$\\mathsfbf{E}$', +u'\U0001d5d9': '$\\mathsfbf{F}$', +u'\U0001d5da': '$\\mathsfbf{G}$', +u'\U0001d5db': '$\\mathsfbf{H}$', +u'\U0001d5dc': '$\\mathsfbf{I}$', +u'\U0001d5dd': '$\\mathsfbf{J}$', +u'\U0001d5de': '$\\mathsfbf{K}$', +u'\U0001d5df': '$\\mathsfbf{L}$', +u'\U0001d5e0': '$\\mathsfbf{M}$', +u'\U0001d5e1': '$\\mathsfbf{N}$', +u'\U0001d5e2': '$\\mathsfbf{O}$', +u'\U0001d5e3': '$\\mathsfbf{P}$', +u'\U0001d5e4': '$\\mathsfbf{Q}$', +u'\U0001d5e5': '$\\mathsfbf{R}$', +u'\U0001d5e6': '$\\mathsfbf{S}$', +u'\U0001d5e7': '$\\mathsfbf{T}$', +u'\U0001d5e8': '$\\mathsfbf{U}$', +u'\U0001d5e9': '$\\mathsfbf{V}$', +u'\U0001d5ea': '$\\mathsfbf{W}$', +u'\U0001d5eb': '$\\mathsfbf{X}$', +u'\U0001d5ec': '$\\mathsfbf{Y}$', +u'\U0001d5ed': '$\\mathsfbf{Z}$', +u'\U0001d5ee': '$\\mathsfbf{a}$', +u'\U0001d5ef': '$\\mathsfbf{b}$', +u'\U0001d5f0': '$\\mathsfbf{c}$', +u'\U0001d5f1': '$\\mathsfbf{d}$', +u'\U0001d5f2': '$\\mathsfbf{e}$', +u'\U0001d5f3': '$\\mathsfbf{f}$', +u'\U0001d5f4': '$\\mathsfbf{g}$', +u'\U0001d5f5': '$\\mathsfbf{h}$', +u'\U0001d5f6': '$\\mathsfbf{i}$', +u'\U0001d5f7': '$\\mathsfbf{j}$', +u'\U0001d5f8': '$\\mathsfbf{k}$', +u'\U0001d5f9': '$\\mathsfbf{l}$', +u'\U0001d5fa': '$\\mathsfbf{m}$', +u'\U0001d5fb': '$\\mathsfbf{n}$', +u'\U0001d5fc': '$\\mathsfbf{o}$', +u'\U0001d5fd': '$\\mathsfbf{p}$', +u'\U0001d5fe': '$\\mathsfbf{q}$', +u'\U0001d5ff': '$\\mathsfbf{r}$', +u'\U0001d600': '$\\mathsfbf{s}$', +u'\U0001d601': '$\\mathsfbf{t}$', +u'\U0001d602': '$\\mathsfbf{u}$', +u'\U0001d603': '$\\mathsfbf{v}$', +u'\U0001d604': '$\\mathsfbf{w}$', +u'\U0001d605': '$\\mathsfbf{x}$', +u'\U0001d606': '$\\mathsfbf{y}$', +u'\U0001d607': '$\\mathsfbf{z}$', +u'\U0001d608': '$\\mathsfsl{A}$', +u'\U0001d609': '$\\mathsfsl{B}$', +u'\U0001d60a': '$\\mathsfsl{C}$', +u'\U0001d60b': '$\\mathsfsl{D}$', +u'\U0001d60c': '$\\mathsfsl{E}$', +u'\U0001d60d': '$\\mathsfsl{F}$', +u'\U0001d60e': '$\\mathsfsl{G}$', +u'\U0001d60f': '$\\mathsfsl{H}$', +u'\U0001d610': '$\\mathsfsl{I}$', +u'\U0001d611': '$\\mathsfsl{J}$', +u'\U0001d612': '$\\mathsfsl{K}$', +u'\U0001d613': '$\\mathsfsl{L}$', +u'\U0001d614': '$\\mathsfsl{M}$', +u'\U0001d615': '$\\mathsfsl{N}$', +u'\U0001d616': '$\\mathsfsl{O}$', +u'\U0001d617': '$\\mathsfsl{P}$', +u'\U0001d618': '$\\mathsfsl{Q}$', +u'\U0001d619': '$\\mathsfsl{R}$', +u'\U0001d61a': '$\\mathsfsl{S}$', +u'\U0001d61b': '$\\mathsfsl{T}$', +u'\U0001d61c': '$\\mathsfsl{U}$', +u'\U0001d61d': '$\\mathsfsl{V}$', +u'\U0001d61e': '$\\mathsfsl{W}$', +u'\U0001d61f': '$\\mathsfsl{X}$', +u'\U0001d620': '$\\mathsfsl{Y}$', +u'\U0001d621': '$\\mathsfsl{Z}$', +u'\U0001d622': '$\\mathsfsl{a}$', +u'\U0001d623': '$\\mathsfsl{b}$', +u'\U0001d624': '$\\mathsfsl{c}$', +u'\U0001d625': '$\\mathsfsl{d}$', +u'\U0001d626': '$\\mathsfsl{e}$', +u'\U0001d627': '$\\mathsfsl{f}$', +u'\U0001d628': '$\\mathsfsl{g}$', +u'\U0001d629': '$\\mathsfsl{h}$', +u'\U0001d62a': '$\\mathsfsl{i}$', +u'\U0001d62b': '$\\mathsfsl{j}$', +u'\U0001d62c': '$\\mathsfsl{k}$', +u'\U0001d62d': '$\\mathsfsl{l}$', +u'\U0001d62e': '$\\mathsfsl{m}$', +u'\U0001d62f': '$\\mathsfsl{n}$', +u'\U0001d630': '$\\mathsfsl{o}$', +u'\U0001d631': '$\\mathsfsl{p}$', +u'\U0001d632': '$\\mathsfsl{q}$', +u'\U0001d633': '$\\mathsfsl{r}$', +u'\U0001d634': '$\\mathsfsl{s}$', +u'\U0001d635': '$\\mathsfsl{t}$', +u'\U0001d636': '$\\mathsfsl{u}$', +u'\U0001d637': '$\\mathsfsl{v}$', +u'\U0001d638': '$\\mathsfsl{w}$', +u'\U0001d639': '$\\mathsfsl{x}$', +u'\U0001d63a': '$\\mathsfsl{y}$', +u'\U0001d63b': '$\\mathsfsl{z}$', +u'\U0001d63c': '$\\mathsfbfsl{A}$', +u'\U0001d63d': '$\\mathsfbfsl{B}$', +u'\U0001d63e': '$\\mathsfbfsl{C}$', +u'\U0001d63f': '$\\mathsfbfsl{D}$', +u'\U0001d640': '$\\mathsfbfsl{E}$', +u'\U0001d641': '$\\mathsfbfsl{F}$', +u'\U0001d642': '$\\mathsfbfsl{G}$', +u'\U0001d643': '$\\mathsfbfsl{H}$', +u'\U0001d644': '$\\mathsfbfsl{I}$', +u'\U0001d645': '$\\mathsfbfsl{J}$', +u'\U0001d646': '$\\mathsfbfsl{K}$', +u'\U0001d647': '$\\mathsfbfsl{L}$', +u'\U0001d648': '$\\mathsfbfsl{M}$', +u'\U0001d649': '$\\mathsfbfsl{N}$', +u'\U0001d64a': '$\\mathsfbfsl{O}$', +u'\U0001d64b': '$\\mathsfbfsl{P}$', +u'\U0001d64c': '$\\mathsfbfsl{Q}$', +u'\U0001d64d': '$\\mathsfbfsl{R}$', +u'\U0001d64e': '$\\mathsfbfsl{S}$', +u'\U0001d64f': '$\\mathsfbfsl{T}$', +u'\U0001d650': '$\\mathsfbfsl{U}$', +u'\U0001d651': '$\\mathsfbfsl{V}$', +u'\U0001d652': '$\\mathsfbfsl{W}$', +u'\U0001d653': '$\\mathsfbfsl{X}$', +u'\U0001d654': '$\\mathsfbfsl{Y}$', +u'\U0001d655': '$\\mathsfbfsl{Z}$', +u'\U0001d656': '$\\mathsfbfsl{a}$', +u'\U0001d657': '$\\mathsfbfsl{b}$', +u'\U0001d658': '$\\mathsfbfsl{c}$', +u'\U0001d659': '$\\mathsfbfsl{d}$', +u'\U0001d65a': '$\\mathsfbfsl{e}$', +u'\U0001d65b': '$\\mathsfbfsl{f}$', +u'\U0001d65c': '$\\mathsfbfsl{g}$', +u'\U0001d65d': '$\\mathsfbfsl{h}$', +u'\U0001d65e': '$\\mathsfbfsl{i}$', +u'\U0001d65f': '$\\mathsfbfsl{j}$', +u'\U0001d660': '$\\mathsfbfsl{k}$', +u'\U0001d661': '$\\mathsfbfsl{l}$', +u'\U0001d662': '$\\mathsfbfsl{m}$', +u'\U0001d663': '$\\mathsfbfsl{n}$', +u'\U0001d664': '$\\mathsfbfsl{o}$', +u'\U0001d665': '$\\mathsfbfsl{p}$', +u'\U0001d666': '$\\mathsfbfsl{q}$', +u'\U0001d667': '$\\mathsfbfsl{r}$', +u'\U0001d668': '$\\mathsfbfsl{s}$', +u'\U0001d669': '$\\mathsfbfsl{t}$', +u'\U0001d66a': '$\\mathsfbfsl{u}$', +u'\U0001d66b': '$\\mathsfbfsl{v}$', +u'\U0001d66c': '$\\mathsfbfsl{w}$', +u'\U0001d66d': '$\\mathsfbfsl{x}$', +u'\U0001d66e': '$\\mathsfbfsl{y}$', +u'\U0001d66f': '$\\mathsfbfsl{z}$', +u'\U0001d670': '$\\mathtt{A}$', +u'\U0001d671': '$\\mathtt{B}$', +u'\U0001d672': '$\\mathtt{C}$', +u'\U0001d673': '$\\mathtt{D}$', +u'\U0001d674': '$\\mathtt{E}$', +u'\U0001d675': '$\\mathtt{F}$', +u'\U0001d676': '$\\mathtt{G}$', +u'\U0001d677': '$\\mathtt{H}$', +u'\U0001d678': '$\\mathtt{I}$', +u'\U0001d679': '$\\mathtt{J}$', +u'\U0001d67a': '$\\mathtt{K}$', +u'\U0001d67b': '$\\mathtt{L}$', +u'\U0001d67c': '$\\mathtt{M}$', +u'\U0001d67d': '$\\mathtt{N}$', +u'\U0001d67e': '$\\mathtt{O}$', +u'\U0001d67f': '$\\mathtt{P}$', +u'\U0001d680': '$\\mathtt{Q}$', +u'\U0001d681': '$\\mathtt{R}$', +u'\U0001d682': '$\\mathtt{S}$', +u'\U0001d683': '$\\mathtt{T}$', +u'\U0001d684': '$\\mathtt{U}$', +u'\U0001d685': '$\\mathtt{V}$', +u'\U0001d686': '$\\mathtt{W}$', +u'\U0001d687': '$\\mathtt{X}$', +u'\U0001d688': '$\\mathtt{Y}$', +u'\U0001d689': '$\\mathtt{Z}$', +u'\U0001d68a': '$\\mathtt{a}$', +u'\U0001d68b': '$\\mathtt{b}$', +u'\U0001d68c': '$\\mathtt{c}$', +u'\U0001d68d': '$\\mathtt{d}$', +u'\U0001d68e': '$\\mathtt{e}$', +u'\U0001d68f': '$\\mathtt{f}$', +u'\U0001d690': '$\\mathtt{g}$', +u'\U0001d691': '$\\mathtt{h}$', +u'\U0001d692': '$\\mathtt{i}$', +u'\U0001d693': '$\\mathtt{j}$', +u'\U0001d694': '$\\mathtt{k}$', +u'\U0001d695': '$\\mathtt{l}$', +u'\U0001d696': '$\\mathtt{m}$', +u'\U0001d697': '$\\mathtt{n}$', +u'\U0001d698': '$\\mathtt{o}$', +u'\U0001d699': '$\\mathtt{p}$', +u'\U0001d69a': '$\\mathtt{q}$', +u'\U0001d69b': '$\\mathtt{r}$', +u'\U0001d69c': '$\\mathtt{s}$', +u'\U0001d69d': '$\\mathtt{t}$', +u'\U0001d69e': '$\\mathtt{u}$', +u'\U0001d69f': '$\\mathtt{v}$', +u'\U0001d6a0': '$\\mathtt{w}$', +u'\U0001d6a1': '$\\mathtt{x}$', +u'\U0001d6a2': '$\\mathtt{y}$', +u'\U0001d6a3': '$\\mathtt{z}$', +u'\U0001d6a8': '$\\mathbf{\\Alpha}$', +u'\U0001d6a9': '$\\mathbf{\\Beta}$', +u'\U0001d6aa': '$\\mathbf{\\Gamma}$', +u'\U0001d6ab': '$\\mathbf{\\Delta}$', +u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', +u'\U0001d6ad': '$\\mathbf{\\Zeta}$', +u'\U0001d6ae': '$\\mathbf{\\Eta}$', +u'\U0001d6af': '$\\mathbf{\\Theta}$', +u'\U0001d6b0': '$\\mathbf{\\Iota}$', +u'\U0001d6b1': '$\\mathbf{\\Kappa}$', +u'\U0001d6b2': '$\\mathbf{\\Lambda}$', +u'\U0001d6b3': '$M$', +u'\U0001d6b4': '$N$', +u'\U0001d6b5': '$\\mathbf{\\Xi}$', +u'\U0001d6b6': '$O$', +u'\U0001d6b7': '$\\mathbf{\\Pi}$', +u'\U0001d6b8': '$\\mathbf{\\Rho}$', +u'\U0001d6b9': '{\\mathbf{\\vartheta}}', +u'\U0001d6ba': '$\\mathbf{\\Sigma}$', +u'\U0001d6bb': '$\\mathbf{\\Tau}$', +u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', +u'\U0001d6bd': '$\\mathbf{\\Phi}$', +u'\U0001d6be': '$\\mathbf{\\Chi}$', +u'\U0001d6bf': '$\\mathbf{\\Psi}$', +u'\U0001d6c0': '$\\mathbf{\\Omega}$', +u'\U0001d6c1': '$\\mathbf{\\nabla}$', +u'\U0001d6c2': '$\\mathbf{\\Alpha}$', +u'\U0001d6c3': '$\\mathbf{\\Beta}$', +u'\U0001d6c4': '$\\mathbf{\\Gamma}$', +u'\U0001d6c5': '$\\mathbf{\\Delta}$', +u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', +u'\U0001d6c7': '$\\mathbf{\\Zeta}$', +u'\U0001d6c8': '$\\mathbf{\\Eta}$', +u'\U0001d6c9': '$\\mathbf{\\theta}$', +u'\U0001d6ca': '$\\mathbf{\\Iota}$', +u'\U0001d6cb': '$\\mathbf{\\Kappa}$', +u'\U0001d6cc': '$\\mathbf{\\Lambda}$', +u'\U0001d6cd': '$M$', +u'\U0001d6ce': '$N$', +u'\U0001d6cf': '$\\mathbf{\\Xi}$', +u'\U0001d6d0': '$O$', +u'\U0001d6d1': '$\\mathbf{\\Pi}$', +u'\U0001d6d2': '$\\mathbf{\\Rho}$', +u'\U0001d6d3': '$\\mathbf{\\varsigma}$', +u'\U0001d6d4': '$\\mathbf{\\Sigma}$', +u'\U0001d6d5': '$\\mathbf{\\Tau}$', +u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', +u'\U0001d6d7': '$\\mathbf{\\Phi}$', +u'\U0001d6d8': '$\\mathbf{\\Chi}$', +u'\U0001d6d9': '$\\mathbf{\\Psi}$', +u'\U0001d6da': '$\\mathbf{\\Omega}$', +u'\U0001d6db': '$\\partial$', +u'\U0001d6dc': '$\\in$', +u'\U0001d6dd': '{\\mathbf{\\vartheta}}', +u'\U0001d6de': '{\\mathbf{\\varkappa}}', +u'\U0001d6df': '{\\mathbf{\\phi}}', +u'\U0001d6e0': '{\\mathbf{\\varrho}}', +u'\U0001d6e1': '{\\mathbf{\\varpi}}', +u'\U0001d6e2': '$\\mathsl{\\Alpha}$', +u'\U0001d6e3': '$\\mathsl{\\Beta}$', +u'\U0001d6e4': '$\\mathsl{\\Gamma}$', +u'\U0001d6e5': '$\\mathsl{\\Delta}$', +u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', +u'\U0001d6e7': '$\\mathsl{\\Zeta}$', +u'\U0001d6e8': '$\\mathsl{\\Eta}$', +u'\U0001d6e9': '$\\mathsl{\\Theta}$', +u'\U0001d6ea': '$\\mathsl{\\Iota}$', +u'\U0001d6eb': '$\\mathsl{\\Kappa}$', +u'\U0001d6ec': '$\\mathsl{\\Lambda}$', +u'\U0001d6ed': '$M$', +u'\U0001d6ee': '$N$', +u'\U0001d6ef': '$\\mathsl{\\Xi}$', +u'\U0001d6f0': '$O$', +u'\U0001d6f1': '$\\mathsl{\\Pi}$', +u'\U0001d6f2': '$\\mathsl{\\Rho}$', +u'\U0001d6f3': '{\\mathsl{\\vartheta}}', +u'\U0001d6f4': '$\\mathsl{\\Sigma}$', +u'\U0001d6f5': '$\\mathsl{\\Tau}$', +u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', +u'\U0001d6f7': '$\\mathsl{\\Phi}$', +u'\U0001d6f8': '$\\mathsl{\\Chi}$', +u'\U0001d6f9': '$\\mathsl{\\Psi}$', +u'\U0001d6fa': '$\\mathsl{\\Omega}$', +u'\U0001d6fb': '$\\mathsl{\\nabla}$', +u'\U0001d6fc': '$\\mathsl{\\Alpha}$', +u'\U0001d6fd': '$\\mathsl{\\Beta}$', +u'\U0001d6fe': '$\\mathsl{\\Gamma}$', +u'\U0001d6ff': '$\\mathsl{\\Delta}$', +u'\U0001d700': '$\\mathsl{\\Epsilon}$', +u'\U0001d701': '$\\mathsl{\\Zeta}$', +u'\U0001d702': '$\\mathsl{\\Eta}$', +u'\U0001d703': '$\\mathsl{\\Theta}$', +u'\U0001d704': '$\\mathsl{\\Iota}$', +u'\U0001d705': '$\\mathsl{\\Kappa}$', +u'\U0001d706': '$\\mathsl{\\Lambda}$', +u'\U0001d707': '$M$', +u'\U0001d708': '$N$', +u'\U0001d709': '$\\mathsl{\\Xi}$', +u'\U0001d70a': '$O$', +u'\U0001d70b': '$\\mathsl{\\Pi}$', +u'\U0001d70c': '$\\mathsl{\\Rho}$', +u'\U0001d70d': '$\\mathsl{\\varsigma}$', +u'\U0001d70e': '$\\mathsl{\\Sigma}$', +u'\U0001d70f': '$\\mathsl{\\Tau}$', +u'\U0001d710': '$\\mathsl{\\Upsilon}$', +u'\U0001d711': '$\\mathsl{\\Phi}$', +u'\U0001d712': '$\\mathsl{\\Chi}$', +u'\U0001d713': '$\\mathsl{\\Psi}$', +u'\U0001d714': '$\\mathsl{\\Omega}$', +u'\U0001d715': '$\\partial$', +u'\U0001d716': '$\\in$', +u'\U0001d717': '{\\mathsl{\\vartheta}}', +u'\U0001d718': '{\\mathsl{\\varkappa}}', +u'\U0001d719': '{\\mathsl{\\phi}}', +u'\U0001d71a': '{\\mathsl{\\varrho}}', +u'\U0001d71b': '{\\mathsl{\\varpi}}', +u'\U0001d71c': '$\\mathbit{\\Alpha}$', +u'\U0001d71d': '$\\mathbit{\\Beta}$', +u'\U0001d71e': '$\\mathbit{\\Gamma}$', +u'\U0001d71f': '$\\mathbit{\\Delta}$', +u'\U0001d720': '$\\mathbit{\\Epsilon}$', +u'\U0001d721': '$\\mathbit{\\Zeta}$', +u'\U0001d722': '$\\mathbit{\\Eta}$', +u'\U0001d723': '$\\mathbit{\\Theta}$', +u'\U0001d724': '$\\mathbit{\\Iota}$', +u'\U0001d725': '$\\mathbit{\\Kappa}$', +u'\U0001d726': '$\\mathbit{\\Lambda}$', +u'\U0001d727': '$M$', +u'\U0001d728': '$N$', +u'\U0001d729': '$\\mathbit{\\Xi}$', +u'\U0001d72a': '$O$', +u'\U0001d72b': '$\\mathbit{\\Pi}$', +u'\U0001d72c': '$\\mathbit{\\Rho}$', +u'\U0001d72d': '{\\mathbit{O}}', +u'\U0001d72e': '$\\mathbit{\\Sigma}$', +u'\U0001d72f': '$\\mathbit{\\Tau}$', +u'\U0001d730': '$\\mathbit{\\Upsilon}$', +u'\U0001d731': '$\\mathbit{\\Phi}$', +u'\U0001d732': '$\\mathbit{\\Chi}$', +u'\U0001d733': '$\\mathbit{\\Psi}$', +u'\U0001d734': '$\\mathbit{\\Omega}$', +u'\U0001d735': '$\\mathbit{\\nabla}$', +u'\U0001d736': '$\\mathbit{\\Alpha}$', +u'\U0001d737': '$\\mathbit{\\Beta}$', +u'\U0001d738': '$\\mathbit{\\Gamma}$', +u'\U0001d739': '$\\mathbit{\\Delta}$', +u'\U0001d73a': '$\\mathbit{\\Epsilon}$', +u'\U0001d73b': '$\\mathbit{\\Zeta}$', +u'\U0001d73c': '$\\mathbit{\\Eta}$', +u'\U0001d73d': '$\\mathbit{\\Theta}$', +u'\U0001d73e': '$\\mathbit{\\Iota}$', +u'\U0001d73f': '$\\mathbit{\\Kappa}$', +u'\U0001d740': '$\\mathbit{\\Lambda}$', +u'\U0001d741': '$M$', +u'\U0001d742': '$N$', +u'\U0001d743': '$\\mathbit{\\Xi}$', +u'\U0001d744': '$O$', +u'\U0001d745': '$\\mathbit{\\Pi}$', +u'\U0001d746': '$\\mathbit{\\Rho}$', +u'\U0001d747': '$\\mathbit{\\varsigma}$', +u'\U0001d748': '$\\mathbit{\\Sigma}$', +u'\U0001d749': '$\\mathbit{\\Tau}$', +u'\U0001d74a': '$\\mathbit{\\Upsilon}$', +u'\U0001d74b': '$\\mathbit{\\Phi}$', +u'\U0001d74c': '$\\mathbit{\\Chi}$', +u'\U0001d74d': '$\\mathbit{\\Psi}$', +u'\U0001d74e': '$\\mathbit{\\Omega}$', +u'\U0001d74f': '$\\partial$', +u'\U0001d750': '$\\in$', +u'\U0001d751': '{\\mathbit{\\vartheta}}', +u'\U0001d752': '{\\mathbit{\\varkappa}}', +u'\U0001d753': '{\\mathbit{\\phi}}', +u'\U0001d754': '{\\mathbit{\\varrho}}', +u'\U0001d755': '{\\mathbit{\\varpi}}', +u'\U0001d756': '$\\mathsfbf{\\Alpha}$', +u'\U0001d757': '$\\mathsfbf{\\Beta}$', +u'\U0001d758': '$\\mathsfbf{\\Gamma}$', +u'\U0001d759': '$\\mathsfbf{\\Delta}$', +u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', +u'\U0001d75c': '$\\mathsfbf{\\Eta}$', +u'\U0001d75d': '$\\mathsfbf{\\Theta}$', +u'\U0001d75e': '$\\mathsfbf{\\Iota}$', +u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', +u'\U0001d760': '$\\mathsfbf{\\Lambda}$', +u'\U0001d761': '$M$', +u'\U0001d762': '$N$', +u'\U0001d763': '$\\mathsfbf{\\Xi}$', +u'\U0001d764': '$O$', +u'\U0001d765': '$\\mathsfbf{\\Pi}$', +u'\U0001d766': '$\\mathsfbf{\\Rho}$', +u'\U0001d767': '{\\mathsfbf{\\vartheta}}', +u'\U0001d768': '$\\mathsfbf{\\Sigma}$', +u'\U0001d769': '$\\mathsfbf{\\Tau}$', +u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d76b': '$\\mathsfbf{\\Phi}$', +u'\U0001d76c': '$\\mathsfbf{\\Chi}$', +u'\U0001d76d': '$\\mathsfbf{\\Psi}$', +u'\U0001d76e': '$\\mathsfbf{\\Omega}$', +u'\U0001d76f': '$\\mathsfbf{\\nabla}$', +u'\U0001d770': '$\\mathsfbf{\\Alpha}$', +u'\U0001d771': '$\\mathsfbf{\\Beta}$', +u'\U0001d772': '$\\mathsfbf{\\Gamma}$', +u'\U0001d773': '$\\mathsfbf{\\Delta}$', +u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d775': '$\\mathsfbf{\\Zeta}$', +u'\U0001d776': '$\\mathsfbf{\\Eta}$', +u'\U0001d777': '$\\mathsfbf{\\Theta}$', +u'\U0001d778': '$\\mathsfbf{\\Iota}$', +u'\U0001d779': '$\\mathsfbf{\\Kappa}$', +u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', +u'\U0001d77b': '$M$', +u'\U0001d77c': '$N$', +u'\U0001d77d': '$\\mathsfbf{\\Xi}$', +u'\U0001d77e': '$O$', +u'\U0001d77f': '$\\mathsfbf{\\Pi}$', +u'\U0001d780': '$\\mathsfbf{\\Rho}$', +u'\U0001d781': '$\\mathsfbf{\\varsigma}$', +u'\U0001d782': '$\\mathsfbf{\\Sigma}$', +u'\U0001d783': '$\\mathsfbf{\\Tau}$', +u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d785': '$\\mathsfbf{\\Phi}$', +u'\U0001d786': '$\\mathsfbf{\\Chi}$', +u'\U0001d787': '$\\mathsfbf{\\Psi}$', +u'\U0001d788': '$\\mathsfbf{\\Omega}$', +u'\U0001d789': '$\\partial$', +u'\U0001d78a': '$\\in$', +u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', +u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', +u'\U0001d78d': '{\\mathsfbf{\\phi}}', +u'\U0001d78e': '{\\mathsfbf{\\varrho}}', +u'\U0001d78f': '{\\mathsfbf{\\varpi}}', +u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d79b': '$M$', +u'\U0001d79c': '$N$', +u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d79e': '$O$', +u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', +u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d7b5': '$M$', +u'\U0001d7b6': '$N$', +u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d7b8': '$O$', +u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', +u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7c3': '$\\partial$', +u'\U0001d7c4': '$\\in$', +u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', +u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', +u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', +u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', +u'\U0001d7ce': '$\\mathbf{0}$', +u'\U0001d7cf': '$\\mathbf{1}$', +u'\U0001d7d0': '$\\mathbf{2}$', +u'\U0001d7d1': '$\\mathbf{3}$', +u'\U0001d7d2': '$\\mathbf{4}$', +u'\U0001d7d3': '$\\mathbf{5}$', +u'\U0001d7d4': '$\\mathbf{6}$', +u'\U0001d7d5': '$\\mathbf{7}$', +u'\U0001d7d6': '$\\mathbf{8}$', +u'\U0001d7d7': '$\\mathbf{9}$', +u'\U0001d7d8': '$\\mathbb{0}$', +u'\U0001d7d9': '$\\mathbb{1}$', +u'\U0001d7da': '$\\mathbb{2}$', +u'\U0001d7db': '$\\mathbb{3}$', +u'\U0001d7dc': '$\\mathbb{4}$', +u'\U0001d7dd': '$\\mathbb{5}$', +u'\U0001d7de': '$\\mathbb{6}$', +u'\U0001d7df': '$\\mathbb{7}$', +u'\U0001d7e0': '$\\mathbb{8}$', +u'\U0001d7e1': '$\\mathbb{9}$', +u'\U0001d7e2': '$\\mathsf{0}$', +u'\U0001d7e3': '$\\mathsf{1}$', +u'\U0001d7e4': '$\\mathsf{2}$', +u'\U0001d7e5': '$\\mathsf{3}$', +u'\U0001d7e6': '$\\mathsf{4}$', +u'\U0001d7e7': '$\\mathsf{5}$', +u'\U0001d7e8': '$\\mathsf{6}$', +u'\U0001d7e9': '$\\mathsf{7}$', +u'\U0001d7ea': '$\\mathsf{8}$', +u'\U0001d7eb': '$\\mathsf{9}$', +u'\U0001d7ec': '$\\mathsfbf{0}$', +u'\U0001d7ed': '$\\mathsfbf{1}$', +u'\U0001d7ee': '$\\mathsfbf{2}$', +u'\U0001d7ef': '$\\mathsfbf{3}$', +u'\U0001d7f0': '$\\mathsfbf{4}$', +u'\U0001d7f1': '$\\mathsfbf{5}$', +u'\U0001d7f2': '$\\mathsfbf{6}$', +u'\U0001d7f3': '$\\mathsfbf{7}$', +u'\U0001d7f4': '$\\mathsfbf{8}$', +u'\U0001d7f5': '$\\mathsfbf{9}$', +u'\U0001d7f6': '$\\mathtt{0}$', +u'\U0001d7f7': '$\\mathtt{1}$', +u'\U0001d7f8': '$\\mathtt{2}$', +u'\U0001d7f9': '$\\mathtt{3}$', +u'\U0001d7fa': '$\\mathtt{4}$', +u'\U0001d7fb': '$\\mathtt{5}$', +u'\U0001d7fc': '$\\mathtt{6}$', +u'\U0001d7fd': '$\\mathtt{7}$', +u'\U0001d7fe': '$\\mathtt{8}$', +u'\U0001d7ff': '$\\mathtt{9}$'} diff --git a/docutils/writers/unicode_latex.py b/docutils/writers/unicode_latex.py deleted file mode 100644 index 2998178f4..000000000 --- a/docutils/writers/unicode_latex.py +++ /dev/null @@ -1,2371 +0,0 @@ -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This file has been placed in the public domain. - -# This is a mapping of Unicode characters to LaTeX equivalents. -# The information has been extracted from -# , written by -# David Carlisle and Sebastian Rahtz. -# -# The extraction has been done by the "create_unimap.py" script -# located at . - -unicode_map = {u'\xa0': '$~$', -u'\xa1': '{\\textexclamdown}', -u'\xa2': '{\\textcent}', -u'\xa3': '{\\textsterling}', -u'\xa4': '{\\textcurrency}', -u'\xa5': '{\\textyen}', -u'\xa6': '{\\textbrokenbar}', -u'\xa7': '{\\textsection}', -u'\xa8': '{\\textasciidieresis}', -u'\xa9': '{\\textcopyright}', -u'\xaa': '{\\textordfeminine}', -u'\xab': '{\\guillemotleft}', -u'\xac': '$\\lnot$', -u'\xad': '$\\-$', -u'\xae': '{\\textregistered}', -u'\xaf': '{\\textasciimacron}', -u'\xb0': '{\\textdegree}', -u'\xb1': '$\\pm$', -u'\xb2': '${^2}$', -u'\xb3': '${^3}$', -u'\xb4': '{\\textasciiacute}', -u'\xb5': '$\\mathrm{\\mu}$', -u'\xb6': '{\\textparagraph}', -u'\xb7': '$\\cdot$', -u'\xb8': '{\\c{}}', -u'\xb9': '${^1}$', -u'\xba': '{\\textordmasculine}', -u'\xbb': '{\\guillemotright}', -u'\xbc': '{\\textonequarter}', -u'\xbd': '{\\textonehalf}', -u'\xbe': '{\\textthreequarters}', -u'\xbf': '{\\textquestiondown}', -u'\xc0': '{\\`{A}}', -u'\xc1': "{\\'{A}}", -u'\xc2': '{\\^{A}}', -u'\xc3': '{\\~{A}}', -u'\xc4': '{\\"{A}}', -u'\xc5': '{\\AA}', -u'\xc6': '{\\AE}', -u'\xc7': '{\\c{C}}', -u'\xc8': '{\\`{E}}', -u'\xc9': "{\\'{E}}", -u'\xca': '{\\^{E}}', -u'\xcb': '{\\"{E}}', -u'\xcc': '{\\`{I}}', -u'\xcd': "{\\'{I}}", -u'\xce': '{\\^{I}}', -u'\xcf': '{\\"{I}}', -u'\xd0': '{\\DH}', -u'\xd1': '{\\~{N}}', -u'\xd2': '{\\`{O}}', -u'\xd3': "{\\'{O}}", -u'\xd4': '{\\^{O}}', -u'\xd5': '{\\~{O}}', -u'\xd6': '{\\"{O}}', -u'\xd7': '{\\texttimes}', -u'\xd8': '{\\O}', -u'\xd9': '{\\`{U}}', -u'\xda': "{\\'{U}}", -u'\xdb': '{\\^{U}}', -u'\xdc': '{\\"{U}}', -u'\xdd': "{\\'{Y}}", -u'\xde': '{\\TH}', -u'\xdf': '{\\ss}', -u'\xe0': '{\\`{a}}', -u'\xe1': "{\\'{a}}", -u'\xe2': '{\\^{a}}', -u'\xe3': '{\\~{a}}', -u'\xe4': '{\\"{a}}', -u'\xe5': '{\\aa}', -u'\xe6': '{\\ae}', -u'\xe7': '{\\c{c}}', -u'\xe8': '{\\`{e}}', -u'\xe9': "{\\'{e}}", -u'\xea': '{\\^{e}}', -u'\xeb': '{\\"{e}}', -u'\xec': '{\\`{\\i}}', -u'\xed': "{\\'{\\i}}", -u'\xee': '{\\^{\\i}}', -u'\xef': '{\\"{\\i}}', -u'\xf0': '{\\dh}', -u'\xf1': '{\\~{n}}', -u'\xf2': '{\\`{o}}', -u'\xf3': "{\\'{o}}", -u'\xf4': '{\\^{o}}', -u'\xf5': '{\\~{o}}', -u'\xf6': '{\\"{o}}', -u'\xf7': '$\\div$', -u'\xf8': '{\\o}', -u'\xf9': '{\\`{u}}', -u'\xfa': "{\\'{u}}", -u'\xfb': '{\\^{u}}', -u'\xfc': '{\\"{u}}', -u'\xfd': "{\\'{y}}", -u'\xfe': '{\\th}', -u'\xff': '{\\"{y}}', -u'\u0100': '{\\={A}}', -u'\u0101': '{\\={a}}', -u'\u0102': '{\\u{A}}', -u'\u0103': '{\\u{a}}', -u'\u0104': '{\\k{A}}', -u'\u0105': '{\\k{a}}', -u'\u0106': "{\\'{C}}", -u'\u0107': "{\\'{c}}", -u'\u0108': '{\\^{C}}', -u'\u0109': '{\\^{c}}', -u'\u010a': '{\\.{C}}', -u'\u010b': '{\\.{c}}', -u'\u010c': '{\\v{C}}', -u'\u010d': '{\\v{c}}', -u'\u010e': '{\\v{D}}', -u'\u010f': '{\\v{d}}', -u'\u0110': '{\\DJ}', -u'\u0111': '{\\dj}', -u'\u0112': '{\\={E}}', -u'\u0113': '{\\={e}}', -u'\u0114': '{\\u{E}}', -u'\u0115': '{\\u{e}}', -u'\u0116': '{\\.{E}}', -u'\u0117': '{\\.{e}}', -u'\u0118': '{\\k{E}}', -u'\u0119': '{\\k{e}}', -u'\u011a': '{\\v{E}}', -u'\u011b': '{\\v{e}}', -u'\u011c': '{\\^{G}}', -u'\u011d': '{\\^{g}}', -u'\u011e': '{\\u{G}}', -u'\u011f': '{\\u{g}}', -u'\u0120': '{\\.{G}}', -u'\u0121': '{\\.{g}}', -u'\u0122': '{\\c{G}}', -u'\u0123': '{\\c{g}}', -u'\u0124': '{\\^{H}}', -u'\u0125': '{\\^{h}}', -u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', -u'\u0127': '$\\Elzxh$', -u'\u0128': '{\\~{I}}', -u'\u0129': '{\\~{\\i}}', -u'\u012a': '{\\={I}}', -u'\u012b': '{\\={\\i}}', -u'\u012c': '{\\u{I}}', -u'\u012d': '{\\u{\\i}}', -u'\u012e': '{\\k{I}}', -u'\u012f': '{\\k{i}}', -u'\u0130': '{\\.{I}}', -u'\u0131': '{\\i}', -u'\u0132': '{IJ}', -u'\u0133': '{ij}', -u'\u0134': '{\\^{J}}', -u'\u0135': '{\\^{\\j}}', -u'\u0136': '{\\c{K}}', -u'\u0137': '{\\c{k}}', -u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', -u'\u0139': "{\\'{L}}", -u'\u013a': "{\\'{l}}", -u'\u013b': '{\\c{L}}', -u'\u013c': '{\\c{l}}', -u'\u013d': '{\\v{L}}', -u'\u013e': '{\\v{l}}', -u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', -u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', -u'\u0141': '{\\L}', -u'\u0142': '{\\l}', -u'\u0143': "{\\'{N}}", -u'\u0144': "{\\'{n}}", -u'\u0145': '{\\c{N}}', -u'\u0146': '{\\c{n}}', -u'\u0147': '{\\v{N}}', -u'\u0148': '{\\v{n}}', -u'\u0149': "{'n}", -u'\u014a': '{\\NG}', -u'\u014b': '{\\ng}', -u'\u014c': '{\\={O}}', -u'\u014d': '{\\={o}}', -u'\u014e': '{\\u{O}}', -u'\u014f': '{\\u{o}}', -u'\u0150': '{\\H{O}}', -u'\u0151': '{\\H{o}}', -u'\u0152': '{\\OE}', -u'\u0153': '{\\oe}', -u'\u0154': "{\\'{R}}", -u'\u0155': "{\\'{r}}", -u'\u0156': '{\\c{R}}', -u'\u0157': '{\\c{r}}', -u'\u0158': '{\\v{R}}', -u'\u0159': '{\\v{r}}', -u'\u015a': "{\\'{S}}", -u'\u015b': "{\\'{s}}", -u'\u015c': '{\\^{S}}', -u'\u015d': '{\\^{s}}', -u'\u015e': '{\\c{S}}', -u'\u015f': '{\\c{s}}', -u'\u0160': '{\\v{S}}', -u'\u0161': '{\\v{s}}', -u'\u0162': '{\\c{T}}', -u'\u0163': '{\\c{t}}', -u'\u0164': '{\\v{T}}', -u'\u0165': '{\\v{t}}', -u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', -u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', -u'\u0168': '{\\~{U}}', -u'\u0169': '{\\~{u}}', -u'\u016a': '{\\={U}}', -u'\u016b': '{\\={u}}', -u'\u016c': '{\\u{U}}', -u'\u016d': '{\\u{u}}', -u'\u016e': '{\\r{U}}', -u'\u016f': '{\\r{u}}', -u'\u0170': '{\\H{U}}', -u'\u0171': '{\\H{u}}', -u'\u0172': '{\\k{U}}', -u'\u0173': '{\\k{u}}', -u'\u0174': '{\\^{W}}', -u'\u0175': '{\\^{w}}', -u'\u0176': '{\\^{Y}}', -u'\u0177': '{\\^{y}}', -u'\u0178': '{\\"{Y}}', -u'\u0179': "{\\'{Z}}", -u'\u017a': "{\\'{z}}", -u'\u017b': '{\\.{Z}}', -u'\u017c': '{\\.{z}}', -u'\u017d': '{\\v{Z}}', -u'\u017e': '{\\v{z}}', -u'\u0192': '$f$', -u'\u0195': '{\\texthvlig}', -u'\u019e': '{\\textnrleg}', -u'\u01aa': '$\\eth$', -u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', -u'\u01c2': '{\\textdoublepipe}', -u'\u01f5': "{\\'{g}}", -u'\u0250': '$\\Elztrna$', -u'\u0252': '$\\Elztrnsa$', -u'\u0254': '$\\Elzopeno$', -u'\u0256': '$\\Elzrtld$', -u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', -u'\u0259': '$\\Elzschwa$', -u'\u025b': '$\\varepsilon$', -u'\u0261': '{g}', -u'\u0263': '$\\Elzpgamma$', -u'\u0264': '$\\Elzpbgam$', -u'\u0265': '$\\Elztrnh$', -u'\u026c': '$\\Elzbtdl$', -u'\u026d': '$\\Elzrtll$', -u'\u026f': '$\\Elztrnm$', -u'\u0270': '$\\Elztrnmlr$', -u'\u0271': '$\\Elzltlmr$', -u'\u0272': '{\\Elzltln}', -u'\u0273': '$\\Elzrtln$', -u'\u0277': '$\\Elzclomeg$', -u'\u0278': '{\\textphi}', -u'\u0279': '$\\Elztrnr$', -u'\u027a': '$\\Elztrnrl$', -u'\u027b': '$\\Elzrttrnr$', -u'\u027c': '$\\Elzrl$', -u'\u027d': '$\\Elzrtlr$', -u'\u027e': '$\\Elzfhr$', -u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', -u'\u0282': '$\\Elzrtls$', -u'\u0283': '$\\Elzesh$', -u'\u0287': '$\\Elztrnt$', -u'\u0288': '$\\Elzrtlt$', -u'\u028a': '$\\Elzpupsil$', -u'\u028b': '$\\Elzpscrv$', -u'\u028c': '$\\Elzinvv$', -u'\u028d': '$\\Elzinvw$', -u'\u028e': '$\\Elztrny$', -u'\u0290': '$\\Elzrtlz$', -u'\u0292': '$\\Elzyogh$', -u'\u0294': '$\\Elzglst$', -u'\u0295': '$\\Elzreglst$', -u'\u0296': '$\\Elzinglst$', -u'\u029e': '{\\textturnk}', -u'\u02a4': '$\\Elzdyogh$', -u'\u02a7': '$\\Elztesh$', -u'\u02bc': "{'}", -u'\u02c7': '{\\textasciicaron}', -u'\u02c8': '$\\Elzverts$', -u'\u02cc': '$\\Elzverti$', -u'\u02d0': '$\\Elzlmrk$', -u'\u02d1': '$\\Elzhlmrk$', -u'\u02d2': '$\\Elzsbrhr$', -u'\u02d3': '$\\Elzsblhr$', -u'\u02d4': '$\\Elzrais$', -u'\u02d5': '$\\Elzlow$', -u'\u02d8': '{\\textasciibreve}', -u'\u02d9': '{\\textperiodcentered}', -u'\u02da': '{\\r{}}', -u'\u02db': '{\\k{}}', -u'\u02dc': '{\\texttildelow}', -u'\u02dd': '{\\H{}}', -u'\u02e5': '{\\tone{55}}', -u'\u02e6': '{\\tone{44}}', -u'\u02e7': '{\\tone{33}}', -u'\u02e8': '{\\tone{22}}', -u'\u02e9': '{\\tone{11}}', -u'\u0300': '{\\`}', -u'\u0301': "{\\'}", -u'\u0302': '{\\^}', -u'\u0303': '{\\~}', -u'\u0304': '{\\=}', -u'\u0306': '{\\u}', -u'\u0307': '{\\.}', -u'\u0308': '{\\"}', -u'\u030a': '{\\r}', -u'\u030b': '{\\H}', -u'\u030c': '{\\v}', -u'\u030f': '{\\cyrchar\\C}', -u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', -u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', -u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', -u'\u0321': '$\\Elzpalh$', -u'\u0322': '{\\Elzrh}', -u'\u0327': '{\\c}', -u'\u0328': '{\\k}', -u'\u032a': '$\\Elzsbbrg$', -u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', -u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', -u'\u0335': '{\\Elzxl}', -u'\u0336': '{\\Elzbar}', -u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', -u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', -u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', -u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', -u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', -u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', -u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', -u'\u0386': "{\\'{A}}", -u'\u0388': "{\\'{E}}", -u'\u0389': "{\\'{H}}", -u'\u038a': "{\\'{}{I}}", -u'\u038c': "{\\'{}O}", -u'\u038e': "$\\mathrm{'Y}$", -u'\u038f': "$\\mathrm{'\\Omega}$", -u'\u0390': '$\\acute{\\ddot{\\iota}}$', -u'\u0391': '$\\Alpha$', -u'\u0392': '$\\Beta$', -u'\u0393': '$\\Gamma$', -u'\u0394': '$\\Delta$', -u'\u0395': '$\\Epsilon$', -u'\u0396': '$\\Zeta$', -u'\u0397': '$\\Eta$', -u'\u0398': '$\\Theta$', -u'\u0399': '$\\Iota$', -u'\u039a': '$\\Kappa$', -u'\u039b': '$\\Lambda$', -u'\u039c': '$M$', -u'\u039d': '$N$', -u'\u039e': '$\\Xi$', -u'\u039f': '$O$', -u'\u03a0': '$\\Pi$', -u'\u03a1': '$\\Rho$', -u'\u03a3': '$\\Sigma$', -u'\u03a4': '$\\Tau$', -u'\u03a5': '$\\Upsilon$', -u'\u03a6': '$\\Phi$', -u'\u03a7': '$\\Chi$', -u'\u03a8': '$\\Psi$', -u'\u03a9': '$\\Omega$', -u'\u03aa': '$\\mathrm{\\ddot{I}}$', -u'\u03ab': '$\\mathrm{\\ddot{Y}}$', -u'\u03ac': "{\\'{$\\alpha$}}", -u'\u03ad': '$\\acute{\\epsilon}$', -u'\u03ae': '$\\acute{\\eta}$', -u'\u03af': '$\\acute{\\iota}$', -u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', -u'\u03b1': '$\\alpha$', -u'\u03b2': '$\\beta$', -u'\u03b3': '$\\gamma$', -u'\u03b4': '$\\delta$', -u'\u03b5': '$\\epsilon$', -u'\u03b6': '$\\zeta$', -u'\u03b7': '$\\eta$', -u'\u03b8': '{\\texttheta}', -u'\u03b9': '$\\iota$', -u'\u03ba': '$\\kappa$', -u'\u03bb': '$\\lambda$', -u'\u03bc': '$\\mu$', -u'\u03bd': '$\\nu$', -u'\u03be': '$\\xi$', -u'\u03bf': '$o$', -u'\u03c0': '$\\pi$', -u'\u03c1': '$\\rho$', -u'\u03c2': '$\\varsigma$', -u'\u03c3': '$\\sigma$', -u'\u03c4': '$\\tau$', -u'\u03c5': '$\\upsilon$', -u'\u03c6': '$\\varphi$', -u'\u03c7': '$\\chi$', -u'\u03c8': '$\\psi$', -u'\u03c9': '$\\omega$', -u'\u03ca': '$\\ddot{\\iota}$', -u'\u03cb': '$\\ddot{\\upsilon}$', -u'\u03cc': "{\\'{o}}", -u'\u03cd': '$\\acute{\\upsilon}$', -u'\u03ce': '$\\acute{\\omega}$', -u'\u03d0': '{\\Pisymbol{ppi022}{87}}', -u'\u03d1': '{\\textvartheta}', -u'\u03d2': '$\\Upsilon$', -u'\u03d5': '$\\phi$', -u'\u03d6': '$\\varpi$', -u'\u03da': '$\\Stigma$', -u'\u03dc': '$\\Digamma$', -u'\u03dd': '$\\digamma$', -u'\u03de': '$\\Koppa$', -u'\u03e0': '$\\Sampi$', -u'\u03f0': '$\\varkappa$', -u'\u03f1': '$\\varrho$', -u'\u03f4': '{\\textTheta}', -u'\u03f6': '$\\backepsilon$', -u'\u0401': '{\\cyrchar\\CYRYO}', -u'\u0402': '{\\cyrchar\\CYRDJE}', -u'\u0403': "{\\cyrchar{\\'\\CYRG}}", -u'\u0404': '{\\cyrchar\\CYRIE}', -u'\u0405': '{\\cyrchar\\CYRDZE}', -u'\u0406': '{\\cyrchar\\CYRII}', -u'\u0407': '{\\cyrchar\\CYRYI}', -u'\u0408': '{\\cyrchar\\CYRJE}', -u'\u0409': '{\\cyrchar\\CYRLJE}', -u'\u040a': '{\\cyrchar\\CYRNJE}', -u'\u040b': '{\\cyrchar\\CYRTSHE}', -u'\u040c': "{\\cyrchar{\\'\\CYRK}}", -u'\u040e': '{\\cyrchar\\CYRUSHRT}', -u'\u040f': '{\\cyrchar\\CYRDZHE}', -u'\u0410': '{\\cyrchar\\CYRA}', -u'\u0411': '{\\cyrchar\\CYRB}', -u'\u0412': '{\\cyrchar\\CYRV}', -u'\u0413': '{\\cyrchar\\CYRG}', -u'\u0414': '{\\cyrchar\\CYRD}', -u'\u0415': '{\\cyrchar\\CYRE}', -u'\u0416': '{\\cyrchar\\CYRZH}', -u'\u0417': '{\\cyrchar\\CYRZ}', -u'\u0418': '{\\cyrchar\\CYRI}', -u'\u0419': '{\\cyrchar\\CYRISHRT}', -u'\u041a': '{\\cyrchar\\CYRK}', -u'\u041b': '{\\cyrchar\\CYRL}', -u'\u041c': '{\\cyrchar\\CYRM}', -u'\u041d': '{\\cyrchar\\CYRN}', -u'\u041e': '{\\cyrchar\\CYRO}', -u'\u041f': '{\\cyrchar\\CYRP}', -u'\u0420': '{\\cyrchar\\CYRR}', -u'\u0421': '{\\cyrchar\\CYRS}', -u'\u0422': '{\\cyrchar\\CYRT}', -u'\u0423': '{\\cyrchar\\CYRU}', -u'\u0424': '{\\cyrchar\\CYRF}', -u'\u0425': '{\\cyrchar\\CYRH}', -u'\u0426': '{\\cyrchar\\CYRC}', -u'\u0427': '{\\cyrchar\\CYRCH}', -u'\u0428': '{\\cyrchar\\CYRSH}', -u'\u0429': '{\\cyrchar\\CYRSHCH}', -u'\u042a': '{\\cyrchar\\CYRHRDSN}', -u'\u042b': '{\\cyrchar\\CYRERY}', -u'\u042c': '{\\cyrchar\\CYRSFTSN}', -u'\u042d': '{\\cyrchar\\CYREREV}', -u'\u042e': '{\\cyrchar\\CYRYU}', -u'\u042f': '{\\cyrchar\\CYRYA}', -u'\u0430': '{\\cyrchar\\cyra}', -u'\u0431': '{\\cyrchar\\cyrb}', -u'\u0432': '{\\cyrchar\\cyrv}', -u'\u0433': '{\\cyrchar\\cyrg}', -u'\u0434': '{\\cyrchar\\cyrd}', -u'\u0435': '{\\cyrchar\\cyre}', -u'\u0436': '{\\cyrchar\\cyrzh}', -u'\u0437': '{\\cyrchar\\cyrz}', -u'\u0438': '{\\cyrchar\\cyri}', -u'\u0439': '{\\cyrchar\\cyrishrt}', -u'\u043a': '{\\cyrchar\\cyrk}', -u'\u043b': '{\\cyrchar\\cyrl}', -u'\u043c': '{\\cyrchar\\cyrm}', -u'\u043d': '{\\cyrchar\\cyrn}', -u'\u043e': '{\\cyrchar\\cyro}', -u'\u043f': '{\\cyrchar\\cyrp}', -u'\u0440': '{\\cyrchar\\cyrr}', -u'\u0441': '{\\cyrchar\\cyrs}', -u'\u0442': '{\\cyrchar\\cyrt}', -u'\u0443': '{\\cyrchar\\cyru}', -u'\u0444': '{\\cyrchar\\cyrf}', -u'\u0445': '{\\cyrchar\\cyrh}', -u'\u0446': '{\\cyrchar\\cyrc}', -u'\u0447': '{\\cyrchar\\cyrch}', -u'\u0448': '{\\cyrchar\\cyrsh}', -u'\u0449': '{\\cyrchar\\cyrshch}', -u'\u044a': '{\\cyrchar\\cyrhrdsn}', -u'\u044b': '{\\cyrchar\\cyrery}', -u'\u044c': '{\\cyrchar\\cyrsftsn}', -u'\u044d': '{\\cyrchar\\cyrerev}', -u'\u044e': '{\\cyrchar\\cyryu}', -u'\u044f': '{\\cyrchar\\cyrya}', -u'\u0451': '{\\cyrchar\\cyryo}', -u'\u0452': '{\\cyrchar\\cyrdje}', -u'\u0453': "{\\cyrchar{\\'\\cyrg}}", -u'\u0454': '{\\cyrchar\\cyrie}', -u'\u0455': '{\\cyrchar\\cyrdze}', -u'\u0456': '{\\cyrchar\\cyrii}', -u'\u0457': '{\\cyrchar\\cyryi}', -u'\u0458': '{\\cyrchar\\cyrje}', -u'\u0459': '{\\cyrchar\\cyrlje}', -u'\u045a': '{\\cyrchar\\cyrnje}', -u'\u045b': '{\\cyrchar\\cyrtshe}', -u'\u045c': "{\\cyrchar{\\'\\cyrk}}", -u'\u045e': '{\\cyrchar\\cyrushrt}', -u'\u045f': '{\\cyrchar\\cyrdzhe}', -u'\u0460': '{\\cyrchar\\CYROMEGA}', -u'\u0461': '{\\cyrchar\\cyromega}', -u'\u0462': '{\\cyrchar\\CYRYAT}', -u'\u0464': '{\\cyrchar\\CYRIOTE}', -u'\u0465': '{\\cyrchar\\cyriote}', -u'\u0466': '{\\cyrchar\\CYRLYUS}', -u'\u0467': '{\\cyrchar\\cyrlyus}', -u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', -u'\u0469': '{\\cyrchar\\cyriotlyus}', -u'\u046a': '{\\cyrchar\\CYRBYUS}', -u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', -u'\u046d': '{\\cyrchar\\cyriotbyus}', -u'\u046e': '{\\cyrchar\\CYRKSI}', -u'\u046f': '{\\cyrchar\\cyrksi}', -u'\u0470': '{\\cyrchar\\CYRPSI}', -u'\u0471': '{\\cyrchar\\cyrpsi}', -u'\u0472': '{\\cyrchar\\CYRFITA}', -u'\u0474': '{\\cyrchar\\CYRIZH}', -u'\u0478': '{\\cyrchar\\CYRUK}', -u'\u0479': '{\\cyrchar\\cyruk}', -u'\u047a': '{\\cyrchar\\CYROMEGARND}', -u'\u047b': '{\\cyrchar\\cyromegarnd}', -u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', -u'\u047d': '{\\cyrchar\\cyromegatitlo}', -u'\u047e': '{\\cyrchar\\CYROT}', -u'\u047f': '{\\cyrchar\\cyrot}', -u'\u0480': '{\\cyrchar\\CYRKOPPA}', -u'\u0481': '{\\cyrchar\\cyrkoppa}', -u'\u0482': '{\\cyrchar\\cyrthousands}', -u'\u0488': '{\\cyrchar\\cyrhundredthousands}', -u'\u0489': '{\\cyrchar\\cyrmillions}', -u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', -u'\u048d': '{\\cyrchar\\cyrsemisftsn}', -u'\u048e': '{\\cyrchar\\CYRRTICK}', -u'\u048f': '{\\cyrchar\\cyrrtick}', -u'\u0490': '{\\cyrchar\\CYRGUP}', -u'\u0491': '{\\cyrchar\\cyrgup}', -u'\u0492': '{\\cyrchar\\CYRGHCRS}', -u'\u0493': '{\\cyrchar\\cyrghcrs}', -u'\u0494': '{\\cyrchar\\CYRGHK}', -u'\u0495': '{\\cyrchar\\cyrghk}', -u'\u0496': '{\\cyrchar\\CYRZHDSC}', -u'\u0497': '{\\cyrchar\\cyrzhdsc}', -u'\u0498': '{\\cyrchar\\CYRZDSC}', -u'\u0499': '{\\cyrchar\\cyrzdsc}', -u'\u049a': '{\\cyrchar\\CYRKDSC}', -u'\u049b': '{\\cyrchar\\cyrkdsc}', -u'\u049c': '{\\cyrchar\\CYRKVCRS}', -u'\u049d': '{\\cyrchar\\cyrkvcrs}', -u'\u049e': '{\\cyrchar\\CYRKHCRS}', -u'\u049f': '{\\cyrchar\\cyrkhcrs}', -u'\u04a0': '{\\cyrchar\\CYRKBEAK}', -u'\u04a1': '{\\cyrchar\\cyrkbeak}', -u'\u04a2': '{\\cyrchar\\CYRNDSC}', -u'\u04a3': '{\\cyrchar\\cyrndsc}', -u'\u04a4': '{\\cyrchar\\CYRNG}', -u'\u04a5': '{\\cyrchar\\cyrng}', -u'\u04a6': '{\\cyrchar\\CYRPHK}', -u'\u04a7': '{\\cyrchar\\cyrphk}', -u'\u04a8': '{\\cyrchar\\CYRABHHA}', -u'\u04a9': '{\\cyrchar\\cyrabhha}', -u'\u04aa': '{\\cyrchar\\CYRSDSC}', -u'\u04ab': '{\\cyrchar\\cyrsdsc}', -u'\u04ac': '{\\cyrchar\\CYRTDSC}', -u'\u04ad': '{\\cyrchar\\cyrtdsc}', -u'\u04ae': '{\\cyrchar\\CYRY}', -u'\u04af': '{\\cyrchar\\cyry}', -u'\u04b0': '{\\cyrchar\\CYRYHCRS}', -u'\u04b1': '{\\cyrchar\\cyryhcrs}', -u'\u04b2': '{\\cyrchar\\CYRHDSC}', -u'\u04b3': '{\\cyrchar\\cyrhdsc}', -u'\u04b4': '{\\cyrchar\\CYRTETSE}', -u'\u04b5': '{\\cyrchar\\cyrtetse}', -u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', -u'\u04b7': '{\\cyrchar\\cyrchrdsc}', -u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', -u'\u04b9': '{\\cyrchar\\cyrchvcrs}', -u'\u04ba': '{\\cyrchar\\CYRSHHA}', -u'\u04bb': '{\\cyrchar\\cyrshha}', -u'\u04bc': '{\\cyrchar\\CYRABHCH}', -u'\u04bd': '{\\cyrchar\\cyrabhch}', -u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', -u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', -u'\u04c0': '{\\cyrchar\\CYRpalochka}', -u'\u04c3': '{\\cyrchar\\CYRKHK}', -u'\u04c4': '{\\cyrchar\\cyrkhk}', -u'\u04c7': '{\\cyrchar\\CYRNHK}', -u'\u04c8': '{\\cyrchar\\cyrnhk}', -u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', -u'\u04cc': '{\\cyrchar\\cyrchldsc}', -u'\u04d4': '{\\cyrchar\\CYRAE}', -u'\u04d5': '{\\cyrchar\\cyrae}', -u'\u04d8': '{\\cyrchar\\CYRSCHWA}', -u'\u04d9': '{\\cyrchar\\cyrschwa}', -u'\u04e0': '{\\cyrchar\\CYRABHDZE}', -u'\u04e1': '{\\cyrchar\\cyrabhdze}', -u'\u04e8': '{\\cyrchar\\CYROTLD}', -u'\u04e9': '{\\cyrchar\\cyrotld}', -u'\u2002': '{\\hspace{0.6em}}', -u'\u2003': '{\\hspace{1em}}', -u'\u2004': '{\\hspace{0.33em}}', -u'\u2005': '{\\hspace{0.25em}}', -u'\u2006': '{\\hspace{0.166em}}', -u'\u2007': '{\\hphantom{0}}', -u'\u2008': '{\\hphantom{,}}', -u'\u2009': '{\\hspace{0.167em}}', -u'\u200a': '$\\mkern1mu$', -u'\u2010': '{-}', -u'\u2013': '{\\textendash}', -u'\u2014': '{\\textemdash}', -u'\u2015': '{\\rule{1em}{1pt}}', -u'\u2016': '$\\Vert$', -u'\u2018': '{`}', -u'\u2019': "{'}", -u'\u201a': '{,}', -u'\u201b': '$\\Elzreapos$', -u'\u201c': '{\\textquotedblleft}', -u'\u201d': '{\\textquotedblright}', -u'\u201e': '{,,}', -u'\u2020': '{\\textdagger}', -u'\u2021': '{\\textdaggerdbl}', -u'\u2022': '{\\textbullet}', -u'\u2024': '{.}', -u'\u2025': '{..}', -u'\u2026': '{\\ldots}', -u'\u2030': '{\\textperthousand}', -u'\u2031': '{\\textpertenthousand}', -u'\u2032': "${'}$", -u'\u2033': "${''}$", -u'\u2034': "${'''}$", -u'\u2035': '$\\backprime$', -u'\u2039': '{\\guilsinglleft}', -u'\u203a': '{\\guilsinglright}', -u'\u2057': "$''''$", -u'\u205f': '{\\mkern4mu}', -u'\u2060': '{\\nolinebreak}', -u'\u20a7': '{\\ensuremath{\\Elzpes}}', -u'\u20ac': '{\\mbox{\\texteuro}}', -u'\u20db': '$\\dddot$', -u'\u20dc': '$\\ddddot$', -u'\u2102': '$\\mathbb{C}$', -u'\u210a': '{\\mathscr{g}}', -u'\u210b': '$\\mathscr{H}$', -u'\u210c': '$\\mathfrak{H}$', -u'\u210d': '$\\mathbb{H}$', -u'\u210f': '$\\hslash$', -u'\u2110': '$\\mathscr{I}$', -u'\u2111': '$\\mathfrak{I}$', -u'\u2112': '$\\mathscr{L}$', -u'\u2113': '$\\mathscr{l}$', -u'\u2115': '$\\mathbb{N}$', -u'\u2116': '{\\cyrchar\\textnumero}', -u'\u2118': '$\\wp$', -u'\u2119': '$\\mathbb{P}$', -u'\u211a': '$\\mathbb{Q}$', -u'\u211b': '$\\mathscr{R}$', -u'\u211c': '$\\mathfrak{R}$', -u'\u211d': '$\\mathbb{R}$', -u'\u211e': '$\\Elzxrat$', -u'\u2122': '{\\texttrademark}', -u'\u2124': '$\\mathbb{Z}$', -u'\u2126': '$\\Omega$', -u'\u2127': '$\\mho$', -u'\u2128': '$\\mathfrak{Z}$', -u'\u2129': '$\\ElsevierGlyph{2129}$', -u'\u212b': '{\\AA}', -u'\u212c': '$\\mathscr{B}$', -u'\u212d': '$\\mathfrak{C}$', -u'\u212f': '$\\mathscr{e}$', -u'\u2130': '$\\mathscr{E}$', -u'\u2131': '$\\mathscr{F}$', -u'\u2133': '$\\mathscr{M}$', -u'\u2134': '$\\mathscr{o}$', -u'\u2135': '$\\aleph$', -u'\u2136': '$\\beth$', -u'\u2137': '$\\gimel$', -u'\u2138': '$\\daleth$', -u'\u2153': '$\\textfrac{1}{3}$', -u'\u2154': '$\\textfrac{2}{3}$', -u'\u2155': '$\\textfrac{1}{5}$', -u'\u2156': '$\\textfrac{2}{5}$', -u'\u2157': '$\\textfrac{3}{5}$', -u'\u2158': '$\\textfrac{4}{5}$', -u'\u2159': '$\\textfrac{1}{6}$', -u'\u215a': '$\\textfrac{5}{6}$', -u'\u215b': '$\\textfrac{1}{8}$', -u'\u215c': '$\\textfrac{3}{8}$', -u'\u215d': '$\\textfrac{5}{8}$', -u'\u215e': '$\\textfrac{7}{8}$', -u'\u2190': '$\\leftarrow$', -u'\u2191': '$\\uparrow$', -u'\u2192': '$\\rightarrow$', -u'\u2193': '$\\downarrow$', -u'\u2194': '$\\leftrightarrow$', -u'\u2195': '$\\updownarrow$', -u'\u2196': '$\\nwarrow$', -u'\u2197': '$\\nearrow$', -u'\u2198': '$\\searrow$', -u'\u2199': '$\\swarrow$', -u'\u219a': '$\\nleftarrow$', -u'\u219b': '$\\nrightarrow$', -u'\u219c': '$\\arrowwaveright$', -u'\u219d': '$\\arrowwaveright$', -u'\u219e': '$\\twoheadleftarrow$', -u'\u21a0': '$\\twoheadrightarrow$', -u'\u21a2': '$\\leftarrowtail$', -u'\u21a3': '$\\rightarrowtail$', -u'\u21a6': '$\\mapsto$', -u'\u21a9': '$\\hookleftarrow$', -u'\u21aa': '$\\hookrightarrow$', -u'\u21ab': '$\\looparrowleft$', -u'\u21ac': '$\\looparrowright$', -u'\u21ad': '$\\leftrightsquigarrow$', -u'\u21ae': '$\\nleftrightarrow$', -u'\u21b0': '$\\Lsh$', -u'\u21b1': '$\\Rsh$', -u'\u21b3': '$\\ElsevierGlyph{21B3}$', -u'\u21b6': '$\\curvearrowleft$', -u'\u21b7': '$\\curvearrowright$', -u'\u21ba': '$\\circlearrowleft$', -u'\u21bb': '$\\circlearrowright$', -u'\u21bc': '$\\leftharpoonup$', -u'\u21bd': '$\\leftharpoondown$', -u'\u21be': '$\\upharpoonright$', -u'\u21bf': '$\\upharpoonleft$', -u'\u21c0': '$\\rightharpoonup$', -u'\u21c1': '$\\rightharpoondown$', -u'\u21c2': '$\\downharpoonright$', -u'\u21c3': '$\\downharpoonleft$', -u'\u21c4': '$\\rightleftarrows$', -u'\u21c5': '$\\dblarrowupdown$', -u'\u21c6': '$\\leftrightarrows$', -u'\u21c7': '$\\leftleftarrows$', -u'\u21c8': '$\\upuparrows$', -u'\u21c9': '$\\rightrightarrows$', -u'\u21ca': '$\\downdownarrows$', -u'\u21cb': '$\\leftrightharpoons$', -u'\u21cc': '$\\rightleftharpoons$', -u'\u21cd': '$\\nLeftarrow$', -u'\u21ce': '$\\nLeftrightarrow$', -u'\u21cf': '$\\nRightarrow$', -u'\u21d0': '$\\Leftarrow$', -u'\u21d1': '$\\Uparrow$', -u'\u21d2': '$\\Rightarrow$', -u'\u21d3': '$\\Downarrow$', -u'\u21d4': '$\\Leftrightarrow$', -u'\u21d5': '$\\Updownarrow$', -u'\u21da': '$\\Lleftarrow$', -u'\u21db': '$\\Rrightarrow$', -u'\u21dd': '$\\rightsquigarrow$', -u'\u21f5': '$\\DownArrowUpArrow$', -u'\u2200': '$\\forall$', -u'\u2201': '$\\complement$', -u'\u2202': '$\\partial$', -u'\u2203': '$\\exists$', -u'\u2204': '$\\nexists$', -u'\u2205': '$\\varnothing$', -u'\u2207': '$\\nabla$', -u'\u2208': '$\\in$', -u'\u2209': '$\\not\\in$', -u'\u220b': '$\\ni$', -u'\u220c': '$\\not\\ni$', -u'\u220f': '$\\prod$', -u'\u2210': '$\\coprod$', -u'\u2211': '$\\sum$', -u'\u2212': '{-}', -u'\u2213': '$\\mp$', -u'\u2214': '$\\dotplus$', -u'\u2216': '$\\setminus$', -u'\u2217': '${_\\ast}$', -u'\u2218': '$\\circ$', -u'\u2219': '$\\bullet$', -u'\u221a': '$\\surd$', -u'\u221d': '$\\propto$', -u'\u221e': '$\\infty$', -u'\u221f': '$\\rightangle$', -u'\u2220': '$\\angle$', -u'\u2221': '$\\measuredangle$', -u'\u2222': '$\\sphericalangle$', -u'\u2223': '$\\mid$', -u'\u2224': '$\\nmid$', -u'\u2225': '$\\parallel$', -u'\u2226': '$\\nparallel$', -u'\u2227': '$\\wedge$', -u'\u2228': '$\\vee$', -u'\u2229': '$\\cap$', -u'\u222a': '$\\cup$', -u'\u222b': '$\\int$', -u'\u222c': '$\\int\\!\\int$', -u'\u222d': '$\\int\\!\\int\\!\\int$', -u'\u222e': '$\\oint$', -u'\u222f': '$\\surfintegral$', -u'\u2230': '$\\volintegral$', -u'\u2231': '$\\clwintegral$', -u'\u2232': '$\\ElsevierGlyph{2232}$', -u'\u2233': '$\\ElsevierGlyph{2233}$', -u'\u2234': '$\\therefore$', -u'\u2235': '$\\because$', -u'\u2237': '$\\Colon$', -u'\u2238': '$\\ElsevierGlyph{2238}$', -u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', -u'\u223b': '$\\homothetic$', -u'\u223c': '$\\sim$', -u'\u223d': '$\\backsim$', -u'\u223e': '$\\lazysinv$', -u'\u2240': '$\\wr$', -u'\u2241': '$\\not\\sim$', -u'\u2242': '$\\ElsevierGlyph{2242}$', -u'\u2243': '$\\simeq$', -u'\u2244': '$\\not\\simeq$', -u'\u2245': '$\\cong$', -u'\u2246': '$\\approxnotequal$', -u'\u2247': '$\\not\\cong$', -u'\u2248': '$\\approx$', -u'\u2249': '$\\not\\approx$', -u'\u224a': '$\\approxeq$', -u'\u224b': '$\\tildetrpl$', -u'\u224c': '$\\allequal$', -u'\u224d': '$\\asymp$', -u'\u224e': '$\\Bumpeq$', -u'\u224f': '$\\bumpeq$', -u'\u2250': '$\\doteq$', -u'\u2251': '$\\doteqdot$', -u'\u2252': '$\\fallingdotseq$', -u'\u2253': '$\\risingdotseq$', -u'\u2254': '{:=}', -u'\u2255': '$=:$', -u'\u2256': '$\\eqcirc$', -u'\u2257': '$\\circeq$', -u'\u2259': '$\\estimates$', -u'\u225a': '$\\ElsevierGlyph{225A}$', -u'\u225b': '$\\starequal$', -u'\u225c': '$\\triangleq$', -u'\u225f': '$\\ElsevierGlyph{225F}$', -u'\u2260': '$\\not =$', -u'\u2261': '$\\equiv$', -u'\u2262': '$\\not\\equiv$', -u'\u2264': '$\\leq$', -u'\u2265': '$\\geq$', -u'\u2266': '$\\leqq$', -u'\u2267': '$\\geqq$', -u'\u2268': '$\\lneqq$', -u'\u2269': '$\\gneqq$', -u'\u226a': '$\\ll$', -u'\u226b': '$\\gg$', -u'\u226c': '$\\between$', -u'\u226d': '$\\not\\kern-0.3em\\times$', -u'\u226e': '$\\not<$', -u'\u226f': '$\\not>$', -u'\u2270': '$\\not\\leq$', -u'\u2271': '$\\not\\geq$', -u'\u2272': '$\\lessequivlnt$', -u'\u2273': '$\\greaterequivlnt$', -u'\u2274': '$\\ElsevierGlyph{2274}$', -u'\u2275': '$\\ElsevierGlyph{2275}$', -u'\u2276': '$\\lessgtr$', -u'\u2277': '$\\gtrless$', -u'\u2278': '$\\notlessgreater$', -u'\u2279': '$\\notgreaterless$', -u'\u227a': '$\\prec$', -u'\u227b': '$\\succ$', -u'\u227c': '$\\preccurlyeq$', -u'\u227d': '$\\succcurlyeq$', -u'\u227e': '$\\precapprox$', -u'\u227f': '$\\succapprox$', -u'\u2280': '$\\not\\prec$', -u'\u2281': '$\\not\\succ$', -u'\u2282': '$\\subset$', -u'\u2283': '$\\supset$', -u'\u2284': '$\\not\\subset$', -u'\u2285': '$\\not\\supset$', -u'\u2286': '$\\subseteq$', -u'\u2287': '$\\supseteq$', -u'\u2288': '$\\not\\subseteq$', -u'\u2289': '$\\not\\supseteq$', -u'\u228a': '$\\subsetneq$', -u'\u228b': '$\\supsetneq$', -u'\u228e': '$\\uplus$', -u'\u228f': '$\\sqsubset$', -u'\u2290': '$\\sqsupset$', -u'\u2291': '$\\sqsubseteq$', -u'\u2292': '$\\sqsupseteq$', -u'\u2293': '$\\sqcap$', -u'\u2294': '$\\sqcup$', -u'\u2295': '$\\oplus$', -u'\u2296': '$\\ominus$', -u'\u2297': '$\\otimes$', -u'\u2298': '$\\oslash$', -u'\u2299': '$\\odot$', -u'\u229a': '$\\circledcirc$', -u'\u229b': '$\\circledast$', -u'\u229d': '$\\circleddash$', -u'\u229e': '$\\boxplus$', -u'\u229f': '$\\boxminus$', -u'\u22a0': '$\\boxtimes$', -u'\u22a1': '$\\boxdot$', -u'\u22a2': '$\\vdash$', -u'\u22a3': '$\\dashv$', -u'\u22a4': '$\\top$', -u'\u22a5': '$\\perp$', -u'\u22a7': '$\\truestate$', -u'\u22a8': '$\\forcesextra$', -u'\u22a9': '$\\Vdash$', -u'\u22aa': '$\\Vvdash$', -u'\u22ab': '$\\VDash$', -u'\u22ac': '$\\nvdash$', -u'\u22ad': '$\\nvDash$', -u'\u22ae': '$\\nVdash$', -u'\u22af': '$\\nVDash$', -u'\u22b2': '$\\vartriangleleft$', -u'\u22b3': '$\\vartriangleright$', -u'\u22b4': '$\\trianglelefteq$', -u'\u22b5': '$\\trianglerighteq$', -u'\u22b6': '$\\original$', -u'\u22b7': '$\\image$', -u'\u22b8': '$\\multimap$', -u'\u22b9': '$\\hermitconjmatrix$', -u'\u22ba': '$\\intercal$', -u'\u22bb': '$\\veebar$', -u'\u22be': '$\\rightanglearc$', -u'\u22c0': '$\\ElsevierGlyph{22C0}$', -u'\u22c1': '$\\ElsevierGlyph{22C1}$', -u'\u22c2': '$\\bigcap$', -u'\u22c3': '$\\bigcup$', -u'\u22c4': '$\\diamond$', -u'\u22c5': '$\\cdot$', -u'\u22c6': '$\\star$', -u'\u22c7': '$\\divideontimes$', -u'\u22c8': '$\\bowtie$', -u'\u22c9': '$\\ltimes$', -u'\u22ca': '$\\rtimes$', -u'\u22cb': '$\\leftthreetimes$', -u'\u22cc': '$\\rightthreetimes$', -u'\u22cd': '$\\backsimeq$', -u'\u22ce': '$\\curlyvee$', -u'\u22cf': '$\\curlywedge$', -u'\u22d0': '$\\Subset$', -u'\u22d1': '$\\Supset$', -u'\u22d2': '$\\Cap$', -u'\u22d3': '$\\Cup$', -u'\u22d4': '$\\pitchfork$', -u'\u22d6': '$\\lessdot$', -u'\u22d7': '$\\gtrdot$', -u'\u22d8': '$\\verymuchless$', -u'\u22d9': '$\\verymuchgreater$', -u'\u22da': '$\\lesseqgtr$', -u'\u22db': '$\\gtreqless$', -u'\u22de': '$\\curlyeqprec$', -u'\u22df': '$\\curlyeqsucc$', -u'\u22e2': '$\\not\\sqsubseteq$', -u'\u22e3': '$\\not\\sqsupseteq$', -u'\u22e5': '$\\Elzsqspne$', -u'\u22e6': '$\\lnsim$', -u'\u22e7': '$\\gnsim$', -u'\u22e8': '$\\precedesnotsimilar$', -u'\u22e9': '$\\succnsim$', -u'\u22ea': '$\\ntriangleleft$', -u'\u22eb': '$\\ntriangleright$', -u'\u22ec': '$\\ntrianglelefteq$', -u'\u22ed': '$\\ntrianglerighteq$', -u'\u22ee': '$\\vdots$', -u'\u22ef': '$\\cdots$', -u'\u22f0': '$\\upslopeellipsis$', -u'\u22f1': '$\\downslopeellipsis$', -u'\u2305': '{\\barwedge}', -u'\u2306': '$\\perspcorrespond$', -u'\u2308': '$\\lceil$', -u'\u2309': '$\\rceil$', -u'\u230a': '$\\lfloor$', -u'\u230b': '$\\rfloor$', -u'\u2315': '$\\recorder$', -u'\u2316': '$\\mathchar"2208$', -u'\u231c': '$\\ulcorner$', -u'\u231d': '$\\urcorner$', -u'\u231e': '$\\llcorner$', -u'\u231f': '$\\lrcorner$', -u'\u2322': '$\\frown$', -u'\u2323': '$\\smile$', -u'\u2329': '$\\langle$', -u'\u232a': '$\\rangle$', -u'\u233d': '$\\ElsevierGlyph{E838}$', -u'\u23a3': '$\\Elzdlcorn$', -u'\u23b0': '$\\lmoustache$', -u'\u23b1': '$\\rmoustache$', -u'\u2423': '{\\textvisiblespace}', -u'\u2460': '{\\ding{172}}', -u'\u2461': '{\\ding{173}}', -u'\u2462': '{\\ding{174}}', -u'\u2463': '{\\ding{175}}', -u'\u2464': '{\\ding{176}}', -u'\u2465': '{\\ding{177}}', -u'\u2466': '{\\ding{178}}', -u'\u2467': '{\\ding{179}}', -u'\u2468': '{\\ding{180}}', -u'\u2469': '{\\ding{181}}', -u'\u24c8': '$\\circledS$', -u'\u2506': '$\\Elzdshfnc$', -u'\u2519': '$\\Elzsqfnw$', -u'\u2571': '$\\diagup$', -u'\u25a0': '{\\ding{110}}', -u'\u25a1': '$\\square$', -u'\u25aa': '$\\blacksquare$', -u'\u25ad': '$\\fbox{~~}$', -u'\u25af': '$\\Elzvrecto$', -u'\u25b1': '$\\ElsevierGlyph{E381}$', -u'\u25b2': '{\\ding{115}}', -u'\u25b3': '$\\bigtriangleup$', -u'\u25b4': '$\\blacktriangle$', -u'\u25b5': '$\\vartriangle$', -u'\u25b8': '$\\blacktriangleright$', -u'\u25b9': '$\\triangleright$', -u'\u25bc': '{\\ding{116}}', -u'\u25bd': '$\\bigtriangledown$', -u'\u25be': '$\\blacktriangledown$', -u'\u25bf': '$\\triangledown$', -u'\u25c2': '$\\blacktriangleleft$', -u'\u25c3': '$\\triangleleft$', -u'\u25c6': '{\\ding{117}}', -u'\u25ca': '$\\lozenge$', -u'\u25cb': '$\\bigcirc$', -u'\u25cf': '{\\ding{108}}', -u'\u25d0': '$\\Elzcirfl$', -u'\u25d1': '$\\Elzcirfr$', -u'\u25d2': '$\\Elzcirfb$', -u'\u25d7': '{\\ding{119}}', -u'\u25d8': '$\\Elzrvbull$', -u'\u25e7': '$\\Elzsqfl$', -u'\u25e8': '$\\Elzsqfr$', -u'\u25ea': '$\\Elzsqfse$', -u'\u25ef': '$\\bigcirc$', -u'\u2605': '{\\ding{72}}', -u'\u2606': '{\\ding{73}}', -u'\u260e': '{\\ding{37}}', -u'\u261b': '{\\ding{42}}', -u'\u261e': '{\\ding{43}}', -u'\u263e': '{\\rightmoon}', -u'\u263f': '{\\mercury}', -u'\u2640': '{\\venus}', -u'\u2642': '{\\male}', -u'\u2643': '{\\jupiter}', -u'\u2644': '{\\saturn}', -u'\u2645': '{\\uranus}', -u'\u2646': '{\\neptune}', -u'\u2647': '{\\pluto}', -u'\u2648': '{\\aries}', -u'\u2649': '{\\taurus}', -u'\u264a': '{\\gemini}', -u'\u264b': '{\\cancer}', -u'\u264c': '{\\leo}', -u'\u264d': '{\\virgo}', -u'\u264e': '{\\libra}', -u'\u264f': '{\\scorpio}', -u'\u2650': '{\\sagittarius}', -u'\u2651': '{\\capricornus}', -u'\u2652': '{\\aquarius}', -u'\u2653': '{\\pisces}', -u'\u2660': '{\\ding{171}}', -u'\u2662': '$\\diamond$', -u'\u2663': '{\\ding{168}}', -u'\u2665': '{\\ding{170}}', -u'\u2666': '{\\ding{169}}', -u'\u2669': '{\\quarternote}', -u'\u266a': '{\\eighthnote}', -u'\u266d': '$\\flat$', -u'\u266e': '$\\natural$', -u'\u266f': '$\\sharp$', -u'\u2701': '{\\ding{33}}', -u'\u2702': '{\\ding{34}}', -u'\u2703': '{\\ding{35}}', -u'\u2704': '{\\ding{36}}', -u'\u2706': '{\\ding{38}}', -u'\u2707': '{\\ding{39}}', -u'\u2708': '{\\ding{40}}', -u'\u2709': '{\\ding{41}}', -u'\u270c': '{\\ding{44}}', -u'\u270d': '{\\ding{45}}', -u'\u270e': '{\\ding{46}}', -u'\u270f': '{\\ding{47}}', -u'\u2710': '{\\ding{48}}', -u'\u2711': '{\\ding{49}}', -u'\u2712': '{\\ding{50}}', -u'\u2713': '{\\ding{51}}', -u'\u2714': '{\\ding{52}}', -u'\u2715': '{\\ding{53}}', -u'\u2716': '{\\ding{54}}', -u'\u2717': '{\\ding{55}}', -u'\u2718': '{\\ding{56}}', -u'\u2719': '{\\ding{57}}', -u'\u271a': '{\\ding{58}}', -u'\u271b': '{\\ding{59}}', -u'\u271c': '{\\ding{60}}', -u'\u271d': '{\\ding{61}}', -u'\u271e': '{\\ding{62}}', -u'\u271f': '{\\ding{63}}', -u'\u2720': '{\\ding{64}}', -u'\u2721': '{\\ding{65}}', -u'\u2722': '{\\ding{66}}', -u'\u2723': '{\\ding{67}}', -u'\u2724': '{\\ding{68}}', -u'\u2725': '{\\ding{69}}', -u'\u2726': '{\\ding{70}}', -u'\u2727': '{\\ding{71}}', -u'\u2729': '{\\ding{73}}', -u'\u272a': '{\\ding{74}}', -u'\u272b': '{\\ding{75}}', -u'\u272c': '{\\ding{76}}', -u'\u272d': '{\\ding{77}}', -u'\u272e': '{\\ding{78}}', -u'\u272f': '{\\ding{79}}', -u'\u2730': '{\\ding{80}}', -u'\u2731': '{\\ding{81}}', -u'\u2732': '{\\ding{82}}', -u'\u2733': '{\\ding{83}}', -u'\u2734': '{\\ding{84}}', -u'\u2735': '{\\ding{85}}', -u'\u2736': '{\\ding{86}}', -u'\u2737': '{\\ding{87}}', -u'\u2738': '{\\ding{88}}', -u'\u2739': '{\\ding{89}}', -u'\u273a': '{\\ding{90}}', -u'\u273b': '{\\ding{91}}', -u'\u273c': '{\\ding{92}}', -u'\u273d': '{\\ding{93}}', -u'\u273e': '{\\ding{94}}', -u'\u273f': '{\\ding{95}}', -u'\u2740': '{\\ding{96}}', -u'\u2741': '{\\ding{97}}', -u'\u2742': '{\\ding{98}}', -u'\u2743': '{\\ding{99}}', -u'\u2744': '{\\ding{100}}', -u'\u2745': '{\\ding{101}}', -u'\u2746': '{\\ding{102}}', -u'\u2747': '{\\ding{103}}', -u'\u2748': '{\\ding{104}}', -u'\u2749': '{\\ding{105}}', -u'\u274a': '{\\ding{106}}', -u'\u274b': '{\\ding{107}}', -u'\u274d': '{\\ding{109}}', -u'\u274f': '{\\ding{111}}', -u'\u2750': '{\\ding{112}}', -u'\u2751': '{\\ding{113}}', -u'\u2752': '{\\ding{114}}', -u'\u2756': '{\\ding{118}}', -u'\u2758': '{\\ding{120}}', -u'\u2759': '{\\ding{121}}', -u'\u275a': '{\\ding{122}}', -u'\u275b': '{\\ding{123}}', -u'\u275c': '{\\ding{124}}', -u'\u275d': '{\\ding{125}}', -u'\u275e': '{\\ding{126}}', -u'\u2761': '{\\ding{161}}', -u'\u2762': '{\\ding{162}}', -u'\u2763': '{\\ding{163}}', -u'\u2764': '{\\ding{164}}', -u'\u2765': '{\\ding{165}}', -u'\u2766': '{\\ding{166}}', -u'\u2767': '{\\ding{167}}', -u'\u2776': '{\\ding{182}}', -u'\u2777': '{\\ding{183}}', -u'\u2778': '{\\ding{184}}', -u'\u2779': '{\\ding{185}}', -u'\u277a': '{\\ding{186}}', -u'\u277b': '{\\ding{187}}', -u'\u277c': '{\\ding{188}}', -u'\u277d': '{\\ding{189}}', -u'\u277e': '{\\ding{190}}', -u'\u277f': '{\\ding{191}}', -u'\u2780': '{\\ding{192}}', -u'\u2781': '{\\ding{193}}', -u'\u2782': '{\\ding{194}}', -u'\u2783': '{\\ding{195}}', -u'\u2784': '{\\ding{196}}', -u'\u2785': '{\\ding{197}}', -u'\u2786': '{\\ding{198}}', -u'\u2787': '{\\ding{199}}', -u'\u2788': '{\\ding{200}}', -u'\u2789': '{\\ding{201}}', -u'\u278a': '{\\ding{202}}', -u'\u278b': '{\\ding{203}}', -u'\u278c': '{\\ding{204}}', -u'\u278d': '{\\ding{205}}', -u'\u278e': '{\\ding{206}}', -u'\u278f': '{\\ding{207}}', -u'\u2790': '{\\ding{208}}', -u'\u2791': '{\\ding{209}}', -u'\u2792': '{\\ding{210}}', -u'\u2793': '{\\ding{211}}', -u'\u2794': '{\\ding{212}}', -u'\u2798': '{\\ding{216}}', -u'\u2799': '{\\ding{217}}', -u'\u279a': '{\\ding{218}}', -u'\u279b': '{\\ding{219}}', -u'\u279c': '{\\ding{220}}', -u'\u279d': '{\\ding{221}}', -u'\u279e': '{\\ding{222}}', -u'\u279f': '{\\ding{223}}', -u'\u27a0': '{\\ding{224}}', -u'\u27a1': '{\\ding{225}}', -u'\u27a2': '{\\ding{226}}', -u'\u27a3': '{\\ding{227}}', -u'\u27a4': '{\\ding{228}}', -u'\u27a5': '{\\ding{229}}', -u'\u27a6': '{\\ding{230}}', -u'\u27a7': '{\\ding{231}}', -u'\u27a8': '{\\ding{232}}', -u'\u27a9': '{\\ding{233}}', -u'\u27aa': '{\\ding{234}}', -u'\u27ab': '{\\ding{235}}', -u'\u27ac': '{\\ding{236}}', -u'\u27ad': '{\\ding{237}}', -u'\u27ae': '{\\ding{238}}', -u'\u27af': '{\\ding{239}}', -u'\u27b1': '{\\ding{241}}', -u'\u27b2': '{\\ding{242}}', -u'\u27b3': '{\\ding{243}}', -u'\u27b4': '{\\ding{244}}', -u'\u27b5': '{\\ding{245}}', -u'\u27b6': '{\\ding{246}}', -u'\u27b7': '{\\ding{247}}', -u'\u27b8': '{\\ding{248}}', -u'\u27b9': '{\\ding{249}}', -u'\u27ba': '{\\ding{250}}', -u'\u27bb': '{\\ding{251}}', -u'\u27bc': '{\\ding{252}}', -u'\u27bd': '{\\ding{253}}', -u'\u27be': '{\\ding{254}}', -u'\u27f5': '$\\longleftarrow$', -u'\u27f6': '$\\longrightarrow$', -u'\u27f7': '$\\longleftrightarrow$', -u'\u27f8': '$\\Longleftarrow$', -u'\u27f9': '$\\Longrightarrow$', -u'\u27fa': '$\\Longleftrightarrow$', -u'\u27fc': '$\\longmapsto$', -u'\u27ff': '$\\sim\\joinrel\\leadsto$', -u'\u2905': '$\\ElsevierGlyph{E212}$', -u'\u2912': '$\\UpArrowBar$', -u'\u2913': '$\\DownArrowBar$', -u'\u2923': '$\\ElsevierGlyph{E20C}$', -u'\u2924': '$\\ElsevierGlyph{E20D}$', -u'\u2925': '$\\ElsevierGlyph{E20B}$', -u'\u2926': '$\\ElsevierGlyph{E20A}$', -u'\u2927': '$\\ElsevierGlyph{E211}$', -u'\u2928': '$\\ElsevierGlyph{E20E}$', -u'\u2929': '$\\ElsevierGlyph{E20F}$', -u'\u292a': '$\\ElsevierGlyph{E210}$', -u'\u2933': '$\\ElsevierGlyph{E21C}$', -u'\u2936': '$\\ElsevierGlyph{E21A}$', -u'\u2937': '$\\ElsevierGlyph{E219}$', -u'\u2940': '$\\Elolarr$', -u'\u2941': '$\\Elorarr$', -u'\u2942': '$\\ElzRlarr$', -u'\u2944': '$\\ElzrLarr$', -u'\u2947': '$\\Elzrarrx$', -u'\u294e': '$\\LeftRightVector$', -u'\u294f': '$\\RightUpDownVector$', -u'\u2950': '$\\DownLeftRightVector$', -u'\u2951': '$\\LeftUpDownVector$', -u'\u2952': '$\\LeftVectorBar$', -u'\u2953': '$\\RightVectorBar$', -u'\u2954': '$\\RightUpVectorBar$', -u'\u2955': '$\\RightDownVectorBar$', -u'\u2956': '$\\DownLeftVectorBar$', -u'\u2957': '$\\DownRightVectorBar$', -u'\u2958': '$\\LeftUpVectorBar$', -u'\u2959': '$\\LeftDownVectorBar$', -u'\u295a': '$\\LeftTeeVector$', -u'\u295b': '$\\RightTeeVector$', -u'\u295c': '$\\RightUpTeeVector$', -u'\u295d': '$\\RightDownTeeVector$', -u'\u295e': '$\\DownLeftTeeVector$', -u'\u295f': '$\\DownRightTeeVector$', -u'\u2960': '$\\LeftUpTeeVector$', -u'\u2961': '$\\LeftDownTeeVector$', -u'\u296e': '$\\UpEquilibrium$', -u'\u296f': '$\\ReverseUpEquilibrium$', -u'\u2970': '$\\RoundImplies$', -u'\u297c': '$\\ElsevierGlyph{E214}$', -u'\u297d': '$\\ElsevierGlyph{E215}$', -u'\u2980': '$\\Elztfnc$', -u'\u2985': '$\\ElsevierGlyph{3018}$', -u'\u2986': '$\\Elroang$', -u'\u2993': '$<\\kern-0.58em($', -u'\u2994': '$\\ElsevierGlyph{E291}$', -u'\u2999': '$\\Elzddfnc$', -u'\u299c': '$\\Angle$', -u'\u29a0': '$\\Elzlpargt$', -u'\u29b5': '$\\ElsevierGlyph{E260}$', -u'\u29b6': '$\\ElsevierGlyph{E61B}$', -u'\u29ca': '$\\ElzLap$', -u'\u29cb': '$\\Elzdefas$', -u'\u29cf': '$\\LeftTriangleBar$', -u'\u29d0': '$\\RightTriangleBar$', -u'\u29dc': '$\\ElsevierGlyph{E372}$', -u'\u29eb': '$\\blacklozenge$', -u'\u29f4': '$\\RuleDelayed$', -u'\u2a04': '$\\Elxuplus$', -u'\u2a05': '$\\ElzThr$', -u'\u2a06': '$\\Elxsqcup$', -u'\u2a07': '$\\ElzInf$', -u'\u2a08': '$\\ElzSup$', -u'\u2a0d': '$\\ElzCint$', -u'\u2a0f': '$\\clockoint$', -u'\u2a10': '$\\ElsevierGlyph{E395}$', -u'\u2a16': '$\\sqrint$', -u'\u2a25': '$\\ElsevierGlyph{E25A}$', -u'\u2a2a': '$\\ElsevierGlyph{E25B}$', -u'\u2a2d': '$\\ElsevierGlyph{E25C}$', -u'\u2a2e': '$\\ElsevierGlyph{E25D}$', -u'\u2a2f': '$\\ElzTimes$', -u'\u2a34': '$\\ElsevierGlyph{E25E}$', -u'\u2a35': '$\\ElsevierGlyph{E25E}$', -u'\u2a3c': '$\\ElsevierGlyph{E259}$', -u'\u2a3f': '$\\amalg$', -u'\u2a53': '$\\ElzAnd$', -u'\u2a54': '$\\ElzOr$', -u'\u2a55': '$\\ElsevierGlyph{E36E}$', -u'\u2a56': '$\\ElOr$', -u'\u2a5e': '$\\perspcorrespond$', -u'\u2a5f': '$\\Elzminhat$', -u'\u2a63': '$\\ElsevierGlyph{225A}$', -u'\u2a6e': '$\\stackrel{*}{=}$', -u'\u2a75': '$\\Equal$', -u'\u2a7d': '$\\leqslant$', -u'\u2a7e': '$\\geqslant$', -u'\u2a85': '$\\lessapprox$', -u'\u2a86': '$\\gtrapprox$', -u'\u2a87': '$\\lneq$', -u'\u2a88': '$\\gneq$', -u'\u2a89': '$\\lnapprox$', -u'\u2a8a': '$\\gnapprox$', -u'\u2a8b': '$\\lesseqqgtr$', -u'\u2a8c': '$\\gtreqqless$', -u'\u2a95': '$\\eqslantless$', -u'\u2a96': '$\\eqslantgtr$', -u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', -u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', -u'\u2aa1': '$\\NestedLessLess$', -u'\u2aa2': '$\\NestedGreaterGreater$', -u'\u2aaf': '$\\preceq$', -u'\u2ab0': '$\\succeq$', -u'\u2ab5': '$\\precneqq$', -u'\u2ab6': '$\\succneqq$', -u'\u2ab7': '$\\precapprox$', -u'\u2ab8': '$\\succapprox$', -u'\u2ab9': '$\\precnapprox$', -u'\u2aba': '$\\succnapprox$', -u'\u2ac5': '$\\subseteqq$', -u'\u2ac6': '$\\supseteqq$', -u'\u2acb': '$\\subsetneqq$', -u'\u2acc': '$\\supsetneqq$', -u'\u2aeb': '$\\ElsevierGlyph{E30D}$', -u'\u2af6': '$\\Elztdcol$', -u'\u2afd': '${{/}\\!\\!{/}}$', -u'\u300a': '$\\ElsevierGlyph{300A}$', -u'\u300b': '$\\ElsevierGlyph{300B}$', -u'\u3018': '$\\ElsevierGlyph{3018}$', -u'\u3019': '$\\ElsevierGlyph{3019}$', -u'\u301a': '$\\openbracketleft$', -u'\u301b': '$\\openbracketright$', -u'\ufb00': '{ff}', -u'\ufb01': '{fi}', -u'\ufb02': '{fl}', -u'\ufb03': '{ffi}', -u'\ufb04': '{ffl}', -u'\U0001d400': '$\\mathbf{A}$', -u'\U0001d401': '$\\mathbf{B}$', -u'\U0001d402': '$\\mathbf{C}$', -u'\U0001d403': '$\\mathbf{D}$', -u'\U0001d404': '$\\mathbf{E}$', -u'\U0001d405': '$\\mathbf{F}$', -u'\U0001d406': '$\\mathbf{G}$', -u'\U0001d407': '$\\mathbf{H}$', -u'\U0001d408': '$\\mathbf{I}$', -u'\U0001d409': '$\\mathbf{J}$', -u'\U0001d40a': '$\\mathbf{K}$', -u'\U0001d40b': '$\\mathbf{L}$', -u'\U0001d40c': '$\\mathbf{M}$', -u'\U0001d40d': '$\\mathbf{N}$', -u'\U0001d40e': '$\\mathbf{O}$', -u'\U0001d40f': '$\\mathbf{P}$', -u'\U0001d410': '$\\mathbf{Q}$', -u'\U0001d411': '$\\mathbf{R}$', -u'\U0001d412': '$\\mathbf{S}$', -u'\U0001d413': '$\\mathbf{T}$', -u'\U0001d414': '$\\mathbf{U}$', -u'\U0001d415': '$\\mathbf{V}$', -u'\U0001d416': '$\\mathbf{W}$', -u'\U0001d417': '$\\mathbf{X}$', -u'\U0001d418': '$\\mathbf{Y}$', -u'\U0001d419': '$\\mathbf{Z}$', -u'\U0001d41a': '$\\mathbf{a}$', -u'\U0001d41b': '$\\mathbf{b}$', -u'\U0001d41c': '$\\mathbf{c}$', -u'\U0001d41d': '$\\mathbf{d}$', -u'\U0001d41e': '$\\mathbf{e}$', -u'\U0001d41f': '$\\mathbf{f}$', -u'\U0001d420': '$\\mathbf{g}$', -u'\U0001d421': '$\\mathbf{h}$', -u'\U0001d422': '$\\mathbf{i}$', -u'\U0001d423': '$\\mathbf{j}$', -u'\U0001d424': '$\\mathbf{k}$', -u'\U0001d425': '$\\mathbf{l}$', -u'\U0001d426': '$\\mathbf{m}$', -u'\U0001d427': '$\\mathbf{n}$', -u'\U0001d428': '$\\mathbf{o}$', -u'\U0001d429': '$\\mathbf{p}$', -u'\U0001d42a': '$\\mathbf{q}$', -u'\U0001d42b': '$\\mathbf{r}$', -u'\U0001d42c': '$\\mathbf{s}$', -u'\U0001d42d': '$\\mathbf{t}$', -u'\U0001d42e': '$\\mathbf{u}$', -u'\U0001d42f': '$\\mathbf{v}$', -u'\U0001d430': '$\\mathbf{w}$', -u'\U0001d431': '$\\mathbf{x}$', -u'\U0001d432': '$\\mathbf{y}$', -u'\U0001d433': '$\\mathbf{z}$', -u'\U0001d434': '$\\mathsl{A}$', -u'\U0001d435': '$\\mathsl{B}$', -u'\U0001d436': '$\\mathsl{C}$', -u'\U0001d437': '$\\mathsl{D}$', -u'\U0001d438': '$\\mathsl{E}$', -u'\U0001d439': '$\\mathsl{F}$', -u'\U0001d43a': '$\\mathsl{G}$', -u'\U0001d43b': '$\\mathsl{H}$', -u'\U0001d43c': '$\\mathsl{I}$', -u'\U0001d43d': '$\\mathsl{J}$', -u'\U0001d43e': '$\\mathsl{K}$', -u'\U0001d43f': '$\\mathsl{L}$', -u'\U0001d440': '$\\mathsl{M}$', -u'\U0001d441': '$\\mathsl{N}$', -u'\U0001d442': '$\\mathsl{O}$', -u'\U0001d443': '$\\mathsl{P}$', -u'\U0001d444': '$\\mathsl{Q}$', -u'\U0001d445': '$\\mathsl{R}$', -u'\U0001d446': '$\\mathsl{S}$', -u'\U0001d447': '$\\mathsl{T}$', -u'\U0001d448': '$\\mathsl{U}$', -u'\U0001d449': '$\\mathsl{V}$', -u'\U0001d44a': '$\\mathsl{W}$', -u'\U0001d44b': '$\\mathsl{X}$', -u'\U0001d44c': '$\\mathsl{Y}$', -u'\U0001d44d': '$\\mathsl{Z}$', -u'\U0001d44e': '$\\mathsl{a}$', -u'\U0001d44f': '$\\mathsl{b}$', -u'\U0001d450': '$\\mathsl{c}$', -u'\U0001d451': '$\\mathsl{d}$', -u'\U0001d452': '$\\mathsl{e}$', -u'\U0001d453': '$\\mathsl{f}$', -u'\U0001d454': '$\\mathsl{g}$', -u'\U0001d456': '$\\mathsl{i}$', -u'\U0001d457': '$\\mathsl{j}$', -u'\U0001d458': '$\\mathsl{k}$', -u'\U0001d459': '$\\mathsl{l}$', -u'\U0001d45a': '$\\mathsl{m}$', -u'\U0001d45b': '$\\mathsl{n}$', -u'\U0001d45c': '$\\mathsl{o}$', -u'\U0001d45d': '$\\mathsl{p}$', -u'\U0001d45e': '$\\mathsl{q}$', -u'\U0001d45f': '$\\mathsl{r}$', -u'\U0001d460': '$\\mathsl{s}$', -u'\U0001d461': '$\\mathsl{t}$', -u'\U0001d462': '$\\mathsl{u}$', -u'\U0001d463': '$\\mathsl{v}$', -u'\U0001d464': '$\\mathsl{w}$', -u'\U0001d465': '$\\mathsl{x}$', -u'\U0001d466': '$\\mathsl{y}$', -u'\U0001d467': '$\\mathsl{z}$', -u'\U0001d468': '$\\mathbit{A}$', -u'\U0001d469': '$\\mathbit{B}$', -u'\U0001d46a': '$\\mathbit{C}$', -u'\U0001d46b': '$\\mathbit{D}$', -u'\U0001d46c': '$\\mathbit{E}$', -u'\U0001d46d': '$\\mathbit{F}$', -u'\U0001d46e': '$\\mathbit{G}$', -u'\U0001d46f': '$\\mathbit{H}$', -u'\U0001d470': '$\\mathbit{I}$', -u'\U0001d471': '$\\mathbit{J}$', -u'\U0001d472': '$\\mathbit{K}$', -u'\U0001d473': '$\\mathbit{L}$', -u'\U0001d474': '$\\mathbit{M}$', -u'\U0001d475': '$\\mathbit{N}$', -u'\U0001d476': '$\\mathbit{O}$', -u'\U0001d477': '$\\mathbit{P}$', -u'\U0001d478': '$\\mathbit{Q}$', -u'\U0001d479': '$\\mathbit{R}$', -u'\U0001d47a': '$\\mathbit{S}$', -u'\U0001d47b': '$\\mathbit{T}$', -u'\U0001d47c': '$\\mathbit{U}$', -u'\U0001d47d': '$\\mathbit{V}$', -u'\U0001d47e': '$\\mathbit{W}$', -u'\U0001d47f': '$\\mathbit{X}$', -u'\U0001d480': '$\\mathbit{Y}$', -u'\U0001d481': '$\\mathbit{Z}$', -u'\U0001d482': '$\\mathbit{a}$', -u'\U0001d483': '$\\mathbit{b}$', -u'\U0001d484': '$\\mathbit{c}$', -u'\U0001d485': '$\\mathbit{d}$', -u'\U0001d486': '$\\mathbit{e}$', -u'\U0001d487': '$\\mathbit{f}$', -u'\U0001d488': '$\\mathbit{g}$', -u'\U0001d489': '$\\mathbit{h}$', -u'\U0001d48a': '$\\mathbit{i}$', -u'\U0001d48b': '$\\mathbit{j}$', -u'\U0001d48c': '$\\mathbit{k}$', -u'\U0001d48d': '$\\mathbit{l}$', -u'\U0001d48e': '$\\mathbit{m}$', -u'\U0001d48f': '$\\mathbit{n}$', -u'\U0001d490': '$\\mathbit{o}$', -u'\U0001d491': '$\\mathbit{p}$', -u'\U0001d492': '$\\mathbit{q}$', -u'\U0001d493': '$\\mathbit{r}$', -u'\U0001d494': '$\\mathbit{s}$', -u'\U0001d495': '$\\mathbit{t}$', -u'\U0001d496': '$\\mathbit{u}$', -u'\U0001d497': '$\\mathbit{v}$', -u'\U0001d498': '$\\mathbit{w}$', -u'\U0001d499': '$\\mathbit{x}$', -u'\U0001d49a': '$\\mathbit{y}$', -u'\U0001d49b': '$\\mathbit{z}$', -u'\U0001d49c': '$\\mathscr{A}$', -u'\U0001d49e': '$\\mathscr{C}$', -u'\U0001d49f': '$\\mathscr{D}$', -u'\U0001d4a2': '$\\mathscr{G}$', -u'\U0001d4a5': '$\\mathscr{J}$', -u'\U0001d4a6': '$\\mathscr{K}$', -u'\U0001d4a9': '$\\mathscr{N}$', -u'\U0001d4aa': '$\\mathscr{O}$', -u'\U0001d4ab': '$\\mathscr{P}$', -u'\U0001d4ac': '$\\mathscr{Q}$', -u'\U0001d4ae': '$\\mathscr{S}$', -u'\U0001d4af': '$\\mathscr{T}$', -u'\U0001d4b0': '$\\mathscr{U}$', -u'\U0001d4b1': '$\\mathscr{V}$', -u'\U0001d4b2': '$\\mathscr{W}$', -u'\U0001d4b3': '$\\mathscr{X}$', -u'\U0001d4b4': '$\\mathscr{Y}$', -u'\U0001d4b5': '$\\mathscr{Z}$', -u'\U0001d4b6': '$\\mathscr{a}$', -u'\U0001d4b7': '$\\mathscr{b}$', -u'\U0001d4b8': '$\\mathscr{c}$', -u'\U0001d4b9': '$\\mathscr{d}$', -u'\U0001d4bb': '$\\mathscr{f}$', -u'\U0001d4bd': '$\\mathscr{h}$', -u'\U0001d4be': '$\\mathscr{i}$', -u'\U0001d4bf': '$\\mathscr{j}$', -u'\U0001d4c0': '$\\mathscr{k}$', -u'\U0001d4c1': '$\\mathscr{l}$', -u'\U0001d4c2': '$\\mathscr{m}$', -u'\U0001d4c3': '$\\mathscr{n}$', -u'\U0001d4c5': '$\\mathscr{p}$', -u'\U0001d4c6': '$\\mathscr{q}$', -u'\U0001d4c7': '$\\mathscr{r}$', -u'\U0001d4c8': '$\\mathscr{s}$', -u'\U0001d4c9': '$\\mathscr{t}$', -u'\U0001d4ca': '$\\mathscr{u}$', -u'\U0001d4cb': '$\\mathscr{v}$', -u'\U0001d4cc': '$\\mathscr{w}$', -u'\U0001d4cd': '$\\mathscr{x}$', -u'\U0001d4ce': '$\\mathscr{y}$', -u'\U0001d4cf': '$\\mathscr{z}$', -u'\U0001d4d0': '$\\mathmit{A}$', -u'\U0001d4d1': '$\\mathmit{B}$', -u'\U0001d4d2': '$\\mathmit{C}$', -u'\U0001d4d3': '$\\mathmit{D}$', -u'\U0001d4d4': '$\\mathmit{E}$', -u'\U0001d4d5': '$\\mathmit{F}$', -u'\U0001d4d6': '$\\mathmit{G}$', -u'\U0001d4d7': '$\\mathmit{H}$', -u'\U0001d4d8': '$\\mathmit{I}$', -u'\U0001d4d9': '$\\mathmit{J}$', -u'\U0001d4da': '$\\mathmit{K}$', -u'\U0001d4db': '$\\mathmit{L}$', -u'\U0001d4dc': '$\\mathmit{M}$', -u'\U0001d4dd': '$\\mathmit{N}$', -u'\U0001d4de': '$\\mathmit{O}$', -u'\U0001d4df': '$\\mathmit{P}$', -u'\U0001d4e0': '$\\mathmit{Q}$', -u'\U0001d4e1': '$\\mathmit{R}$', -u'\U0001d4e2': '$\\mathmit{S}$', -u'\U0001d4e3': '$\\mathmit{T}$', -u'\U0001d4e4': '$\\mathmit{U}$', -u'\U0001d4e5': '$\\mathmit{V}$', -u'\U0001d4e6': '$\\mathmit{W}$', -u'\U0001d4e7': '$\\mathmit{X}$', -u'\U0001d4e8': '$\\mathmit{Y}$', -u'\U0001d4e9': '$\\mathmit{Z}$', -u'\U0001d4ea': '$\\mathmit{a}$', -u'\U0001d4eb': '$\\mathmit{b}$', -u'\U0001d4ec': '$\\mathmit{c}$', -u'\U0001d4ed': '$\\mathmit{d}$', -u'\U0001d4ee': '$\\mathmit{e}$', -u'\U0001d4ef': '$\\mathmit{f}$', -u'\U0001d4f0': '$\\mathmit{g}$', -u'\U0001d4f1': '$\\mathmit{h}$', -u'\U0001d4f2': '$\\mathmit{i}$', -u'\U0001d4f3': '$\\mathmit{j}$', -u'\U0001d4f4': '$\\mathmit{k}$', -u'\U0001d4f5': '$\\mathmit{l}$', -u'\U0001d4f6': '$\\mathmit{m}$', -u'\U0001d4f7': '$\\mathmit{n}$', -u'\U0001d4f8': '$\\mathmit{o}$', -u'\U0001d4f9': '$\\mathmit{p}$', -u'\U0001d4fa': '$\\mathmit{q}$', -u'\U0001d4fb': '$\\mathmit{r}$', -u'\U0001d4fc': '$\\mathmit{s}$', -u'\U0001d4fd': '$\\mathmit{t}$', -u'\U0001d4fe': '$\\mathmit{u}$', -u'\U0001d4ff': '$\\mathmit{v}$', -u'\U0001d500': '$\\mathmit{w}$', -u'\U0001d501': '$\\mathmit{x}$', -u'\U0001d502': '$\\mathmit{y}$', -u'\U0001d503': '$\\mathmit{z}$', -u'\U0001d504': '$\\mathfrak{A}$', -u'\U0001d505': '$\\mathfrak{B}$', -u'\U0001d507': '$\\mathfrak{D}$', -u'\U0001d508': '$\\mathfrak{E}$', -u'\U0001d509': '$\\mathfrak{F}$', -u'\U0001d50a': '$\\mathfrak{G}$', -u'\U0001d50d': '$\\mathfrak{J}$', -u'\U0001d50e': '$\\mathfrak{K}$', -u'\U0001d50f': '$\\mathfrak{L}$', -u'\U0001d510': '$\\mathfrak{M}$', -u'\U0001d511': '$\\mathfrak{N}$', -u'\U0001d512': '$\\mathfrak{O}$', -u'\U0001d513': '$\\mathfrak{P}$', -u'\U0001d514': '$\\mathfrak{Q}$', -u'\U0001d516': '$\\mathfrak{S}$', -u'\U0001d517': '$\\mathfrak{T}$', -u'\U0001d518': '$\\mathfrak{U}$', -u'\U0001d519': '$\\mathfrak{V}$', -u'\U0001d51a': '$\\mathfrak{W}$', -u'\U0001d51b': '$\\mathfrak{X}$', -u'\U0001d51c': '$\\mathfrak{Y}$', -u'\U0001d51e': '$\\mathfrak{a}$', -u'\U0001d51f': '$\\mathfrak{b}$', -u'\U0001d520': '$\\mathfrak{c}$', -u'\U0001d521': '$\\mathfrak{d}$', -u'\U0001d522': '$\\mathfrak{e}$', -u'\U0001d523': '$\\mathfrak{f}$', -u'\U0001d524': '$\\mathfrak{g}$', -u'\U0001d525': '$\\mathfrak{h}$', -u'\U0001d526': '$\\mathfrak{i}$', -u'\U0001d527': '$\\mathfrak{j}$', -u'\U0001d528': '$\\mathfrak{k}$', -u'\U0001d529': '$\\mathfrak{l}$', -u'\U0001d52a': '$\\mathfrak{m}$', -u'\U0001d52b': '$\\mathfrak{n}$', -u'\U0001d52c': '$\\mathfrak{o}$', -u'\U0001d52d': '$\\mathfrak{p}$', -u'\U0001d52e': '$\\mathfrak{q}$', -u'\U0001d52f': '$\\mathfrak{r}$', -u'\U0001d530': '$\\mathfrak{s}$', -u'\U0001d531': '$\\mathfrak{t}$', -u'\U0001d532': '$\\mathfrak{u}$', -u'\U0001d533': '$\\mathfrak{v}$', -u'\U0001d534': '$\\mathfrak{w}$', -u'\U0001d535': '$\\mathfrak{x}$', -u'\U0001d536': '$\\mathfrak{y}$', -u'\U0001d537': '$\\mathfrak{z}$', -u'\U0001d538': '$\\mathbb{A}$', -u'\U0001d539': '$\\mathbb{B}$', -u'\U0001d53b': '$\\mathbb{D}$', -u'\U0001d53c': '$\\mathbb{E}$', -u'\U0001d53d': '$\\mathbb{F}$', -u'\U0001d53e': '$\\mathbb{G}$', -u'\U0001d540': '$\\mathbb{I}$', -u'\U0001d541': '$\\mathbb{J}$', -u'\U0001d542': '$\\mathbb{K}$', -u'\U0001d543': '$\\mathbb{L}$', -u'\U0001d544': '$\\mathbb{M}$', -u'\U0001d546': '$\\mathbb{O}$', -u'\U0001d54a': '$\\mathbb{S}$', -u'\U0001d54b': '$\\mathbb{T}$', -u'\U0001d54c': '$\\mathbb{U}$', -u'\U0001d54d': '$\\mathbb{V}$', -u'\U0001d54e': '$\\mathbb{W}$', -u'\U0001d54f': '$\\mathbb{X}$', -u'\U0001d550': '$\\mathbb{Y}$', -u'\U0001d552': '$\\mathbb{a}$', -u'\U0001d553': '$\\mathbb{b}$', -u'\U0001d554': '$\\mathbb{c}$', -u'\U0001d555': '$\\mathbb{d}$', -u'\U0001d556': '$\\mathbb{e}$', -u'\U0001d557': '$\\mathbb{f}$', -u'\U0001d558': '$\\mathbb{g}$', -u'\U0001d559': '$\\mathbb{h}$', -u'\U0001d55a': '$\\mathbb{i}$', -u'\U0001d55b': '$\\mathbb{j}$', -u'\U0001d55c': '$\\mathbb{k}$', -u'\U0001d55d': '$\\mathbb{l}$', -u'\U0001d55e': '$\\mathbb{m}$', -u'\U0001d55f': '$\\mathbb{n}$', -u'\U0001d560': '$\\mathbb{o}$', -u'\U0001d561': '$\\mathbb{p}$', -u'\U0001d562': '$\\mathbb{q}$', -u'\U0001d563': '$\\mathbb{r}$', -u'\U0001d564': '$\\mathbb{s}$', -u'\U0001d565': '$\\mathbb{t}$', -u'\U0001d566': '$\\mathbb{u}$', -u'\U0001d567': '$\\mathbb{v}$', -u'\U0001d568': '$\\mathbb{w}$', -u'\U0001d569': '$\\mathbb{x}$', -u'\U0001d56a': '$\\mathbb{y}$', -u'\U0001d56b': '$\\mathbb{z}$', -u'\U0001d56c': '$\\mathslbb{A}$', -u'\U0001d56d': '$\\mathslbb{B}$', -u'\U0001d56e': '$\\mathslbb{C}$', -u'\U0001d56f': '$\\mathslbb{D}$', -u'\U0001d570': '$\\mathslbb{E}$', -u'\U0001d571': '$\\mathslbb{F}$', -u'\U0001d572': '$\\mathslbb{G}$', -u'\U0001d573': '$\\mathslbb{H}$', -u'\U0001d574': '$\\mathslbb{I}$', -u'\U0001d575': '$\\mathslbb{J}$', -u'\U0001d576': '$\\mathslbb{K}$', -u'\U0001d577': '$\\mathslbb{L}$', -u'\U0001d578': '$\\mathslbb{M}$', -u'\U0001d579': '$\\mathslbb{N}$', -u'\U0001d57a': '$\\mathslbb{O}$', -u'\U0001d57b': '$\\mathslbb{P}$', -u'\U0001d57c': '$\\mathslbb{Q}$', -u'\U0001d57d': '$\\mathslbb{R}$', -u'\U0001d57e': '$\\mathslbb{S}$', -u'\U0001d57f': '$\\mathslbb{T}$', -u'\U0001d580': '$\\mathslbb{U}$', -u'\U0001d581': '$\\mathslbb{V}$', -u'\U0001d582': '$\\mathslbb{W}$', -u'\U0001d583': '$\\mathslbb{X}$', -u'\U0001d584': '$\\mathslbb{Y}$', -u'\U0001d585': '$\\mathslbb{Z}$', -u'\U0001d586': '$\\mathslbb{a}$', -u'\U0001d587': '$\\mathslbb{b}$', -u'\U0001d588': '$\\mathslbb{c}$', -u'\U0001d589': '$\\mathslbb{d}$', -u'\U0001d58a': '$\\mathslbb{e}$', -u'\U0001d58b': '$\\mathslbb{f}$', -u'\U0001d58c': '$\\mathslbb{g}$', -u'\U0001d58d': '$\\mathslbb{h}$', -u'\U0001d58e': '$\\mathslbb{i}$', -u'\U0001d58f': '$\\mathslbb{j}$', -u'\U0001d590': '$\\mathslbb{k}$', -u'\U0001d591': '$\\mathslbb{l}$', -u'\U0001d592': '$\\mathslbb{m}$', -u'\U0001d593': '$\\mathslbb{n}$', -u'\U0001d594': '$\\mathslbb{o}$', -u'\U0001d595': '$\\mathslbb{p}$', -u'\U0001d596': '$\\mathslbb{q}$', -u'\U0001d597': '$\\mathslbb{r}$', -u'\U0001d598': '$\\mathslbb{s}$', -u'\U0001d599': '$\\mathslbb{t}$', -u'\U0001d59a': '$\\mathslbb{u}$', -u'\U0001d59b': '$\\mathslbb{v}$', -u'\U0001d59c': '$\\mathslbb{w}$', -u'\U0001d59d': '$\\mathslbb{x}$', -u'\U0001d59e': '$\\mathslbb{y}$', -u'\U0001d59f': '$\\mathslbb{z}$', -u'\U0001d5a0': '$\\mathsf{A}$', -u'\U0001d5a1': '$\\mathsf{B}$', -u'\U0001d5a2': '$\\mathsf{C}$', -u'\U0001d5a3': '$\\mathsf{D}$', -u'\U0001d5a4': '$\\mathsf{E}$', -u'\U0001d5a5': '$\\mathsf{F}$', -u'\U0001d5a6': '$\\mathsf{G}$', -u'\U0001d5a7': '$\\mathsf{H}$', -u'\U0001d5a8': '$\\mathsf{I}$', -u'\U0001d5a9': '$\\mathsf{J}$', -u'\U0001d5aa': '$\\mathsf{K}$', -u'\U0001d5ab': '$\\mathsf{L}$', -u'\U0001d5ac': '$\\mathsf{M}$', -u'\U0001d5ad': '$\\mathsf{N}$', -u'\U0001d5ae': '$\\mathsf{O}$', -u'\U0001d5af': '$\\mathsf{P}$', -u'\U0001d5b0': '$\\mathsf{Q}$', -u'\U0001d5b1': '$\\mathsf{R}$', -u'\U0001d5b2': '$\\mathsf{S}$', -u'\U0001d5b3': '$\\mathsf{T}$', -u'\U0001d5b4': '$\\mathsf{U}$', -u'\U0001d5b5': '$\\mathsf{V}$', -u'\U0001d5b6': '$\\mathsf{W}$', -u'\U0001d5b7': '$\\mathsf{X}$', -u'\U0001d5b8': '$\\mathsf{Y}$', -u'\U0001d5b9': '$\\mathsf{Z}$', -u'\U0001d5ba': '$\\mathsf{a}$', -u'\U0001d5bb': '$\\mathsf{b}$', -u'\U0001d5bc': '$\\mathsf{c}$', -u'\U0001d5bd': '$\\mathsf{d}$', -u'\U0001d5be': '$\\mathsf{e}$', -u'\U0001d5bf': '$\\mathsf{f}$', -u'\U0001d5c0': '$\\mathsf{g}$', -u'\U0001d5c1': '$\\mathsf{h}$', -u'\U0001d5c2': '$\\mathsf{i}$', -u'\U0001d5c3': '$\\mathsf{j}$', -u'\U0001d5c4': '$\\mathsf{k}$', -u'\U0001d5c5': '$\\mathsf{l}$', -u'\U0001d5c6': '$\\mathsf{m}$', -u'\U0001d5c7': '$\\mathsf{n}$', -u'\U0001d5c8': '$\\mathsf{o}$', -u'\U0001d5c9': '$\\mathsf{p}$', -u'\U0001d5ca': '$\\mathsf{q}$', -u'\U0001d5cb': '$\\mathsf{r}$', -u'\U0001d5cc': '$\\mathsf{s}$', -u'\U0001d5cd': '$\\mathsf{t}$', -u'\U0001d5ce': '$\\mathsf{u}$', -u'\U0001d5cf': '$\\mathsf{v}$', -u'\U0001d5d0': '$\\mathsf{w}$', -u'\U0001d5d1': '$\\mathsf{x}$', -u'\U0001d5d2': '$\\mathsf{y}$', -u'\U0001d5d3': '$\\mathsf{z}$', -u'\U0001d5d4': '$\\mathsfbf{A}$', -u'\U0001d5d5': '$\\mathsfbf{B}$', -u'\U0001d5d6': '$\\mathsfbf{C}$', -u'\U0001d5d7': '$\\mathsfbf{D}$', -u'\U0001d5d8': '$\\mathsfbf{E}$', -u'\U0001d5d9': '$\\mathsfbf{F}$', -u'\U0001d5da': '$\\mathsfbf{G}$', -u'\U0001d5db': '$\\mathsfbf{H}$', -u'\U0001d5dc': '$\\mathsfbf{I}$', -u'\U0001d5dd': '$\\mathsfbf{J}$', -u'\U0001d5de': '$\\mathsfbf{K}$', -u'\U0001d5df': '$\\mathsfbf{L}$', -u'\U0001d5e0': '$\\mathsfbf{M}$', -u'\U0001d5e1': '$\\mathsfbf{N}$', -u'\U0001d5e2': '$\\mathsfbf{O}$', -u'\U0001d5e3': '$\\mathsfbf{P}$', -u'\U0001d5e4': '$\\mathsfbf{Q}$', -u'\U0001d5e5': '$\\mathsfbf{R}$', -u'\U0001d5e6': '$\\mathsfbf{S}$', -u'\U0001d5e7': '$\\mathsfbf{T}$', -u'\U0001d5e8': '$\\mathsfbf{U}$', -u'\U0001d5e9': '$\\mathsfbf{V}$', -u'\U0001d5ea': '$\\mathsfbf{W}$', -u'\U0001d5eb': '$\\mathsfbf{X}$', -u'\U0001d5ec': '$\\mathsfbf{Y}$', -u'\U0001d5ed': '$\\mathsfbf{Z}$', -u'\U0001d5ee': '$\\mathsfbf{a}$', -u'\U0001d5ef': '$\\mathsfbf{b}$', -u'\U0001d5f0': '$\\mathsfbf{c}$', -u'\U0001d5f1': '$\\mathsfbf{d}$', -u'\U0001d5f2': '$\\mathsfbf{e}$', -u'\U0001d5f3': '$\\mathsfbf{f}$', -u'\U0001d5f4': '$\\mathsfbf{g}$', -u'\U0001d5f5': '$\\mathsfbf{h}$', -u'\U0001d5f6': '$\\mathsfbf{i}$', -u'\U0001d5f7': '$\\mathsfbf{j}$', -u'\U0001d5f8': '$\\mathsfbf{k}$', -u'\U0001d5f9': '$\\mathsfbf{l}$', -u'\U0001d5fa': '$\\mathsfbf{m}$', -u'\U0001d5fb': '$\\mathsfbf{n}$', -u'\U0001d5fc': '$\\mathsfbf{o}$', -u'\U0001d5fd': '$\\mathsfbf{p}$', -u'\U0001d5fe': '$\\mathsfbf{q}$', -u'\U0001d5ff': '$\\mathsfbf{r}$', -u'\U0001d600': '$\\mathsfbf{s}$', -u'\U0001d601': '$\\mathsfbf{t}$', -u'\U0001d602': '$\\mathsfbf{u}$', -u'\U0001d603': '$\\mathsfbf{v}$', -u'\U0001d604': '$\\mathsfbf{w}$', -u'\U0001d605': '$\\mathsfbf{x}$', -u'\U0001d606': '$\\mathsfbf{y}$', -u'\U0001d607': '$\\mathsfbf{z}$', -u'\U0001d608': '$\\mathsfsl{A}$', -u'\U0001d609': '$\\mathsfsl{B}$', -u'\U0001d60a': '$\\mathsfsl{C}$', -u'\U0001d60b': '$\\mathsfsl{D}$', -u'\U0001d60c': '$\\mathsfsl{E}$', -u'\U0001d60d': '$\\mathsfsl{F}$', -u'\U0001d60e': '$\\mathsfsl{G}$', -u'\U0001d60f': '$\\mathsfsl{H}$', -u'\U0001d610': '$\\mathsfsl{I}$', -u'\U0001d611': '$\\mathsfsl{J}$', -u'\U0001d612': '$\\mathsfsl{K}$', -u'\U0001d613': '$\\mathsfsl{L}$', -u'\U0001d614': '$\\mathsfsl{M}$', -u'\U0001d615': '$\\mathsfsl{N}$', -u'\U0001d616': '$\\mathsfsl{O}$', -u'\U0001d617': '$\\mathsfsl{P}$', -u'\U0001d618': '$\\mathsfsl{Q}$', -u'\U0001d619': '$\\mathsfsl{R}$', -u'\U0001d61a': '$\\mathsfsl{S}$', -u'\U0001d61b': '$\\mathsfsl{T}$', -u'\U0001d61c': '$\\mathsfsl{U}$', -u'\U0001d61d': '$\\mathsfsl{V}$', -u'\U0001d61e': '$\\mathsfsl{W}$', -u'\U0001d61f': '$\\mathsfsl{X}$', -u'\U0001d620': '$\\mathsfsl{Y}$', -u'\U0001d621': '$\\mathsfsl{Z}$', -u'\U0001d622': '$\\mathsfsl{a}$', -u'\U0001d623': '$\\mathsfsl{b}$', -u'\U0001d624': '$\\mathsfsl{c}$', -u'\U0001d625': '$\\mathsfsl{d}$', -u'\U0001d626': '$\\mathsfsl{e}$', -u'\U0001d627': '$\\mathsfsl{f}$', -u'\U0001d628': '$\\mathsfsl{g}$', -u'\U0001d629': '$\\mathsfsl{h}$', -u'\U0001d62a': '$\\mathsfsl{i}$', -u'\U0001d62b': '$\\mathsfsl{j}$', -u'\U0001d62c': '$\\mathsfsl{k}$', -u'\U0001d62d': '$\\mathsfsl{l}$', -u'\U0001d62e': '$\\mathsfsl{m}$', -u'\U0001d62f': '$\\mathsfsl{n}$', -u'\U0001d630': '$\\mathsfsl{o}$', -u'\U0001d631': '$\\mathsfsl{p}$', -u'\U0001d632': '$\\mathsfsl{q}$', -u'\U0001d633': '$\\mathsfsl{r}$', -u'\U0001d634': '$\\mathsfsl{s}$', -u'\U0001d635': '$\\mathsfsl{t}$', -u'\U0001d636': '$\\mathsfsl{u}$', -u'\U0001d637': '$\\mathsfsl{v}$', -u'\U0001d638': '$\\mathsfsl{w}$', -u'\U0001d639': '$\\mathsfsl{x}$', -u'\U0001d63a': '$\\mathsfsl{y}$', -u'\U0001d63b': '$\\mathsfsl{z}$', -u'\U0001d63c': '$\\mathsfbfsl{A}$', -u'\U0001d63d': '$\\mathsfbfsl{B}$', -u'\U0001d63e': '$\\mathsfbfsl{C}$', -u'\U0001d63f': '$\\mathsfbfsl{D}$', -u'\U0001d640': '$\\mathsfbfsl{E}$', -u'\U0001d641': '$\\mathsfbfsl{F}$', -u'\U0001d642': '$\\mathsfbfsl{G}$', -u'\U0001d643': '$\\mathsfbfsl{H}$', -u'\U0001d644': '$\\mathsfbfsl{I}$', -u'\U0001d645': '$\\mathsfbfsl{J}$', -u'\U0001d646': '$\\mathsfbfsl{K}$', -u'\U0001d647': '$\\mathsfbfsl{L}$', -u'\U0001d648': '$\\mathsfbfsl{M}$', -u'\U0001d649': '$\\mathsfbfsl{N}$', -u'\U0001d64a': '$\\mathsfbfsl{O}$', -u'\U0001d64b': '$\\mathsfbfsl{P}$', -u'\U0001d64c': '$\\mathsfbfsl{Q}$', -u'\U0001d64d': '$\\mathsfbfsl{R}$', -u'\U0001d64e': '$\\mathsfbfsl{S}$', -u'\U0001d64f': '$\\mathsfbfsl{T}$', -u'\U0001d650': '$\\mathsfbfsl{U}$', -u'\U0001d651': '$\\mathsfbfsl{V}$', -u'\U0001d652': '$\\mathsfbfsl{W}$', -u'\U0001d653': '$\\mathsfbfsl{X}$', -u'\U0001d654': '$\\mathsfbfsl{Y}$', -u'\U0001d655': '$\\mathsfbfsl{Z}$', -u'\U0001d656': '$\\mathsfbfsl{a}$', -u'\U0001d657': '$\\mathsfbfsl{b}$', -u'\U0001d658': '$\\mathsfbfsl{c}$', -u'\U0001d659': '$\\mathsfbfsl{d}$', -u'\U0001d65a': '$\\mathsfbfsl{e}$', -u'\U0001d65b': '$\\mathsfbfsl{f}$', -u'\U0001d65c': '$\\mathsfbfsl{g}$', -u'\U0001d65d': '$\\mathsfbfsl{h}$', -u'\U0001d65e': '$\\mathsfbfsl{i}$', -u'\U0001d65f': '$\\mathsfbfsl{j}$', -u'\U0001d660': '$\\mathsfbfsl{k}$', -u'\U0001d661': '$\\mathsfbfsl{l}$', -u'\U0001d662': '$\\mathsfbfsl{m}$', -u'\U0001d663': '$\\mathsfbfsl{n}$', -u'\U0001d664': '$\\mathsfbfsl{o}$', -u'\U0001d665': '$\\mathsfbfsl{p}$', -u'\U0001d666': '$\\mathsfbfsl{q}$', -u'\U0001d667': '$\\mathsfbfsl{r}$', -u'\U0001d668': '$\\mathsfbfsl{s}$', -u'\U0001d669': '$\\mathsfbfsl{t}$', -u'\U0001d66a': '$\\mathsfbfsl{u}$', -u'\U0001d66b': '$\\mathsfbfsl{v}$', -u'\U0001d66c': '$\\mathsfbfsl{w}$', -u'\U0001d66d': '$\\mathsfbfsl{x}$', -u'\U0001d66e': '$\\mathsfbfsl{y}$', -u'\U0001d66f': '$\\mathsfbfsl{z}$', -u'\U0001d670': '$\\mathtt{A}$', -u'\U0001d671': '$\\mathtt{B}$', -u'\U0001d672': '$\\mathtt{C}$', -u'\U0001d673': '$\\mathtt{D}$', -u'\U0001d674': '$\\mathtt{E}$', -u'\U0001d675': '$\\mathtt{F}$', -u'\U0001d676': '$\\mathtt{G}$', -u'\U0001d677': '$\\mathtt{H}$', -u'\U0001d678': '$\\mathtt{I}$', -u'\U0001d679': '$\\mathtt{J}$', -u'\U0001d67a': '$\\mathtt{K}$', -u'\U0001d67b': '$\\mathtt{L}$', -u'\U0001d67c': '$\\mathtt{M}$', -u'\U0001d67d': '$\\mathtt{N}$', -u'\U0001d67e': '$\\mathtt{O}$', -u'\U0001d67f': '$\\mathtt{P}$', -u'\U0001d680': '$\\mathtt{Q}$', -u'\U0001d681': '$\\mathtt{R}$', -u'\U0001d682': '$\\mathtt{S}$', -u'\U0001d683': '$\\mathtt{T}$', -u'\U0001d684': '$\\mathtt{U}$', -u'\U0001d685': '$\\mathtt{V}$', -u'\U0001d686': '$\\mathtt{W}$', -u'\U0001d687': '$\\mathtt{X}$', -u'\U0001d688': '$\\mathtt{Y}$', -u'\U0001d689': '$\\mathtt{Z}$', -u'\U0001d68a': '$\\mathtt{a}$', -u'\U0001d68b': '$\\mathtt{b}$', -u'\U0001d68c': '$\\mathtt{c}$', -u'\U0001d68d': '$\\mathtt{d}$', -u'\U0001d68e': '$\\mathtt{e}$', -u'\U0001d68f': '$\\mathtt{f}$', -u'\U0001d690': '$\\mathtt{g}$', -u'\U0001d691': '$\\mathtt{h}$', -u'\U0001d692': '$\\mathtt{i}$', -u'\U0001d693': '$\\mathtt{j}$', -u'\U0001d694': '$\\mathtt{k}$', -u'\U0001d695': '$\\mathtt{l}$', -u'\U0001d696': '$\\mathtt{m}$', -u'\U0001d697': '$\\mathtt{n}$', -u'\U0001d698': '$\\mathtt{o}$', -u'\U0001d699': '$\\mathtt{p}$', -u'\U0001d69a': '$\\mathtt{q}$', -u'\U0001d69b': '$\\mathtt{r}$', -u'\U0001d69c': '$\\mathtt{s}$', -u'\U0001d69d': '$\\mathtt{t}$', -u'\U0001d69e': '$\\mathtt{u}$', -u'\U0001d69f': '$\\mathtt{v}$', -u'\U0001d6a0': '$\\mathtt{w}$', -u'\U0001d6a1': '$\\mathtt{x}$', -u'\U0001d6a2': '$\\mathtt{y}$', -u'\U0001d6a3': '$\\mathtt{z}$', -u'\U0001d6a8': '$\\mathbf{\\Alpha}$', -u'\U0001d6a9': '$\\mathbf{\\Beta}$', -u'\U0001d6aa': '$\\mathbf{\\Gamma}$', -u'\U0001d6ab': '$\\mathbf{\\Delta}$', -u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', -u'\U0001d6ad': '$\\mathbf{\\Zeta}$', -u'\U0001d6ae': '$\\mathbf{\\Eta}$', -u'\U0001d6af': '$\\mathbf{\\Theta}$', -u'\U0001d6b0': '$\\mathbf{\\Iota}$', -u'\U0001d6b1': '$\\mathbf{\\Kappa}$', -u'\U0001d6b2': '$\\mathbf{\\Lambda}$', -u'\U0001d6b3': '$M$', -u'\U0001d6b4': '$N$', -u'\U0001d6b5': '$\\mathbf{\\Xi}$', -u'\U0001d6b6': '$O$', -u'\U0001d6b7': '$\\mathbf{\\Pi}$', -u'\U0001d6b8': '$\\mathbf{\\Rho}$', -u'\U0001d6b9': '{\\mathbf{\\vartheta}}', -u'\U0001d6ba': '$\\mathbf{\\Sigma}$', -u'\U0001d6bb': '$\\mathbf{\\Tau}$', -u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', -u'\U0001d6bd': '$\\mathbf{\\Phi}$', -u'\U0001d6be': '$\\mathbf{\\Chi}$', -u'\U0001d6bf': '$\\mathbf{\\Psi}$', -u'\U0001d6c0': '$\\mathbf{\\Omega}$', -u'\U0001d6c1': '$\\mathbf{\\nabla}$', -u'\U0001d6c2': '$\\mathbf{\\Alpha}$', -u'\U0001d6c3': '$\\mathbf{\\Beta}$', -u'\U0001d6c4': '$\\mathbf{\\Gamma}$', -u'\U0001d6c5': '$\\mathbf{\\Delta}$', -u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', -u'\U0001d6c7': '$\\mathbf{\\Zeta}$', -u'\U0001d6c8': '$\\mathbf{\\Eta}$', -u'\U0001d6c9': '$\\mathbf{\\theta}$', -u'\U0001d6ca': '$\\mathbf{\\Iota}$', -u'\U0001d6cb': '$\\mathbf{\\Kappa}$', -u'\U0001d6cc': '$\\mathbf{\\Lambda}$', -u'\U0001d6cd': '$M$', -u'\U0001d6ce': '$N$', -u'\U0001d6cf': '$\\mathbf{\\Xi}$', -u'\U0001d6d0': '$O$', -u'\U0001d6d1': '$\\mathbf{\\Pi}$', -u'\U0001d6d2': '$\\mathbf{\\Rho}$', -u'\U0001d6d3': '$\\mathbf{\\varsigma}$', -u'\U0001d6d4': '$\\mathbf{\\Sigma}$', -u'\U0001d6d5': '$\\mathbf{\\Tau}$', -u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', -u'\U0001d6d7': '$\\mathbf{\\Phi}$', -u'\U0001d6d8': '$\\mathbf{\\Chi}$', -u'\U0001d6d9': '$\\mathbf{\\Psi}$', -u'\U0001d6da': '$\\mathbf{\\Omega}$', -u'\U0001d6db': '$\\partial$', -u'\U0001d6dc': '$\\in$', -u'\U0001d6dd': '{\\mathbf{\\vartheta}}', -u'\U0001d6de': '{\\mathbf{\\varkappa}}', -u'\U0001d6df': '{\\mathbf{\\phi}}', -u'\U0001d6e0': '{\\mathbf{\\varrho}}', -u'\U0001d6e1': '{\\mathbf{\\varpi}}', -u'\U0001d6e2': '$\\mathsl{\\Alpha}$', -u'\U0001d6e3': '$\\mathsl{\\Beta}$', -u'\U0001d6e4': '$\\mathsl{\\Gamma}$', -u'\U0001d6e5': '$\\mathsl{\\Delta}$', -u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', -u'\U0001d6e7': '$\\mathsl{\\Zeta}$', -u'\U0001d6e8': '$\\mathsl{\\Eta}$', -u'\U0001d6e9': '$\\mathsl{\\Theta}$', -u'\U0001d6ea': '$\\mathsl{\\Iota}$', -u'\U0001d6eb': '$\\mathsl{\\Kappa}$', -u'\U0001d6ec': '$\\mathsl{\\Lambda}$', -u'\U0001d6ed': '$M$', -u'\U0001d6ee': '$N$', -u'\U0001d6ef': '$\\mathsl{\\Xi}$', -u'\U0001d6f0': '$O$', -u'\U0001d6f1': '$\\mathsl{\\Pi}$', -u'\U0001d6f2': '$\\mathsl{\\Rho}$', -u'\U0001d6f3': '{\\mathsl{\\vartheta}}', -u'\U0001d6f4': '$\\mathsl{\\Sigma}$', -u'\U0001d6f5': '$\\mathsl{\\Tau}$', -u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', -u'\U0001d6f7': '$\\mathsl{\\Phi}$', -u'\U0001d6f8': '$\\mathsl{\\Chi}$', -u'\U0001d6f9': '$\\mathsl{\\Psi}$', -u'\U0001d6fa': '$\\mathsl{\\Omega}$', -u'\U0001d6fb': '$\\mathsl{\\nabla}$', -u'\U0001d6fc': '$\\mathsl{\\Alpha}$', -u'\U0001d6fd': '$\\mathsl{\\Beta}$', -u'\U0001d6fe': '$\\mathsl{\\Gamma}$', -u'\U0001d6ff': '$\\mathsl{\\Delta}$', -u'\U0001d700': '$\\mathsl{\\Epsilon}$', -u'\U0001d701': '$\\mathsl{\\Zeta}$', -u'\U0001d702': '$\\mathsl{\\Eta}$', -u'\U0001d703': '$\\mathsl{\\Theta}$', -u'\U0001d704': '$\\mathsl{\\Iota}$', -u'\U0001d705': '$\\mathsl{\\Kappa}$', -u'\U0001d706': '$\\mathsl{\\Lambda}$', -u'\U0001d707': '$M$', -u'\U0001d708': '$N$', -u'\U0001d709': '$\\mathsl{\\Xi}$', -u'\U0001d70a': '$O$', -u'\U0001d70b': '$\\mathsl{\\Pi}$', -u'\U0001d70c': '$\\mathsl{\\Rho}$', -u'\U0001d70d': '$\\mathsl{\\varsigma}$', -u'\U0001d70e': '$\\mathsl{\\Sigma}$', -u'\U0001d70f': '$\\mathsl{\\Tau}$', -u'\U0001d710': '$\\mathsl{\\Upsilon}$', -u'\U0001d711': '$\\mathsl{\\Phi}$', -u'\U0001d712': '$\\mathsl{\\Chi}$', -u'\U0001d713': '$\\mathsl{\\Psi}$', -u'\U0001d714': '$\\mathsl{\\Omega}$', -u'\U0001d715': '$\\partial$', -u'\U0001d716': '$\\in$', -u'\U0001d717': '{\\mathsl{\\vartheta}}', -u'\U0001d718': '{\\mathsl{\\varkappa}}', -u'\U0001d719': '{\\mathsl{\\phi}}', -u'\U0001d71a': '{\\mathsl{\\varrho}}', -u'\U0001d71b': '{\\mathsl{\\varpi}}', -u'\U0001d71c': '$\\mathbit{\\Alpha}$', -u'\U0001d71d': '$\\mathbit{\\Beta}$', -u'\U0001d71e': '$\\mathbit{\\Gamma}$', -u'\U0001d71f': '$\\mathbit{\\Delta}$', -u'\U0001d720': '$\\mathbit{\\Epsilon}$', -u'\U0001d721': '$\\mathbit{\\Zeta}$', -u'\U0001d722': '$\\mathbit{\\Eta}$', -u'\U0001d723': '$\\mathbit{\\Theta}$', -u'\U0001d724': '$\\mathbit{\\Iota}$', -u'\U0001d725': '$\\mathbit{\\Kappa}$', -u'\U0001d726': '$\\mathbit{\\Lambda}$', -u'\U0001d727': '$M$', -u'\U0001d728': '$N$', -u'\U0001d729': '$\\mathbit{\\Xi}$', -u'\U0001d72a': '$O$', -u'\U0001d72b': '$\\mathbit{\\Pi}$', -u'\U0001d72c': '$\\mathbit{\\Rho}$', -u'\U0001d72d': '{\\mathbit{O}}', -u'\U0001d72e': '$\\mathbit{\\Sigma}$', -u'\U0001d72f': '$\\mathbit{\\Tau}$', -u'\U0001d730': '$\\mathbit{\\Upsilon}$', -u'\U0001d731': '$\\mathbit{\\Phi}$', -u'\U0001d732': '$\\mathbit{\\Chi}$', -u'\U0001d733': '$\\mathbit{\\Psi}$', -u'\U0001d734': '$\\mathbit{\\Omega}$', -u'\U0001d735': '$\\mathbit{\\nabla}$', -u'\U0001d736': '$\\mathbit{\\Alpha}$', -u'\U0001d737': '$\\mathbit{\\Beta}$', -u'\U0001d738': '$\\mathbit{\\Gamma}$', -u'\U0001d739': '$\\mathbit{\\Delta}$', -u'\U0001d73a': '$\\mathbit{\\Epsilon}$', -u'\U0001d73b': '$\\mathbit{\\Zeta}$', -u'\U0001d73c': '$\\mathbit{\\Eta}$', -u'\U0001d73d': '$\\mathbit{\\Theta}$', -u'\U0001d73e': '$\\mathbit{\\Iota}$', -u'\U0001d73f': '$\\mathbit{\\Kappa}$', -u'\U0001d740': '$\\mathbit{\\Lambda}$', -u'\U0001d741': '$M$', -u'\U0001d742': '$N$', -u'\U0001d743': '$\\mathbit{\\Xi}$', -u'\U0001d744': '$O$', -u'\U0001d745': '$\\mathbit{\\Pi}$', -u'\U0001d746': '$\\mathbit{\\Rho}$', -u'\U0001d747': '$\\mathbit{\\varsigma}$', -u'\U0001d748': '$\\mathbit{\\Sigma}$', -u'\U0001d749': '$\\mathbit{\\Tau}$', -u'\U0001d74a': '$\\mathbit{\\Upsilon}$', -u'\U0001d74b': '$\\mathbit{\\Phi}$', -u'\U0001d74c': '$\\mathbit{\\Chi}$', -u'\U0001d74d': '$\\mathbit{\\Psi}$', -u'\U0001d74e': '$\\mathbit{\\Omega}$', -u'\U0001d74f': '$\\partial$', -u'\U0001d750': '$\\in$', -u'\U0001d751': '{\\mathbit{\\vartheta}}', -u'\U0001d752': '{\\mathbit{\\varkappa}}', -u'\U0001d753': '{\\mathbit{\\phi}}', -u'\U0001d754': '{\\mathbit{\\varrho}}', -u'\U0001d755': '{\\mathbit{\\varpi}}', -u'\U0001d756': '$\\mathsfbf{\\Alpha}$', -u'\U0001d757': '$\\mathsfbf{\\Beta}$', -u'\U0001d758': '$\\mathsfbf{\\Gamma}$', -u'\U0001d759': '$\\mathsfbf{\\Delta}$', -u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', -u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', -u'\U0001d75c': '$\\mathsfbf{\\Eta}$', -u'\U0001d75d': '$\\mathsfbf{\\Theta}$', -u'\U0001d75e': '$\\mathsfbf{\\Iota}$', -u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', -u'\U0001d760': '$\\mathsfbf{\\Lambda}$', -u'\U0001d761': '$M$', -u'\U0001d762': '$N$', -u'\U0001d763': '$\\mathsfbf{\\Xi}$', -u'\U0001d764': '$O$', -u'\U0001d765': '$\\mathsfbf{\\Pi}$', -u'\U0001d766': '$\\mathsfbf{\\Rho}$', -u'\U0001d767': '{\\mathsfbf{\\vartheta}}', -u'\U0001d768': '$\\mathsfbf{\\Sigma}$', -u'\U0001d769': '$\\mathsfbf{\\Tau}$', -u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', -u'\U0001d76b': '$\\mathsfbf{\\Phi}$', -u'\U0001d76c': '$\\mathsfbf{\\Chi}$', -u'\U0001d76d': '$\\mathsfbf{\\Psi}$', -u'\U0001d76e': '$\\mathsfbf{\\Omega}$', -u'\U0001d76f': '$\\mathsfbf{\\nabla}$', -u'\U0001d770': '$\\mathsfbf{\\Alpha}$', -u'\U0001d771': '$\\mathsfbf{\\Beta}$', -u'\U0001d772': '$\\mathsfbf{\\Gamma}$', -u'\U0001d773': '$\\mathsfbf{\\Delta}$', -u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', -u'\U0001d775': '$\\mathsfbf{\\Zeta}$', -u'\U0001d776': '$\\mathsfbf{\\Eta}$', -u'\U0001d777': '$\\mathsfbf{\\Theta}$', -u'\U0001d778': '$\\mathsfbf{\\Iota}$', -u'\U0001d779': '$\\mathsfbf{\\Kappa}$', -u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', -u'\U0001d77b': '$M$', -u'\U0001d77c': '$N$', -u'\U0001d77d': '$\\mathsfbf{\\Xi}$', -u'\U0001d77e': '$O$', -u'\U0001d77f': '$\\mathsfbf{\\Pi}$', -u'\U0001d780': '$\\mathsfbf{\\Rho}$', -u'\U0001d781': '$\\mathsfbf{\\varsigma}$', -u'\U0001d782': '$\\mathsfbf{\\Sigma}$', -u'\U0001d783': '$\\mathsfbf{\\Tau}$', -u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', -u'\U0001d785': '$\\mathsfbf{\\Phi}$', -u'\U0001d786': '$\\mathsfbf{\\Chi}$', -u'\U0001d787': '$\\mathsfbf{\\Psi}$', -u'\U0001d788': '$\\mathsfbf{\\Omega}$', -u'\U0001d789': '$\\partial$', -u'\U0001d78a': '$\\in$', -u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', -u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', -u'\U0001d78d': '{\\mathsfbf{\\phi}}', -u'\U0001d78e': '{\\mathsfbf{\\varrho}}', -u'\U0001d78f': '{\\mathsfbf{\\varpi}}', -u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', -u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', -u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', -u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', -u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', -u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', -u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', -u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', -u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', -u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', -u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', -u'\U0001d79b': '$M$', -u'\U0001d79c': '$N$', -u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', -u'\U0001d79e': '$O$', -u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', -u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', -u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', -u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', -u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', -u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', -u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', -u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', -u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', -u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', -u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', -u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', -u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', -u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', -u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', -u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', -u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', -u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', -u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', -u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', -u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', -u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', -u'\U0001d7b5': '$M$', -u'\U0001d7b6': '$N$', -u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', -u'\U0001d7b8': '$O$', -u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', -u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', -u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', -u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', -u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', -u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', -u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', -u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', -u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', -u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', -u'\U0001d7c3': '$\\partial$', -u'\U0001d7c4': '$\\in$', -u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', -u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', -u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', -u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', -u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', -u'\U0001d7ce': '$\\mathbf{0}$', -u'\U0001d7cf': '$\\mathbf{1}$', -u'\U0001d7d0': '$\\mathbf{2}$', -u'\U0001d7d1': '$\\mathbf{3}$', -u'\U0001d7d2': '$\\mathbf{4}$', -u'\U0001d7d3': '$\\mathbf{5}$', -u'\U0001d7d4': '$\\mathbf{6}$', -u'\U0001d7d5': '$\\mathbf{7}$', -u'\U0001d7d6': '$\\mathbf{8}$', -u'\U0001d7d7': '$\\mathbf{9}$', -u'\U0001d7d8': '$\\mathbb{0}$', -u'\U0001d7d9': '$\\mathbb{1}$', -u'\U0001d7da': '$\\mathbb{2}$', -u'\U0001d7db': '$\\mathbb{3}$', -u'\U0001d7dc': '$\\mathbb{4}$', -u'\U0001d7dd': '$\\mathbb{5}$', -u'\U0001d7de': '$\\mathbb{6}$', -u'\U0001d7df': '$\\mathbb{7}$', -u'\U0001d7e0': '$\\mathbb{8}$', -u'\U0001d7e1': '$\\mathbb{9}$', -u'\U0001d7e2': '$\\mathsf{0}$', -u'\U0001d7e3': '$\\mathsf{1}$', -u'\U0001d7e4': '$\\mathsf{2}$', -u'\U0001d7e5': '$\\mathsf{3}$', -u'\U0001d7e6': '$\\mathsf{4}$', -u'\U0001d7e7': '$\\mathsf{5}$', -u'\U0001d7e8': '$\\mathsf{6}$', -u'\U0001d7e9': '$\\mathsf{7}$', -u'\U0001d7ea': '$\\mathsf{8}$', -u'\U0001d7eb': '$\\mathsf{9}$', -u'\U0001d7ec': '$\\mathsfbf{0}$', -u'\U0001d7ed': '$\\mathsfbf{1}$', -u'\U0001d7ee': '$\\mathsfbf{2}$', -u'\U0001d7ef': '$\\mathsfbf{3}$', -u'\U0001d7f0': '$\\mathsfbf{4}$', -u'\U0001d7f1': '$\\mathsfbf{5}$', -u'\U0001d7f2': '$\\mathsfbf{6}$', -u'\U0001d7f3': '$\\mathsfbf{7}$', -u'\U0001d7f4': '$\\mathsfbf{8}$', -u'\U0001d7f5': '$\\mathsfbf{9}$', -u'\U0001d7f6': '$\\mathtt{0}$', -u'\U0001d7f7': '$\\mathtt{1}$', -u'\U0001d7f8': '$\\mathtt{2}$', -u'\U0001d7f9': '$\\mathtt{3}$', -u'\U0001d7fa': '$\\mathtt{4}$', -u'\U0001d7fb': '$\\mathtt{5}$', -u'\U0001d7fc': '$\\mathtt{6}$', -u'\U0001d7fd': '$\\mathtt{7}$', -u'\U0001d7fe': '$\\mathtt{8}$', -u'\U0001d7ff': '$\\mathtt{9}$'} -- cgit v1.2.1 From 954c213bb271a9a2b91e694c8fbf155925dd9f4e Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 15 Sep 2005 14:16:33 +0000 Subject: Added support for specifying runtime settings at the suite level git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3879 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/frontend.py | 4 ++ test/DocutilsTestSupport.py | 55 +++++++++++++++++---------- test/test_transforms/test_expose_internals.py | 11 +++--- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/docutils/frontend.py b/docutils/frontend.py index b0e0048cd..93506bce5 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -219,6 +219,10 @@ class Values(optparse.Values): del other_dict[setting] self._update_loose(other_dict) + def copy(self): + """Return a shallow copy of `self`.""" + return self.__class__(defaults=self.__dict__) + class Option(optparse.Option): diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index ba4a14f81..ea1672d1b 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -135,7 +135,8 @@ class CustomTestCase(StandardTestCase): compare = docutils_difflib.Differ().compare """Comparison method shared by all subclasses.""" - def __init__(self, method_name, input, expected, id, run_in_debugger=0): + def __init__(self, method_name, input, expected, id, run_in_debugger=0, + suite_settings=None): """ Initialise the CustomTestCase. @@ -146,11 +147,13 @@ class CustomTestCase(StandardTestCase): expected -- expected output from the parser. id -- unique test identifier, used by the test framework. run_in_debugger -- if true, run this test under the pdb debugger. + suite_settings -- settings overrides for this test suite. """ self.id = id self.input = input self.expected = expected self.run_in_debugger = run_in_debugger + self.suite_settings = suite_settings or {} # Ring your mother. unittest.TestCase.__init__(self, method_name) @@ -205,15 +208,17 @@ class CustomTestSuite(unittest.TestSuite): next_test_case_id = 0 """The next identifier to use for non-identified test cases.""" - def __init__(self, tests=(), id=None): + def __init__(self, tests=(), id=None, suite_settings=None): """ Initialize the CustomTestSuite. Arguments: id -- identifier for the suite, prepended to test cases. + suite_settings -- settings overrides for this test suite. """ unittest.TestSuite.__init__(self, tests) + self.suite_settings = suite_settings or {} if id is None: mypath = os.path.abspath( sys.modules[CustomTestSuite.__module__].__file__) @@ -256,6 +261,9 @@ class CustomTestSuite(unittest.TestSuite): self.next_test_case_id += 1 # test identifier will become suiteid.testid tcid = '%s: %s' % (self.id, id) + # suite_settings may be passed as a parameter; + # if not, set from attribute: + kwargs.setdefault('suite_settings', self.suite_settings) # generate and add test case tc = test_case_class(method_name, input, expected, tcid, run_in_debugger=run_in_debugger, **kwargs) @@ -300,7 +308,9 @@ class TransformTestCase(CustomTestCase): def test_transforms(self): if self.run_in_debugger: pdb.set_trace() - document = utils.new_document('test data', self.settings) + settings = self.settings.copy() + settings.__dict__.update(self.suite_settings) + document = utils.new_document('test data', settings) self.parser.parse(self.input, document) # Don't do a ``populate_from_components()`` because that would # enable the Transformer's default transforms. @@ -317,7 +327,9 @@ class TransformTestCase(CustomTestCase): print '\n', self.id print '-' * 70 print self.input - document = utils.new_document('test data', self.settings) + settings = self.settings.copy() + settings.__dict__.update(self.suite_settings) + document = utils.new_document('test data', settings) self.parser.parse(self.input, document) print '-' * 70 print document.pformat() @@ -339,11 +351,11 @@ class TransformTestSuite(CustomTestSuite): setUp and tearDown). """ - def __init__(self, parser): + def __init__(self, parser, suite_settings=None): self.parser = parser """Parser shared by all test cases.""" - CustomTestSuite.__init__(self) + CustomTestSuite.__init__(self, suite_settings=suite_settings) def generateTests(self, dict, dictname='totest', testmethod='test_transforms'): @@ -363,6 +375,11 @@ class TransformTestSuite(CustomTestSuite): case = cases[casenum] run_in_debugger = 0 if len(case)==3: + # TODO: (maybe) change the 3rd argument to a dict, so it + # can handle more cases by keyword ('disable', 'debug', + # 'settings'), here and in other generateTests methods. + # But there's also the method that + # HtmlPublishPartsTestSuite uses if case[2]: run_in_debugger = 1 else: @@ -397,7 +414,9 @@ class ParserTestCase(CustomTestCase): def test_parser(self): if self.run_in_debugger: pdb.set_trace() - document = utils.new_document('test data', self.settings) + settings = self.settings.copy() + settings.__dict__.update(self.suite_settings) + document = utils.new_document('test data', settings) # Remove any additions made by "role" directives: roles._roles = {} self.parser.parse(self.input, document) @@ -655,17 +674,18 @@ class WriterPublishTestCase(CustomTestCase, docutils.SettingsSpec): reader_name='standalone', parser_name='restructuredtext', writer_name=self.writer_name, - settings_spec=self) + settings_spec=self, + settings_overrides=self.suite_settings) self.compare_output(self.input, output, self.expected) class PublishTestSuite(CustomTestSuite): - def __init__(self, writer_name): + def __init__(self, writer_name, suite_settings=None): """ `writer_name` is the name of the writer to use. """ - CustomTestSuite.__init__(self) + CustomTestSuite.__init__(self, suite_settings=suite_settings) self.test_class = WriterPublishTestCase self.writer_name = writer_name @@ -692,6 +712,8 @@ class HtmlPublishPartsTestSuite(CustomTestSuite): def generateTests(self, dict, dictname='totest'): for name, (settings_overrides, cases) in dict.items(): + settings = self.suite_settings.copy() + settings.update(settings_overrides) for casenum in range(len(cases)): case = cases[casenum] run_in_debugger = 0 @@ -702,10 +724,10 @@ class HtmlPublishPartsTestSuite(CustomTestSuite): continue self.addTestCase( HtmlWriterPublishPartsTestCase, 'test_publish', - settings_overrides=settings_overrides, input=case[0], expected=case[1], id='%s[%r][%s]' % (dictname, name, casenum), - run_in_debugger=run_in_debugger) + run_in_debugger=run_in_debugger, + suite_settings=settings) class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): @@ -720,13 +742,6 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): WriterPublishTestCase.settings_default_overrides.copy() settings_default_overrides['stylesheet'] = '' - def __init__(self, *args, **kwargs): - self.settings_overrides = kwargs['settings_overrides'] - """Settings overrides to use for this test case.""" - - del kwargs['settings_overrides'] # only wanted here - CustomTestCase.__init__(self, *args, **kwargs) - def test_publish(self): if self.run_in_debugger: pdb.set_trace() @@ -736,7 +751,7 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): parser_name='restructuredtext', writer_name=self.writer_name, settings_spec=self, - settings_overrides=self.settings_overrides) + settings_overrides=self.suite_settings) output = self.format_output(parts) # interpolate standard variables: expected = self.expected % {'version': docutils.__version__} diff --git a/test/test_transforms/test_expose_internals.py b/test/test_transforms/test_expose_internals.py index 37747a68b..db19d2a0a 100755 --- a/test/test_transforms/test_expose_internals.py +++ b/test/test_transforms/test_expose_internals.py @@ -17,7 +17,8 @@ from docutils.parsers.rst import Parser def suite(): parser = Parser() - s = DocutilsTestSupport.TransformTestSuite(parser) + s = DocutilsTestSupport.TransformTestSuite( + parser, suite_settings={'expose_internals': ['rawsource', 'source']}) s.generateTests(totest) return s @@ -29,10 +30,10 @@ totest['transitions'] = ((ExposeInternals,), [ This is a test. """, """\ -[Test disabled at the moment. How do we activate the expose_internals -setting for this test suite?] -""", -0], + + + This is a test. +"""], ]) -- cgit v1.2.1 From bbb4c700f21865d2f925acb7b6b50c2340af1851 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 15 Sep 2005 14:16:46 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3880 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 6 ++++++ docs/dev/todo.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 4af33a6e3..d20f1e743 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -85,6 +85,8 @@ Changes Since 0.3.9 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). * docutils/transforms/writer_aux.py: Added to project; auxiliary transforms for writers. @@ -133,6 +135,10 @@ Changes Since 0.3.9 * test/coverage.sh: Added to project; test coverage script. +* test/DocutilsTestSupport.py: + + - Added support for specifying runtime settings at the suite level. + * tools/rst2html.py: Made stylesheet requirement explicit (via ``_stylesheet_required`` setting). diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 18689dd8b..c54eb4a9f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1191,6 +1191,8 @@ when used in a document. - "highlight" a range of lines + - include only a specified range of lines + - "number" or "line-numbers" - "styled" could indicate that the directive should check for -- cgit v1.2.1 From 9a747c5991eb8ec2919238d767f3bd1893df5d4d Mon Sep 17 00:00:00 2001 From: blais Date: Thu, 15 Sep 2005 17:06:26 +0000 Subject: Fixed minor bug with indented section titles being discovered when they should not. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3881 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 14 +++++++-- tools/editors/emacs/tests/tests-basic.el | 51 +++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 9d43734ef..86f7806fe 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -205,6 +205,14 @@ is for which (pred elem) is true)" )) )) +(defun rest-line-homogeneous-nodent-p (&optional accept-special) + (save-excursion + (beginning-of-line) + (if (looking-at "^[ \t]+") + nil + (rest-line-homogeneous-p accept-special) + ))) + (defun rest-compare-decorations (deco1 deco2) "Compare decorations. Returns true if both are equal, @@ -367,7 +375,7 @@ have been seen. (save-excursion (beginning-of-buffer) (while (< (point) (buffer-end 1)) - (if (rest-line-homogeneous-p) + (if (rest-line-homogeneous-nodent-p) (progn (setq curline (+ curline (rest-normalize-cursor-position))) @@ -450,11 +458,11 @@ have been seen. (if (looking-at rest-section-text-regexp) (let* ((over (save-excursion (forward-line -1) - (rest-line-homogeneous-p))) + (rest-line-homogeneous-nodent-p))) (under (save-excursion (forward-line +1) - (rest-line-homogeneous-p))) + (rest-line-homogeneous-nodent-p))) ) ;; Check that the line above the overline is not part of a title diff --git a/tools/editors/emacs/tests/tests-basic.el b/tools/editors/emacs/tests/tests-basic.el index 73054742f..847effd52 100644 --- a/tools/editors/emacs/tests/tests-basic.el +++ b/tools/editors/emacs/tests/tests-basic.el @@ -24,7 +24,7 @@ (simple "Blablabla bla@" nil) (true "-----------@" ?-) (indented " -----------@" ?-) -(letter " aaaa@aaa" ?a) +(letter "aaaa@aaa" ?a) (true2 "uuuuuuuuuuuuuuuuu@" ?u) (misleading "--=---------@" nil) (notstrip " uuuuuuuuuuuuuuuuu@" ?u) @@ -38,6 +38,26 @@ "Tests for predicate for one char line." rest-line-homogeneous-p-tests 'rest-line-homogeneous-p nil)) +(setq rest-line-homogeneous-nodent-p-tests + '( +;;------------------------------------------------------------------------------ +(simple "Blablabla bla@" nil) +(true "-----------@" ?-) +(indented " -----------@" nil) +(letter "aaaa@aaa" ?a) +(true2 "uuuuuuuuuuuuuuuuu@" ?u) +(misleading "--=---------@" nil) +(notstrip " uuuuuuuuuuuuuuuuu@" nil) +(notstrip2 " uuuuuuuuuuuuuuuuu @" nil) +(position "-------@----" ?-) +(one-char "-@" nil) +)) + +(progn + (regression-test-compare-expect-values + "Tests for predicate for one char line." + rest-line-homogeneous-nodent-p-tests 'rest-line-homogeneous-nodent-p nil)) + @@ -398,6 +418,16 @@ Du bon vin tous les jours " (45 over-and-under 2)) +;;------------------------------------------------------------------------------ +(indented-1 +" + + Du bon vin tous les jours@ + ========================= + +" +(nil nil 2)) + )) @@ -472,6 +502,20 @@ Next ") +(setq text-3 +" + +Previous +-------- + +Current@ +~~~~~~~ + + Next + ++++ + +") + ;; ~~~~~~~~~~~~~~~~~~ ;; Buggy Decoration ;; ~~~~~~ @@ -501,6 +545,11 @@ Next (9 43 simple 0)) ) + (basic-3 ,text-3 + ((3 45 simple 0) + (6 126 simple 0)) + ) + )) -- cgit v1.2.1 From 2585824cf71cac6cea7eda21640e968b54c13cd6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 17 Sep 2005 19:29:40 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3882 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/stylesheets/latex.tex | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex index eb19ddb8e..231f3911f 100644 --- a/tools/stylesheets/latex.tex +++ b/tools/stylesheets/latex.tex @@ -844,14 +844,10 @@ {% \ifthenelse{\equal{\Dinsidetabular}{true}}{% % Inside longtable; we cannot have nested longtables. - % The following \vspace *adds* vertical space. I have no idea - % how to do this in a cleaner way. - %\mbox{}\par\vspace{-0.5em}% \begin{tabular}{#1}% \hline% #2% \end{tabular}% - %\par\noindent\vspace{-0.5em}% }{% \renewcommand{\Dinsidetabular}{true}% \begin{longtable}{#1}% @@ -900,6 +896,7 @@ \vspace{-1em}\vspace{-\parskip}\par% }{}% #1% + % No need to add an ampersand ("&"); that's done by \Dsubsequententry. } \providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} \providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} -- cgit v1.2.1 From 8327158676328972e0e83dd2d7a8f3691d0345d1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 17 Sep 2005 22:43:04 +0000 Subject: made cloaking of email addresses with ``--cloak-email-addresses`` less obtrusive; updated documentation; added warning about incorrectly decoded cloaked email addresses git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3883 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docs/user/config.txt | 22 ++++++++++++++-------- docutils/writers/html4css1.py | 29 +++++++++++++++-------------- test/functional/expected/pep_html.html | 4 ++-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index d20f1e743..86705449f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -110,6 +110,8 @@ Changes Since 0.3.9 - 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. * docutils/writers/docutils_xml.py: diff --git a/docs/user/config.txt b/docs/user/config.txt index ea3916bfc..32be81764 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -564,16 +564,22 @@ attribution __ `attribution [latex2e writer]`_ _`cloak_email_addresses` - Scramble email addresses to confuse harvesters. In the visible - text of an email address, the "@" and all periods (".") will be - surrounded by ```` tags. In the reference URI, the address - will be replaced by %-escapes. For example, "abc@example.org" - will be output as:: - - + Scramble email addresses to confuse harvesters. In the reference + URI, the "@" will be replaced by %-escapes (as of RFC 1738). In + the visible text (link text) of an email reference, the "@" and + all periods (".") will be surrounded by ```` tags. + Furthermore, HTML entities are used to encode these characters in + order to further complicate decoding the email address. For + example, "abc@example.org" will be output as:: + + abc@example.org + .. Note:: While cloaking email addresses will have little to no + impact on the rendering and usability of email links in most + browsers, some browsers (e.g. the ``links`` browser) may decode + cloaked email addresses incorrectly. + Default: don't cloak (None). Option: ``--cloak-email-addresses``. _`compact_lists` diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 876cbe140..e10d1d570 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -112,10 +112,8 @@ class Writer(writers.Writer): ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', 'validator': frontend.validate_boolean}), - ('Scramble email addresses to confuse harvesters. ' - 'For example, "abc@example.org" will become ' - '``abc@' - 'example.org``.', + ('Obfuscate email addresses to confuse harvesters while still ' + 'keeping email links usable with standards-compliant browsers.', ['--cloak-email-addresses'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) @@ -291,17 +289,15 @@ class HTMLTranslator(nodes.NodeVisitor): def cloak_mailto(self, uri): """Try to hide a mailto: URL from harvesters.""" - addr = uri.split(':', 1)[1] - if '?' in addr: - addr, query = addr.split('?', 1) - query = '?' + query - else: - query = '' - # Bug: This destroys percent signs in email addresses. - escaped = ['%%%02X' % ord(c) for c in addr] - return 'mailto:%s%s' % (''.join(escaped), query) + # Encode "@" using a URL octet reference (see RFC 1738). + # Further cloaking with HTML entities will be done in the + # `attval` function. + return uri.replace('@', '%40') def cloak_email(self, addr): + """Try to hide the link text of a email link from harversters.""" + # Surround at-signs and periods with tags. ("@" has + # already been encoded to "@" by the `encode` method.) addr = addr.replace('@', '@') addr = addr.replace('.', '.') return addr @@ -309,7 +305,12 @@ class HTMLTranslator(nodes.NodeVisitor): def attval(self, text, whitespace=re.compile('[\n\r\t\v\f]')): """Cleanse, HTML encode, and return attribute value text.""" - return self.encode(whitespace.sub(' ', text)) + encoded = self.encode(whitespace.sub(' ', text)) + if self.in_mailto and self.settings.cloak_email_addresses: + # Cloak at-signs ("%40") and periods with HTML entities. + encoded = encoded.replace('%40', '%40') + encoded = encoded.replace('.', '.') + return encoded def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): """ diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index d48b8fb99..c3809bf17 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -38,7 +38,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! Author:John Doe <john at example.org> -Discussions-To:<devnull at example.org> +Discussions-To:<devnull at example.org> Status:Draft @@ -75,7 +75,7 @@ thing.

    - +
    [1]PEP editors: peps@python.org
    [1]PEP editors: peps@python.org
    -- cgit v1.2.1 From 50026aa92c1147e0786874ee793017dd46539f55 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 18 Sep 2005 16:08:13 +0000 Subject: added
    to make PEP writer output valid XHTML git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3888 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/pep_html.html | 1 + tools/pep-html-template | 1 + 2 files changed, 2 insertions(+) diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index c3809bf17..92b6772ab 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -24,6 +24,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! [PEP Index] [PEP Source]
    +
    diff --git a/tools/pep-html-template b/tools/pep-html-template index bbaeb64b2..6f96977e8 100644 --- a/tools/pep-html-template +++ b/tools/pep-html-template @@ -23,5 +23,6 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! [PEP Index] [PEP Source]
    +
    %(body)s %(body_suffix)s -- cgit v1.2.1 From 1920ac5081c5a617abd6a46caca014f62276f83c Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 19 Sep 2005 13:03:58 +0000 Subject: added entry for moving writer support files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3889 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c54eb4a9f..1d53baf61 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -72,6 +72,23 @@ for inclusion in the Python standard library. General ======= +* Move the following _`support files` to docutils/writers/support: + + - tools/stylesheets/pep.css & default.css (renamed to html4css1.css) + - tools/stylesheets/style.tex (renamed to latex2e.tex) & latex.tex + (renamed to newlatex2e.tex or newlatex2e/style.tex). + - tools/pep-html-template (renamed to pep_html.template or + pep_html/template.txt) + + The docutils/writers/support/unicode_latex.py module should probably + be moved to newlatex2e/unicode_map.py. + + Add to docs: + + Keep the basenames (e.g. "pep_html") of support files consistent + with the writer names. If there are multiple support files, + create a subdirectory whose name matches the writer. + * Move some general-interest sandboxes out of individuals' directories, into subprojects? -- cgit v1.2.1 From d00d026357ce0a61022bf5a9de8babaddd981912 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 19 Sep 2005 18:36:09 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3890 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 1d53baf61..e4d8186d4 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -74,14 +74,14 @@ General * Move the following _`support files` to docutils/writers/support: - - tools/stylesheets/pep.css & default.css (renamed to html4css1.css) + - tools/stylesheets/pep.css (renamed to pep_html/pep.css) + - tools/stylesheets/default.css (renamed to html4css1.css) - tools/stylesheets/style.tex (renamed to latex2e.tex) & latex.tex - (renamed to newlatex2e.tex or newlatex2e/style.tex). - - tools/pep-html-template (renamed to pep_html.template or - pep_html/template.txt) + (renamed or newlatex2e/base.tex). + - tools/pep-html-template (renamed pep_html/template.txt) - The docutils/writers/support/unicode_latex.py module should probably - be moved to newlatex2e/unicode_map.py. + Rename docutils/writers/support/unicode_latex.py to + newlatex2e/unicode_map.py. Add to docs: -- cgit v1.2.1 From 5b111006c653af57889892100b7adc5ffcca8e6f Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 20 Sep 2005 20:04:53 +0000 Subject: Merged "transforms" branch into trunk. - Replaced ``default_transforms`` attribute of TransformSpec with ``get_transforms()`` method. - Added universal.Decorations and universal.ExposeInternals transforms as default transforms for all readers. - Added universal.Messages and universal.FilterMessages transforms as default transforms for all writers. - Added ``ReReader`` base class for readers that reread an existing document tree. - Added ``UnfilteredWriter`` base class for writers that pass the document tree on unchanged. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3892 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 21 ++++++++++++++++----- docs/ref/transforms.txt | 8 ++++---- docutils/__init__.py | 16 +++++++++++----- docutils/core.py | 18 +++--------------- docutils/nodes.py | 2 +- docutils/readers/__init__.py | 22 ++++++++++++++++++++++ docutils/readers/doctree.py | 2 +- docutils/readers/pep.py | 23 +++++++++-------------- docutils/readers/standalone.py | 28 +++++++++++++++------------- docutils/transforms/__init__.py | 19 +------------------ docutils/writers/__init__.py | 23 +++++++++++++++++++++++ docutils/writers/html4css1.py | 3 ++- docutils/writers/newlatex2e.py | 3 ++- docutils/writers/null.py | 2 +- 14 files changed, 111 insertions(+), 79 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 86705449f..09d98f94d 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -21,7 +21,8 @@ Changes Since 0.3.9 - Added ``__version_details__`` attribute to describe code source (repository/snapshot/release). - - Added ``TransformSpec.reprocess_transforms`` attribute. + - Replaced ``default_transforms`` attribute of TransformSpec with + ``get_transforms()`` method. * docutils/core.py: @@ -59,12 +60,15 @@ Changes Since 0.3.9 standard data files for the "include" directive. Initial contents: character entity substitution definition sets. -* docutils/readers/doctree.py: Added to project; a reader for existing - document trees. +* docutils/readers/__init__.py: -* docutils/transforms/__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. - - Added ``Transformer.reprocess_transforms`` attribute. +* docutils/readers/doctree.py: Added to project; a reader for existing + document trees. * docutils/transforms/html.py: Added to project; transforms specific to the html4css1 Writer. @@ -93,6 +97,13 @@ Changes Since 0.3.9 - Added ``Compound`` transform, which flattens compound paragraphs. +* 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/html4css1.py: - Added support for image width and height units. diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 05185d6ef..8cd01c895 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -73,15 +73,15 @@ components.Filter "meta" (d/p) 780 writer_aux.Compound newlatex2e (w) 810 -universal.Decorations Transformer 820 +universal.Decorations Reader (r) 820 misc.Transitions standalone (r), pep (r) 830 -universal.ExposeInternals Transformer 840 +universal.ExposeInternals Reader (r) 840 -universal.Messages Transformer 860 +universal.Messages Writer (w) 860 -universal.FilterMessages Transformer 870 +universal.FilterMessages Writer (w) 870 universal.TestMessages DocutilsTestSupport 880 diff --git a/docutils/__init__.py b/docutils/__init__.py index 26587b1ad..4a6e447f5 100644 --- a/docutils/__init__.py +++ b/docutils/__init__.py @@ -137,13 +137,19 @@ class TransformSpec: 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 = () - """Transforms required by this class. Override in subclasses.""" - reprocess_transforms = () - """Transforms suggested as replacements for `default_transforms` when - reprocessing a document tree.""" - unknown_reference_resolvers = () """List of functions to try to resolve unknown references. Unknown references have a 'refname' attribute which doesn't correspond to any diff --git a/docutils/core.py b/docutils/core.py index 6c7c6c599..043c8ebfc 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -187,16 +187,11 @@ class Publisher: def publish(self, argv=None, usage=None, description=None, settings_spec=None, settings_overrides=None, - config_section=None, enable_exit_status=None, stage=None): + config_section=None, enable_exit_status=None): """ Process command line options and arguments (if `self.settings` not already set), run `self.reader` and then `self.writer`. Return `self.writer`'s output. - - Pass ``stage=1`` to set transformer.default_transforms to the - stage-1 transforms; dito for ``stage=2`` and stage-2 - transforms, resp. See the documentation in the - `transforms.Transformer` class. """ if self.settings is None: self.process_command_line( @@ -207,13 +202,6 @@ class Publisher: try: self.document = self.reader.read(self.source, self.parser, self.settings) - assert stage in (1, 2, None) - if stage == 1: - self.document.transformer.default_transforms = ( - self.document.transformer.stage1_transforms) - elif stage == 2: - self.document.transformer.default_transforms = ( - self.document.transformer.stage2_transforms) self.apply_transforms() output = self.writer.write(self.document, self.destination) self.writer.assemble_parts() @@ -465,7 +453,7 @@ def publish_doctree(source, source_path=None, settings_spec, settings_overrides, config_section) pub.set_source(source, source_path) pub.set_destination(None, None) - output = pub.publish(enable_exit_status=enable_exit_status, stage=1) + output = pub.publish(enable_exit_status=enable_exit_status) return pub.document def publish_from_doctree(document, destination_path=None, @@ -505,7 +493,7 @@ def publish_from_doctree(document, destination_path=None, pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) pub.set_destination(None, destination_path) - return pub.publish(enable_exit_status=enable_exit_status, stage=2) + return pub.publish(enable_exit_status=enable_exit_status) def publish_programmatically(source_class, source, source_path, destination_class, destination, destination_path, diff --git a/docutils/nodes.py b/docutils/nodes.py index 4684bfd68..0a574d77b 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -203,7 +203,7 @@ class Node: r = [] if ascend: siblings=1 - if isinstance(condition, ClassType) and issubclass(condition, Node): + if isinstance(condition, ClassType): node_class = condition def condition(node, node_class=node_class): return isinstance(node, node_class) diff --git a/docutils/readers/__init__.py b/docutils/readers/__init__.py index 36a5264bf..ae5b3e6bc 100644 --- a/docutils/readers/__init__.py +++ b/docutils/readers/__init__.py @@ -12,6 +12,7 @@ __docformat__ = 'reStructuredText' from docutils import utils, parsers, Component +from docutils.transforms import universal class Reader(Component): @@ -28,6 +29,12 @@ class Reader(Component): component_type = 'reader' config_section = 'readers' + def get_transforms(self): + return Component.get_transforms(self) + [ + universal.Decorations, + universal.ExposeInternals, + ] + def __init__(self, parser=None, parser_name=None): """ Initialize the Reader instance. @@ -76,6 +83,21 @@ class Reader(Component): return document +class ReReader(Reader): + + """ + A reader which rereads an existing document tree (e.g. a + deserializer). + + Often used in conjunction with `writers.UnfilteredWriter`. + """ + + def get_transforms(self): + # Do not add any transforms. They have already been applied + # by the reader which originally created the document. + return Component.get_transforms(self) + + _reader_aliases = {} def get_reader_class(reader_name): diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py index 4ae7bd792..a1984e966 100644 --- a/docutils/readers/doctree.py +++ b/docutils/readers/doctree.py @@ -9,7 +9,7 @@ from docutils import readers, utils, transforms -class Reader(readers.Reader): +class Reader(readers.ReReader): """ Adapt the Reader API for an existing document tree. diff --git a/docutils/readers/pep.py b/docutils/readers/pep.py index 3f2fc66cb..b181e20c8 100644 --- a/docutils/readers/pep.py +++ b/docutils/readers/pep.py @@ -12,7 +12,7 @@ __docformat__ = 'reStructuredText' from docutils.readers import standalone -from docutils.transforms import peps, references, misc +from docutils.transforms import peps, references, misc, frontmatter from docutils.parsers import rst @@ -30,19 +30,14 @@ class Reader(standalone.Reader): config_section = 'pep reader' config_section_dependencies = ('readers', 'standalone reader') - default_transforms = (references.Substitutions, - references.PropagateTargets, - peps.Headers, - peps.Contents, - references.AnonymousHyperlinks, - references.IndirectHyperlinks, - peps.TargetNotes, - references.Footnotes, - references.ExternalTargets, - references.InternalTargets, - references.DanglingReferences, - misc.Transitions, - ) + def get_transforms(self): + transforms = standalone.Reader.get_transforms(self) + # We have PEP-specific frontmatter handling. + transforms.remove(frontmatter.DocTitle) + transforms.remove(frontmatter.SectionSubTitle) + transforms.remove(frontmatter.DocInfo) + transforms.extend([peps.Headers, peps.Contents, peps.TargetNotes]) + return transforms settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} diff --git a/docutils/readers/standalone.py b/docutils/readers/standalone.py index 1f5bd9dfc..df291128f 100644 --- a/docutils/readers/standalone.py +++ b/docutils/readers/standalone.py @@ -52,16 +52,18 @@ class Reader(readers.Reader): config_section = 'standalone reader' config_section_dependencies = ('readers',) - default_transforms = (references.Substitutions, - references.PropagateTargets, - frontmatter.DocTitle, - frontmatter.SectionSubTitle, - frontmatter.DocInfo, - references.AnonymousHyperlinks, - references.IndirectHyperlinks, - references.Footnotes, - references.ExternalTargets, - references.InternalTargets, - references.DanglingReferences, - misc.Transitions, - ) + def get_transforms(self): + return readers.Reader.get_transforms(self) + [ + references.Substitutions, + references.PropagateTargets, + frontmatter.DocTitle, + frontmatter.SectionSubTitle, + frontmatter.DocInfo, + references.AnonymousHyperlinks, + references.IndirectHyperlinks, + references.Footnotes, + references.ExternalTargets, + references.InternalTargets, + references.DanglingReferences, + misc.Transitions, + ] diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py index 0bc302b77..36aa4e735 100644 --- a/docutils/transforms/__init__.py +++ b/docutils/transforms/__init__.py @@ -72,22 +72,6 @@ class Transformer(TransformSpec): trees. Also keeps track of components by component type name. """ - from docutils.transforms import universal - - stage1_transforms = (universal.Decorations, - universal.ExposeInternals) - """Suggested replacement for `default_transforms` when generating - a document tree without writing it.""" - - stage2_transforms = (universal.Messages, - universal.FilterMessages) - """Suggested replacement for `default_transforms` when writing a - previously-parsed document tree. Only transforms which *must* be applied - after writer-specific transforms should be added to this list.""" - - default_transforms = stage1_transforms + stage2_transforms - """These transforms are applied to all document trees.""" - def __init__(self, document): self.transforms = [] """List of transforms to apply. Each item is a 3-tuple: @@ -160,11 +144,10 @@ class Transformer(TransformSpec): Store each component's default transforms, with default priorities. Also, store components by type name in a mapping for later lookup. """ - self.add_transforms(self.default_transforms) for component in components: if component is None: continue - self.add_transforms(component.default_transforms) + 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 diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 4e262bb29..2fcdd2d7b 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -32,6 +32,12 @@ class Writer(Component): component_type = 'writer' config_section = 'writers' + def get_transforms(self): + return Component.get_transforms(self) + [ + universal.Messages, + universal.FilterMessages, + ] + document = None """The document to write (Docutils doctree); set by `write`.""" @@ -92,6 +98,23 @@ class Writer(Component): self.parts['whole'] = self.output +class UnfilteredWriter(Writer): + + """ + A writer that passes the document tree on unchanged (e.g. a + serializer.) + + Documents written by UnfilteredWriters are typically reused at a + later date using a subclass of `readers.ReReader`. + """ + + def get_transforms(self): + # Do not add any transforms. When the document is reused + # later, the then-used writer will add the appropriate + # transforms. + return Component.get_transforms(self) + + _writer_aliases = { 'html': 'html4css1', 'latex': 'latex2e', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index e10d1d570..9f1465c58 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -125,7 +125,8 @@ class Writer(writers.Writer): config_section = 'html4css1 writer' config_section_dependencies = ('writers',) - default_transforms = (html.StylesheetCheck,) + def get_transforms(self): + return writers.Writer.get_transforms(self) + [html.StylesheetCheck] def __init__(self): writers.Writer.__init__(self) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index c934ff972..9d81ff7bf 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -75,7 +75,8 @@ class Writer(writers.Writer): output = None """Final translated form of `document`.""" - default_transforms = (writer_aux.Compound,) + def get_transforms(self): + return writers.Writer.get_transforms(self) + [writer_aux.Compound] def __init__(self): writers.Writer.__init__(self) diff --git a/docutils/writers/null.py b/docutils/writers/null.py index cf3566480..4632c7457 100644 --- a/docutils/writers/null.py +++ b/docutils/writers/null.py @@ -11,7 +11,7 @@ A do-nothing Writer. from docutils import writers -class Writer(writers.Writer): +class Writer(writers.UnfilteredWriter): supported = ('null',) """Formats this writer supports.""" -- cgit v1.2.1 From c01aad4e43f778039596074edfe1989e14701290 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 20 Sep 2005 20:06:17 +0000 Subject: fixed malformed hyperlink target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3893 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/testing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index 9feac9c6a..681cb7ae9 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -79,7 +79,7 @@ For more details on how to write tests, please refer to the documentation of the ``unittest`` module. -.. _functional:: +.. _functional: Functional Tests ================ -- cgit v1.2.1 From 385e2baff5f65bec97bba47106282d9e8363db0b Mon Sep 17 00:00:00 2001 From: blais Date: Wed, 21 Sep 2005 14:14:19 +0000 Subject: Minor fixes to emacs hook and documentation additions. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3894 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 6 +++ tools/editors/emacs/tests/tests-adjust-section.el | 2 + tools/editors/emacs/tests/tests-basic.el | 2 + tools/editors/emacs/tests/tests-runner.el | 45 +++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 86f7806fe..390210228 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -43,6 +43,9 @@ ;; suggestion, and to always use the preferred decorations to do that. ;; + +(require 'cl) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Generic Filter function. @@ -92,6 +95,9 @@ is for which (pred elem) is true)" ;; how many characters and over-and-under style is hanging outside of the ;; title at the beginning and ending. ;; +;; Important note: an existing decoration must be formed by at least two +;; characters to be recognized. +;; ;; Here are two examples of decorations (| represents the window border, column ;; 0): ;; diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index d544fda98..be27dc8e3 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -8,6 +8,8 @@ ;; ;; emacs --script tests-adjust-section.el ;; +;; See test-runner.el for documentation on how the format of tests. + ;; Define tests. (setq rest-adjust-decoration-tests diff --git a/tools/editors/emacs/tests/tests-basic.el b/tools/editors/emacs/tests/tests-basic.el index 847effd52..b5c5d7948 100644 --- a/tools/editors/emacs/tests/tests-basic.el +++ b/tools/editors/emacs/tests/tests-basic.el @@ -8,6 +8,8 @@ ;; ;; emacs --script tests-adjust-section.el ;; +;; See test-runner.el for documentation on how the format of tests. + ;; Import the module from the file in the parent directory directly. (add-to-list 'load-path ".") diff --git a/tools/editors/emacs/tests/tests-runner.el b/tools/editors/emacs/tests/tests-runner.el index 2304ae54a..014093e6d 100644 --- a/tools/editors/emacs/tests/tests-runner.el +++ b/tools/editors/emacs/tests/tests-runner.el @@ -8,6 +8,51 @@ ;; ;; emacs --script .el ;; +;; +;; There are mainly two useful functions from this pacakge: +;; +;; 1. regression-test-compare-expect-values : used to compare expected output +;; values from running a function; +;; +;; 2. regression-test-compare-expect-buffer : used to compare expected output +;; buffer contents after running the function. +;; +;; regression-test-compare-expect-values test format +;; ------------------------------------------------- +;; +;; The tests are a list of tuples, with the following entries: +;; +;; - a SYMBOL that uniquely identifies the test. +;; +;; - the input buffer CONTENTS to prepare and run the test on. If char @ is +;; present in the buffer, it is removed and the cursor is placed at that +;; position before running the tested function. +;; +;; - the expected OUTPUT value that the function should return. If the actual +;; output is different from this, the test will fail. +;; +;; - an optional list of INPUT ARGUMENTS that the test function is called with +;; for this test. +;; +;; regression-test-compare-expect-buffer test format +;; ------------------------------------------------- +;; +;; - a SYMBOL that uniquely identifies the test. +;; +;; - the input buffer CONTENTS to prepare and run the test on. Here too, char @ +;; is present in the buffer, it is removed and the cursor is placed at that +;; position before running the tested function. +;; +;; - the EXPECTED buffer contents after the function has been run. +;; Additionally, if char @ is present, it is checked that the cursor is +;; located at that position in the buffer after the function is run (this is +;; optional). +;; +;; - an optional list of PREFIX ARGUMENTS, which indicates to the test program +;; to set those prefix arguments before running the given function. If there +;; are multiple prefix args, the function is invoked many times. +;; + (require 'cl) -- cgit v1.2.1 From 1128d21e8937874a2c5cefa018187ad8c8e23799 Mon Sep 17 00:00:00 2001 From: blais Date: Wed, 21 Sep 2005 14:22:33 +0000 Subject: Fixed bug with transient mark mode. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3895 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 390210228..e0c0a1c0f 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -632,7 +632,7 @@ b. a negative numerical argument, which generally inverts the (toggle-style (and current-prefix-arg (not reverse-direction)))) - (if mark-active + (if (and transient-mark-mode mark-active) ;; Adjust decorations within region. (rest-promote-region current-prefix-arg) ;; Adjust decoration around point. -- cgit v1.2.1 From b709706e194b0134660d39a918d3f5429fe952ef Mon Sep 17 00:00:00 2001 From: wiemann Date: Wed, 21 Sep 2005 19:15:45 +0000 Subject: adjusted spec to conform to actual behavior git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3896 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 6bbdd9361..ed6056e96 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -939,14 +939,9 @@ Processed, the "status" element's text will become simply "expansion text". The dollar sign delimiters and leading RCS keyword name are removed. -The RCS keyword processing only kicks in when both of these conditions -hold: - -1. The field list is in bibliographic context (first non-comment - construct in the document, after a document title if there is - one). - -2. The field name is a recognized bibliographic field name. +The RCS keyword processing only kicks in when the field list is in +bibliographic context (first non-comment construct in the document, +after a document title if there is one). Option Lists -- cgit v1.2.1 From c976bf8ced13397135c52212701c0ad3aed45013 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 22 Sep 2005 18:51:33 +0000 Subject: changed DanglingReferences priority back to 850 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3897 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/transforms.txt | 4 +- docutils/transforms/references.py | 2 +- .../expected/standalone_rst_html4css1.html | 186 ++++++++++----------- .../expected/standalone_rst_pseudoxml.txt | 178 ++++++++++---------- 4 files changed, 185 insertions(+), 185 deletions(-) diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 8cd01c895..5e844e45c 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -60,8 +60,6 @@ references.ExternalTargets standalone (r), pep (r) 640 references.InternalTargets standalone (r), pep (r) 660 -references.DanglingReferences standalone (r), pep (r) 680 - parts.SectNum "sectnum" (d/p) 710 parts.Contents "contents" (d/p), 720 @@ -79,6 +77,8 @@ misc.Transitions standalone (r), pep (r) 830 universal.ExposeInternals Reader (r) 840 +references.DanglingReferences standalone (r), pep (r) 850 + universal.Messages Writer (w) 860 universal.FilterMessages Writer (w) 870 diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 92ab1b529..35dabddd3 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -775,7 +775,7 @@ class DanglingReferences(Transform): unreferenced targets. """ - default_priority = 680 + default_priority = 850 def apply(self): visitor = DanglingReferencesVisitor( diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 4aa0e097d..032e37a47 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -88,67 +88,67 @@ They are transformed from section titles after parsing. -->

    Table of Contents

    -

    1   Structural Elements

    +

    1   Structural Elements

    -

    1.1   Section Title

    +

    1.1   Section Title

    Section Subtitle

    That's it, the text just above this line.

    -

    1.3   Transitions

    +

    1.3   Transitions

    Here's a transition:


    It divides the section. Transitions may also occur between sections:

    @@ -156,12 +156,12 @@ They are transformed from section titles after parsing. -->

    -

    2   Body Elements

    +

    2   Body Elements

    -

    2.1   Paragraphs

    +

    2.1   Paragraphs

    A paragraph.

    -

    2.1.1   Inline Markup

    +

    2.1.1   Inline Markup

    Paragraphs contain text and may contain inline markup: emphasis, strong emphasis, inline literals, standalone hyperlinks (http://www.python.org), external hyperlinks (Python [5]), internal @@ -192,7 +192,7 @@ live link to PEP 258 here.

    -

    2.2   Bullet Lists

    +

    2.2   Bullet Lists

    • A bullet list

        @@ -217,7 +217,7 @@ live link to PEP 258 here.

    -

    2.3   Enumerated Lists

    +

    2.3   Enumerated Lists

    1. Arabic numerals.

        @@ -250,7 +250,7 @@ live link to PEP 258 here.

    -

    2.4   Definition Lists

    +

    2.4   Definition Lists

    Term
    Definition
    @@ -265,7 +265,7 @@ live link to PEP 258 here.

    -

    2.5   Field Lists

    +

    2.5   Field Lists

    @@ -289,7 +289,7 @@ doesn't get stripped away.)

    -

    2.6   Option Lists

    +

    2.6   Option Lists

    For listing command-line options:

    @@ -335,7 +335,7 @@ regardless of where it starts.

    description.

    -

    2.7   Literal Blocks

    +

    2.7   Literal Blocks

    Literal blocks are indicated with a double-colon ("::") at the end of the preceding paragraph (over there -->). They can be indented:

    @@ -352,7 +352,7 @@ if literal_block:
     
    -

    2.8   Line Blocks

    +

    2.8   Line Blocks

    This section tests line blocks. Line blocks are body elements which consist of lines and other line blocks. Nested line blocks cause indentation.

    @@ -411,7 +411,7 @@ the left edge of the text above it.
    -

    2.9   Block Quotes

    +

    2.9   Block Quotes

    Block quotes consist of indented body elements:

    My theory by A. Elk. Brackets Miss, brackets. This theory goes @@ -423,7 +423,7 @@ own it, and what it is too.

    -

    2.10   Doctest Blocks

    +

    2.10   Doctest Blocks

     >>> print 'Python-specific usage examples; begun with ">>>"'
     Python-specific usage examples; begun with ">>>"
    @@ -432,7 +432,7 @@ Python-specific usage examples; begun with ">>>"
     
    @@ -479,12 +479,12 @@ Here's a reference to the next footnote: +nonexistent footnote: [5]_.
    [4]Here's an unreferenced footnote, with a reference to a -nonexistent footnote: [5]_.
    -

    2.12   Citations

    +

    2.12   Citations

    @@ -492,11 +492,11 @@ nonexistent footnote: [CIT2002], and a [nonexistent]_ +

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    -

    2.13   Targets

    +

    2.13   Targets

    This paragraph is pointed to by the explicit "example" target. A reference can be found under Inline Markup, above. Inline hyperlink targets are also possible.

    @@ -506,45 +506,45 @@ hyperlink targets are also possible.

    "Python [5]".

    Targets may be indirect and anonymous. Thus this phrase may also refer to the Targets section.

    -

    Here's a `hyperlink reference without a target`_, which generates an +

    Here's a `hyperlink reference without a target`_, which generates an error.

    -

    2.13.1   Duplicate Target Names

    +

    2.13.1   Duplicate Target Names

    Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages.

    -

    2.13.2   Duplicate Target Names

    +

    2.13.2   Duplicate Target Names

    Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: `Duplicate Target Names`_), an error is generated.

    +this: `Duplicate Target Names`_), an error is generated.

    -

    2.14   Directives

    +

    2.14   Directives

    These are just a sample of the many reStructuredText Directives. For others, please see http://docutils.sourceforge.net/docs/ref/rst/directives.html.

    -

    2.14.1   Document Parts

    +

    2.14.1   Document Parts

    An example of the "contents" directive can be seen above this section (a local, untitled table of contents) and at the beginning of the document (a document-wide table of contents).

    -

    2.14.2   Images

    +

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png

    Image with multiple IDs:

    @@ -606,7 +606,7 @@ document (a document-wide table o ../../../docs/user/rst/images/biohazard.png
    -

    2.14.3   Admonitions

    +

    2.14.3   Admonitions

    Attention!

    Directives at large.

    @@ -655,7 +655,7 @@ Reader discretion is strongly advised.

    -

    2.14.4   Topics, Sidebars, and Rubrics

    +

    2.14.4   Topics, Sidebars, and Rubrics

    @@ -681,11 +681,11 @@ background color.

    -

    2.14.7   Compound Paragraph

    +

    2.14.7   Compound Paragraph

    Compound 1, paragraph 1.

    Compound 1, paragraph 2.

    @@ -754,12 +754,12 @@ paragraph.
    -

    2.15   Substitution Definitions

    +

    2.15   Substitution Definitions

    An inline image (EXAMPLE) example:

    (Substitution definitions are not visible in the HTML source.)

    -

    2.16   Comments

    +

    2.16   Comments

    Here's one:

    (View the HTML source to see the comment.)

    -

    2.17   Raw text

    +

    2.17   Raw text

    This does not necessarily look nice, because there may be missing white space.

    It's just there to freeze the behavior.

    A test.Second test.
    Another test with myclass set.

    This is the fourth test with myrawroleclass set.

    Fifth test in HTML.
    Line two.
    -

    2.18   Colspanning tables

    +

    2.18   Colspanning tables

    This table has a cell spanning two columns:

    @@ -813,7 +813,7 @@ Fifth test in HTML.
    Line two.
    -

    2.19   Rowspanning tables

    +

    2.19   Rowspanning tables

    Here's a table with cells spanning several rows:

    @@ -846,7 +846,7 @@ cell.
    -

    2.20   Complex tables

    +

    2.20   Complex tables

    Here's a complex table, which should test all features.

    @@ -895,7 +895,7 @@ empty: -->
    -

    2.21   List Tables

    +

    2.21   List Tables

    Here's a list table exercising all features:

    @@ -929,7 +929,7 @@ crunchy, now would it?
    -

    3   Error Handling

    +

    3   Error Handling

    Any errors caught during processing will generate system messages.

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    @@ -940,17 +940,17 @@ section, "Docutils System Messages":

    System Message: ERROR/3 (functional/input/data/standard.txt, line 100); backlink

    Undefined substitution referenced: "problematic".
    -
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 354); backlink

    +
    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 354); backlink

    Unknown target name: "5".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 363); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 363); backlink

    Unknown target name: "nonexistent".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 390); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 390); backlink

    Unknown target name: "hyperlink reference without a target".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 403); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 403); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index cab207a70..dc7940ee1 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -91,238 +91,238 @@ - + 1    Structural Elements - + 1.1    Section Title - + 1.2    Empty Section - + 1.3    Transitions - + 2    Body Elements - + 2.1    Paragraphs - + 2.1.1    Inline Markup - + 2.2    Bullet Lists - + 2.3    Enumerated Lists - + 2.4    Definition Lists - + 2.5    Field Lists - + 2.6    Option Lists - + 2.7    Literal Blocks - + 2.8    Line Blocks - + 2.9    Block Quotes - + 2.10    Doctest Blocks - + 2.11    Footnotes - + 2.12    Citations - + 2.13    Targets - + 2.13.1    Duplicate Target Names - + 2.13.2    Duplicate Target Names - + 2.14    Directives - + 2.14.1    Document Parts - + 2.14.2    Images - + 2.14.3    Admonitions - + 2.14.4    Topics, Sidebars, and Rubrics - + 2.14.5    Target Footnotes - + 2.14.6    Replacement Text - + 2.14.7    Compound Paragraph - + 2.15    Substitution Definitions - + 2.16    Comments - + 2.17    Raw text - + 2.18    Colspanning tables - + 2.19    Rowspanning tables - + 2.20    Complex tables - + 2.21    List Tables - + 3    Error Handling
    - + <title auto="1" refid="id25"> <generated classes="sectnum"> 1    Structural Elements <section ids="section-title" names="section title"> - <title auto="1" refid="id34"> + <title auto="1" refid="id26"> <generated classes="sectnum"> 1.1    Section Title @@ -331,12 +331,12 @@ <paragraph> That's it, the text just above this line. <section ids="empty-section" names="empty section"> - <title auto="1" refid="id35"> + <title auto="1" refid="id27"> <generated classes="sectnum"> 1.2    Empty Section <section ids="transitions" names="transitions"> - <title auto="1" refid="id36"> + <title auto="1" refid="id28"> <generated classes="sectnum"> 1.3    Transitions @@ -347,19 +347,19 @@ It divides the section. Transitions may also occur between sections: <transition> <section ids="body-elements" names="body elements"> - <title auto="1" refid="id37"> + <title auto="1" refid="id29"> <generated classes="sectnum"> 2    Body Elements <section ids="paragraphs" names="paragraphs"> - <title auto="1" refid="id38"> + <title auto="1" refid="id30"> <generated classes="sectnum"> 2.1    Paragraphs <paragraph> A paragraph. <section ids="inline-markup" names="inline markup"> - <title auto="1" refid="id39"> + <title auto="1" refid="id31"> <generated classes="sectnum"> 2.1.1    Inline Markup @@ -484,7 +484,7 @@ option was supplied, there should be a live link to PEP 258 here. <section ids="bullet-lists" names="bullet lists"> - <title auto="1" refid="id40"> + <title auto="1" refid="id32"> <generated classes="sectnum"> 2.2    Bullet Lists @@ -528,7 +528,7 @@ <comment xml:space="preserve"> Even if this item contains a target and a comment. <section ids="enumerated-lists" names="enumerated lists"> - <title auto="1" refid="id41"> + <title auto="1" refid="id33"> <generated classes="sectnum"> 2.3    Enumerated Lists @@ -577,7 +577,7 @@ <paragraph> iv <section ids="definition-lists" names="definition lists"> - <title auto="1" refid="id42"> + <title auto="1" refid="id34"> <generated classes="sectnum"> 2.4    Definition Lists @@ -615,7 +615,7 @@ <paragraph> Definition <section ids="field-lists" names="field lists"> - <title auto="1" refid="id43"> + <title auto="1" refid="id35"> <generated classes="sectnum"> 2.5    Field Lists @@ -649,7 +649,7 @@ about credits but just for ensuring that the class attribute doesn't get stripped away.) <section ids="option-lists" names="option lists"> - <title auto="1" refid="id44"> + <title auto="1" refid="id36"> <generated classes="sectnum"> 2.6    Option Lists @@ -762,7 +762,7 @@ There must be at least two spaces between the option and the description. <section ids="literal-blocks" names="literal blocks"> - <title auto="1" refid="id45"> + <title auto="1" refid="id37"> <generated classes="sectnum"> 2.7    Literal Blocks @@ -784,7 +784,7 @@ > > Why didn't I think of that? <section ids="line-blocks" names="line blocks"> - <title auto="1" refid="id46"> + <title auto="1" refid="id38"> <generated classes="sectnum"> 2.8    Line Blocks @@ -862,7 +862,7 @@ <line> Singing... <section ids="block-quotes" names="block quotes"> - <title auto="1" refid="id47"> + <title auto="1" refid="id39"> <generated classes="sectnum"> 2.9    Block Quotes @@ -878,7 +878,7 @@ <attribution> Anne Elk (Miss) <section ids="doctest-blocks" names="doctest blocks"> - <title auto="1" refid="id48"> + <title auto="1" refid="id40"> <generated classes="sectnum"> 2.10    Doctest Blocks @@ -888,7 +888,7 @@ >>> print '(cut and pasted from interactive Python sessions)' (cut and pasted from interactive Python sessions) <section ids="footnotes" names="footnotes"> - <title auto="1" refid="id49"> + <title auto="1" refid="id41"> <generated classes="sectnum"> 2.11    Footnotes @@ -948,11 +948,11 @@ <paragraph> Here's an unreferenced footnote, with a reference to a nonexistent footnote: - <problematic ids="id26 id14" refid="id25"> + <problematic ids="id70 id14" refid="id69"> [5]_ . <section ids="citations" names="citations"> - <title auto="1" refid="id50"> + <title auto="1" refid="id42"> <generated classes="sectnum"> 2.12    Citations @@ -967,13 +967,13 @@ <citation_reference ids="id15" refid="cit2002"> CIT2002 , and a - <problematic ids="id28 id16" refid="id27"> + <problematic ids="id72 id16" refid="id71"> [nonexistent]_ citation. <target refid="another-target"> <section ids="targets another-target" names="targets another target"> - <title auto="1" refid="id51"> + <title auto="1" refid="id43"> <generated classes="sectnum"> 2.13    Targets @@ -1018,12 +1018,12 @@ <target anonymous="1" ids="id17" refid="targets"> <paragraph> Here's a - <problematic ids="id30" refid="id29"> + <problematic ids="id74" refid="id73"> `hyperlink reference without a target`_ , which generates an error. <section dupnames="duplicate target names" ids="duplicate-target-names"> - <title auto="1" refid="id52"> + <title auto="1" refid="id44"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names @@ -1032,7 +1032,7 @@ generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages. <section dupnames="duplicate target names" ids="id18"> - <title auto="1" refid="id53"> + <title auto="1" refid="id45"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names @@ -1040,11 +1040,11 @@ Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: - <problematic ids="id32" refid="id31"> + <problematic ids="id76" refid="id75"> `Duplicate Target Names`_ ), an error is generated. <section ids="directives" names="directives"> - <title auto="1" refid="id54"> + <title auto="1" refid="id46"> <generated classes="sectnum"> 2.14    Directives @@ -1052,43 +1052,43 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id70" refid="document-parts"> + <reference ids="id62" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id71" refid="images"> + <reference ids="id63" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id72" refid="admonitions"> + <reference ids="id64" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id73" refid="topics-sidebars-and-rubrics"> + <reference ids="id65" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id74" refid="target-footnotes"> + <reference ids="id66" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id75" refid="replacement-text"> + <reference ids="id67" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id76" refid="compound-paragraph"> + <reference ids="id68" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1099,7 +1099,7 @@ http://docutils.sourceforge.net/docs/ref/rst/directives.html . <section ids="document-parts" names="document parts"> - <title auto="1" refid="id70"> + <title auto="1" refid="id62"> <generated classes="sectnum"> 2.14.1    Document Parts @@ -1114,7 +1114,7 @@ table of contents ). <section ids="images" names="images"> - <title auto="1" refid="id71"> + <title auto="1" refid="id63"> <generated classes="sectnum"> 2.14.2    Images @@ -1206,7 +1206,7 @@ An image 3 cm high: <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> - <title auto="1" refid="id72"> + <title auto="1" refid="id64"> <generated classes="sectnum"> 2.14.3    Admonitions @@ -1256,7 +1256,7 @@ You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> <section ids="topics-sidebars-and-rubrics" names="topics, sidebars, and rubrics"> - <title auto="1" refid="id73"> + <title auto="1" refid="id65"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics @@ -1281,7 +1281,7 @@ <rubric> This is a rubric <section ids="target-footnotes" names="target footnotes"> - <title auto="1" refid="id74"> + <title auto="1" refid="id66"> <generated classes="sectnum"> 2.14.5    Target Footnotes @@ -1292,7 +1292,7 @@ <reference refuri="http://www.python.org/"> http://www.python.org/ <section ids="replacement-text" names="replacement text"> - <title auto="1" refid="id75"> + <title auto="1" refid="id67"> <generated classes="sectnum"> 2.14.6    Replacement Text @@ -1313,7 +1313,7 @@ the best language around <section ids="compound-paragraph" names="compound paragraph"> - <title auto="1" refid="id76"> + <title auto="1" refid="id68"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1399,7 +1399,7 @@ <paragraph> Compound 7, another paragraph. <section ids="substitution-definitions" names="substitution definitions"> - <title auto="1" refid="id62"> + <title auto="1" refid="id54"> <generated classes="sectnum"> 2.15    Substitution Definitions @@ -1412,7 +1412,7 @@ <paragraph> (Substitution definitions are not visible in the HTML source.) <section ids="comments" names="comments"> - <title auto="1" refid="id63"> + <title auto="1" refid="id55"> <generated classes="sectnum"> 2.16    Comments @@ -1427,7 +1427,7 @@ <paragraph> (View the HTML source to see the comment.) <section ids="raw-text" names="raw text"> - <title auto="1" refid="id64"> + <title auto="1" refid="id56"> <generated classes="sectnum"> 2.17    Raw text @@ -1451,7 +1451,7 @@ <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. <section ids="colspanning-tables" names="colspanning tables"> - <title auto="1" refid="id65"> + <title auto="1" refid="id57"> <generated classes="sectnum"> 2.18    Colspanning tables @@ -1522,7 +1522,7 @@ <paragraph> True <section ids="rowspanning-tables" names="rowspanning tables"> - <title auto="1" refid="id66"> + <title auto="1" refid="id58"> <generated classes="sectnum"> 2.19    Rowspanning tables @@ -1574,7 +1574,7 @@ <paragraph> body row 3 <section ids="complex-tables" names="complex tables"> - <title auto="1" refid="id67"> + <title auto="1" refid="id59"> <generated classes="sectnum"> 2.20    Complex tables @@ -1659,7 +1659,7 @@ --> <entry> <section ids="list-tables" names="list tables"> - <title auto="1" refid="id68"> + <title auto="1" refid="id60"> <generated classes="sectnum"> 2.21    List Tables @@ -1716,7 +1716,7 @@ <paragraph> On a stick! <section ids="error-handling" names="error handling"> - <title auto="1" refid="id69"> + <title auto="1" refid="id61"> <generated classes="sectnum"> 3    Error Handling @@ -1733,15 +1733,15 @@ <system_message backrefs="id20" ids="id19" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id26" ids="id25" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id70" ids="id69" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id28" ids="id27" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id72" ids="id71" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id30" ids="id29" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id74" ids="id73" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id32" ids="id31" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id76" ids="id75" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". -- cgit v1.2.1 From 896e789c933f0f2b12fca283776eb6123fd923d2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 22 Sep 2005 19:03:42 +0000 Subject: grouped substitution bugs together git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3898 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 8e2473df6..e4eb4c37c 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -146,30 +146,35 @@ Also see the `SourceForge Bug Tracker`_. Quite a few nodes are getting a "None" source attribute as well. In particular, see the bodies of definition lists. -* There's a bug with _`doubly-indirect substitutions` but only when - there's multiple references and in certain cases. See the - commented-out test case in test_transforms/test_substitutions.py - (line 104 on, in revision 3808) which fails. +* .. _substitutions: - This is tricky. Substitution definitions have to propagate back - completely, through multiple levels of references. + "Active" content inside of substitution definitions does not work. + This bug becomes manifest in the following cases: -* .. _substitutions and references: + * There's a bug with _`doubly-indirect substitutions` but only when + there's multiple references and in certain cases. See the + commented-out test case in test_transforms/test_substitutions.py + (line 104 on, in revision 3808) which fails. - Another bug from David Abrahams (run with ``rst2html.py --traceback``):: + This is tricky. Substitution definitions have to propagate back + completely, through multiple levels of references. - |substitution| and again a |substitution|. + * .. _substitutions and references: - .. |substitution| replace:: ref__ + Another bug from David Abrahams (run with ``rst2html.py --traceback``):: - __ a.html - __ b.html + |substitution| and again a |substitution|. - Change the references.Substitutions tranform's priority from 220 to - 680, so it happens after reference resolution? Then we have to deal - with multiple IDs. Perhaps the Substitution transform should remove - all IDs from definitions after the first substitution reference is - processed. + .. |substitution| replace:: ref__ + + __ a.html + __ b.html + + Change the references.Substitutions tranform's priority from 220 to + 680, so it happens after reference resolution? Then we have to deal + with multiple IDs. Perhaps the Substitution transform should remove + all IDs from definitions after the first substitution reference is + processed. * Footnote label "5" should be "4" when processing the following input:: -- cgit v1.2.1 From 7c052574fa82d5aec1ca66d4611a640bff9e4dfd Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 22 Sep 2005 19:05:30 +0000 Subject: added another substitution bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3899 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index e4eb4c37c..f74933efa 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -176,6 +176,22 @@ Also see the `SourceForge Bug Tracker`_. all IDs from definitions after the first substitution reference is processed. + * _`Targets inside substitution definitions` cause duplicate IDs:: + + $ rst2pseudoxml.py + .. |target| replace:: _`foo` + + |target|\ |target| + <document source="<stdin>"> + <substitution_definition names="target"> + <target ids="foo" names="foo"> + foo + <paragraph> + <target ids="foo" names="foo"> + foo + <target ids="foo" names="foo"> + foo + * Footnote label "5" should be "4" when processing the following input:: -- cgit v1.2.1 From f80815602799ff058440771456e212325fd6d2f6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 24 Sep 2005 15:11:20 +0000 Subject: added clarifying comment; thanks to Anthony Baxter for pointing this out git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3900 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 1 + docutils/parsers/rst/directives/tables.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/THANKS.txt b/THANKS.txt index cf9208556..c326be75d 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -19,6 +19,7 @@ donations, tasty treats, and related projects: * David Ascher * Ned Batchelder * Heiko Baumann +* Anthony Baxter * Eric Bellot * Ian Bicking * Marek Blaha diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index dadcdae68..70a0de5ab 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -392,6 +392,9 @@ def check_list_content(node, name, options, content, lineno, block_text, nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(error) elif item_index: + # ATTN pychecker users: num_cols is guaranteed to be set in the + # "else" clause below for item_index==0, before this branch is + # triggered. if len(item[0]) != num_cols: error = state_machine.reporter.error( 'Error parsing content block for the "%s" directive: ' -- cgit v1.2.1 From 1b0c89fafde2292c03a0a21822ba083dca903bb1 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 25 Sep 2005 15:49:54 +0000 Subject: added docutils/writers/support/ directory and removed tools/stylesheets/; updated defaults; removed docutils/transforms/html.py (no longer needed); removed ``_stylesheet_required`` internal setting; updated setup.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3901 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 17 +- HISTORY.txt | 26 +- docs/peps/pep-0258.txt | 21 +- docs/ref/transforms.txt | 2 - docs/user/config.txt | 21 +- docs/user/tools.txt | 31 +- docutils/transforms/html.py | 30 - docutils/writers/__init__.py | 6 +- docutils/writers/html4css1.py | 29 +- docutils/writers/latex2e.py | 1 + docutils/writers/newlatex2e.py | 6 +- docutils/writers/pep_html.py | 26 +- docutils/writers/support/html4css1.css | 276 +++ docutils/writers/support/latex2e.tex | 74 + docutils/writers/support/newlatex2e/__init__.py | 1 + docutils/writers/support/newlatex2e/base.tex | 1108 +++++++++ docutils/writers/support/newlatex2e/unicode_map.py | 2371 ++++++++++++++++++++ docutils/writers/support/pep_html/pep.css | 349 +++ docutils/writers/support/pep_html/template.txt | 28 + docutils/writers/support/unicode_latex.py | 2371 -------------------- setup.py | 29 +- test/functional/tests/misc_rst_html4css1.py | 2 + test/functional/tests/pep_html.py | 7 +- test/test_writers/test_html4css1.py | 7 +- tools/docutils.conf | 6 - tools/pep-html-template | 28 - tools/rst2html.py | 3 +- tools/stylesheets/default.css | 276 --- tools/stylesheets/latex.tex | 1108 --------- tools/stylesheets/pep.css | 349 --- tools/stylesheets/style.tex | 74 - 31 files changed, 4358 insertions(+), 4325 deletions(-) delete mode 100644 docutils/transforms/html.py create mode 100644 docutils/writers/support/html4css1.css create mode 100644 docutils/writers/support/latex2e.tex create mode 100644 docutils/writers/support/newlatex2e/__init__.py create mode 100644 docutils/writers/support/newlatex2e/base.tex create mode 100644 docutils/writers/support/newlatex2e/unicode_map.py create mode 100644 docutils/writers/support/pep_html/pep.css create mode 100644 docutils/writers/support/pep_html/template.txt delete mode 100644 docutils/writers/support/unicode_latex.py delete mode 100644 tools/pep-html-template delete mode 100644 tools/stylesheets/default.css delete mode 100644 tools/stylesheets/latex.tex delete mode 100644 tools/stylesheets/pep.css delete mode 100644 tools/stylesheets/style.tex diff --git a/FAQ.txt b/FAQ.txt index 1d34962ec..37b955a3e 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -710,10 +710,13 @@ What kind of HTML does it produce? ---------------------------------- It produces XHTML compatible with the `XHTML 1.0`_ specification. A -cascading stylesheet (provided as "tools/stylesheets/default.css") is -required for proper viewing with a modern graphical browser. Correct -rendering of the HTML produced depends on the CSS support of the -browser. +cascading stylesheet is required for proper viewing with a modern +graphical browser. Correct rendering of the HTML produced depends on +the CSS support of the browser. A general-purpose stylesheet, +``html4css1.css`` is provided with the code, and is embedded by +default. It is installed in the "writers/support/" subdirectory +within the Docutils package. Use the ``--help`` command-line option +to see the specific location on your machine. .. _XHTML 1.0: http://www.w3.org/TR/xhtml1/ @@ -794,9 +797,9 @@ effectively reserve these tags to provide 6 levels of heading beyond the single document title. HTML is being used for dumb formatting for nothing but final display. -A stylesheet *is required*, and one is provided: -``tools/stylesheets/default.css``. Of course, you're welcome to roll -your own. The default stylesheet provides rules to format ``<h1 +A stylesheet *is required*, and one is provided; see `What kind of +HTML does it produce?`_ above. Of course, you're welcome to roll your +own. The default stylesheet provides rules to format ``<h1 class="title">`` and ``<h2 class="subtitle">`` differently from ordinary ``<h1>`` and ``<h2>``:: diff --git a/HISTORY.txt b/HISTORY.txt index 09d98f94d..df87608d1 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -70,9 +70,6 @@ Changes Since 0.3.9 * docutils/readers/doctree.py: Added to project; a reader for existing document trees. -* docutils/transforms/html.py: Added to project; transforms specific - to the html4css1 Writer. - * docutils/transforms/misc.py: - Added misc.Transitions transform, extracted from @@ -104,6 +101,11 @@ Changes Since 0.3.9 - 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.py: - Added support for image width and height units. @@ -114,7 +116,6 @@ Changes Since 0.3.9 - Made ``--embed-stylesheet`` the default rather than ``--link-stylesheet``. - Added writer-specific transform to check the stylesheet setting. - - Added ``_stylesheet_required`` internal setting, defaulting to 0. - Moved "id" attribute from container (section etc.) to title's <a> tag, to be on the same tag as "name". (!!! To be reverted in Docutils 0.5.) @@ -124,13 +125,11 @@ Changes Since 0.3.9 - Made cloaking of email addresses with ``--cloak-email-addresses`` less obtrusive. -* docutils/writers/docutils_xml.py: - - - Made ``xmlcharrefreplace`` the default output encoding error - handler. +* docutils/writers/support/: Directory added to project. Modules and + data files that support writers have been moved here. -* docutils/writers/unicode_latex.py: Added to project; mapping of - Unicode characters to LaTeX equivalents. +* docutils/writers/support/newlatex2e/unicode_map.py: Added to + project; mapping of Unicode characters to LaTeX equivalents. * docs/dev/distributing.txt: Added to project; guide for distributors (package maintainers). @@ -152,9 +151,6 @@ Changes Since 0.3.9 - Added support for specifying runtime settings at the suite level. -* tools/rst2html.py: Made stylesheet requirement explicit (via - ``_stylesheet_required`` setting). - * tools/rstpep2html.py: Renamed from pep.py. * tools/dev/create_unimap.py: Added to project; script to create the @@ -164,6 +160,10 @@ Changes Since 0.3.9 * tools/dev/unicode2rstsubs.py: Moved from tools/unicode2rstsubs.py. +* tools/stylesheets: Removed from project. Stylesheets have been + renamed and moved to docutils/writers/support/ or its + subdirectories. + Release 0.3.9 (2005-05-26) ========================== diff --git a/docs/peps/pep-0258.txt b/docs/peps/pep-0258.txt index 7779411a6..47ede6c21 100644 --- a/docs/peps/pep-0258.txt +++ b/docs/peps/pep-0258.txt @@ -402,6 +402,9 @@ Docutils Package Structure - Module "docutils.readers.pep" reads PEPs (Python Enhancement Proposals). + - Module "docutils.readers.doctree" is used to re-read a + previously stored document tree for reprocessing. + - Readers to be added for: Python source code (structure & docstrings), email, FAQ, and perhaps Wiki and others. @@ -416,18 +419,32 @@ Docutils Package Structure - Module "docutils.writers.html4css1" is a simple HyperText Markup Language document tree writer for HTML 4.01 and CSS1. + - Module "docutils.writers.latex2e" writes LaTeX. + + - Module "docutils.writers.newlatex2e" also writes LaTeX; it is a + new implementation. + - Module "docutils.writers.docutils_xml" writes the internal document tree in XML form. - Module "docutils.writers.pseudoxml" is a simple internal document tree writer; it writes indented pseudo-XML. + - Module "docutils.writers.null" is a do-nothing writer; it is + used for specialized purposes such as storing the internal + document tree. + - Writers to be added: HTML 3.2 or 4.01-loose, XML (various forms, - such as DocBook), PDF, TeX, plaintext, reStructuredText, and - perhaps others. + such as DocBook), PDF, plaintext, reStructuredText, and perhaps + others. See `Writers`_ above. + - Package "docutils.writers.support": modules and data files that + support the various writers. The names of subdirectories and + basenames of files immediately within the support/ directory must + match the corresponding writer module names. + - Package "docutils.transforms": tree transform classes. - Class "Transformer" stores transforms and applies them to diff --git a/docs/ref/transforms.txt b/docs/ref/transforms.txt index 5e844e45c..0595175b4 100644 --- a/docs/ref/transforms.txt +++ b/docs/ref/transforms.txt @@ -40,8 +40,6 @@ peps.Headers pep (r) 360 peps.Contents pep (r) 380 -html.StylesheetCheck html4css1 (w) 420 - references.AnonymousHyperlinks standalone (r), pep (r) 440 references.IndirectHyperlinks standalone (r), pep (r) 460 diff --git a/docs/user/config.txt b/docs/user/config.txt index 32be81764..db38ac1ab 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -662,18 +662,12 @@ stylesheet_path relative to the output HTML file. Also defined for the `LaTeX Writer`__. - Default: None. Options: ``--stylesheet-path``. + Default: "html4css1.css" in the docutils/writers/support directory + (installed automatically; for the exact machine-specific path, use + the ``--help`` option). Options: ``--stylesheet-path``. __ `stylesheet_path [latex2e writer]`_ -_`_stylesheet_required` - Warn if valid stylesheet settings are absent. For programmatic - use only. - - Default: not required (0), except when using the ``rst2html.py`` - front-end tool. No command-line options; pass ``--stylesheet=`` - (i.e., with no argument) to disable the stylesheet explicitly. - .. _xml_declaration [html4css1 writer]: xml_declaration @@ -694,7 +688,14 @@ xml_declaration The PEP/HTML Writer derives from the standard HTML Writer, and shares all settings defined in the `[html4css1 writer]`_ section. The -"[html4css1 writer]" section is processed before "[pep_html writer]". +"[html4css1 writer]" section of configuration files is processed +before the "[pep_html writer]" section. + +The PEP/HTML Writer's default for the ``stylesheet_path`` setting +differs from that of the standard HTML Writer: +``docutils/writers/support/pep_html/pep.css`` in the installation +directory is used. For the exact machine-specific path, use the +``--help`` option. _`no_random` Do not use a random banner image. Mainly used to get predictable diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 9a2ddbcc4..20e22e356 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -84,10 +84,10 @@ The current directory (and all subdirectories) is chosen by default if no directory is named. Some files may generate system messages (docs/user/rst/demo.txt contains intentional errors); use the ``--quiet`` option to suppress all warnings. The ``--config`` option -ensures that the correct stylesheets, templates, and settings are in -place (a ``docutils.conf`` configuration file in the current directory -is picked up automatically). Command-line options may be used to -override config file settings or replace them altogether. +ensures that the correct settings are in place (a ``docutils.conf`` +`configuration file`_ in the current directory is picked up +automatically). Command-line options may be used to override config +file settings or replace them altogether. rst2html.py @@ -100,8 +100,8 @@ rst2html.py The ``rst2html.py`` front end reads standalone reStructuredText source files and produces HTML 4 (XHTML 1) output compatible with modern browsers that support cascading stylesheets (CSS). A stylesheet is -required for proper rendering; an example is provided in -``tools/stylesheets/default.css`` (see Stylesheets_ below). +required for proper rendering; a simple but complete stylesheet is +installed and used by default (see Stylesheets_ below). For example, to process a reStructuredText file "``test.txt``" into HTML:: @@ -110,7 +110,7 @@ HTML:: Now open the "``test.html``" file in your favorite browser to see the results. To get a footer with a link to the source file, date & time -of processing, and links to the Docutils projects, add some options:: +of processing, and links to the Docutils project, add some options:: rst2html.py --stylesheet=mystyles.css -stg test.txt test.html @@ -120,14 +120,15 @@ Stylesheets ``rst2html.py`` inserts into the generated HTML a cascading stylesheet (or a link to a stylesheet, when passing the "``--link-stylesheet``" -option). You must specify the location of the stylesheet (normally -``tools/stylesheets/default.css`` in the Docutils distribution -tarball) with a "``--stylesheet``" or "``--stylesheet-path``" -command-line option unless a configuration file -(e.g. ``/etc/docutils.conf`` or ``~/.docutils.conf``) does so for you. -The "``tools/stylesheets/default.css``" stylesheet is provided for -basic use. To experiment with styles, please see the `guide to -writing HTML (CSS) stylesheets for Docutils`__. +option). A stylesheet is required for proper rendering. The default +stylesheet (``docutils/writers/support/html4css1.css``, located in the +installation directory) is provided for basic use. To use a different +stylesheet, you must specify the stylesheet's location with a +"``--stylesheet``" (for a URL) or "``--stylesheet-path``" (for a local +file) command-line option, or with `configuration file`_ settings +(e.g. ``./docutils.conf`` or ``~/.docutils.conf``). To experiment +with styles, please see the `guide to writing HTML (CSS) stylesheets +for Docutils`__. __ ../howto/html-stylesheets.html diff --git a/docutils/transforms/html.py b/docutils/transforms/html.py deleted file mode 100644 index 59b8fb4a9..000000000 --- a/docutils/transforms/html.py +++ /dev/null @@ -1,30 +0,0 @@ -# Author: David Goodger -# Contact: goodger@python.org -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -Transforms specific to the HTML writer. -""" - -__docformat__ = 'reStructuredText' - -from docutils import nodes, utils -from docutils.transforms import Transform, TransformError - - -class StylesheetCheck(Transform): - - """Check for a proper stylesheet setting.""" - - default_priority = 420 - - def apply(self): - if ( self.document.settings._stylesheet_required and - utils.get_stylesheet_reference(self.document.settings) is None): - self.document.reporter.warning( - 'No stylesheet path or URI given. Use the --stylesheet ' - 'or --stylesheet-path option to specify the location of ' - 'default.css (in the tools/stylesheets/ directory of the ' - 'Docutils distribution).') diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index 2fcdd2d7b..c020fbf62 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -11,10 +11,14 @@ This package contains Docutils Writer modules. __docformat__ = 'reStructuredText' -import sys +import os.path import docutils from docutils import languages, Component from docutils.transforms import universal +from docutils.writers import support + + +support_path = os.path.dirname(support.__file__) class Writer(Component): diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 9f1465c58..bb3c1789e 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -28,7 +28,6 @@ except ImportError: Image = None import docutils from docutils import frontend, nodes, utils, writers, languages -from docutils.transforms import html class Writer(writers.Writer): @@ -36,6 +35,12 @@ class Writer(writers.Writer): supported = ('html', 'html4css1', 'xhtml') """Formats this writer supports.""" + default_stylesheet = 'html4css1.css' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(writers.support_path, default_stylesheet)) + settings_spec = ( 'HTML-Specific Options', None, @@ -46,20 +51,22 @@ class Writer(writers.Writer): {'metavar': '<URL>', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' 'directory. The path is adjusted relative to the output HTML ' - 'file. Overrides --stylesheet.', + 'file. Overrides --stylesheet. Default: %r' + % default_stylesheet_path, ['--stylesheet-path'], - {'metavar': '<file>', 'overrides': 'stylesheet'}), - ('Link to the stylesheet in the output HTML file. Default: ' - 'embed the stylesheet, do not link to it.', - ['--link-stylesheet'], - {'dest': 'embed_stylesheet', 'action': 'store_false', - 'validator': frontend.validate_boolean}), + {'metavar': '<file>', 'overrides': 'stylesheet', + 'default': default_stylesheet_path}), ('Embed the stylesheet in the output HTML file. The stylesheet ' 'file must be accessible during processing (--stylesheet-path is ' 'recommended). This is the default.', ['--embed-stylesheet'], {'default': 1, 'action': 'store_true', 'validator': frontend.validate_boolean}), + ('Link to the stylesheet in the output HTML file. Default: ' + 'embed the stylesheet, do not link to it.', + ['--link-stylesheet'], + {'dest': 'embed_stylesheet', 'action': 'store_false', + 'validator': frontend.validate_boolean}), ('Specify the initial header level. Default is 1 for "<h1>". ' 'Does not affect document title & subtitle (see --no-doc-title).', ['--initial-header-level'], @@ -117,17 +124,13 @@ class Writer(writers.Writer): ['--cloak-email-addresses'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) - settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace', - '_stylesheet_required': 0} + settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} relative_path_settings = ('stylesheet_path',) config_section = 'html4css1 writer' config_section_dependencies = ('writers',) - def get_transforms(self): - return writers.Writer.get_transforms(self) + [html.StylesheetCheck] - def __init__(self): writers.Writer.__init__(self) self.translator_class = HTMLTranslator diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 4bbe9db08..824946204 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -22,6 +22,7 @@ import string from types import ListType from docutils import frontend, nodes, languages, writers, utils + class Writer(writers.Writer): supported = ('latex','latex2e') diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 9d81ff7bf..6845a7b72 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -21,7 +21,7 @@ from types import ListType import docutils from docutils import nodes, writers, utils -from docutils.writers.support import unicode_latex +from docutils.writers.support.newlatex2e import unicode_map from docutils.transforms import writer_aux @@ -55,7 +55,7 @@ class Writer(writers.Writer): ),) settings_defaults = { - # Many Unicode characters are provided by unicode_latex.py. + # Many Unicode characters are provided by unicode_map.py. 'output_encoding': 'ascii', 'output_encoding_error_handler': 'strict', # Since we are using superscript footnotes, it is necessary to @@ -217,7 +217,7 @@ class LaTeXTranslator(nodes.SparseNodeVisitor): a(r'\providecommand{\Dparagraphindented}{false} % variable') a('\n\n') - unicode_map = unicode_latex.unicode_map # comprehensive Unicode map + unicode_map = unicode_map.unicode_map # comprehensive Unicode map # Fix problems with unimap.py. unicode_map.update({ # We have AE or T1 encoding, so "``" etc. work. The macros diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 1e9b8744a..16b305087 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -12,19 +12,35 @@ __docformat__ = 'reStructuredText' import sys +import os +import os.path import docutils -from docutils import frontend, nodes, utils +from docutils import frontend, nodes, utils, writers from docutils.writers import html4css1 class Writer(html4css1.Writer): + default_stylesheet = 'pep_html/pep.css' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(writers.support_path, default_stylesheet)) + + default_template = 'pep_html/template.txt' + + default_template_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(writers.support_path, default_template)) + settings_spec = html4css1.Writer.settings_spec + ( 'PEP/HTML-Specific Options', - None, - (('Specify a template file. Default is "pep-html-template".', + 'The default value for the --stylesheet-path option (defined in ' + 'HTML-Specific Options above) is %r for the PEP/HTML writer.' + % default_stylesheet_path, + (('Specify a template file. Default is %r.' % default_template_path, ['--template'], - {'default': 'pep-html-template', 'metavar': '<file>'}), + {'default': default_template_path, 'metavar': '<file>'}), ('Python\'s home URL. Default is "http://www.python.org".', ['--python-home'], {'default': 'http://www.python.org', 'metavar': '<URL>'}), @@ -36,6 +52,8 @@ class Writer(html4css1.Writer): ['--no-random'], {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + settings_default_overrides = {'stylesheet_path': default_stylesheet_path} + relative_path_settings = (html4css1.Writer.relative_path_settings + ('template',)) diff --git a/docutils/writers/support/html4css1.css b/docutils/writers/support/html4css1.css new file mode 100644 index 000000000..a418a7a00 --- /dev/null +++ b/docutils/writers/support/html4css1.css @@ -0,0 +1,276 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. +*/ + +/* "! important" is used here to override other ``margin-top`` and + ``margin-bottom`` styles that are later in the stylesheet or + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ +.first { + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +dl.docutils dd { + margin-bottom: 0.5em } + +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +img.align-left { + clear: left } + +img.align-right { + clear: right } + +img.borderless { + border: 0 } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid thin gray } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid thin black } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } diff --git a/docutils/writers/support/latex2e.tex b/docutils/writers/support/latex2e.tex new file mode 100644 index 000000000..6e041a14b --- /dev/null +++ b/docutils/writers/support/latex2e.tex @@ -0,0 +1,74 @@ +% latex include file for docutils latex writer +% -------------------------------------------- +% +% CVS: $Id$ +% +% This is included at the end of the latex header in the generated file, +% to allow overwriting defaults, although this could get hairy. +% Generated files should process well standalone too, LaTeX might give a +% message about a missing file. + +% donot indent first line of paragraph. +\setlength{\parindent}{0pt} +\setlength{\parskip}{5pt plus 2pt minus 1pt} + +% sloppy +% ------ +% Less strict (opposite to default fussy) space size between words. Therefore +% less hyphenation. +\sloppy + +% fonts +% ----- +% times for pdf generation, gives smaller pdf files. +% +% But in standard postscript fonts: courier and times/helvetica do not fit. +% Maybe use pslatex. +\usepackage{times} + +% pagestyle +% --------- +% headings might put section titles in the page heading, but not if +% the table of contents is done by docutils. +% If pagestyle{headings} is used, \geometry{headheight=10pt,headsep=1pt} +% should be set too. +%\pagestyle{plain} +% +% or use fancyhdr (untested !) +%\usepackage{fancyhdr} +%\pagestyle{fancy} +%\addtolength{\headheight}{\\baselineskip} +%\renewcommand{\sectionmark}[1]{\markboth{#1}{}} +%\renewcommand{\subsectionmark}[1]{\markright{#1}} +%\fancyhf{} +%\fancyhead[LE,RO]{\\bfseries\\textsf{\Large\\thepage}} +%\fancyhead[LO]{\\textsf{\\footnotesize\\rightmark}} +%\fancyhead[RE]{\\textsc{\\textsf{\\footnotesize\leftmark}}} +%\\fancyfoot[LE,RO]{\\bfseries\\textsf{\scriptsize Docutils}} +%\fancyfoot[RE,LO]{\\textsf{\scriptsize\\today}} + +% geometry +% -------- +% = papersizes and margins +%\geometry{a4paper,twoside,tmargin=1.5cm, +% headheight=1cm,headsep=0.75cm} + +% Do section number display +% ------------------------- +%\makeatletter +%\def\@seccntformat#1{} +%\makeatother +% no numbers in toc +%\renewcommand{\numberline}[1]{} + + +% change maketitle +% ---------------- +%\renewcommand{\maketitle}{ +% \begin{titlepage} +% \begin{center} +% \textsf{TITLE \@title} \\ +% Date: \today +% \end{center} +% \end{titlepage} +%} diff --git a/docutils/writers/support/newlatex2e/__init__.py b/docutils/writers/support/newlatex2e/__init__.py new file mode 100644 index 000000000..87197468a --- /dev/null +++ b/docutils/writers/support/newlatex2e/__init__.py @@ -0,0 +1 @@ +# This file is needed for Python to treat this directory as a package. diff --git a/docutils/writers/support/newlatex2e/base.tex b/docutils/writers/support/newlatex2e/base.tex new file mode 100644 index 000000000..231f3911f --- /dev/null +++ b/docutils/writers/support/newlatex2e/base.tex @@ -0,0 +1,1108 @@ +\makeatletter + +% Development notes at +% http://docutils.python-hosting.com/wiki/NewLatex + + +\providecommand{\Dprinting}{false} + + +\providecommand{\DSearly}{} +\providecommand{\DSlate}{} + +\providecommand{\Ddocumentclass}{scrartcl} +\providecommand{\Ddocumentoptions}{a4paper} + +\documentclass[\Ddocumentoptions]{\Ddocumentclass} + +\DSearly + + +\providecommand{\DSfontencoding}{ + % Set up font encoding. + % AE is a T1-emulation. It provides most characters and features + % as T1-encoded fonts but doesn't use ugly bitmap fonts. + \usepackage{ae} + % Provide the characters not contained in AE from EC bitmap fonts. + \usepackage{aecompl} + % Guillemets ("<<", ">>") in AE. + \usepackage{aeguill} +} + + +\providecommand{\DSsymbols}{% + % Fix up symbols. + % The Euro symbol in Computer Modern looks, um, funny. Let's get a + % proper Euro symbol. + \RequirePackage{eurosym}% + \renewcommand{\texteuro}{\euro}% +} + + +% Taken from +% <http://groups.google.de/groups?selm=1i0n5tgtplti420e1omp4pctlv19jpuhbb%404ax.com> +% and modified. Used with permission. +\providecommand{\Dprovidelength}[2]{% + \begingroup% + \escapechar\m@ne% + \xdef\@gtempa{{\string#1}}% + \endgroup% + \expandafter\@ifundefined\@gtempa% + {\newlength{#1}\setlength{#1}{#2}}% + {}% +} + +\providecommand{\Dprovidecounter}[1]{% + % Like \newcounter except that it doesn't crash if the counter + % already exists. + \@ifundefined{c@#1}{\newcounter{#1}}{} +} + +\Dprovidelength{\Dboxparindent}{\parindent} +\providecommand{\Dmakeboxminipage}[1]{% + % Make minipage for use in a box created by \Dmakefbox. + \begin{minipage}[t]{0.9\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% +} +\providecommand{\Dmakefbox}[1]{% + % Make a centered, framed box. Useful e.g. for admonitions. + \vspace{0.4\baselineskip}% + \begin{center}% + \fbox{\Dmakeboxminipage{#1}}% + \end{center}% + \vspace{0.4\baselineskip}% +} +\providecommand{\Dmakebox}[1]{% + % Make a centered, frameless box. Useful e.g. for block quotes. + % Do not use minipages here, but create pseudo-lists to allow + % page-breaking. (Don't use KOMA-script's addmargin environment + % because it messes up bullet lists.) + \Dmakelistenvironment{}{}{% + \setlength{\parskip}{0pt}% + \setlength{\parindent}{\Dboxparindent}% + \item{#1}% + }% +} + + +\RequirePackage{ifthen} +\providecommand{\Dfrenchspacing}{true} +\ifthenelse{\equal{\Dfrenchspacing}{true}}{\frenchspacing}{} + + +\Dprovidelength{\Dblocklevelvspace}{% + % Space between block-level elements other than paragraphs. + 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% +} +\providecommand{\Dauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \par\noindent% +} +\providecommand{\Dparagraphspace}{\par} +\providecommand{\Dneedvspace}{true} + + +\providecommand{\DSlinks}{ + % Targets and references. + \RequirePackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} + + \providecommand{\Draisedlink}[1]{\Hy@raisedlink{##1}} + + % References. + % We're assuming here that the "refid" and "refuri" attributes occur + % only in inline context (in TextElements). + \providecommand{\DArefid}[5]{% + \ifthenelse{\equal{##4}{reference}}{% + \Dexplicitreference{\###3}{##5}% + }{% + % If this is not a target node (targets with refids are + % uninteresting and should be silently dropped). + \ifthenelse{\not\equal{##4}{target}}{% + % If this is a footnote reference, call special macro. + \ifthenelse{\equal{##4}{footnotereference}}{% + \Dimplicitfootnotereference{\###3}{##5}% + }{% + \ifthenelse{\equal{##4}{citationreference}}{% + \Dimplicitcitationreference{\###3}{##5}% + }{% + \Dimplicitreference{\###3}{##5}% + }% + }% + }{}% + }% + } + \providecommand{\DArefuri}[5]{% + \ifthenelse{\equal{##4}{target}}{% + % Hyperlink targets can (and should be) ignored because they are + % invisible. + }{% + % We only have explicit URI references, so one macro suffices. + \Durireference{##3}{##5}% + }% + } + % Targets. + \providecommand{\DAids}[5]{% + \label{##3}% + \ifthenelse{\equal{##4}{footnotereference}}{% + {% + \renewcommand{\HyperRaiseLinkDefault}{% + % Dirty hack to make backrefs to footnote references work. + % For some reason, \baselineskip is 0pt in fn references. + 0.5\Doriginalbaselineskip% + }% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + }{% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + } + % Color in references. + \RequirePackage{color} + \providecommand{\Dimplicitreference}[2]{% + % Create implicit reference to ID. Implicit references occur + % e.g. in TOC-backlinks of section titles. Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{##2}% + } + \providecommand{\Dimplicitfootnotereference}[2]{% + % Ditto, but for the special case of footnotes. + % We want them to be rendered like explicit references. + \Dexplicitreference{##1}{##2}% + } + \providecommand{\Dimplicitcitationreference}[2]{% + % Ditto for citation references. + \Dimplicitfootnotereference{##1}{##2}% + } + \ifthenelse{\equal{\Dprinting}{true}}{ + \providecommand{\Dexplicitreferencecolor}{black} + }{ + \providecommand{\Dexplicitreferencecolor}{blue} + } + \providecommand{\Dexplicitreference}[2]{% + % Create explicit reference to ID, e.g. created with "foo_". + % Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{{\color{\Dexplicitreferencecolor}##2}}% + } + \providecommand{\Durireferencecolor}{\Dexplicitreferencecolor} + \providecommand{\Durireference}[2]{% + % Create reference to URI. Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{{\color{\Durireferencecolor}##2}}% + } +} + + +\providecommand{\DSlanguage}{% + % Set up babel. + \ifthenelse{\equal{\Dlanguagebabel}{}}{}{ + \RequirePackage[\Dlanguagebabel]{babel} + } +} + + + + +\providecommand{\DAclasses}[5]{% + \Difdefined{DN#4C#3}{% + % Pass only contents, nothing else! + \csname DN#4C#3\endcsname{#5}% + }{% + \Difdefined{DC#3}{% + \csname DC#3\endcsname{#5}% + }{% + #5% + }% + }% +} + +\providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}} + +\providecommand{\Dattr}[5]{% + % Global attribute dispatcher. + % Parameters: + % 1. Attribute number. + % 2. Attribute name. + % 3. Attribute value. + % 4. Node name. + % 5. Node contents. + \Difdefined{DN#4A#2V#3}{% + \csname DN#4A#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DN#4A#2}{% + \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DA#2V#3}{% + \csname DA#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DA#2}{% + \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }{#5% + }}}}% +} + +\providecommand{\DNparagraph}[1]{% + \ifthenelse{\equal{\Dparagraphindented}{true}}{\indent}{\noindent}% + #1% +} +\providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} +\providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} +\providecommand{\Dtopictitle}[1]{% + \Difinsidetoc{\vspace{1em}\par}{}% + \noindent\Dformatboxtitle{#1}% + \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% + \par% +} +\providecommand{\Dtopicsubtitle}[1]{% + \noindent\Dformatboxsubtitle{#1}% + \vspace{1em}% + \par% +} +\providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}} +\providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}} +\providecommand{\Ddocumenttitle}[1]{% + \begin{center}{\Huge#1}\end{center}% + \ifthenelse{\equal{\Dhassubtitle}{true}}{\vspace{0.1cm}}{\vspace{1cm}}% +} +\providecommand{\Ddocumentsubtitle}[1]{% + \begin{center}{\huge#1}\end{center}% + \vspace{1cm}% +} +% Can be overwritten by user stylesheet. +\providecommand{\Dformatsectiontitle}[1]{#1} +\providecommand{\Dformatsectionsubtitle}[1]{\Dformatsectiontitle{#1}} +\providecommand{\Dbookmarksectiontitle}[1]{% + % Return text suitable for use in \section*, \subsection*, etc., + % containing a PDF bookmark. Parameter: The title (as node tree). + \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% + #1% +} +\providecommand{\Dsectiontitlehook}[1]{#1} +\providecommand{\Dsectiontitle}[1]{% + \Dsectiontitlehook{% + \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% + }% +} +\providecommand{\Ddispatchsectiontitle}[1]{% + \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% + \Ddeepsectiontitle{#1}% + }{% + \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% + }% +} +\providecommand{\Ddispatchsectionsubtitle}[1]{% + \Ddispatchsectiontitle{#1}% +} +\providecommand{\Dsectiontitlei}[1]{\section*{#1}} +\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} +\providecommand{\Ddeepsectiontitle}[1]{% + % Anything below \subsubsection (like \paragraph or \subparagraph) + % is useless because it uses the same font. The only way to + % (visually) distinguish such deeply nested sections is to use + % section numbering. + \subsubsection*{#1}% +} +\providecommand{\Dsectionsubtitlehook}[1]{#1} +\Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} +\providecommand{\Dsectionsubtitlescaling}{0.85} +\providecommand{\Dsectionsubtitle}[1]{% + \Dsectionsubtitlehook{% + % Move the subtitle nearer to the title. + \vspace{-\Dsectionsubtitleraisedistance}% + % Don't create a PDF bookmark. + \Ddispatchsectionsubtitle{% + \Dformatsectionsubtitle{\scalebox{\Dsectionsubtitlescaling}{#1}}% + }% + }% +} +% Boolean variable. +\providecommand{\Dhassubtitle}{false} +\providecommand{\DNtitle}[1]{% + \csname D\Dparent title\endcsname{#1}% +} +\providecommand{\DNsubtitle}[1]{% + \csname D\Dparent subtitle\endcsname{#1}% +} +\newcounter{Dpdfbookmarkid} +\setcounter{Dpdfbookmarkid}{0} +\providecommand{\Dpdfbookmark}[1]{% + % Temporarily decrement Desctionlevel counter. + \addtocounter{Dsectionlevel}{-1}% + %\typeout{\arabic{Dsectionlevel}}% + %\typeout{#1}% + %\typeout{docutils\roman{Dpdfbookmarkid}}% + %\typeout{}% + \pdfbookmark[\arabic{Dsectionlevel}]{#1}{docutils\arabic{Dpdfbookmarkid}}% + \addtocounter{Dsectionlevel}{1}% + \addtocounter{Dpdfbookmarkid}{1}% +} + +%\providecommand{\DNliteralblock}[1]{\begin{quote}\ttfamily\raggedright#1\end{quote}} +\providecommand{\DNliteralblock}[1]{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + \setlength{\leftmargin}{0pt}% + }{}% + \setlength{\rightmargin}{0pt}% + }{% + \raggedright\item\noindent\nohyphens{\textnhtt{#1\Dfinalstrut}}% + }% +} +\providecommand{\DNdoctestblock}[1]{% + % Treat doctest blocks the same as literal blocks. + \DNliteralblock{#1}% +} +\RequirePackage{hyphenat} +\providecommand{\DNliteral}[1]{\textnhtt{#1}} +\providecommand{\DNemphasis}[1]{\emph{#1}} +\providecommand{\DNstrong}[1]{\textbf{#1}} +\providecommand{\Dvisitdocument}{\begin{document}\noindent} +\providecommand{\Ddepartdocument}{\end{document}} +\providecommand{\DNtopic}[1]{% + \ifthenelse{\equal{\DcurrentNtopicAcontents}{1}}{% + \addtocounter{Dtoclevel}{1}% + \par\noindent% + #1% + \addtocounter{Dtoclevel}{-1}% + }{% + \par\noindent% + \Dmakebox{#1}% + }% +} +\providecommand{\Dformatrubric}[1]{\textbf{#1}} +\Dprovidelength{\Dprerubricspace}{0.3em} +\providecommand{\DNrubric}[1]{% + \vspace{\Dprerubricspace}\par\noindent\Dformatrubric{#1}\par% +} + +\providecommand{\Dbullet}{} +\providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} +\providecommand{\DNbulletlist}[1]{% + \Difinsidetoc{% + \Dtocbulletlist{#1}% + }{% + \Dmakelistenvironment{\Dbullet}{}{#1}% + }% +} +\renewcommand{\@pnumwidth}{2.2em} +\providecommand{\DNlistitem}[1]{% + \Difinsidetoc{% + \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{% + {% + \par\addvspace{1em}\noindent% + \sectfont% + #1\hfill\pageref{\DcurrentNlistitemAtocrefid}% + }% + }{% + \@dottedtocline{0}{\Dtocindent}{0em}{#1}{% + \pageref{\DcurrentNlistitemAtocrefid}% + }% + }% + }{% + \item{#1}% + }% +} +\providecommand{\DNenumeratedlist}[1]{#1} +\newcounter{Dsectionlevel} +\providecommand{\Dvisitsectionhook}{} +\providecommand{\Ddepartsectionhook}{} +\providecommand{\Dvisitsection}{% + \addtocounter{Dsectionlevel}{1}% + \Dvisitsectionhook% +} +\providecommand{\Ddepartsection}{% + \Ddepartsectionhook% + \addtocounter{Dsectionlevel}{-1}% +} + +% Using \_ will cause hyphenation after _ even in \textnhtt-typewriter +% because the hyphenat package redefines \_. So we use +% \textunderscore here. +\providecommand{\Dtextunderscore}{\textunderscore} + +\providecommand{\Dtextinlineliteralfirstspace}{{ }} +\providecommand{\Dtextinlineliteralsecondspace}{{~}} + +\Dprovidelength{\Dlistspacing}{0.8\baselineskip} + +\providecommand{\Dsetlistrightmargin}{% + \ifthenelse{\lengthtest{\linewidth>12em}}{% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + }{% + % If the line is narrower than 10em, we don't remove any further + % space from the right. + \setlength{\rightmargin}{0pt}% + }% +} +\providecommand{\Dresetlistdepth}{false} +\Dprovidelength{\Doriginallabelsep}{\labelsep} +\providecommand{\Dmakelistenvironment}[3]{% + % Make list environment with support for unlimited nesting and with + % reasonable default lengths. Parameters: + % 1. Label (same as in list environment). + % 2. Spacing (same as in list environment). + % 3. List contents (contents of list environment). + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Unfortunately, vertical spacing doesn't work correctly when + % using lists inside tabular environments, so we use a minipage. + \begin{minipage}[t]{\linewidth}% + }{}% + {% + \renewcommand{\Dneedvspace}{false}% + % \parsep0.5\baselineskip + \renewcommand{\Dresetlistdepth}{false}% + \ifnum \@listdepth>5% + \protect\renewcommand{\Dresetlistdepth}{true}% + \@listdepth=5% + \fi% + \begin{list}{% + #1% + }{% + \setlength{\itemsep}{0pt}% + \setlength{\partopsep}{0pt}% + \setlength{\topsep}{0pt}% + % List should take 90% of total width. + \setlength{\leftmargin}{0.05\linewidth}% + \ifthenelse{\lengthtest{\leftmargin<1.8em}}{% + \setlength{\leftmargin}{1.8em}% + }{}% + \setlength{\labelsep}{\Doriginallabelsep}% + \Dsetlistrightmargin% + #2% + }{% + #3% + }% + \end{list}% + \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% + }% + \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% +} +\providecommand{\Dfinalstrut}{\@finalstrut\@arstrutbox} +\providecommand{\DAlastitem}[5]{#5\Dfinalstrut} + +\Dprovidelength{\Ditemsep}{0pt} +\providecommand{\Dmakeenumeratedlist}[6]{% + % Make enumerated list. + % Parameters: + % - prefix + % - type (\arabic, \roman, ...) + % - suffix + % - suggested counter name + % - start number - 1 + % - list contents + \newcounter{#4}% + \Dmakelistenvironment{#1#2{#4}#3}{% + % Use as much space as needed for the label. + \setlength{\labelwidth}{10em}% + % Reserve enough space so that the label doesn't go beyond the + % left margin of preceding paragraphs. Like that: + % + % A paragraph. + % + % 1. First item. + \setlength{\leftmargin}{2.5em}% + \Dsetlistrightmargin% + \setlength{\itemsep}{\Ditemsep}% + % Use counter recommended by Python module. + \usecounter{#4}% + % Set start value. + \addtocounter{#4}{#5}% + }{% + % The list contents. + #6% + }% +} + + +% Single quote in literal mode. \textquotesingle from package +% textcomp has wrong width when using package ae, so we use a normal +% single curly quote here. +\providecommand{\Dtextliteralsinglequote}{'} + + +% "Tabular lists" are field lists and options lists (not definition +% lists because there the term always appears on its own line). We'll +% use the terminology of field lists now ("field", "field name", +% "field body"), but the same is also analogously applicable to option +% lists. +% +% We want these lists to be breakable across pages. We cannot +% automatically get the narrowest possible size for the left column +% (i.e. the field names or option groups) because tabularx does not +% support multi-page tables, ltxtable needs to have the table in an +% external file and we don't want to clutter the user's directories +% with auxiliary files created by the filecontents environment, and +% ltablex is not included in teTeX. +% +% Thus we set a fixed length for the left column and use list +% environments. This also has the nice side effect that breaking is +% now possible anywhere, not just between fields. +% +% Note that we are creating a distinct list environment for each +% field. There is no macro for a whole tabular list! +\Dprovidelength{\Dtabularlistfieldnamewidth}{6em} +\Dprovidelength{\Dtabularlistfieldnamesep}{0.5em} +\providecommand{\Dinsidetabular}{false} +\providecommand{\Dsavefieldname}{} +\providecommand{\Dsavefieldbody}{} +\Dprovidelength{\Dusedfieldnamewidth}{0pt} +\Dprovidelength{\Drealfieldnamewidth}{0pt} +\providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}} +\providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}} +\Dprovidelength{\Dparskiptemp}{0pt} +\providecommand{\Dtabularlistfield}[1]{% + {% + % This only saves field name and field body in \Dsavefieldname and + % \Dsavefieldbody, resp. It does not insert any text into the + % document. + #1% + % Recalculate the real field name width everytime we encounter a + % tabular list field because it may have been changed using a + % "raw" node. + \setlength{\Drealfieldnamewidth}{\Dtabularlistfieldnamewidth}% + \addtolength{\Drealfieldnamewidth}{\Dtabularlistfieldnamesep}% + \Dmakelistenvironment{% + \makebox[\Drealfieldnamewidth][l]{\Dsavefieldname}% + }{% + \setlength{\labelwidth}{\Drealfieldnamewidth}% + \setlength{\leftmargin}{\Drealfieldnamewidth}% + \setlength{\rightmargin}{0pt}% + \setlength{\labelsep}{0pt}% + }{% + \item% + \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}% + \setlength{\Dparskiptemp}{\parskip}% + \ifthenelse{% + \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% + }{% + \mbox{}\par% + \setlength{\parskip}{0pt}% + }{}% + \Dsavefieldbody% + \setlength{\parskip}{\Dparskiptemp}% + %XXX Why did we need this? + %\@finalstrut\@arstrutbox% + }% + \par% + }% +} + +\providecommand{\Dformatfieldname}[1]{\textbf{#1:}} +\providecommand{\DNfieldlist}[1]{#1} +\providecommand{\DNfield}[1]{\Dtabularlistfield{#1}} +\providecommand{\DNfieldname}[1]{% + \Dtabularlistfieldname{% + \Dformatfieldname{#1}% + }% +} +\providecommand{\DNfieldbody}[1]{\Dtabularlistfieldbody{#1}} + +\providecommand{\Dformatoptiongroup}[1]{% + % Format option group, e.g. "-f file, --input file". + \texttt{#1}% +} +\providecommand{\Dformatoption}[1]{% + % Format option, e.g. "-f file". + % Put into mbox to avoid line-breaking at spaces. + \mbox{#1}% +} +\providecommand{\Dformatoptionstring}[1]{% + % Format option string, e.g. "-f". + #1% +} +\providecommand{\Dformatoptionargument}[1]{% + % Format option argument, e.g. "file". + \textsl{#1}% +} +\providecommand{\Dformatoptiondescription}[1]{% + % Format option description, e.g. + % "\DNparagraph{Read input data from file.}" + #1% +} +\providecommand{\DNoptionlist}[1]{#1} +\providecommand{\Doptiongroupjoiner}{,{ }} +\providecommand{\Disfirstoption}{% + % Auxiliary macro indicating if a given option is the first child + % of its option group (if it's not, it has to preceded by + % \Doptiongroupjoiner). + false% +} +\providecommand{\DNoptionlistitem}[1]{% + \Dtabularlistfield{#1}% +} +\providecommand{\DNoptiongroup}[1]{% + \renewcommand{\Disfirstoption}{true}% + \Dtabularlistfieldname{\Dformatoptiongroup{#1}}% +} +\providecommand{\DNoption}[1]{% + % If this is not the first option in this option group, add a + % joiner. + \ifthenelse{\equal{\Disfirstoption}{true}}{% + \renewcommand{\Disfirstoption}{false}% + }{% + \Doptiongroupjoiner% + }% + \Dformatoption{#1}% +} +\providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}} +\providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}} +\providecommand{\DNdescription}[1]{% + \Dtabularlistfieldbody{\Dformatoptiondescription{#1}}% +} + +\providecommand{\DNdefinitionlist}[1]{% + \begin{description}% + \parskip0pt% + #1% + \end{description}% +} +\providecommand{\DNdefinitionlistitem}[1]{% + % LaTeX expects the label in square brackets; we provide an empty + % label. + \item[]#1% +} +\providecommand{\Dformatterm}[1]{#1} +\providecommand{\DNterm}[1]{\hspace{-5pt}\Dformatterm{#1}} +% I'm still not sure what's the best rendering for classifiers. The +% colon syntax is used by reStructuredText, so it's at least WYSIWYG. +% Use slanted text because italic would cause too much emphasis. +\providecommand{\Dformatclassifier}[1]{\textsl{#1}} +\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} +\providecommand{\Dformatdefinition}[1]{#1} +\providecommand{\DNdefinition}[1]{\par\Dformatdefinition{#1}} + +\providecommand{\Dlineblockindentation}{2.5em} +\providecommand{\DNlineblock}[1]{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dparent}{lineblock}}{% + % Parent is a line block, so indent. + \setlength{\leftmargin}{\Dlineblockindentation}% + }{% + % At top level; don't indent. + \setlength{\leftmargin}{0pt}% + }% + \setlength{\rightmargin}{0pt}% + \setlength{\parsep}{0pt}% + }{% + #1% + }% +} +\providecommand{\DNline}[1]{\item#1} + + +\providecommand{\DNtransition}{% + \raisebox{0.25em}{\parbox{\linewidth}{\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}}}% +} + + +\providecommand{\Dformatblockquote}[1]{% + % Format contents of block quote. + % This occurs in block-level context, so we cannot use \textsl. + {\slshape#1}% +} +\providecommand{\Dformatattribution}[1]{---\textup{#1}} +\providecommand{\DNblockquote}[1]{% + \Dmakebox{% + \Dformatblockquote{#1} + }% +} +\providecommand{\DNattribution}[1]{% + \par% + \begin{flushright}\Dformatattribution{#1}\end{flushright}% +} + + +% Sidebars: +\RequirePackage{picins} +% Vertical and horizontal margins. +\Dprovidelength{\Dsidebarvmargin}{0.5em} +\Dprovidelength{\Dsidebarhmargin}{1em} +% Padding (space between contents and frame). +\Dprovidelength{\Dsidebarpadding}{1em} +% Frame width. +\Dprovidelength{\Dsidebarframewidth}{2\fboxrule} +% Position ("l" or "r"). +\providecommand{\Dsidebarposition}{r} +% Width. +\Dprovidelength{\Dsidebarwidth}{0.45\linewidth} +\providecommand{\DNsidebar}[1]{ + \parpic[\Dsidebarposition]{% + \begin{minipage}[t]{\Dsidebarwidth}% + % Doing this with nested minipages is ugly, but I haven't found + % another way to place vertical space before and after the fbox. + \vspace{\Dsidebarvmargin}% + {% + \setlength{\fboxrule}{\Dsidebarframewidth}% + \setlength{\fboxsep}{\Dsidebarpadding}% + \fbox{% + \begin{minipage}[t]{\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% + }% + }% + \vspace{\Dsidebarvmargin}% + \end{minipage}% + }% +} + + +% Citations and footnotes. +\providecommand{\Dformatfootnote}[1]{% + % Format footnote. + {% + \footnotesize#1% + % \par is necessary for LaTeX to adjust baselineskip to the + % changed font size. + \par% + }% +} +\providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}} +\Dprovidelength{\Doriginalbaselineskip}{0pt} +\providecommand{\DNfootnotereference}[1]{% + {% + % \baselineskip is 0pt in \textsuperscript, so we save it here. + \setlength{\Doriginalbaselineskip}{\baselineskip}% + \textsuperscript{#1}% + }% +} +\providecommand{\DNcitationreference}[1]{{[}#1{]}} +\Dprovidelength{\Dfootnotesep}{3.5pt} +\providecommand{\Dsetfootnotespacing}{% + % Spacing commands executed at the beginning of footnotes. + \setlength{\parindent}{0pt}% + \hspace{1em}% +} +\providecommand{\DNfootnote}[1]{% + % See ltfloat.dtx for details. + {% + \insert\footins{% + \vspace{\Dfootnotesep}% + \Dsetfootnotespacing% + \Dformatfootnote{#1}% + }% + }% +} +\providecommand{\DNcitation}[1]{\DNfootnote{#1}} +\providecommand{\Dformatfootnotelabel}[1]{% + % Keep \footnotesize in footnote labels (\textsuperscript would + % reduce the font size even more). + \textsuperscript{\footnotesize#1{ }}% +} +\providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }} +\providecommand{\Dformatmultiplebackrefs}[1]{% + % If in printing mode, do not write out multiple backrefs. + \ifthenelse{\equal{\Dprinting}{true}}{}{\textsl{#1}}% +} +\providecommand{\Dthislabel}{} +\providecommand{\DNlabel}[1]{% + \renewcommand{\Dthislabel}{#1} + \ifthenelse{\not\equal{\Dsinglebackref}{}}{% + \let\Doriginallabel=\Dthislabel% + \def\Dthislabel{% + \Dsinglefootnotebacklink{\Dsinglebackref}{\Doriginallabel}% + }% + }{}% + \ifthenelse{\equal{\Dparent}{footnote}}{% + % Footnote label. + \Dformatfootnotelabel{\Dthislabel}% + }{% + \ifthenelse{\equal{\Dparent}{citation}}{% + % Citation label. + \Dformatcitationlabel{\Dthislabel}% + }{}% + }% + % If there are multiple backrefs, add them now. + \Dformatmultiplebackrefs{\Dmultiplebackrefs}% +} +\providecommand{\Dsinglefootnotebacklink}[2]{% + % Create normal backlink of a footnote label. Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dmultifootnotebacklink}[2]{% + % Create generated backlink, as in (1, 2). Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dsinglecitationbacklink}[2]{\Dsinglefootnotebacklink{#1}{#2}} +\providecommand{\Dmulticitationbacklink}[2]{\Dmultifootnotebacklink{#1}{#2}} + + +\RequirePackage{longtable} +\providecommand{\Dmaketable}[2]{% + % Make table. Parameters: + % 1. Table spec (like "|p|p|"). + % 2. Table contents. + {% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Inside longtable; we cannot have nested longtables. + \begin{tabular}{#1}% + \hline% + #2% + \end{tabular}% + }{% + \renewcommand{\Dinsidetabular}{true}% + \begin{longtable}{#1}% + \hline% + #2% + \end{longtable}% + }% + }% +} +\providecommand{\DNthead}[1]{% + #1% + \endhead% +} +\providecommand{\DNrow}[1]{% + #1\tabularnewline% + \hline% +} +\providecommand{\Dinsidemulticolumn}{false} +\providecommand{\Dcompensatingmulticol}[3]{% + \multicolumn{#1}{#2}{% + {% + \renewcommand{\Dinsidemulticolumn}{true}% + % Compensate for weird missing vertical space at top of paragraph. + \raisebox{-2.5pt}{#3}% + }% + }% +} +\providecommand{\Dcolspan}[2]{% + % Take care of the morecols attribute (but incremented by 1). + &% + \Dcompensatingmulticol{#1}{l|}{#2}% +} +\providecommand{\Dcolspanleft}[2]{% + % Like \Dmorecols, but called for the leftmost entries in a table + % row. + \Dcompensatingmulticol{#1}{|l|}{#2}% +} +\providecommand{\Dsubsequententry}[1]{% + % +} +\providecommand{\DNentry}[1]{% + % The following sequence adds minimal vertical space above the top + % lines of the first cell paragraph, so that vertical space is + % balanced at the top and bottom of table cells. + \ifthenelse{\equal{\Dinsidemulticolumn}{false}}{% + \vspace{-1em}\vspace{-\parskip}\par% + }{}% + #1% + % No need to add an ampersand ("&"); that's done by \Dsubsequententry. +} +\providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} +\providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} + + +\providecommand{\DNsystemmessage}[1]{% + {% + \ifthenelse{\equal{\Dprinting}{false}}{\color{red}}{}% + \bfseries% + #1% + }% +} + + +\providecommand{\Dinsidehalign}{false} +\newsavebox{\Dalignedimagebox} +\Dprovidelength{\Dalignedimagewidth}{0pt} +\providecommand{\Dhalign}[2]{% + % Horizontally align the contents to the left or right so that the + % text flows around it. + % Parameters: + % 1. l or r + % 2. Contents. + \renewcommand{\Dinsidehalign}{true}% + % For some obscure reason \parpic consumes some vertical space. + \vspace{-3pt}% + % Now we do something *really* ugly, but this enables us to wrap the + % image in a minipage while still allowing tight frames when + % class=border (see \DNimageCborder). + \sbox{\Dalignedimagebox}{#2}% + \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}% + \parpic[#1]{% + \begin{minipage}[b]{\Dalignedimagewidth}% + % Compensate for previously added space, but not entirely. + \vspace*{2.0pt}% + \vspace*{\Dfloatimagetopmargin}% + \usebox{\Dalignedimagebox}% + \vspace*{1.5pt}% + \vspace*{\Dfloatimagebottommargin}% + \end{minipage}% + }% + \renewcommand{\Dinsidehalign}{false}% +} + + +\RequirePackage{graphicx} +% Maximum width of an image. +\providecommand{\Dimagemaxwidth}{\linewidth} +\providecommand{\Dfloatimagemaxwidth}{0.5\linewidth} +% Auxiliary variable. +\Dprovidelength{\Dcurrentimagewidth}{0pt} +\providecommand{\DNimageAalign}[5]{% + \ifthenelse{\equal{#3}{left}}{% + \Dhalign{l}{#5}% + }{% + \ifthenelse{\equal{#3}{right}}{% + \Dhalign{r}{#5}% + }{% + \ifthenelse{\equal{#3}{center}}{% + % Text floating around centered figures is a bad idea. Thus + % we use a center environment. Note that no extra space is + % added by the writer, so the space added by the center + % environment is fine. + \begin{center}#5\end{center}% + }{% + #5% + }% + }% + }% +} +% Base path for images. +\providecommand{\Dimagebase}{} +% Auxiliary command. Current image path. +\providecommand{\Dimagepath}{} +\providecommand{\DNimageAuri}[5]{% + % Insert image. We treat the URI like a path here. + \renewcommand{\Dimagepath}{\Dimagebase#3}% + \Difdefined{DcurrentNimageAwidth}{% + \Dwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% + }{% + \Dsimpleimage{\Dimagepath}% + }% +} +\Dprovidelength{\Dfloatimagevmargin}{0pt} +\providecommand{\Dfloatimagetopmargin}{\Dfloatimagevmargin} +\providecommand{\Dfloatimagebottommargin}{\Dfloatimagevmargin} +\providecommand{\Dwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width. + % 2. Image path. + % Need to make bottom-alignment dependent on align attribute (add + % functional test first). Need to observe height attribute. + %\begin{minipage}[b]{#1}% + \includegraphics[width=#1,height=\textheight,keepaspectratio]{#2}% + %\end{minipage}% +} +\providecommand{\Dcurrentimagemaxwidth}{} +\providecommand{\Dsimpleimage}[1]{% + % Insert image, without much parametrization. + \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dfloatimagemaxwidth}% + }{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}% + }% + \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{% + \Dwidthimage{\Dcurrentimagemaxwidth}{#1}% + }{% + \Dwidthimage{\Dcurrentimagewidth}{#1}% + }% +} +\providecommand{\Dwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width. + % 2. Image path. + \Dwidthimage{#1}{#2}% +} + +% Figures. +\providecommand{\DNfigureAalign}[5]{% + % Hack to make it work Right Now. + %\def\DcurrentNimageAwidth{\DcurrentNfigureAwidth}% + % + %\def\DcurrentNimageAwidth{\linewidth}% + \DNimageAalign{#1}{#2}{#3}{#4}{% + \begin{minipage}[b]{0.4\linewidth}#5\end{minipage}}% + %\let\DcurrentNimageAwidth=\relax% + % + %\let\DcurrentNimageAwidth=\relax% +} +\providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}} +\providecommand{\DNlegend}[1]{\Dauxiliaryspace#1} + +\providecommand{\DCborder}[1]{\fbox{#1}} +% No padding between image and border. +\providecommand{\DNimageCborder}[1]{\frame{#1}} + + +% Need to replace with language-specific stuff. Maybe look at +% csquotes.sty and ask the author for permission to use parts of it. +\providecommand{\Dtextleftdblquote}{``} +\providecommand{\Dtextrightdblquote}{''} + +% Table of contents: +\Dprovidelength{\Dtocininitialsectnumwidth}{2.4em} +\Dprovidelength{\Dtocadditionalsectnumwidth}{0.7em} +% Level inside a table of contents. While this is at -1, we are not +% inside a TOC. +\Dprovidecounter{Dtoclevel}% +\setcounter{Dtoclevel}{-1} +\providecommand{\Dlocaltoc}{false}% +\providecommand{\DNtopicClocal}[1]{% + \renewcommand{\Dlocaltoc}{true}% + \addtolength{\Dtocsectnumwidth}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-2\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocindent}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{-2\Dtocadditionalsectnumwidth}% + \renewcommand{\Dlocaltoc}{false}% +} +\Dprovidelength{\Dtocindent}{0pt}% +\Dprovidelength{\Dtocsectnumwidth}{\Dtocininitialsectnumwidth} +% Compensate for one additional TOC indentation space so that the +% top-level is unindented. +\addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth} +\addtolength{\Dtocindent}{-\Dtocsectnumwidth} +\providecommand{\Difinsidetoc}[2]{% + \ifthenelse{\not\equal{\theDtoclevel}{-1}}{#1}{#2}% +} +\providecommand{\DNgeneratedCsectnum}[1]{% + \Difinsidetoc{% + % Section number inside TOC. + \makebox[\Dtocsectnumwidth][l]{#1}% + }{% + % Section number inside section title. + #1\quad% + }% +} +\providecommand{\Dtocbulletlist}[1]{% + \addtocounter{Dtoclevel}{1}% + \addtolength{\Dtocindent}{\Dtocsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% + \addtocounter{Dtoclevel}{-1}% +} + + +% For \Dpixelunit, the length value is pre-multiplied with 0.75, so by +% specifying "pt" we get the same notion of "pixel" as graphicx. +\providecommand{\Dpixelunit}{pt} +% Normally lengths are relative to the current linewidth. +\providecommand{\Drelativeunit}{\linewidth} + + +%\RequirePackage{fixmath} +%\RequirePackage{amsmath} + + +\DSfontencoding +\DSlanguage +\DSlinks +\DSsymbols +\DSlate + +\makeatother diff --git a/docutils/writers/support/newlatex2e/unicode_map.py b/docutils/writers/support/newlatex2e/unicode_map.py new file mode 100644 index 000000000..2998178f4 --- /dev/null +++ b/docutils/writers/support/newlatex2e/unicode_map.py @@ -0,0 +1,2371 @@ +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This file has been placed in the public domain. + +# This is a mapping of Unicode characters to LaTeX equivalents. +# The information has been extracted from +# <http://www.w3.org/2003/entities/xml/unicode.xml>, written by +# David Carlisle and Sebastian Rahtz. +# +# The extraction has been done by the "create_unimap.py" script +# located at <http://docutils.sf.net/tools/dev/create_unimap.py>. + +unicode_map = {u'\xa0': '$~$', +u'\xa1': '{\\textexclamdown}', +u'\xa2': '{\\textcent}', +u'\xa3': '{\\textsterling}', +u'\xa4': '{\\textcurrency}', +u'\xa5': '{\\textyen}', +u'\xa6': '{\\textbrokenbar}', +u'\xa7': '{\\textsection}', +u'\xa8': '{\\textasciidieresis}', +u'\xa9': '{\\textcopyright}', +u'\xaa': '{\\textordfeminine}', +u'\xab': '{\\guillemotleft}', +u'\xac': '$\\lnot$', +u'\xad': '$\\-$', +u'\xae': '{\\textregistered}', +u'\xaf': '{\\textasciimacron}', +u'\xb0': '{\\textdegree}', +u'\xb1': '$\\pm$', +u'\xb2': '${^2}$', +u'\xb3': '${^3}$', +u'\xb4': '{\\textasciiacute}', +u'\xb5': '$\\mathrm{\\mu}$', +u'\xb6': '{\\textparagraph}', +u'\xb7': '$\\cdot$', +u'\xb8': '{\\c{}}', +u'\xb9': '${^1}$', +u'\xba': '{\\textordmasculine}', +u'\xbb': '{\\guillemotright}', +u'\xbc': '{\\textonequarter}', +u'\xbd': '{\\textonehalf}', +u'\xbe': '{\\textthreequarters}', +u'\xbf': '{\\textquestiondown}', +u'\xc0': '{\\`{A}}', +u'\xc1': "{\\'{A}}", +u'\xc2': '{\\^{A}}', +u'\xc3': '{\\~{A}}', +u'\xc4': '{\\"{A}}', +u'\xc5': '{\\AA}', +u'\xc6': '{\\AE}', +u'\xc7': '{\\c{C}}', +u'\xc8': '{\\`{E}}', +u'\xc9': "{\\'{E}}", +u'\xca': '{\\^{E}}', +u'\xcb': '{\\"{E}}', +u'\xcc': '{\\`{I}}', +u'\xcd': "{\\'{I}}", +u'\xce': '{\\^{I}}', +u'\xcf': '{\\"{I}}', +u'\xd0': '{\\DH}', +u'\xd1': '{\\~{N}}', +u'\xd2': '{\\`{O}}', +u'\xd3': "{\\'{O}}", +u'\xd4': '{\\^{O}}', +u'\xd5': '{\\~{O}}', +u'\xd6': '{\\"{O}}', +u'\xd7': '{\\texttimes}', +u'\xd8': '{\\O}', +u'\xd9': '{\\`{U}}', +u'\xda': "{\\'{U}}", +u'\xdb': '{\\^{U}}', +u'\xdc': '{\\"{U}}', +u'\xdd': "{\\'{Y}}", +u'\xde': '{\\TH}', +u'\xdf': '{\\ss}', +u'\xe0': '{\\`{a}}', +u'\xe1': "{\\'{a}}", +u'\xe2': '{\\^{a}}', +u'\xe3': '{\\~{a}}', +u'\xe4': '{\\"{a}}', +u'\xe5': '{\\aa}', +u'\xe6': '{\\ae}', +u'\xe7': '{\\c{c}}', +u'\xe8': '{\\`{e}}', +u'\xe9': "{\\'{e}}", +u'\xea': '{\\^{e}}', +u'\xeb': '{\\"{e}}', +u'\xec': '{\\`{\\i}}', +u'\xed': "{\\'{\\i}}", +u'\xee': '{\\^{\\i}}', +u'\xef': '{\\"{\\i}}', +u'\xf0': '{\\dh}', +u'\xf1': '{\\~{n}}', +u'\xf2': '{\\`{o}}', +u'\xf3': "{\\'{o}}", +u'\xf4': '{\\^{o}}', +u'\xf5': '{\\~{o}}', +u'\xf6': '{\\"{o}}', +u'\xf7': '$\\div$', +u'\xf8': '{\\o}', +u'\xf9': '{\\`{u}}', +u'\xfa': "{\\'{u}}", +u'\xfb': '{\\^{u}}', +u'\xfc': '{\\"{u}}', +u'\xfd': "{\\'{y}}", +u'\xfe': '{\\th}', +u'\xff': '{\\"{y}}', +u'\u0100': '{\\={A}}', +u'\u0101': '{\\={a}}', +u'\u0102': '{\\u{A}}', +u'\u0103': '{\\u{a}}', +u'\u0104': '{\\k{A}}', +u'\u0105': '{\\k{a}}', +u'\u0106': "{\\'{C}}", +u'\u0107': "{\\'{c}}", +u'\u0108': '{\\^{C}}', +u'\u0109': '{\\^{c}}', +u'\u010a': '{\\.{C}}', +u'\u010b': '{\\.{c}}', +u'\u010c': '{\\v{C}}', +u'\u010d': '{\\v{c}}', +u'\u010e': '{\\v{D}}', +u'\u010f': '{\\v{d}}', +u'\u0110': '{\\DJ}', +u'\u0111': '{\\dj}', +u'\u0112': '{\\={E}}', +u'\u0113': '{\\={e}}', +u'\u0114': '{\\u{E}}', +u'\u0115': '{\\u{e}}', +u'\u0116': '{\\.{E}}', +u'\u0117': '{\\.{e}}', +u'\u0118': '{\\k{E}}', +u'\u0119': '{\\k{e}}', +u'\u011a': '{\\v{E}}', +u'\u011b': '{\\v{e}}', +u'\u011c': '{\\^{G}}', +u'\u011d': '{\\^{g}}', +u'\u011e': '{\\u{G}}', +u'\u011f': '{\\u{g}}', +u'\u0120': '{\\.{G}}', +u'\u0121': '{\\.{g}}', +u'\u0122': '{\\c{G}}', +u'\u0123': '{\\c{g}}', +u'\u0124': '{\\^{H}}', +u'\u0125': '{\\^{h}}', +u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', +u'\u0127': '$\\Elzxh$', +u'\u0128': '{\\~{I}}', +u'\u0129': '{\\~{\\i}}', +u'\u012a': '{\\={I}}', +u'\u012b': '{\\={\\i}}', +u'\u012c': '{\\u{I}}', +u'\u012d': '{\\u{\\i}}', +u'\u012e': '{\\k{I}}', +u'\u012f': '{\\k{i}}', +u'\u0130': '{\\.{I}}', +u'\u0131': '{\\i}', +u'\u0132': '{IJ}', +u'\u0133': '{ij}', +u'\u0134': '{\\^{J}}', +u'\u0135': '{\\^{\\j}}', +u'\u0136': '{\\c{K}}', +u'\u0137': '{\\c{k}}', +u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', +u'\u0139': "{\\'{L}}", +u'\u013a': "{\\'{l}}", +u'\u013b': '{\\c{L}}', +u'\u013c': '{\\c{l}}', +u'\u013d': '{\\v{L}}', +u'\u013e': '{\\v{l}}', +u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', +u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', +u'\u0141': '{\\L}', +u'\u0142': '{\\l}', +u'\u0143': "{\\'{N}}", +u'\u0144': "{\\'{n}}", +u'\u0145': '{\\c{N}}', +u'\u0146': '{\\c{n}}', +u'\u0147': '{\\v{N}}', +u'\u0148': '{\\v{n}}', +u'\u0149': "{'n}", +u'\u014a': '{\\NG}', +u'\u014b': '{\\ng}', +u'\u014c': '{\\={O}}', +u'\u014d': '{\\={o}}', +u'\u014e': '{\\u{O}}', +u'\u014f': '{\\u{o}}', +u'\u0150': '{\\H{O}}', +u'\u0151': '{\\H{o}}', +u'\u0152': '{\\OE}', +u'\u0153': '{\\oe}', +u'\u0154': "{\\'{R}}", +u'\u0155': "{\\'{r}}", +u'\u0156': '{\\c{R}}', +u'\u0157': '{\\c{r}}', +u'\u0158': '{\\v{R}}', +u'\u0159': '{\\v{r}}', +u'\u015a': "{\\'{S}}", +u'\u015b': "{\\'{s}}", +u'\u015c': '{\\^{S}}', +u'\u015d': '{\\^{s}}', +u'\u015e': '{\\c{S}}', +u'\u015f': '{\\c{s}}', +u'\u0160': '{\\v{S}}', +u'\u0161': '{\\v{s}}', +u'\u0162': '{\\c{T}}', +u'\u0163': '{\\c{t}}', +u'\u0164': '{\\v{T}}', +u'\u0165': '{\\v{t}}', +u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', +u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', +u'\u0168': '{\\~{U}}', +u'\u0169': '{\\~{u}}', +u'\u016a': '{\\={U}}', +u'\u016b': '{\\={u}}', +u'\u016c': '{\\u{U}}', +u'\u016d': '{\\u{u}}', +u'\u016e': '{\\r{U}}', +u'\u016f': '{\\r{u}}', +u'\u0170': '{\\H{U}}', +u'\u0171': '{\\H{u}}', +u'\u0172': '{\\k{U}}', +u'\u0173': '{\\k{u}}', +u'\u0174': '{\\^{W}}', +u'\u0175': '{\\^{w}}', +u'\u0176': '{\\^{Y}}', +u'\u0177': '{\\^{y}}', +u'\u0178': '{\\"{Y}}', +u'\u0179': "{\\'{Z}}", +u'\u017a': "{\\'{z}}", +u'\u017b': '{\\.{Z}}', +u'\u017c': '{\\.{z}}', +u'\u017d': '{\\v{Z}}', +u'\u017e': '{\\v{z}}', +u'\u0192': '$f$', +u'\u0195': '{\\texthvlig}', +u'\u019e': '{\\textnrleg}', +u'\u01aa': '$\\eth$', +u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', +u'\u01c2': '{\\textdoublepipe}', +u'\u01f5': "{\\'{g}}", +u'\u0250': '$\\Elztrna$', +u'\u0252': '$\\Elztrnsa$', +u'\u0254': '$\\Elzopeno$', +u'\u0256': '$\\Elzrtld$', +u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', +u'\u0259': '$\\Elzschwa$', +u'\u025b': '$\\varepsilon$', +u'\u0261': '{g}', +u'\u0263': '$\\Elzpgamma$', +u'\u0264': '$\\Elzpbgam$', +u'\u0265': '$\\Elztrnh$', +u'\u026c': '$\\Elzbtdl$', +u'\u026d': '$\\Elzrtll$', +u'\u026f': '$\\Elztrnm$', +u'\u0270': '$\\Elztrnmlr$', +u'\u0271': '$\\Elzltlmr$', +u'\u0272': '{\\Elzltln}', +u'\u0273': '$\\Elzrtln$', +u'\u0277': '$\\Elzclomeg$', +u'\u0278': '{\\textphi}', +u'\u0279': '$\\Elztrnr$', +u'\u027a': '$\\Elztrnrl$', +u'\u027b': '$\\Elzrttrnr$', +u'\u027c': '$\\Elzrl$', +u'\u027d': '$\\Elzrtlr$', +u'\u027e': '$\\Elzfhr$', +u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', +u'\u0282': '$\\Elzrtls$', +u'\u0283': '$\\Elzesh$', +u'\u0287': '$\\Elztrnt$', +u'\u0288': '$\\Elzrtlt$', +u'\u028a': '$\\Elzpupsil$', +u'\u028b': '$\\Elzpscrv$', +u'\u028c': '$\\Elzinvv$', +u'\u028d': '$\\Elzinvw$', +u'\u028e': '$\\Elztrny$', +u'\u0290': '$\\Elzrtlz$', +u'\u0292': '$\\Elzyogh$', +u'\u0294': '$\\Elzglst$', +u'\u0295': '$\\Elzreglst$', +u'\u0296': '$\\Elzinglst$', +u'\u029e': '{\\textturnk}', +u'\u02a4': '$\\Elzdyogh$', +u'\u02a7': '$\\Elztesh$', +u'\u02bc': "{'}", +u'\u02c7': '{\\textasciicaron}', +u'\u02c8': '$\\Elzverts$', +u'\u02cc': '$\\Elzverti$', +u'\u02d0': '$\\Elzlmrk$', +u'\u02d1': '$\\Elzhlmrk$', +u'\u02d2': '$\\Elzsbrhr$', +u'\u02d3': '$\\Elzsblhr$', +u'\u02d4': '$\\Elzrais$', +u'\u02d5': '$\\Elzlow$', +u'\u02d8': '{\\textasciibreve}', +u'\u02d9': '{\\textperiodcentered}', +u'\u02da': '{\\r{}}', +u'\u02db': '{\\k{}}', +u'\u02dc': '{\\texttildelow}', +u'\u02dd': '{\\H{}}', +u'\u02e5': '{\\tone{55}}', +u'\u02e6': '{\\tone{44}}', +u'\u02e7': '{\\tone{33}}', +u'\u02e8': '{\\tone{22}}', +u'\u02e9': '{\\tone{11}}', +u'\u0300': '{\\`}', +u'\u0301': "{\\'}", +u'\u0302': '{\\^}', +u'\u0303': '{\\~}', +u'\u0304': '{\\=}', +u'\u0306': '{\\u}', +u'\u0307': '{\\.}', +u'\u0308': '{\\"}', +u'\u030a': '{\\r}', +u'\u030b': '{\\H}', +u'\u030c': '{\\v}', +u'\u030f': '{\\cyrchar\\C}', +u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', +u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', +u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', +u'\u0321': '$\\Elzpalh$', +u'\u0322': '{\\Elzrh}', +u'\u0327': '{\\c}', +u'\u0328': '{\\k}', +u'\u032a': '$\\Elzsbbrg$', +u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', +u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', +u'\u0335': '{\\Elzxl}', +u'\u0336': '{\\Elzbar}', +u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', +u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', +u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', +u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', +u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', +u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', +u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', +u'\u0386': "{\\'{A}}", +u'\u0388': "{\\'{E}}", +u'\u0389': "{\\'{H}}", +u'\u038a': "{\\'{}{I}}", +u'\u038c': "{\\'{}O}", +u'\u038e': "$\\mathrm{'Y}$", +u'\u038f': "$\\mathrm{'\\Omega}$", +u'\u0390': '$\\acute{\\ddot{\\iota}}$', +u'\u0391': '$\\Alpha$', +u'\u0392': '$\\Beta$', +u'\u0393': '$\\Gamma$', +u'\u0394': '$\\Delta$', +u'\u0395': '$\\Epsilon$', +u'\u0396': '$\\Zeta$', +u'\u0397': '$\\Eta$', +u'\u0398': '$\\Theta$', +u'\u0399': '$\\Iota$', +u'\u039a': '$\\Kappa$', +u'\u039b': '$\\Lambda$', +u'\u039c': '$M$', +u'\u039d': '$N$', +u'\u039e': '$\\Xi$', +u'\u039f': '$O$', +u'\u03a0': '$\\Pi$', +u'\u03a1': '$\\Rho$', +u'\u03a3': '$\\Sigma$', +u'\u03a4': '$\\Tau$', +u'\u03a5': '$\\Upsilon$', +u'\u03a6': '$\\Phi$', +u'\u03a7': '$\\Chi$', +u'\u03a8': '$\\Psi$', +u'\u03a9': '$\\Omega$', +u'\u03aa': '$\\mathrm{\\ddot{I}}$', +u'\u03ab': '$\\mathrm{\\ddot{Y}}$', +u'\u03ac': "{\\'{$\\alpha$}}", +u'\u03ad': '$\\acute{\\epsilon}$', +u'\u03ae': '$\\acute{\\eta}$', +u'\u03af': '$\\acute{\\iota}$', +u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', +u'\u03b1': '$\\alpha$', +u'\u03b2': '$\\beta$', +u'\u03b3': '$\\gamma$', +u'\u03b4': '$\\delta$', +u'\u03b5': '$\\epsilon$', +u'\u03b6': '$\\zeta$', +u'\u03b7': '$\\eta$', +u'\u03b8': '{\\texttheta}', +u'\u03b9': '$\\iota$', +u'\u03ba': '$\\kappa$', +u'\u03bb': '$\\lambda$', +u'\u03bc': '$\\mu$', +u'\u03bd': '$\\nu$', +u'\u03be': '$\\xi$', +u'\u03bf': '$o$', +u'\u03c0': '$\\pi$', +u'\u03c1': '$\\rho$', +u'\u03c2': '$\\varsigma$', +u'\u03c3': '$\\sigma$', +u'\u03c4': '$\\tau$', +u'\u03c5': '$\\upsilon$', +u'\u03c6': '$\\varphi$', +u'\u03c7': '$\\chi$', +u'\u03c8': '$\\psi$', +u'\u03c9': '$\\omega$', +u'\u03ca': '$\\ddot{\\iota}$', +u'\u03cb': '$\\ddot{\\upsilon}$', +u'\u03cc': "{\\'{o}}", +u'\u03cd': '$\\acute{\\upsilon}$', +u'\u03ce': '$\\acute{\\omega}$', +u'\u03d0': '{\\Pisymbol{ppi022}{87}}', +u'\u03d1': '{\\textvartheta}', +u'\u03d2': '$\\Upsilon$', +u'\u03d5': '$\\phi$', +u'\u03d6': '$\\varpi$', +u'\u03da': '$\\Stigma$', +u'\u03dc': '$\\Digamma$', +u'\u03dd': '$\\digamma$', +u'\u03de': '$\\Koppa$', +u'\u03e0': '$\\Sampi$', +u'\u03f0': '$\\varkappa$', +u'\u03f1': '$\\varrho$', +u'\u03f4': '{\\textTheta}', +u'\u03f6': '$\\backepsilon$', +u'\u0401': '{\\cyrchar\\CYRYO}', +u'\u0402': '{\\cyrchar\\CYRDJE}', +u'\u0403': "{\\cyrchar{\\'\\CYRG}}", +u'\u0404': '{\\cyrchar\\CYRIE}', +u'\u0405': '{\\cyrchar\\CYRDZE}', +u'\u0406': '{\\cyrchar\\CYRII}', +u'\u0407': '{\\cyrchar\\CYRYI}', +u'\u0408': '{\\cyrchar\\CYRJE}', +u'\u0409': '{\\cyrchar\\CYRLJE}', +u'\u040a': '{\\cyrchar\\CYRNJE}', +u'\u040b': '{\\cyrchar\\CYRTSHE}', +u'\u040c': "{\\cyrchar{\\'\\CYRK}}", +u'\u040e': '{\\cyrchar\\CYRUSHRT}', +u'\u040f': '{\\cyrchar\\CYRDZHE}', +u'\u0410': '{\\cyrchar\\CYRA}', +u'\u0411': '{\\cyrchar\\CYRB}', +u'\u0412': '{\\cyrchar\\CYRV}', +u'\u0413': '{\\cyrchar\\CYRG}', +u'\u0414': '{\\cyrchar\\CYRD}', +u'\u0415': '{\\cyrchar\\CYRE}', +u'\u0416': '{\\cyrchar\\CYRZH}', +u'\u0417': '{\\cyrchar\\CYRZ}', +u'\u0418': '{\\cyrchar\\CYRI}', +u'\u0419': '{\\cyrchar\\CYRISHRT}', +u'\u041a': '{\\cyrchar\\CYRK}', +u'\u041b': '{\\cyrchar\\CYRL}', +u'\u041c': '{\\cyrchar\\CYRM}', +u'\u041d': '{\\cyrchar\\CYRN}', +u'\u041e': '{\\cyrchar\\CYRO}', +u'\u041f': '{\\cyrchar\\CYRP}', +u'\u0420': '{\\cyrchar\\CYRR}', +u'\u0421': '{\\cyrchar\\CYRS}', +u'\u0422': '{\\cyrchar\\CYRT}', +u'\u0423': '{\\cyrchar\\CYRU}', +u'\u0424': '{\\cyrchar\\CYRF}', +u'\u0425': '{\\cyrchar\\CYRH}', +u'\u0426': '{\\cyrchar\\CYRC}', +u'\u0427': '{\\cyrchar\\CYRCH}', +u'\u0428': '{\\cyrchar\\CYRSH}', +u'\u0429': '{\\cyrchar\\CYRSHCH}', +u'\u042a': '{\\cyrchar\\CYRHRDSN}', +u'\u042b': '{\\cyrchar\\CYRERY}', +u'\u042c': '{\\cyrchar\\CYRSFTSN}', +u'\u042d': '{\\cyrchar\\CYREREV}', +u'\u042e': '{\\cyrchar\\CYRYU}', +u'\u042f': '{\\cyrchar\\CYRYA}', +u'\u0430': '{\\cyrchar\\cyra}', +u'\u0431': '{\\cyrchar\\cyrb}', +u'\u0432': '{\\cyrchar\\cyrv}', +u'\u0433': '{\\cyrchar\\cyrg}', +u'\u0434': '{\\cyrchar\\cyrd}', +u'\u0435': '{\\cyrchar\\cyre}', +u'\u0436': '{\\cyrchar\\cyrzh}', +u'\u0437': '{\\cyrchar\\cyrz}', +u'\u0438': '{\\cyrchar\\cyri}', +u'\u0439': '{\\cyrchar\\cyrishrt}', +u'\u043a': '{\\cyrchar\\cyrk}', +u'\u043b': '{\\cyrchar\\cyrl}', +u'\u043c': '{\\cyrchar\\cyrm}', +u'\u043d': '{\\cyrchar\\cyrn}', +u'\u043e': '{\\cyrchar\\cyro}', +u'\u043f': '{\\cyrchar\\cyrp}', +u'\u0440': '{\\cyrchar\\cyrr}', +u'\u0441': '{\\cyrchar\\cyrs}', +u'\u0442': '{\\cyrchar\\cyrt}', +u'\u0443': '{\\cyrchar\\cyru}', +u'\u0444': '{\\cyrchar\\cyrf}', +u'\u0445': '{\\cyrchar\\cyrh}', +u'\u0446': '{\\cyrchar\\cyrc}', +u'\u0447': '{\\cyrchar\\cyrch}', +u'\u0448': '{\\cyrchar\\cyrsh}', +u'\u0449': '{\\cyrchar\\cyrshch}', +u'\u044a': '{\\cyrchar\\cyrhrdsn}', +u'\u044b': '{\\cyrchar\\cyrery}', +u'\u044c': '{\\cyrchar\\cyrsftsn}', +u'\u044d': '{\\cyrchar\\cyrerev}', +u'\u044e': '{\\cyrchar\\cyryu}', +u'\u044f': '{\\cyrchar\\cyrya}', +u'\u0451': '{\\cyrchar\\cyryo}', +u'\u0452': '{\\cyrchar\\cyrdje}', +u'\u0453': "{\\cyrchar{\\'\\cyrg}}", +u'\u0454': '{\\cyrchar\\cyrie}', +u'\u0455': '{\\cyrchar\\cyrdze}', +u'\u0456': '{\\cyrchar\\cyrii}', +u'\u0457': '{\\cyrchar\\cyryi}', +u'\u0458': '{\\cyrchar\\cyrje}', +u'\u0459': '{\\cyrchar\\cyrlje}', +u'\u045a': '{\\cyrchar\\cyrnje}', +u'\u045b': '{\\cyrchar\\cyrtshe}', +u'\u045c': "{\\cyrchar{\\'\\cyrk}}", +u'\u045e': '{\\cyrchar\\cyrushrt}', +u'\u045f': '{\\cyrchar\\cyrdzhe}', +u'\u0460': '{\\cyrchar\\CYROMEGA}', +u'\u0461': '{\\cyrchar\\cyromega}', +u'\u0462': '{\\cyrchar\\CYRYAT}', +u'\u0464': '{\\cyrchar\\CYRIOTE}', +u'\u0465': '{\\cyrchar\\cyriote}', +u'\u0466': '{\\cyrchar\\CYRLYUS}', +u'\u0467': '{\\cyrchar\\cyrlyus}', +u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', +u'\u0469': '{\\cyrchar\\cyriotlyus}', +u'\u046a': '{\\cyrchar\\CYRBYUS}', +u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', +u'\u046d': '{\\cyrchar\\cyriotbyus}', +u'\u046e': '{\\cyrchar\\CYRKSI}', +u'\u046f': '{\\cyrchar\\cyrksi}', +u'\u0470': '{\\cyrchar\\CYRPSI}', +u'\u0471': '{\\cyrchar\\cyrpsi}', +u'\u0472': '{\\cyrchar\\CYRFITA}', +u'\u0474': '{\\cyrchar\\CYRIZH}', +u'\u0478': '{\\cyrchar\\CYRUK}', +u'\u0479': '{\\cyrchar\\cyruk}', +u'\u047a': '{\\cyrchar\\CYROMEGARND}', +u'\u047b': '{\\cyrchar\\cyromegarnd}', +u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', +u'\u047d': '{\\cyrchar\\cyromegatitlo}', +u'\u047e': '{\\cyrchar\\CYROT}', +u'\u047f': '{\\cyrchar\\cyrot}', +u'\u0480': '{\\cyrchar\\CYRKOPPA}', +u'\u0481': '{\\cyrchar\\cyrkoppa}', +u'\u0482': '{\\cyrchar\\cyrthousands}', +u'\u0488': '{\\cyrchar\\cyrhundredthousands}', +u'\u0489': '{\\cyrchar\\cyrmillions}', +u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', +u'\u048d': '{\\cyrchar\\cyrsemisftsn}', +u'\u048e': '{\\cyrchar\\CYRRTICK}', +u'\u048f': '{\\cyrchar\\cyrrtick}', +u'\u0490': '{\\cyrchar\\CYRGUP}', +u'\u0491': '{\\cyrchar\\cyrgup}', +u'\u0492': '{\\cyrchar\\CYRGHCRS}', +u'\u0493': '{\\cyrchar\\cyrghcrs}', +u'\u0494': '{\\cyrchar\\CYRGHK}', +u'\u0495': '{\\cyrchar\\cyrghk}', +u'\u0496': '{\\cyrchar\\CYRZHDSC}', +u'\u0497': '{\\cyrchar\\cyrzhdsc}', +u'\u0498': '{\\cyrchar\\CYRZDSC}', +u'\u0499': '{\\cyrchar\\cyrzdsc}', +u'\u049a': '{\\cyrchar\\CYRKDSC}', +u'\u049b': '{\\cyrchar\\cyrkdsc}', +u'\u049c': '{\\cyrchar\\CYRKVCRS}', +u'\u049d': '{\\cyrchar\\cyrkvcrs}', +u'\u049e': '{\\cyrchar\\CYRKHCRS}', +u'\u049f': '{\\cyrchar\\cyrkhcrs}', +u'\u04a0': '{\\cyrchar\\CYRKBEAK}', +u'\u04a1': '{\\cyrchar\\cyrkbeak}', +u'\u04a2': '{\\cyrchar\\CYRNDSC}', +u'\u04a3': '{\\cyrchar\\cyrndsc}', +u'\u04a4': '{\\cyrchar\\CYRNG}', +u'\u04a5': '{\\cyrchar\\cyrng}', +u'\u04a6': '{\\cyrchar\\CYRPHK}', +u'\u04a7': '{\\cyrchar\\cyrphk}', +u'\u04a8': '{\\cyrchar\\CYRABHHA}', +u'\u04a9': '{\\cyrchar\\cyrabhha}', +u'\u04aa': '{\\cyrchar\\CYRSDSC}', +u'\u04ab': '{\\cyrchar\\cyrsdsc}', +u'\u04ac': '{\\cyrchar\\CYRTDSC}', +u'\u04ad': '{\\cyrchar\\cyrtdsc}', +u'\u04ae': '{\\cyrchar\\CYRY}', +u'\u04af': '{\\cyrchar\\cyry}', +u'\u04b0': '{\\cyrchar\\CYRYHCRS}', +u'\u04b1': '{\\cyrchar\\cyryhcrs}', +u'\u04b2': '{\\cyrchar\\CYRHDSC}', +u'\u04b3': '{\\cyrchar\\cyrhdsc}', +u'\u04b4': '{\\cyrchar\\CYRTETSE}', +u'\u04b5': '{\\cyrchar\\cyrtetse}', +u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', +u'\u04b7': '{\\cyrchar\\cyrchrdsc}', +u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', +u'\u04b9': '{\\cyrchar\\cyrchvcrs}', +u'\u04ba': '{\\cyrchar\\CYRSHHA}', +u'\u04bb': '{\\cyrchar\\cyrshha}', +u'\u04bc': '{\\cyrchar\\CYRABHCH}', +u'\u04bd': '{\\cyrchar\\cyrabhch}', +u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', +u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', +u'\u04c0': '{\\cyrchar\\CYRpalochka}', +u'\u04c3': '{\\cyrchar\\CYRKHK}', +u'\u04c4': '{\\cyrchar\\cyrkhk}', +u'\u04c7': '{\\cyrchar\\CYRNHK}', +u'\u04c8': '{\\cyrchar\\cyrnhk}', +u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', +u'\u04cc': '{\\cyrchar\\cyrchldsc}', +u'\u04d4': '{\\cyrchar\\CYRAE}', +u'\u04d5': '{\\cyrchar\\cyrae}', +u'\u04d8': '{\\cyrchar\\CYRSCHWA}', +u'\u04d9': '{\\cyrchar\\cyrschwa}', +u'\u04e0': '{\\cyrchar\\CYRABHDZE}', +u'\u04e1': '{\\cyrchar\\cyrabhdze}', +u'\u04e8': '{\\cyrchar\\CYROTLD}', +u'\u04e9': '{\\cyrchar\\cyrotld}', +u'\u2002': '{\\hspace{0.6em}}', +u'\u2003': '{\\hspace{1em}}', +u'\u2004': '{\\hspace{0.33em}}', +u'\u2005': '{\\hspace{0.25em}}', +u'\u2006': '{\\hspace{0.166em}}', +u'\u2007': '{\\hphantom{0}}', +u'\u2008': '{\\hphantom{,}}', +u'\u2009': '{\\hspace{0.167em}}', +u'\u200a': '$\\mkern1mu$', +u'\u2010': '{-}', +u'\u2013': '{\\textendash}', +u'\u2014': '{\\textemdash}', +u'\u2015': '{\\rule{1em}{1pt}}', +u'\u2016': '$\\Vert$', +u'\u2018': '{`}', +u'\u2019': "{'}", +u'\u201a': '{,}', +u'\u201b': '$\\Elzreapos$', +u'\u201c': '{\\textquotedblleft}', +u'\u201d': '{\\textquotedblright}', +u'\u201e': '{,,}', +u'\u2020': '{\\textdagger}', +u'\u2021': '{\\textdaggerdbl}', +u'\u2022': '{\\textbullet}', +u'\u2024': '{.}', +u'\u2025': '{..}', +u'\u2026': '{\\ldots}', +u'\u2030': '{\\textperthousand}', +u'\u2031': '{\\textpertenthousand}', +u'\u2032': "${'}$", +u'\u2033': "${''}$", +u'\u2034': "${'''}$", +u'\u2035': '$\\backprime$', +u'\u2039': '{\\guilsinglleft}', +u'\u203a': '{\\guilsinglright}', +u'\u2057': "$''''$", +u'\u205f': '{\\mkern4mu}', +u'\u2060': '{\\nolinebreak}', +u'\u20a7': '{\\ensuremath{\\Elzpes}}', +u'\u20ac': '{\\mbox{\\texteuro}}', +u'\u20db': '$\\dddot$', +u'\u20dc': '$\\ddddot$', +u'\u2102': '$\\mathbb{C}$', +u'\u210a': '{\\mathscr{g}}', +u'\u210b': '$\\mathscr{H}$', +u'\u210c': '$\\mathfrak{H}$', +u'\u210d': '$\\mathbb{H}$', +u'\u210f': '$\\hslash$', +u'\u2110': '$\\mathscr{I}$', +u'\u2111': '$\\mathfrak{I}$', +u'\u2112': '$\\mathscr{L}$', +u'\u2113': '$\\mathscr{l}$', +u'\u2115': '$\\mathbb{N}$', +u'\u2116': '{\\cyrchar\\textnumero}', +u'\u2118': '$\\wp$', +u'\u2119': '$\\mathbb{P}$', +u'\u211a': '$\\mathbb{Q}$', +u'\u211b': '$\\mathscr{R}$', +u'\u211c': '$\\mathfrak{R}$', +u'\u211d': '$\\mathbb{R}$', +u'\u211e': '$\\Elzxrat$', +u'\u2122': '{\\texttrademark}', +u'\u2124': '$\\mathbb{Z}$', +u'\u2126': '$\\Omega$', +u'\u2127': '$\\mho$', +u'\u2128': '$\\mathfrak{Z}$', +u'\u2129': '$\\ElsevierGlyph{2129}$', +u'\u212b': '{\\AA}', +u'\u212c': '$\\mathscr{B}$', +u'\u212d': '$\\mathfrak{C}$', +u'\u212f': '$\\mathscr{e}$', +u'\u2130': '$\\mathscr{E}$', +u'\u2131': '$\\mathscr{F}$', +u'\u2133': '$\\mathscr{M}$', +u'\u2134': '$\\mathscr{o}$', +u'\u2135': '$\\aleph$', +u'\u2136': '$\\beth$', +u'\u2137': '$\\gimel$', +u'\u2138': '$\\daleth$', +u'\u2153': '$\\textfrac{1}{3}$', +u'\u2154': '$\\textfrac{2}{3}$', +u'\u2155': '$\\textfrac{1}{5}$', +u'\u2156': '$\\textfrac{2}{5}$', +u'\u2157': '$\\textfrac{3}{5}$', +u'\u2158': '$\\textfrac{4}{5}$', +u'\u2159': '$\\textfrac{1}{6}$', +u'\u215a': '$\\textfrac{5}{6}$', +u'\u215b': '$\\textfrac{1}{8}$', +u'\u215c': '$\\textfrac{3}{8}$', +u'\u215d': '$\\textfrac{5}{8}$', +u'\u215e': '$\\textfrac{7}{8}$', +u'\u2190': '$\\leftarrow$', +u'\u2191': '$\\uparrow$', +u'\u2192': '$\\rightarrow$', +u'\u2193': '$\\downarrow$', +u'\u2194': '$\\leftrightarrow$', +u'\u2195': '$\\updownarrow$', +u'\u2196': '$\\nwarrow$', +u'\u2197': '$\\nearrow$', +u'\u2198': '$\\searrow$', +u'\u2199': '$\\swarrow$', +u'\u219a': '$\\nleftarrow$', +u'\u219b': '$\\nrightarrow$', +u'\u219c': '$\\arrowwaveright$', +u'\u219d': '$\\arrowwaveright$', +u'\u219e': '$\\twoheadleftarrow$', +u'\u21a0': '$\\twoheadrightarrow$', +u'\u21a2': '$\\leftarrowtail$', +u'\u21a3': '$\\rightarrowtail$', +u'\u21a6': '$\\mapsto$', +u'\u21a9': '$\\hookleftarrow$', +u'\u21aa': '$\\hookrightarrow$', +u'\u21ab': '$\\looparrowleft$', +u'\u21ac': '$\\looparrowright$', +u'\u21ad': '$\\leftrightsquigarrow$', +u'\u21ae': '$\\nleftrightarrow$', +u'\u21b0': '$\\Lsh$', +u'\u21b1': '$\\Rsh$', +u'\u21b3': '$\\ElsevierGlyph{21B3}$', +u'\u21b6': '$\\curvearrowleft$', +u'\u21b7': '$\\curvearrowright$', +u'\u21ba': '$\\circlearrowleft$', +u'\u21bb': '$\\circlearrowright$', +u'\u21bc': '$\\leftharpoonup$', +u'\u21bd': '$\\leftharpoondown$', +u'\u21be': '$\\upharpoonright$', +u'\u21bf': '$\\upharpoonleft$', +u'\u21c0': '$\\rightharpoonup$', +u'\u21c1': '$\\rightharpoondown$', +u'\u21c2': '$\\downharpoonright$', +u'\u21c3': '$\\downharpoonleft$', +u'\u21c4': '$\\rightleftarrows$', +u'\u21c5': '$\\dblarrowupdown$', +u'\u21c6': '$\\leftrightarrows$', +u'\u21c7': '$\\leftleftarrows$', +u'\u21c8': '$\\upuparrows$', +u'\u21c9': '$\\rightrightarrows$', +u'\u21ca': '$\\downdownarrows$', +u'\u21cb': '$\\leftrightharpoons$', +u'\u21cc': '$\\rightleftharpoons$', +u'\u21cd': '$\\nLeftarrow$', +u'\u21ce': '$\\nLeftrightarrow$', +u'\u21cf': '$\\nRightarrow$', +u'\u21d0': '$\\Leftarrow$', +u'\u21d1': '$\\Uparrow$', +u'\u21d2': '$\\Rightarrow$', +u'\u21d3': '$\\Downarrow$', +u'\u21d4': '$\\Leftrightarrow$', +u'\u21d5': '$\\Updownarrow$', +u'\u21da': '$\\Lleftarrow$', +u'\u21db': '$\\Rrightarrow$', +u'\u21dd': '$\\rightsquigarrow$', +u'\u21f5': '$\\DownArrowUpArrow$', +u'\u2200': '$\\forall$', +u'\u2201': '$\\complement$', +u'\u2202': '$\\partial$', +u'\u2203': '$\\exists$', +u'\u2204': '$\\nexists$', +u'\u2205': '$\\varnothing$', +u'\u2207': '$\\nabla$', +u'\u2208': '$\\in$', +u'\u2209': '$\\not\\in$', +u'\u220b': '$\\ni$', +u'\u220c': '$\\not\\ni$', +u'\u220f': '$\\prod$', +u'\u2210': '$\\coprod$', +u'\u2211': '$\\sum$', +u'\u2212': '{-}', +u'\u2213': '$\\mp$', +u'\u2214': '$\\dotplus$', +u'\u2216': '$\\setminus$', +u'\u2217': '${_\\ast}$', +u'\u2218': '$\\circ$', +u'\u2219': '$\\bullet$', +u'\u221a': '$\\surd$', +u'\u221d': '$\\propto$', +u'\u221e': '$\\infty$', +u'\u221f': '$\\rightangle$', +u'\u2220': '$\\angle$', +u'\u2221': '$\\measuredangle$', +u'\u2222': '$\\sphericalangle$', +u'\u2223': '$\\mid$', +u'\u2224': '$\\nmid$', +u'\u2225': '$\\parallel$', +u'\u2226': '$\\nparallel$', +u'\u2227': '$\\wedge$', +u'\u2228': '$\\vee$', +u'\u2229': '$\\cap$', +u'\u222a': '$\\cup$', +u'\u222b': '$\\int$', +u'\u222c': '$\\int\\!\\int$', +u'\u222d': '$\\int\\!\\int\\!\\int$', +u'\u222e': '$\\oint$', +u'\u222f': '$\\surfintegral$', +u'\u2230': '$\\volintegral$', +u'\u2231': '$\\clwintegral$', +u'\u2232': '$\\ElsevierGlyph{2232}$', +u'\u2233': '$\\ElsevierGlyph{2233}$', +u'\u2234': '$\\therefore$', +u'\u2235': '$\\because$', +u'\u2237': '$\\Colon$', +u'\u2238': '$\\ElsevierGlyph{2238}$', +u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', +u'\u223b': '$\\homothetic$', +u'\u223c': '$\\sim$', +u'\u223d': '$\\backsim$', +u'\u223e': '$\\lazysinv$', +u'\u2240': '$\\wr$', +u'\u2241': '$\\not\\sim$', +u'\u2242': '$\\ElsevierGlyph{2242}$', +u'\u2243': '$\\simeq$', +u'\u2244': '$\\not\\simeq$', +u'\u2245': '$\\cong$', +u'\u2246': '$\\approxnotequal$', +u'\u2247': '$\\not\\cong$', +u'\u2248': '$\\approx$', +u'\u2249': '$\\not\\approx$', +u'\u224a': '$\\approxeq$', +u'\u224b': '$\\tildetrpl$', +u'\u224c': '$\\allequal$', +u'\u224d': '$\\asymp$', +u'\u224e': '$\\Bumpeq$', +u'\u224f': '$\\bumpeq$', +u'\u2250': '$\\doteq$', +u'\u2251': '$\\doteqdot$', +u'\u2252': '$\\fallingdotseq$', +u'\u2253': '$\\risingdotseq$', +u'\u2254': '{:=}', +u'\u2255': '$=:$', +u'\u2256': '$\\eqcirc$', +u'\u2257': '$\\circeq$', +u'\u2259': '$\\estimates$', +u'\u225a': '$\\ElsevierGlyph{225A}$', +u'\u225b': '$\\starequal$', +u'\u225c': '$\\triangleq$', +u'\u225f': '$\\ElsevierGlyph{225F}$', +u'\u2260': '$\\not =$', +u'\u2261': '$\\equiv$', +u'\u2262': '$\\not\\equiv$', +u'\u2264': '$\\leq$', +u'\u2265': '$\\geq$', +u'\u2266': '$\\leqq$', +u'\u2267': '$\\geqq$', +u'\u2268': '$\\lneqq$', +u'\u2269': '$\\gneqq$', +u'\u226a': '$\\ll$', +u'\u226b': '$\\gg$', +u'\u226c': '$\\between$', +u'\u226d': '$\\not\\kern-0.3em\\times$', +u'\u226e': '$\\not<$', +u'\u226f': '$\\not>$', +u'\u2270': '$\\not\\leq$', +u'\u2271': '$\\not\\geq$', +u'\u2272': '$\\lessequivlnt$', +u'\u2273': '$\\greaterequivlnt$', +u'\u2274': '$\\ElsevierGlyph{2274}$', +u'\u2275': '$\\ElsevierGlyph{2275}$', +u'\u2276': '$\\lessgtr$', +u'\u2277': '$\\gtrless$', +u'\u2278': '$\\notlessgreater$', +u'\u2279': '$\\notgreaterless$', +u'\u227a': '$\\prec$', +u'\u227b': '$\\succ$', +u'\u227c': '$\\preccurlyeq$', +u'\u227d': '$\\succcurlyeq$', +u'\u227e': '$\\precapprox$', +u'\u227f': '$\\succapprox$', +u'\u2280': '$\\not\\prec$', +u'\u2281': '$\\not\\succ$', +u'\u2282': '$\\subset$', +u'\u2283': '$\\supset$', +u'\u2284': '$\\not\\subset$', +u'\u2285': '$\\not\\supset$', +u'\u2286': '$\\subseteq$', +u'\u2287': '$\\supseteq$', +u'\u2288': '$\\not\\subseteq$', +u'\u2289': '$\\not\\supseteq$', +u'\u228a': '$\\subsetneq$', +u'\u228b': '$\\supsetneq$', +u'\u228e': '$\\uplus$', +u'\u228f': '$\\sqsubset$', +u'\u2290': '$\\sqsupset$', +u'\u2291': '$\\sqsubseteq$', +u'\u2292': '$\\sqsupseteq$', +u'\u2293': '$\\sqcap$', +u'\u2294': '$\\sqcup$', +u'\u2295': '$\\oplus$', +u'\u2296': '$\\ominus$', +u'\u2297': '$\\otimes$', +u'\u2298': '$\\oslash$', +u'\u2299': '$\\odot$', +u'\u229a': '$\\circledcirc$', +u'\u229b': '$\\circledast$', +u'\u229d': '$\\circleddash$', +u'\u229e': '$\\boxplus$', +u'\u229f': '$\\boxminus$', +u'\u22a0': '$\\boxtimes$', +u'\u22a1': '$\\boxdot$', +u'\u22a2': '$\\vdash$', +u'\u22a3': '$\\dashv$', +u'\u22a4': '$\\top$', +u'\u22a5': '$\\perp$', +u'\u22a7': '$\\truestate$', +u'\u22a8': '$\\forcesextra$', +u'\u22a9': '$\\Vdash$', +u'\u22aa': '$\\Vvdash$', +u'\u22ab': '$\\VDash$', +u'\u22ac': '$\\nvdash$', +u'\u22ad': '$\\nvDash$', +u'\u22ae': '$\\nVdash$', +u'\u22af': '$\\nVDash$', +u'\u22b2': '$\\vartriangleleft$', +u'\u22b3': '$\\vartriangleright$', +u'\u22b4': '$\\trianglelefteq$', +u'\u22b5': '$\\trianglerighteq$', +u'\u22b6': '$\\original$', +u'\u22b7': '$\\image$', +u'\u22b8': '$\\multimap$', +u'\u22b9': '$\\hermitconjmatrix$', +u'\u22ba': '$\\intercal$', +u'\u22bb': '$\\veebar$', +u'\u22be': '$\\rightanglearc$', +u'\u22c0': '$\\ElsevierGlyph{22C0}$', +u'\u22c1': '$\\ElsevierGlyph{22C1}$', +u'\u22c2': '$\\bigcap$', +u'\u22c3': '$\\bigcup$', +u'\u22c4': '$\\diamond$', +u'\u22c5': '$\\cdot$', +u'\u22c6': '$\\star$', +u'\u22c7': '$\\divideontimes$', +u'\u22c8': '$\\bowtie$', +u'\u22c9': '$\\ltimes$', +u'\u22ca': '$\\rtimes$', +u'\u22cb': '$\\leftthreetimes$', +u'\u22cc': '$\\rightthreetimes$', +u'\u22cd': '$\\backsimeq$', +u'\u22ce': '$\\curlyvee$', +u'\u22cf': '$\\curlywedge$', +u'\u22d0': '$\\Subset$', +u'\u22d1': '$\\Supset$', +u'\u22d2': '$\\Cap$', +u'\u22d3': '$\\Cup$', +u'\u22d4': '$\\pitchfork$', +u'\u22d6': '$\\lessdot$', +u'\u22d7': '$\\gtrdot$', +u'\u22d8': '$\\verymuchless$', +u'\u22d9': '$\\verymuchgreater$', +u'\u22da': '$\\lesseqgtr$', +u'\u22db': '$\\gtreqless$', +u'\u22de': '$\\curlyeqprec$', +u'\u22df': '$\\curlyeqsucc$', +u'\u22e2': '$\\not\\sqsubseteq$', +u'\u22e3': '$\\not\\sqsupseteq$', +u'\u22e5': '$\\Elzsqspne$', +u'\u22e6': '$\\lnsim$', +u'\u22e7': '$\\gnsim$', +u'\u22e8': '$\\precedesnotsimilar$', +u'\u22e9': '$\\succnsim$', +u'\u22ea': '$\\ntriangleleft$', +u'\u22eb': '$\\ntriangleright$', +u'\u22ec': '$\\ntrianglelefteq$', +u'\u22ed': '$\\ntrianglerighteq$', +u'\u22ee': '$\\vdots$', +u'\u22ef': '$\\cdots$', +u'\u22f0': '$\\upslopeellipsis$', +u'\u22f1': '$\\downslopeellipsis$', +u'\u2305': '{\\barwedge}', +u'\u2306': '$\\perspcorrespond$', +u'\u2308': '$\\lceil$', +u'\u2309': '$\\rceil$', +u'\u230a': '$\\lfloor$', +u'\u230b': '$\\rfloor$', +u'\u2315': '$\\recorder$', +u'\u2316': '$\\mathchar"2208$', +u'\u231c': '$\\ulcorner$', +u'\u231d': '$\\urcorner$', +u'\u231e': '$\\llcorner$', +u'\u231f': '$\\lrcorner$', +u'\u2322': '$\\frown$', +u'\u2323': '$\\smile$', +u'\u2329': '$\\langle$', +u'\u232a': '$\\rangle$', +u'\u233d': '$\\ElsevierGlyph{E838}$', +u'\u23a3': '$\\Elzdlcorn$', +u'\u23b0': '$\\lmoustache$', +u'\u23b1': '$\\rmoustache$', +u'\u2423': '{\\textvisiblespace}', +u'\u2460': '{\\ding{172}}', +u'\u2461': '{\\ding{173}}', +u'\u2462': '{\\ding{174}}', +u'\u2463': '{\\ding{175}}', +u'\u2464': '{\\ding{176}}', +u'\u2465': '{\\ding{177}}', +u'\u2466': '{\\ding{178}}', +u'\u2467': '{\\ding{179}}', +u'\u2468': '{\\ding{180}}', +u'\u2469': '{\\ding{181}}', +u'\u24c8': '$\\circledS$', +u'\u2506': '$\\Elzdshfnc$', +u'\u2519': '$\\Elzsqfnw$', +u'\u2571': '$\\diagup$', +u'\u25a0': '{\\ding{110}}', +u'\u25a1': '$\\square$', +u'\u25aa': '$\\blacksquare$', +u'\u25ad': '$\\fbox{~~}$', +u'\u25af': '$\\Elzvrecto$', +u'\u25b1': '$\\ElsevierGlyph{E381}$', +u'\u25b2': '{\\ding{115}}', +u'\u25b3': '$\\bigtriangleup$', +u'\u25b4': '$\\blacktriangle$', +u'\u25b5': '$\\vartriangle$', +u'\u25b8': '$\\blacktriangleright$', +u'\u25b9': '$\\triangleright$', +u'\u25bc': '{\\ding{116}}', +u'\u25bd': '$\\bigtriangledown$', +u'\u25be': '$\\blacktriangledown$', +u'\u25bf': '$\\triangledown$', +u'\u25c2': '$\\blacktriangleleft$', +u'\u25c3': '$\\triangleleft$', +u'\u25c6': '{\\ding{117}}', +u'\u25ca': '$\\lozenge$', +u'\u25cb': '$\\bigcirc$', +u'\u25cf': '{\\ding{108}}', +u'\u25d0': '$\\Elzcirfl$', +u'\u25d1': '$\\Elzcirfr$', +u'\u25d2': '$\\Elzcirfb$', +u'\u25d7': '{\\ding{119}}', +u'\u25d8': '$\\Elzrvbull$', +u'\u25e7': '$\\Elzsqfl$', +u'\u25e8': '$\\Elzsqfr$', +u'\u25ea': '$\\Elzsqfse$', +u'\u25ef': '$\\bigcirc$', +u'\u2605': '{\\ding{72}}', +u'\u2606': '{\\ding{73}}', +u'\u260e': '{\\ding{37}}', +u'\u261b': '{\\ding{42}}', +u'\u261e': '{\\ding{43}}', +u'\u263e': '{\\rightmoon}', +u'\u263f': '{\\mercury}', +u'\u2640': '{\\venus}', +u'\u2642': '{\\male}', +u'\u2643': '{\\jupiter}', +u'\u2644': '{\\saturn}', +u'\u2645': '{\\uranus}', +u'\u2646': '{\\neptune}', +u'\u2647': '{\\pluto}', +u'\u2648': '{\\aries}', +u'\u2649': '{\\taurus}', +u'\u264a': '{\\gemini}', +u'\u264b': '{\\cancer}', +u'\u264c': '{\\leo}', +u'\u264d': '{\\virgo}', +u'\u264e': '{\\libra}', +u'\u264f': '{\\scorpio}', +u'\u2650': '{\\sagittarius}', +u'\u2651': '{\\capricornus}', +u'\u2652': '{\\aquarius}', +u'\u2653': '{\\pisces}', +u'\u2660': '{\\ding{171}}', +u'\u2662': '$\\diamond$', +u'\u2663': '{\\ding{168}}', +u'\u2665': '{\\ding{170}}', +u'\u2666': '{\\ding{169}}', +u'\u2669': '{\\quarternote}', +u'\u266a': '{\\eighthnote}', +u'\u266d': '$\\flat$', +u'\u266e': '$\\natural$', +u'\u266f': '$\\sharp$', +u'\u2701': '{\\ding{33}}', +u'\u2702': '{\\ding{34}}', +u'\u2703': '{\\ding{35}}', +u'\u2704': '{\\ding{36}}', +u'\u2706': '{\\ding{38}}', +u'\u2707': '{\\ding{39}}', +u'\u2708': '{\\ding{40}}', +u'\u2709': '{\\ding{41}}', +u'\u270c': '{\\ding{44}}', +u'\u270d': '{\\ding{45}}', +u'\u270e': '{\\ding{46}}', +u'\u270f': '{\\ding{47}}', +u'\u2710': '{\\ding{48}}', +u'\u2711': '{\\ding{49}}', +u'\u2712': '{\\ding{50}}', +u'\u2713': '{\\ding{51}}', +u'\u2714': '{\\ding{52}}', +u'\u2715': '{\\ding{53}}', +u'\u2716': '{\\ding{54}}', +u'\u2717': '{\\ding{55}}', +u'\u2718': '{\\ding{56}}', +u'\u2719': '{\\ding{57}}', +u'\u271a': '{\\ding{58}}', +u'\u271b': '{\\ding{59}}', +u'\u271c': '{\\ding{60}}', +u'\u271d': '{\\ding{61}}', +u'\u271e': '{\\ding{62}}', +u'\u271f': '{\\ding{63}}', +u'\u2720': '{\\ding{64}}', +u'\u2721': '{\\ding{65}}', +u'\u2722': '{\\ding{66}}', +u'\u2723': '{\\ding{67}}', +u'\u2724': '{\\ding{68}}', +u'\u2725': '{\\ding{69}}', +u'\u2726': '{\\ding{70}}', +u'\u2727': '{\\ding{71}}', +u'\u2729': '{\\ding{73}}', +u'\u272a': '{\\ding{74}}', +u'\u272b': '{\\ding{75}}', +u'\u272c': '{\\ding{76}}', +u'\u272d': '{\\ding{77}}', +u'\u272e': '{\\ding{78}}', +u'\u272f': '{\\ding{79}}', +u'\u2730': '{\\ding{80}}', +u'\u2731': '{\\ding{81}}', +u'\u2732': '{\\ding{82}}', +u'\u2733': '{\\ding{83}}', +u'\u2734': '{\\ding{84}}', +u'\u2735': '{\\ding{85}}', +u'\u2736': '{\\ding{86}}', +u'\u2737': '{\\ding{87}}', +u'\u2738': '{\\ding{88}}', +u'\u2739': '{\\ding{89}}', +u'\u273a': '{\\ding{90}}', +u'\u273b': '{\\ding{91}}', +u'\u273c': '{\\ding{92}}', +u'\u273d': '{\\ding{93}}', +u'\u273e': '{\\ding{94}}', +u'\u273f': '{\\ding{95}}', +u'\u2740': '{\\ding{96}}', +u'\u2741': '{\\ding{97}}', +u'\u2742': '{\\ding{98}}', +u'\u2743': '{\\ding{99}}', +u'\u2744': '{\\ding{100}}', +u'\u2745': '{\\ding{101}}', +u'\u2746': '{\\ding{102}}', +u'\u2747': '{\\ding{103}}', +u'\u2748': '{\\ding{104}}', +u'\u2749': '{\\ding{105}}', +u'\u274a': '{\\ding{106}}', +u'\u274b': '{\\ding{107}}', +u'\u274d': '{\\ding{109}}', +u'\u274f': '{\\ding{111}}', +u'\u2750': '{\\ding{112}}', +u'\u2751': '{\\ding{113}}', +u'\u2752': '{\\ding{114}}', +u'\u2756': '{\\ding{118}}', +u'\u2758': '{\\ding{120}}', +u'\u2759': '{\\ding{121}}', +u'\u275a': '{\\ding{122}}', +u'\u275b': '{\\ding{123}}', +u'\u275c': '{\\ding{124}}', +u'\u275d': '{\\ding{125}}', +u'\u275e': '{\\ding{126}}', +u'\u2761': '{\\ding{161}}', +u'\u2762': '{\\ding{162}}', +u'\u2763': '{\\ding{163}}', +u'\u2764': '{\\ding{164}}', +u'\u2765': '{\\ding{165}}', +u'\u2766': '{\\ding{166}}', +u'\u2767': '{\\ding{167}}', +u'\u2776': '{\\ding{182}}', +u'\u2777': '{\\ding{183}}', +u'\u2778': '{\\ding{184}}', +u'\u2779': '{\\ding{185}}', +u'\u277a': '{\\ding{186}}', +u'\u277b': '{\\ding{187}}', +u'\u277c': '{\\ding{188}}', +u'\u277d': '{\\ding{189}}', +u'\u277e': '{\\ding{190}}', +u'\u277f': '{\\ding{191}}', +u'\u2780': '{\\ding{192}}', +u'\u2781': '{\\ding{193}}', +u'\u2782': '{\\ding{194}}', +u'\u2783': '{\\ding{195}}', +u'\u2784': '{\\ding{196}}', +u'\u2785': '{\\ding{197}}', +u'\u2786': '{\\ding{198}}', +u'\u2787': '{\\ding{199}}', +u'\u2788': '{\\ding{200}}', +u'\u2789': '{\\ding{201}}', +u'\u278a': '{\\ding{202}}', +u'\u278b': '{\\ding{203}}', +u'\u278c': '{\\ding{204}}', +u'\u278d': '{\\ding{205}}', +u'\u278e': '{\\ding{206}}', +u'\u278f': '{\\ding{207}}', +u'\u2790': '{\\ding{208}}', +u'\u2791': '{\\ding{209}}', +u'\u2792': '{\\ding{210}}', +u'\u2793': '{\\ding{211}}', +u'\u2794': '{\\ding{212}}', +u'\u2798': '{\\ding{216}}', +u'\u2799': '{\\ding{217}}', +u'\u279a': '{\\ding{218}}', +u'\u279b': '{\\ding{219}}', +u'\u279c': '{\\ding{220}}', +u'\u279d': '{\\ding{221}}', +u'\u279e': '{\\ding{222}}', +u'\u279f': '{\\ding{223}}', +u'\u27a0': '{\\ding{224}}', +u'\u27a1': '{\\ding{225}}', +u'\u27a2': '{\\ding{226}}', +u'\u27a3': '{\\ding{227}}', +u'\u27a4': '{\\ding{228}}', +u'\u27a5': '{\\ding{229}}', +u'\u27a6': '{\\ding{230}}', +u'\u27a7': '{\\ding{231}}', +u'\u27a8': '{\\ding{232}}', +u'\u27a9': '{\\ding{233}}', +u'\u27aa': '{\\ding{234}}', +u'\u27ab': '{\\ding{235}}', +u'\u27ac': '{\\ding{236}}', +u'\u27ad': '{\\ding{237}}', +u'\u27ae': '{\\ding{238}}', +u'\u27af': '{\\ding{239}}', +u'\u27b1': '{\\ding{241}}', +u'\u27b2': '{\\ding{242}}', +u'\u27b3': '{\\ding{243}}', +u'\u27b4': '{\\ding{244}}', +u'\u27b5': '{\\ding{245}}', +u'\u27b6': '{\\ding{246}}', +u'\u27b7': '{\\ding{247}}', +u'\u27b8': '{\\ding{248}}', +u'\u27b9': '{\\ding{249}}', +u'\u27ba': '{\\ding{250}}', +u'\u27bb': '{\\ding{251}}', +u'\u27bc': '{\\ding{252}}', +u'\u27bd': '{\\ding{253}}', +u'\u27be': '{\\ding{254}}', +u'\u27f5': '$\\longleftarrow$', +u'\u27f6': '$\\longrightarrow$', +u'\u27f7': '$\\longleftrightarrow$', +u'\u27f8': '$\\Longleftarrow$', +u'\u27f9': '$\\Longrightarrow$', +u'\u27fa': '$\\Longleftrightarrow$', +u'\u27fc': '$\\longmapsto$', +u'\u27ff': '$\\sim\\joinrel\\leadsto$', +u'\u2905': '$\\ElsevierGlyph{E212}$', +u'\u2912': '$\\UpArrowBar$', +u'\u2913': '$\\DownArrowBar$', +u'\u2923': '$\\ElsevierGlyph{E20C}$', +u'\u2924': '$\\ElsevierGlyph{E20D}$', +u'\u2925': '$\\ElsevierGlyph{E20B}$', +u'\u2926': '$\\ElsevierGlyph{E20A}$', +u'\u2927': '$\\ElsevierGlyph{E211}$', +u'\u2928': '$\\ElsevierGlyph{E20E}$', +u'\u2929': '$\\ElsevierGlyph{E20F}$', +u'\u292a': '$\\ElsevierGlyph{E210}$', +u'\u2933': '$\\ElsevierGlyph{E21C}$', +u'\u2936': '$\\ElsevierGlyph{E21A}$', +u'\u2937': '$\\ElsevierGlyph{E219}$', +u'\u2940': '$\\Elolarr$', +u'\u2941': '$\\Elorarr$', +u'\u2942': '$\\ElzRlarr$', +u'\u2944': '$\\ElzrLarr$', +u'\u2947': '$\\Elzrarrx$', +u'\u294e': '$\\LeftRightVector$', +u'\u294f': '$\\RightUpDownVector$', +u'\u2950': '$\\DownLeftRightVector$', +u'\u2951': '$\\LeftUpDownVector$', +u'\u2952': '$\\LeftVectorBar$', +u'\u2953': '$\\RightVectorBar$', +u'\u2954': '$\\RightUpVectorBar$', +u'\u2955': '$\\RightDownVectorBar$', +u'\u2956': '$\\DownLeftVectorBar$', +u'\u2957': '$\\DownRightVectorBar$', +u'\u2958': '$\\LeftUpVectorBar$', +u'\u2959': '$\\LeftDownVectorBar$', +u'\u295a': '$\\LeftTeeVector$', +u'\u295b': '$\\RightTeeVector$', +u'\u295c': '$\\RightUpTeeVector$', +u'\u295d': '$\\RightDownTeeVector$', +u'\u295e': '$\\DownLeftTeeVector$', +u'\u295f': '$\\DownRightTeeVector$', +u'\u2960': '$\\LeftUpTeeVector$', +u'\u2961': '$\\LeftDownTeeVector$', +u'\u296e': '$\\UpEquilibrium$', +u'\u296f': '$\\ReverseUpEquilibrium$', +u'\u2970': '$\\RoundImplies$', +u'\u297c': '$\\ElsevierGlyph{E214}$', +u'\u297d': '$\\ElsevierGlyph{E215}$', +u'\u2980': '$\\Elztfnc$', +u'\u2985': '$\\ElsevierGlyph{3018}$', +u'\u2986': '$\\Elroang$', +u'\u2993': '$<\\kern-0.58em($', +u'\u2994': '$\\ElsevierGlyph{E291}$', +u'\u2999': '$\\Elzddfnc$', +u'\u299c': '$\\Angle$', +u'\u29a0': '$\\Elzlpargt$', +u'\u29b5': '$\\ElsevierGlyph{E260}$', +u'\u29b6': '$\\ElsevierGlyph{E61B}$', +u'\u29ca': '$\\ElzLap$', +u'\u29cb': '$\\Elzdefas$', +u'\u29cf': '$\\LeftTriangleBar$', +u'\u29d0': '$\\RightTriangleBar$', +u'\u29dc': '$\\ElsevierGlyph{E372}$', +u'\u29eb': '$\\blacklozenge$', +u'\u29f4': '$\\RuleDelayed$', +u'\u2a04': '$\\Elxuplus$', +u'\u2a05': '$\\ElzThr$', +u'\u2a06': '$\\Elxsqcup$', +u'\u2a07': '$\\ElzInf$', +u'\u2a08': '$\\ElzSup$', +u'\u2a0d': '$\\ElzCint$', +u'\u2a0f': '$\\clockoint$', +u'\u2a10': '$\\ElsevierGlyph{E395}$', +u'\u2a16': '$\\sqrint$', +u'\u2a25': '$\\ElsevierGlyph{E25A}$', +u'\u2a2a': '$\\ElsevierGlyph{E25B}$', +u'\u2a2d': '$\\ElsevierGlyph{E25C}$', +u'\u2a2e': '$\\ElsevierGlyph{E25D}$', +u'\u2a2f': '$\\ElzTimes$', +u'\u2a34': '$\\ElsevierGlyph{E25E}$', +u'\u2a35': '$\\ElsevierGlyph{E25E}$', +u'\u2a3c': '$\\ElsevierGlyph{E259}$', +u'\u2a3f': '$\\amalg$', +u'\u2a53': '$\\ElzAnd$', +u'\u2a54': '$\\ElzOr$', +u'\u2a55': '$\\ElsevierGlyph{E36E}$', +u'\u2a56': '$\\ElOr$', +u'\u2a5e': '$\\perspcorrespond$', +u'\u2a5f': '$\\Elzminhat$', +u'\u2a63': '$\\ElsevierGlyph{225A}$', +u'\u2a6e': '$\\stackrel{*}{=}$', +u'\u2a75': '$\\Equal$', +u'\u2a7d': '$\\leqslant$', +u'\u2a7e': '$\\geqslant$', +u'\u2a85': '$\\lessapprox$', +u'\u2a86': '$\\gtrapprox$', +u'\u2a87': '$\\lneq$', +u'\u2a88': '$\\gneq$', +u'\u2a89': '$\\lnapprox$', +u'\u2a8a': '$\\gnapprox$', +u'\u2a8b': '$\\lesseqqgtr$', +u'\u2a8c': '$\\gtreqqless$', +u'\u2a95': '$\\eqslantless$', +u'\u2a96': '$\\eqslantgtr$', +u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', +u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', +u'\u2aa1': '$\\NestedLessLess$', +u'\u2aa2': '$\\NestedGreaterGreater$', +u'\u2aaf': '$\\preceq$', +u'\u2ab0': '$\\succeq$', +u'\u2ab5': '$\\precneqq$', +u'\u2ab6': '$\\succneqq$', +u'\u2ab7': '$\\precapprox$', +u'\u2ab8': '$\\succapprox$', +u'\u2ab9': '$\\precnapprox$', +u'\u2aba': '$\\succnapprox$', +u'\u2ac5': '$\\subseteqq$', +u'\u2ac6': '$\\supseteqq$', +u'\u2acb': '$\\subsetneqq$', +u'\u2acc': '$\\supsetneqq$', +u'\u2aeb': '$\\ElsevierGlyph{E30D}$', +u'\u2af6': '$\\Elztdcol$', +u'\u2afd': '${{/}\\!\\!{/}}$', +u'\u300a': '$\\ElsevierGlyph{300A}$', +u'\u300b': '$\\ElsevierGlyph{300B}$', +u'\u3018': '$\\ElsevierGlyph{3018}$', +u'\u3019': '$\\ElsevierGlyph{3019}$', +u'\u301a': '$\\openbracketleft$', +u'\u301b': '$\\openbracketright$', +u'\ufb00': '{ff}', +u'\ufb01': '{fi}', +u'\ufb02': '{fl}', +u'\ufb03': '{ffi}', +u'\ufb04': '{ffl}', +u'\U0001d400': '$\\mathbf{A}$', +u'\U0001d401': '$\\mathbf{B}$', +u'\U0001d402': '$\\mathbf{C}$', +u'\U0001d403': '$\\mathbf{D}$', +u'\U0001d404': '$\\mathbf{E}$', +u'\U0001d405': '$\\mathbf{F}$', +u'\U0001d406': '$\\mathbf{G}$', +u'\U0001d407': '$\\mathbf{H}$', +u'\U0001d408': '$\\mathbf{I}$', +u'\U0001d409': '$\\mathbf{J}$', +u'\U0001d40a': '$\\mathbf{K}$', +u'\U0001d40b': '$\\mathbf{L}$', +u'\U0001d40c': '$\\mathbf{M}$', +u'\U0001d40d': '$\\mathbf{N}$', +u'\U0001d40e': '$\\mathbf{O}$', +u'\U0001d40f': '$\\mathbf{P}$', +u'\U0001d410': '$\\mathbf{Q}$', +u'\U0001d411': '$\\mathbf{R}$', +u'\U0001d412': '$\\mathbf{S}$', +u'\U0001d413': '$\\mathbf{T}$', +u'\U0001d414': '$\\mathbf{U}$', +u'\U0001d415': '$\\mathbf{V}$', +u'\U0001d416': '$\\mathbf{W}$', +u'\U0001d417': '$\\mathbf{X}$', +u'\U0001d418': '$\\mathbf{Y}$', +u'\U0001d419': '$\\mathbf{Z}$', +u'\U0001d41a': '$\\mathbf{a}$', +u'\U0001d41b': '$\\mathbf{b}$', +u'\U0001d41c': '$\\mathbf{c}$', +u'\U0001d41d': '$\\mathbf{d}$', +u'\U0001d41e': '$\\mathbf{e}$', +u'\U0001d41f': '$\\mathbf{f}$', +u'\U0001d420': '$\\mathbf{g}$', +u'\U0001d421': '$\\mathbf{h}$', +u'\U0001d422': '$\\mathbf{i}$', +u'\U0001d423': '$\\mathbf{j}$', +u'\U0001d424': '$\\mathbf{k}$', +u'\U0001d425': '$\\mathbf{l}$', +u'\U0001d426': '$\\mathbf{m}$', +u'\U0001d427': '$\\mathbf{n}$', +u'\U0001d428': '$\\mathbf{o}$', +u'\U0001d429': '$\\mathbf{p}$', +u'\U0001d42a': '$\\mathbf{q}$', +u'\U0001d42b': '$\\mathbf{r}$', +u'\U0001d42c': '$\\mathbf{s}$', +u'\U0001d42d': '$\\mathbf{t}$', +u'\U0001d42e': '$\\mathbf{u}$', +u'\U0001d42f': '$\\mathbf{v}$', +u'\U0001d430': '$\\mathbf{w}$', +u'\U0001d431': '$\\mathbf{x}$', +u'\U0001d432': '$\\mathbf{y}$', +u'\U0001d433': '$\\mathbf{z}$', +u'\U0001d434': '$\\mathsl{A}$', +u'\U0001d435': '$\\mathsl{B}$', +u'\U0001d436': '$\\mathsl{C}$', +u'\U0001d437': '$\\mathsl{D}$', +u'\U0001d438': '$\\mathsl{E}$', +u'\U0001d439': '$\\mathsl{F}$', +u'\U0001d43a': '$\\mathsl{G}$', +u'\U0001d43b': '$\\mathsl{H}$', +u'\U0001d43c': '$\\mathsl{I}$', +u'\U0001d43d': '$\\mathsl{J}$', +u'\U0001d43e': '$\\mathsl{K}$', +u'\U0001d43f': '$\\mathsl{L}$', +u'\U0001d440': '$\\mathsl{M}$', +u'\U0001d441': '$\\mathsl{N}$', +u'\U0001d442': '$\\mathsl{O}$', +u'\U0001d443': '$\\mathsl{P}$', +u'\U0001d444': '$\\mathsl{Q}$', +u'\U0001d445': '$\\mathsl{R}$', +u'\U0001d446': '$\\mathsl{S}$', +u'\U0001d447': '$\\mathsl{T}$', +u'\U0001d448': '$\\mathsl{U}$', +u'\U0001d449': '$\\mathsl{V}$', +u'\U0001d44a': '$\\mathsl{W}$', +u'\U0001d44b': '$\\mathsl{X}$', +u'\U0001d44c': '$\\mathsl{Y}$', +u'\U0001d44d': '$\\mathsl{Z}$', +u'\U0001d44e': '$\\mathsl{a}$', +u'\U0001d44f': '$\\mathsl{b}$', +u'\U0001d450': '$\\mathsl{c}$', +u'\U0001d451': '$\\mathsl{d}$', +u'\U0001d452': '$\\mathsl{e}$', +u'\U0001d453': '$\\mathsl{f}$', +u'\U0001d454': '$\\mathsl{g}$', +u'\U0001d456': '$\\mathsl{i}$', +u'\U0001d457': '$\\mathsl{j}$', +u'\U0001d458': '$\\mathsl{k}$', +u'\U0001d459': '$\\mathsl{l}$', +u'\U0001d45a': '$\\mathsl{m}$', +u'\U0001d45b': '$\\mathsl{n}$', +u'\U0001d45c': '$\\mathsl{o}$', +u'\U0001d45d': '$\\mathsl{p}$', +u'\U0001d45e': '$\\mathsl{q}$', +u'\U0001d45f': '$\\mathsl{r}$', +u'\U0001d460': '$\\mathsl{s}$', +u'\U0001d461': '$\\mathsl{t}$', +u'\U0001d462': '$\\mathsl{u}$', +u'\U0001d463': '$\\mathsl{v}$', +u'\U0001d464': '$\\mathsl{w}$', +u'\U0001d465': '$\\mathsl{x}$', +u'\U0001d466': '$\\mathsl{y}$', +u'\U0001d467': '$\\mathsl{z}$', +u'\U0001d468': '$\\mathbit{A}$', +u'\U0001d469': '$\\mathbit{B}$', +u'\U0001d46a': '$\\mathbit{C}$', +u'\U0001d46b': '$\\mathbit{D}$', +u'\U0001d46c': '$\\mathbit{E}$', +u'\U0001d46d': '$\\mathbit{F}$', +u'\U0001d46e': '$\\mathbit{G}$', +u'\U0001d46f': '$\\mathbit{H}$', +u'\U0001d470': '$\\mathbit{I}$', +u'\U0001d471': '$\\mathbit{J}$', +u'\U0001d472': '$\\mathbit{K}$', +u'\U0001d473': '$\\mathbit{L}$', +u'\U0001d474': '$\\mathbit{M}$', +u'\U0001d475': '$\\mathbit{N}$', +u'\U0001d476': '$\\mathbit{O}$', +u'\U0001d477': '$\\mathbit{P}$', +u'\U0001d478': '$\\mathbit{Q}$', +u'\U0001d479': '$\\mathbit{R}$', +u'\U0001d47a': '$\\mathbit{S}$', +u'\U0001d47b': '$\\mathbit{T}$', +u'\U0001d47c': '$\\mathbit{U}$', +u'\U0001d47d': '$\\mathbit{V}$', +u'\U0001d47e': '$\\mathbit{W}$', +u'\U0001d47f': '$\\mathbit{X}$', +u'\U0001d480': '$\\mathbit{Y}$', +u'\U0001d481': '$\\mathbit{Z}$', +u'\U0001d482': '$\\mathbit{a}$', +u'\U0001d483': '$\\mathbit{b}$', +u'\U0001d484': '$\\mathbit{c}$', +u'\U0001d485': '$\\mathbit{d}$', +u'\U0001d486': '$\\mathbit{e}$', +u'\U0001d487': '$\\mathbit{f}$', +u'\U0001d488': '$\\mathbit{g}$', +u'\U0001d489': '$\\mathbit{h}$', +u'\U0001d48a': '$\\mathbit{i}$', +u'\U0001d48b': '$\\mathbit{j}$', +u'\U0001d48c': '$\\mathbit{k}$', +u'\U0001d48d': '$\\mathbit{l}$', +u'\U0001d48e': '$\\mathbit{m}$', +u'\U0001d48f': '$\\mathbit{n}$', +u'\U0001d490': '$\\mathbit{o}$', +u'\U0001d491': '$\\mathbit{p}$', +u'\U0001d492': '$\\mathbit{q}$', +u'\U0001d493': '$\\mathbit{r}$', +u'\U0001d494': '$\\mathbit{s}$', +u'\U0001d495': '$\\mathbit{t}$', +u'\U0001d496': '$\\mathbit{u}$', +u'\U0001d497': '$\\mathbit{v}$', +u'\U0001d498': '$\\mathbit{w}$', +u'\U0001d499': '$\\mathbit{x}$', +u'\U0001d49a': '$\\mathbit{y}$', +u'\U0001d49b': '$\\mathbit{z}$', +u'\U0001d49c': '$\\mathscr{A}$', +u'\U0001d49e': '$\\mathscr{C}$', +u'\U0001d49f': '$\\mathscr{D}$', +u'\U0001d4a2': '$\\mathscr{G}$', +u'\U0001d4a5': '$\\mathscr{J}$', +u'\U0001d4a6': '$\\mathscr{K}$', +u'\U0001d4a9': '$\\mathscr{N}$', +u'\U0001d4aa': '$\\mathscr{O}$', +u'\U0001d4ab': '$\\mathscr{P}$', +u'\U0001d4ac': '$\\mathscr{Q}$', +u'\U0001d4ae': '$\\mathscr{S}$', +u'\U0001d4af': '$\\mathscr{T}$', +u'\U0001d4b0': '$\\mathscr{U}$', +u'\U0001d4b1': '$\\mathscr{V}$', +u'\U0001d4b2': '$\\mathscr{W}$', +u'\U0001d4b3': '$\\mathscr{X}$', +u'\U0001d4b4': '$\\mathscr{Y}$', +u'\U0001d4b5': '$\\mathscr{Z}$', +u'\U0001d4b6': '$\\mathscr{a}$', +u'\U0001d4b7': '$\\mathscr{b}$', +u'\U0001d4b8': '$\\mathscr{c}$', +u'\U0001d4b9': '$\\mathscr{d}$', +u'\U0001d4bb': '$\\mathscr{f}$', +u'\U0001d4bd': '$\\mathscr{h}$', +u'\U0001d4be': '$\\mathscr{i}$', +u'\U0001d4bf': '$\\mathscr{j}$', +u'\U0001d4c0': '$\\mathscr{k}$', +u'\U0001d4c1': '$\\mathscr{l}$', +u'\U0001d4c2': '$\\mathscr{m}$', +u'\U0001d4c3': '$\\mathscr{n}$', +u'\U0001d4c5': '$\\mathscr{p}$', +u'\U0001d4c6': '$\\mathscr{q}$', +u'\U0001d4c7': '$\\mathscr{r}$', +u'\U0001d4c8': '$\\mathscr{s}$', +u'\U0001d4c9': '$\\mathscr{t}$', +u'\U0001d4ca': '$\\mathscr{u}$', +u'\U0001d4cb': '$\\mathscr{v}$', +u'\U0001d4cc': '$\\mathscr{w}$', +u'\U0001d4cd': '$\\mathscr{x}$', +u'\U0001d4ce': '$\\mathscr{y}$', +u'\U0001d4cf': '$\\mathscr{z}$', +u'\U0001d4d0': '$\\mathmit{A}$', +u'\U0001d4d1': '$\\mathmit{B}$', +u'\U0001d4d2': '$\\mathmit{C}$', +u'\U0001d4d3': '$\\mathmit{D}$', +u'\U0001d4d4': '$\\mathmit{E}$', +u'\U0001d4d5': '$\\mathmit{F}$', +u'\U0001d4d6': '$\\mathmit{G}$', +u'\U0001d4d7': '$\\mathmit{H}$', +u'\U0001d4d8': '$\\mathmit{I}$', +u'\U0001d4d9': '$\\mathmit{J}$', +u'\U0001d4da': '$\\mathmit{K}$', +u'\U0001d4db': '$\\mathmit{L}$', +u'\U0001d4dc': '$\\mathmit{M}$', +u'\U0001d4dd': '$\\mathmit{N}$', +u'\U0001d4de': '$\\mathmit{O}$', +u'\U0001d4df': '$\\mathmit{P}$', +u'\U0001d4e0': '$\\mathmit{Q}$', +u'\U0001d4e1': '$\\mathmit{R}$', +u'\U0001d4e2': '$\\mathmit{S}$', +u'\U0001d4e3': '$\\mathmit{T}$', +u'\U0001d4e4': '$\\mathmit{U}$', +u'\U0001d4e5': '$\\mathmit{V}$', +u'\U0001d4e6': '$\\mathmit{W}$', +u'\U0001d4e7': '$\\mathmit{X}$', +u'\U0001d4e8': '$\\mathmit{Y}$', +u'\U0001d4e9': '$\\mathmit{Z}$', +u'\U0001d4ea': '$\\mathmit{a}$', +u'\U0001d4eb': '$\\mathmit{b}$', +u'\U0001d4ec': '$\\mathmit{c}$', +u'\U0001d4ed': '$\\mathmit{d}$', +u'\U0001d4ee': '$\\mathmit{e}$', +u'\U0001d4ef': '$\\mathmit{f}$', +u'\U0001d4f0': '$\\mathmit{g}$', +u'\U0001d4f1': '$\\mathmit{h}$', +u'\U0001d4f2': '$\\mathmit{i}$', +u'\U0001d4f3': '$\\mathmit{j}$', +u'\U0001d4f4': '$\\mathmit{k}$', +u'\U0001d4f5': '$\\mathmit{l}$', +u'\U0001d4f6': '$\\mathmit{m}$', +u'\U0001d4f7': '$\\mathmit{n}$', +u'\U0001d4f8': '$\\mathmit{o}$', +u'\U0001d4f9': '$\\mathmit{p}$', +u'\U0001d4fa': '$\\mathmit{q}$', +u'\U0001d4fb': '$\\mathmit{r}$', +u'\U0001d4fc': '$\\mathmit{s}$', +u'\U0001d4fd': '$\\mathmit{t}$', +u'\U0001d4fe': '$\\mathmit{u}$', +u'\U0001d4ff': '$\\mathmit{v}$', +u'\U0001d500': '$\\mathmit{w}$', +u'\U0001d501': '$\\mathmit{x}$', +u'\U0001d502': '$\\mathmit{y}$', +u'\U0001d503': '$\\mathmit{z}$', +u'\U0001d504': '$\\mathfrak{A}$', +u'\U0001d505': '$\\mathfrak{B}$', +u'\U0001d507': '$\\mathfrak{D}$', +u'\U0001d508': '$\\mathfrak{E}$', +u'\U0001d509': '$\\mathfrak{F}$', +u'\U0001d50a': '$\\mathfrak{G}$', +u'\U0001d50d': '$\\mathfrak{J}$', +u'\U0001d50e': '$\\mathfrak{K}$', +u'\U0001d50f': '$\\mathfrak{L}$', +u'\U0001d510': '$\\mathfrak{M}$', +u'\U0001d511': '$\\mathfrak{N}$', +u'\U0001d512': '$\\mathfrak{O}$', +u'\U0001d513': '$\\mathfrak{P}$', +u'\U0001d514': '$\\mathfrak{Q}$', +u'\U0001d516': '$\\mathfrak{S}$', +u'\U0001d517': '$\\mathfrak{T}$', +u'\U0001d518': '$\\mathfrak{U}$', +u'\U0001d519': '$\\mathfrak{V}$', +u'\U0001d51a': '$\\mathfrak{W}$', +u'\U0001d51b': '$\\mathfrak{X}$', +u'\U0001d51c': '$\\mathfrak{Y}$', +u'\U0001d51e': '$\\mathfrak{a}$', +u'\U0001d51f': '$\\mathfrak{b}$', +u'\U0001d520': '$\\mathfrak{c}$', +u'\U0001d521': '$\\mathfrak{d}$', +u'\U0001d522': '$\\mathfrak{e}$', +u'\U0001d523': '$\\mathfrak{f}$', +u'\U0001d524': '$\\mathfrak{g}$', +u'\U0001d525': '$\\mathfrak{h}$', +u'\U0001d526': '$\\mathfrak{i}$', +u'\U0001d527': '$\\mathfrak{j}$', +u'\U0001d528': '$\\mathfrak{k}$', +u'\U0001d529': '$\\mathfrak{l}$', +u'\U0001d52a': '$\\mathfrak{m}$', +u'\U0001d52b': '$\\mathfrak{n}$', +u'\U0001d52c': '$\\mathfrak{o}$', +u'\U0001d52d': '$\\mathfrak{p}$', +u'\U0001d52e': '$\\mathfrak{q}$', +u'\U0001d52f': '$\\mathfrak{r}$', +u'\U0001d530': '$\\mathfrak{s}$', +u'\U0001d531': '$\\mathfrak{t}$', +u'\U0001d532': '$\\mathfrak{u}$', +u'\U0001d533': '$\\mathfrak{v}$', +u'\U0001d534': '$\\mathfrak{w}$', +u'\U0001d535': '$\\mathfrak{x}$', +u'\U0001d536': '$\\mathfrak{y}$', +u'\U0001d537': '$\\mathfrak{z}$', +u'\U0001d538': '$\\mathbb{A}$', +u'\U0001d539': '$\\mathbb{B}$', +u'\U0001d53b': '$\\mathbb{D}$', +u'\U0001d53c': '$\\mathbb{E}$', +u'\U0001d53d': '$\\mathbb{F}$', +u'\U0001d53e': '$\\mathbb{G}$', +u'\U0001d540': '$\\mathbb{I}$', +u'\U0001d541': '$\\mathbb{J}$', +u'\U0001d542': '$\\mathbb{K}$', +u'\U0001d543': '$\\mathbb{L}$', +u'\U0001d544': '$\\mathbb{M}$', +u'\U0001d546': '$\\mathbb{O}$', +u'\U0001d54a': '$\\mathbb{S}$', +u'\U0001d54b': '$\\mathbb{T}$', +u'\U0001d54c': '$\\mathbb{U}$', +u'\U0001d54d': '$\\mathbb{V}$', +u'\U0001d54e': '$\\mathbb{W}$', +u'\U0001d54f': '$\\mathbb{X}$', +u'\U0001d550': '$\\mathbb{Y}$', +u'\U0001d552': '$\\mathbb{a}$', +u'\U0001d553': '$\\mathbb{b}$', +u'\U0001d554': '$\\mathbb{c}$', +u'\U0001d555': '$\\mathbb{d}$', +u'\U0001d556': '$\\mathbb{e}$', +u'\U0001d557': '$\\mathbb{f}$', +u'\U0001d558': '$\\mathbb{g}$', +u'\U0001d559': '$\\mathbb{h}$', +u'\U0001d55a': '$\\mathbb{i}$', +u'\U0001d55b': '$\\mathbb{j}$', +u'\U0001d55c': '$\\mathbb{k}$', +u'\U0001d55d': '$\\mathbb{l}$', +u'\U0001d55e': '$\\mathbb{m}$', +u'\U0001d55f': '$\\mathbb{n}$', +u'\U0001d560': '$\\mathbb{o}$', +u'\U0001d561': '$\\mathbb{p}$', +u'\U0001d562': '$\\mathbb{q}$', +u'\U0001d563': '$\\mathbb{r}$', +u'\U0001d564': '$\\mathbb{s}$', +u'\U0001d565': '$\\mathbb{t}$', +u'\U0001d566': '$\\mathbb{u}$', +u'\U0001d567': '$\\mathbb{v}$', +u'\U0001d568': '$\\mathbb{w}$', +u'\U0001d569': '$\\mathbb{x}$', +u'\U0001d56a': '$\\mathbb{y}$', +u'\U0001d56b': '$\\mathbb{z}$', +u'\U0001d56c': '$\\mathslbb{A}$', +u'\U0001d56d': '$\\mathslbb{B}$', +u'\U0001d56e': '$\\mathslbb{C}$', +u'\U0001d56f': '$\\mathslbb{D}$', +u'\U0001d570': '$\\mathslbb{E}$', +u'\U0001d571': '$\\mathslbb{F}$', +u'\U0001d572': '$\\mathslbb{G}$', +u'\U0001d573': '$\\mathslbb{H}$', +u'\U0001d574': '$\\mathslbb{I}$', +u'\U0001d575': '$\\mathslbb{J}$', +u'\U0001d576': '$\\mathslbb{K}$', +u'\U0001d577': '$\\mathslbb{L}$', +u'\U0001d578': '$\\mathslbb{M}$', +u'\U0001d579': '$\\mathslbb{N}$', +u'\U0001d57a': '$\\mathslbb{O}$', +u'\U0001d57b': '$\\mathslbb{P}$', +u'\U0001d57c': '$\\mathslbb{Q}$', +u'\U0001d57d': '$\\mathslbb{R}$', +u'\U0001d57e': '$\\mathslbb{S}$', +u'\U0001d57f': '$\\mathslbb{T}$', +u'\U0001d580': '$\\mathslbb{U}$', +u'\U0001d581': '$\\mathslbb{V}$', +u'\U0001d582': '$\\mathslbb{W}$', +u'\U0001d583': '$\\mathslbb{X}$', +u'\U0001d584': '$\\mathslbb{Y}$', +u'\U0001d585': '$\\mathslbb{Z}$', +u'\U0001d586': '$\\mathslbb{a}$', +u'\U0001d587': '$\\mathslbb{b}$', +u'\U0001d588': '$\\mathslbb{c}$', +u'\U0001d589': '$\\mathslbb{d}$', +u'\U0001d58a': '$\\mathslbb{e}$', +u'\U0001d58b': '$\\mathslbb{f}$', +u'\U0001d58c': '$\\mathslbb{g}$', +u'\U0001d58d': '$\\mathslbb{h}$', +u'\U0001d58e': '$\\mathslbb{i}$', +u'\U0001d58f': '$\\mathslbb{j}$', +u'\U0001d590': '$\\mathslbb{k}$', +u'\U0001d591': '$\\mathslbb{l}$', +u'\U0001d592': '$\\mathslbb{m}$', +u'\U0001d593': '$\\mathslbb{n}$', +u'\U0001d594': '$\\mathslbb{o}$', +u'\U0001d595': '$\\mathslbb{p}$', +u'\U0001d596': '$\\mathslbb{q}$', +u'\U0001d597': '$\\mathslbb{r}$', +u'\U0001d598': '$\\mathslbb{s}$', +u'\U0001d599': '$\\mathslbb{t}$', +u'\U0001d59a': '$\\mathslbb{u}$', +u'\U0001d59b': '$\\mathslbb{v}$', +u'\U0001d59c': '$\\mathslbb{w}$', +u'\U0001d59d': '$\\mathslbb{x}$', +u'\U0001d59e': '$\\mathslbb{y}$', +u'\U0001d59f': '$\\mathslbb{z}$', +u'\U0001d5a0': '$\\mathsf{A}$', +u'\U0001d5a1': '$\\mathsf{B}$', +u'\U0001d5a2': '$\\mathsf{C}$', +u'\U0001d5a3': '$\\mathsf{D}$', +u'\U0001d5a4': '$\\mathsf{E}$', +u'\U0001d5a5': '$\\mathsf{F}$', +u'\U0001d5a6': '$\\mathsf{G}$', +u'\U0001d5a7': '$\\mathsf{H}$', +u'\U0001d5a8': '$\\mathsf{I}$', +u'\U0001d5a9': '$\\mathsf{J}$', +u'\U0001d5aa': '$\\mathsf{K}$', +u'\U0001d5ab': '$\\mathsf{L}$', +u'\U0001d5ac': '$\\mathsf{M}$', +u'\U0001d5ad': '$\\mathsf{N}$', +u'\U0001d5ae': '$\\mathsf{O}$', +u'\U0001d5af': '$\\mathsf{P}$', +u'\U0001d5b0': '$\\mathsf{Q}$', +u'\U0001d5b1': '$\\mathsf{R}$', +u'\U0001d5b2': '$\\mathsf{S}$', +u'\U0001d5b3': '$\\mathsf{T}$', +u'\U0001d5b4': '$\\mathsf{U}$', +u'\U0001d5b5': '$\\mathsf{V}$', +u'\U0001d5b6': '$\\mathsf{W}$', +u'\U0001d5b7': '$\\mathsf{X}$', +u'\U0001d5b8': '$\\mathsf{Y}$', +u'\U0001d5b9': '$\\mathsf{Z}$', +u'\U0001d5ba': '$\\mathsf{a}$', +u'\U0001d5bb': '$\\mathsf{b}$', +u'\U0001d5bc': '$\\mathsf{c}$', +u'\U0001d5bd': '$\\mathsf{d}$', +u'\U0001d5be': '$\\mathsf{e}$', +u'\U0001d5bf': '$\\mathsf{f}$', +u'\U0001d5c0': '$\\mathsf{g}$', +u'\U0001d5c1': '$\\mathsf{h}$', +u'\U0001d5c2': '$\\mathsf{i}$', +u'\U0001d5c3': '$\\mathsf{j}$', +u'\U0001d5c4': '$\\mathsf{k}$', +u'\U0001d5c5': '$\\mathsf{l}$', +u'\U0001d5c6': '$\\mathsf{m}$', +u'\U0001d5c7': '$\\mathsf{n}$', +u'\U0001d5c8': '$\\mathsf{o}$', +u'\U0001d5c9': '$\\mathsf{p}$', +u'\U0001d5ca': '$\\mathsf{q}$', +u'\U0001d5cb': '$\\mathsf{r}$', +u'\U0001d5cc': '$\\mathsf{s}$', +u'\U0001d5cd': '$\\mathsf{t}$', +u'\U0001d5ce': '$\\mathsf{u}$', +u'\U0001d5cf': '$\\mathsf{v}$', +u'\U0001d5d0': '$\\mathsf{w}$', +u'\U0001d5d1': '$\\mathsf{x}$', +u'\U0001d5d2': '$\\mathsf{y}$', +u'\U0001d5d3': '$\\mathsf{z}$', +u'\U0001d5d4': '$\\mathsfbf{A}$', +u'\U0001d5d5': '$\\mathsfbf{B}$', +u'\U0001d5d6': '$\\mathsfbf{C}$', +u'\U0001d5d7': '$\\mathsfbf{D}$', +u'\U0001d5d8': '$\\mathsfbf{E}$', +u'\U0001d5d9': '$\\mathsfbf{F}$', +u'\U0001d5da': '$\\mathsfbf{G}$', +u'\U0001d5db': '$\\mathsfbf{H}$', +u'\U0001d5dc': '$\\mathsfbf{I}$', +u'\U0001d5dd': '$\\mathsfbf{J}$', +u'\U0001d5de': '$\\mathsfbf{K}$', +u'\U0001d5df': '$\\mathsfbf{L}$', +u'\U0001d5e0': '$\\mathsfbf{M}$', +u'\U0001d5e1': '$\\mathsfbf{N}$', +u'\U0001d5e2': '$\\mathsfbf{O}$', +u'\U0001d5e3': '$\\mathsfbf{P}$', +u'\U0001d5e4': '$\\mathsfbf{Q}$', +u'\U0001d5e5': '$\\mathsfbf{R}$', +u'\U0001d5e6': '$\\mathsfbf{S}$', +u'\U0001d5e7': '$\\mathsfbf{T}$', +u'\U0001d5e8': '$\\mathsfbf{U}$', +u'\U0001d5e9': '$\\mathsfbf{V}$', +u'\U0001d5ea': '$\\mathsfbf{W}$', +u'\U0001d5eb': '$\\mathsfbf{X}$', +u'\U0001d5ec': '$\\mathsfbf{Y}$', +u'\U0001d5ed': '$\\mathsfbf{Z}$', +u'\U0001d5ee': '$\\mathsfbf{a}$', +u'\U0001d5ef': '$\\mathsfbf{b}$', +u'\U0001d5f0': '$\\mathsfbf{c}$', +u'\U0001d5f1': '$\\mathsfbf{d}$', +u'\U0001d5f2': '$\\mathsfbf{e}$', +u'\U0001d5f3': '$\\mathsfbf{f}$', +u'\U0001d5f4': '$\\mathsfbf{g}$', +u'\U0001d5f5': '$\\mathsfbf{h}$', +u'\U0001d5f6': '$\\mathsfbf{i}$', +u'\U0001d5f7': '$\\mathsfbf{j}$', +u'\U0001d5f8': '$\\mathsfbf{k}$', +u'\U0001d5f9': '$\\mathsfbf{l}$', +u'\U0001d5fa': '$\\mathsfbf{m}$', +u'\U0001d5fb': '$\\mathsfbf{n}$', +u'\U0001d5fc': '$\\mathsfbf{o}$', +u'\U0001d5fd': '$\\mathsfbf{p}$', +u'\U0001d5fe': '$\\mathsfbf{q}$', +u'\U0001d5ff': '$\\mathsfbf{r}$', +u'\U0001d600': '$\\mathsfbf{s}$', +u'\U0001d601': '$\\mathsfbf{t}$', +u'\U0001d602': '$\\mathsfbf{u}$', +u'\U0001d603': '$\\mathsfbf{v}$', +u'\U0001d604': '$\\mathsfbf{w}$', +u'\U0001d605': '$\\mathsfbf{x}$', +u'\U0001d606': '$\\mathsfbf{y}$', +u'\U0001d607': '$\\mathsfbf{z}$', +u'\U0001d608': '$\\mathsfsl{A}$', +u'\U0001d609': '$\\mathsfsl{B}$', +u'\U0001d60a': '$\\mathsfsl{C}$', +u'\U0001d60b': '$\\mathsfsl{D}$', +u'\U0001d60c': '$\\mathsfsl{E}$', +u'\U0001d60d': '$\\mathsfsl{F}$', +u'\U0001d60e': '$\\mathsfsl{G}$', +u'\U0001d60f': '$\\mathsfsl{H}$', +u'\U0001d610': '$\\mathsfsl{I}$', +u'\U0001d611': '$\\mathsfsl{J}$', +u'\U0001d612': '$\\mathsfsl{K}$', +u'\U0001d613': '$\\mathsfsl{L}$', +u'\U0001d614': '$\\mathsfsl{M}$', +u'\U0001d615': '$\\mathsfsl{N}$', +u'\U0001d616': '$\\mathsfsl{O}$', +u'\U0001d617': '$\\mathsfsl{P}$', +u'\U0001d618': '$\\mathsfsl{Q}$', +u'\U0001d619': '$\\mathsfsl{R}$', +u'\U0001d61a': '$\\mathsfsl{S}$', +u'\U0001d61b': '$\\mathsfsl{T}$', +u'\U0001d61c': '$\\mathsfsl{U}$', +u'\U0001d61d': '$\\mathsfsl{V}$', +u'\U0001d61e': '$\\mathsfsl{W}$', +u'\U0001d61f': '$\\mathsfsl{X}$', +u'\U0001d620': '$\\mathsfsl{Y}$', +u'\U0001d621': '$\\mathsfsl{Z}$', +u'\U0001d622': '$\\mathsfsl{a}$', +u'\U0001d623': '$\\mathsfsl{b}$', +u'\U0001d624': '$\\mathsfsl{c}$', +u'\U0001d625': '$\\mathsfsl{d}$', +u'\U0001d626': '$\\mathsfsl{e}$', +u'\U0001d627': '$\\mathsfsl{f}$', +u'\U0001d628': '$\\mathsfsl{g}$', +u'\U0001d629': '$\\mathsfsl{h}$', +u'\U0001d62a': '$\\mathsfsl{i}$', +u'\U0001d62b': '$\\mathsfsl{j}$', +u'\U0001d62c': '$\\mathsfsl{k}$', +u'\U0001d62d': '$\\mathsfsl{l}$', +u'\U0001d62e': '$\\mathsfsl{m}$', +u'\U0001d62f': '$\\mathsfsl{n}$', +u'\U0001d630': '$\\mathsfsl{o}$', +u'\U0001d631': '$\\mathsfsl{p}$', +u'\U0001d632': '$\\mathsfsl{q}$', +u'\U0001d633': '$\\mathsfsl{r}$', +u'\U0001d634': '$\\mathsfsl{s}$', +u'\U0001d635': '$\\mathsfsl{t}$', +u'\U0001d636': '$\\mathsfsl{u}$', +u'\U0001d637': '$\\mathsfsl{v}$', +u'\U0001d638': '$\\mathsfsl{w}$', +u'\U0001d639': '$\\mathsfsl{x}$', +u'\U0001d63a': '$\\mathsfsl{y}$', +u'\U0001d63b': '$\\mathsfsl{z}$', +u'\U0001d63c': '$\\mathsfbfsl{A}$', +u'\U0001d63d': '$\\mathsfbfsl{B}$', +u'\U0001d63e': '$\\mathsfbfsl{C}$', +u'\U0001d63f': '$\\mathsfbfsl{D}$', +u'\U0001d640': '$\\mathsfbfsl{E}$', +u'\U0001d641': '$\\mathsfbfsl{F}$', +u'\U0001d642': '$\\mathsfbfsl{G}$', +u'\U0001d643': '$\\mathsfbfsl{H}$', +u'\U0001d644': '$\\mathsfbfsl{I}$', +u'\U0001d645': '$\\mathsfbfsl{J}$', +u'\U0001d646': '$\\mathsfbfsl{K}$', +u'\U0001d647': '$\\mathsfbfsl{L}$', +u'\U0001d648': '$\\mathsfbfsl{M}$', +u'\U0001d649': '$\\mathsfbfsl{N}$', +u'\U0001d64a': '$\\mathsfbfsl{O}$', +u'\U0001d64b': '$\\mathsfbfsl{P}$', +u'\U0001d64c': '$\\mathsfbfsl{Q}$', +u'\U0001d64d': '$\\mathsfbfsl{R}$', +u'\U0001d64e': '$\\mathsfbfsl{S}$', +u'\U0001d64f': '$\\mathsfbfsl{T}$', +u'\U0001d650': '$\\mathsfbfsl{U}$', +u'\U0001d651': '$\\mathsfbfsl{V}$', +u'\U0001d652': '$\\mathsfbfsl{W}$', +u'\U0001d653': '$\\mathsfbfsl{X}$', +u'\U0001d654': '$\\mathsfbfsl{Y}$', +u'\U0001d655': '$\\mathsfbfsl{Z}$', +u'\U0001d656': '$\\mathsfbfsl{a}$', +u'\U0001d657': '$\\mathsfbfsl{b}$', +u'\U0001d658': '$\\mathsfbfsl{c}$', +u'\U0001d659': '$\\mathsfbfsl{d}$', +u'\U0001d65a': '$\\mathsfbfsl{e}$', +u'\U0001d65b': '$\\mathsfbfsl{f}$', +u'\U0001d65c': '$\\mathsfbfsl{g}$', +u'\U0001d65d': '$\\mathsfbfsl{h}$', +u'\U0001d65e': '$\\mathsfbfsl{i}$', +u'\U0001d65f': '$\\mathsfbfsl{j}$', +u'\U0001d660': '$\\mathsfbfsl{k}$', +u'\U0001d661': '$\\mathsfbfsl{l}$', +u'\U0001d662': '$\\mathsfbfsl{m}$', +u'\U0001d663': '$\\mathsfbfsl{n}$', +u'\U0001d664': '$\\mathsfbfsl{o}$', +u'\U0001d665': '$\\mathsfbfsl{p}$', +u'\U0001d666': '$\\mathsfbfsl{q}$', +u'\U0001d667': '$\\mathsfbfsl{r}$', +u'\U0001d668': '$\\mathsfbfsl{s}$', +u'\U0001d669': '$\\mathsfbfsl{t}$', +u'\U0001d66a': '$\\mathsfbfsl{u}$', +u'\U0001d66b': '$\\mathsfbfsl{v}$', +u'\U0001d66c': '$\\mathsfbfsl{w}$', +u'\U0001d66d': '$\\mathsfbfsl{x}$', +u'\U0001d66e': '$\\mathsfbfsl{y}$', +u'\U0001d66f': '$\\mathsfbfsl{z}$', +u'\U0001d670': '$\\mathtt{A}$', +u'\U0001d671': '$\\mathtt{B}$', +u'\U0001d672': '$\\mathtt{C}$', +u'\U0001d673': '$\\mathtt{D}$', +u'\U0001d674': '$\\mathtt{E}$', +u'\U0001d675': '$\\mathtt{F}$', +u'\U0001d676': '$\\mathtt{G}$', +u'\U0001d677': '$\\mathtt{H}$', +u'\U0001d678': '$\\mathtt{I}$', +u'\U0001d679': '$\\mathtt{J}$', +u'\U0001d67a': '$\\mathtt{K}$', +u'\U0001d67b': '$\\mathtt{L}$', +u'\U0001d67c': '$\\mathtt{M}$', +u'\U0001d67d': '$\\mathtt{N}$', +u'\U0001d67e': '$\\mathtt{O}$', +u'\U0001d67f': '$\\mathtt{P}$', +u'\U0001d680': '$\\mathtt{Q}$', +u'\U0001d681': '$\\mathtt{R}$', +u'\U0001d682': '$\\mathtt{S}$', +u'\U0001d683': '$\\mathtt{T}$', +u'\U0001d684': '$\\mathtt{U}$', +u'\U0001d685': '$\\mathtt{V}$', +u'\U0001d686': '$\\mathtt{W}$', +u'\U0001d687': '$\\mathtt{X}$', +u'\U0001d688': '$\\mathtt{Y}$', +u'\U0001d689': '$\\mathtt{Z}$', +u'\U0001d68a': '$\\mathtt{a}$', +u'\U0001d68b': '$\\mathtt{b}$', +u'\U0001d68c': '$\\mathtt{c}$', +u'\U0001d68d': '$\\mathtt{d}$', +u'\U0001d68e': '$\\mathtt{e}$', +u'\U0001d68f': '$\\mathtt{f}$', +u'\U0001d690': '$\\mathtt{g}$', +u'\U0001d691': '$\\mathtt{h}$', +u'\U0001d692': '$\\mathtt{i}$', +u'\U0001d693': '$\\mathtt{j}$', +u'\U0001d694': '$\\mathtt{k}$', +u'\U0001d695': '$\\mathtt{l}$', +u'\U0001d696': '$\\mathtt{m}$', +u'\U0001d697': '$\\mathtt{n}$', +u'\U0001d698': '$\\mathtt{o}$', +u'\U0001d699': '$\\mathtt{p}$', +u'\U0001d69a': '$\\mathtt{q}$', +u'\U0001d69b': '$\\mathtt{r}$', +u'\U0001d69c': '$\\mathtt{s}$', +u'\U0001d69d': '$\\mathtt{t}$', +u'\U0001d69e': '$\\mathtt{u}$', +u'\U0001d69f': '$\\mathtt{v}$', +u'\U0001d6a0': '$\\mathtt{w}$', +u'\U0001d6a1': '$\\mathtt{x}$', +u'\U0001d6a2': '$\\mathtt{y}$', +u'\U0001d6a3': '$\\mathtt{z}$', +u'\U0001d6a8': '$\\mathbf{\\Alpha}$', +u'\U0001d6a9': '$\\mathbf{\\Beta}$', +u'\U0001d6aa': '$\\mathbf{\\Gamma}$', +u'\U0001d6ab': '$\\mathbf{\\Delta}$', +u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', +u'\U0001d6ad': '$\\mathbf{\\Zeta}$', +u'\U0001d6ae': '$\\mathbf{\\Eta}$', +u'\U0001d6af': '$\\mathbf{\\Theta}$', +u'\U0001d6b0': '$\\mathbf{\\Iota}$', +u'\U0001d6b1': '$\\mathbf{\\Kappa}$', +u'\U0001d6b2': '$\\mathbf{\\Lambda}$', +u'\U0001d6b3': '$M$', +u'\U0001d6b4': '$N$', +u'\U0001d6b5': '$\\mathbf{\\Xi}$', +u'\U0001d6b6': '$O$', +u'\U0001d6b7': '$\\mathbf{\\Pi}$', +u'\U0001d6b8': '$\\mathbf{\\Rho}$', +u'\U0001d6b9': '{\\mathbf{\\vartheta}}', +u'\U0001d6ba': '$\\mathbf{\\Sigma}$', +u'\U0001d6bb': '$\\mathbf{\\Tau}$', +u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', +u'\U0001d6bd': '$\\mathbf{\\Phi}$', +u'\U0001d6be': '$\\mathbf{\\Chi}$', +u'\U0001d6bf': '$\\mathbf{\\Psi}$', +u'\U0001d6c0': '$\\mathbf{\\Omega}$', +u'\U0001d6c1': '$\\mathbf{\\nabla}$', +u'\U0001d6c2': '$\\mathbf{\\Alpha}$', +u'\U0001d6c3': '$\\mathbf{\\Beta}$', +u'\U0001d6c4': '$\\mathbf{\\Gamma}$', +u'\U0001d6c5': '$\\mathbf{\\Delta}$', +u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', +u'\U0001d6c7': '$\\mathbf{\\Zeta}$', +u'\U0001d6c8': '$\\mathbf{\\Eta}$', +u'\U0001d6c9': '$\\mathbf{\\theta}$', +u'\U0001d6ca': '$\\mathbf{\\Iota}$', +u'\U0001d6cb': '$\\mathbf{\\Kappa}$', +u'\U0001d6cc': '$\\mathbf{\\Lambda}$', +u'\U0001d6cd': '$M$', +u'\U0001d6ce': '$N$', +u'\U0001d6cf': '$\\mathbf{\\Xi}$', +u'\U0001d6d0': '$O$', +u'\U0001d6d1': '$\\mathbf{\\Pi}$', +u'\U0001d6d2': '$\\mathbf{\\Rho}$', +u'\U0001d6d3': '$\\mathbf{\\varsigma}$', +u'\U0001d6d4': '$\\mathbf{\\Sigma}$', +u'\U0001d6d5': '$\\mathbf{\\Tau}$', +u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', +u'\U0001d6d7': '$\\mathbf{\\Phi}$', +u'\U0001d6d8': '$\\mathbf{\\Chi}$', +u'\U0001d6d9': '$\\mathbf{\\Psi}$', +u'\U0001d6da': '$\\mathbf{\\Omega}$', +u'\U0001d6db': '$\\partial$', +u'\U0001d6dc': '$\\in$', +u'\U0001d6dd': '{\\mathbf{\\vartheta}}', +u'\U0001d6de': '{\\mathbf{\\varkappa}}', +u'\U0001d6df': '{\\mathbf{\\phi}}', +u'\U0001d6e0': '{\\mathbf{\\varrho}}', +u'\U0001d6e1': '{\\mathbf{\\varpi}}', +u'\U0001d6e2': '$\\mathsl{\\Alpha}$', +u'\U0001d6e3': '$\\mathsl{\\Beta}$', +u'\U0001d6e4': '$\\mathsl{\\Gamma}$', +u'\U0001d6e5': '$\\mathsl{\\Delta}$', +u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', +u'\U0001d6e7': '$\\mathsl{\\Zeta}$', +u'\U0001d6e8': '$\\mathsl{\\Eta}$', +u'\U0001d6e9': '$\\mathsl{\\Theta}$', +u'\U0001d6ea': '$\\mathsl{\\Iota}$', +u'\U0001d6eb': '$\\mathsl{\\Kappa}$', +u'\U0001d6ec': '$\\mathsl{\\Lambda}$', +u'\U0001d6ed': '$M$', +u'\U0001d6ee': '$N$', +u'\U0001d6ef': '$\\mathsl{\\Xi}$', +u'\U0001d6f0': '$O$', +u'\U0001d6f1': '$\\mathsl{\\Pi}$', +u'\U0001d6f2': '$\\mathsl{\\Rho}$', +u'\U0001d6f3': '{\\mathsl{\\vartheta}}', +u'\U0001d6f4': '$\\mathsl{\\Sigma}$', +u'\U0001d6f5': '$\\mathsl{\\Tau}$', +u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', +u'\U0001d6f7': '$\\mathsl{\\Phi}$', +u'\U0001d6f8': '$\\mathsl{\\Chi}$', +u'\U0001d6f9': '$\\mathsl{\\Psi}$', +u'\U0001d6fa': '$\\mathsl{\\Omega}$', +u'\U0001d6fb': '$\\mathsl{\\nabla}$', +u'\U0001d6fc': '$\\mathsl{\\Alpha}$', +u'\U0001d6fd': '$\\mathsl{\\Beta}$', +u'\U0001d6fe': '$\\mathsl{\\Gamma}$', +u'\U0001d6ff': '$\\mathsl{\\Delta}$', +u'\U0001d700': '$\\mathsl{\\Epsilon}$', +u'\U0001d701': '$\\mathsl{\\Zeta}$', +u'\U0001d702': '$\\mathsl{\\Eta}$', +u'\U0001d703': '$\\mathsl{\\Theta}$', +u'\U0001d704': '$\\mathsl{\\Iota}$', +u'\U0001d705': '$\\mathsl{\\Kappa}$', +u'\U0001d706': '$\\mathsl{\\Lambda}$', +u'\U0001d707': '$M$', +u'\U0001d708': '$N$', +u'\U0001d709': '$\\mathsl{\\Xi}$', +u'\U0001d70a': '$O$', +u'\U0001d70b': '$\\mathsl{\\Pi}$', +u'\U0001d70c': '$\\mathsl{\\Rho}$', +u'\U0001d70d': '$\\mathsl{\\varsigma}$', +u'\U0001d70e': '$\\mathsl{\\Sigma}$', +u'\U0001d70f': '$\\mathsl{\\Tau}$', +u'\U0001d710': '$\\mathsl{\\Upsilon}$', +u'\U0001d711': '$\\mathsl{\\Phi}$', +u'\U0001d712': '$\\mathsl{\\Chi}$', +u'\U0001d713': '$\\mathsl{\\Psi}$', +u'\U0001d714': '$\\mathsl{\\Omega}$', +u'\U0001d715': '$\\partial$', +u'\U0001d716': '$\\in$', +u'\U0001d717': '{\\mathsl{\\vartheta}}', +u'\U0001d718': '{\\mathsl{\\varkappa}}', +u'\U0001d719': '{\\mathsl{\\phi}}', +u'\U0001d71a': '{\\mathsl{\\varrho}}', +u'\U0001d71b': '{\\mathsl{\\varpi}}', +u'\U0001d71c': '$\\mathbit{\\Alpha}$', +u'\U0001d71d': '$\\mathbit{\\Beta}$', +u'\U0001d71e': '$\\mathbit{\\Gamma}$', +u'\U0001d71f': '$\\mathbit{\\Delta}$', +u'\U0001d720': '$\\mathbit{\\Epsilon}$', +u'\U0001d721': '$\\mathbit{\\Zeta}$', +u'\U0001d722': '$\\mathbit{\\Eta}$', +u'\U0001d723': '$\\mathbit{\\Theta}$', +u'\U0001d724': '$\\mathbit{\\Iota}$', +u'\U0001d725': '$\\mathbit{\\Kappa}$', +u'\U0001d726': '$\\mathbit{\\Lambda}$', +u'\U0001d727': '$M$', +u'\U0001d728': '$N$', +u'\U0001d729': '$\\mathbit{\\Xi}$', +u'\U0001d72a': '$O$', +u'\U0001d72b': '$\\mathbit{\\Pi}$', +u'\U0001d72c': '$\\mathbit{\\Rho}$', +u'\U0001d72d': '{\\mathbit{O}}', +u'\U0001d72e': '$\\mathbit{\\Sigma}$', +u'\U0001d72f': '$\\mathbit{\\Tau}$', +u'\U0001d730': '$\\mathbit{\\Upsilon}$', +u'\U0001d731': '$\\mathbit{\\Phi}$', +u'\U0001d732': '$\\mathbit{\\Chi}$', +u'\U0001d733': '$\\mathbit{\\Psi}$', +u'\U0001d734': '$\\mathbit{\\Omega}$', +u'\U0001d735': '$\\mathbit{\\nabla}$', +u'\U0001d736': '$\\mathbit{\\Alpha}$', +u'\U0001d737': '$\\mathbit{\\Beta}$', +u'\U0001d738': '$\\mathbit{\\Gamma}$', +u'\U0001d739': '$\\mathbit{\\Delta}$', +u'\U0001d73a': '$\\mathbit{\\Epsilon}$', +u'\U0001d73b': '$\\mathbit{\\Zeta}$', +u'\U0001d73c': '$\\mathbit{\\Eta}$', +u'\U0001d73d': '$\\mathbit{\\Theta}$', +u'\U0001d73e': '$\\mathbit{\\Iota}$', +u'\U0001d73f': '$\\mathbit{\\Kappa}$', +u'\U0001d740': '$\\mathbit{\\Lambda}$', +u'\U0001d741': '$M$', +u'\U0001d742': '$N$', +u'\U0001d743': '$\\mathbit{\\Xi}$', +u'\U0001d744': '$O$', +u'\U0001d745': '$\\mathbit{\\Pi}$', +u'\U0001d746': '$\\mathbit{\\Rho}$', +u'\U0001d747': '$\\mathbit{\\varsigma}$', +u'\U0001d748': '$\\mathbit{\\Sigma}$', +u'\U0001d749': '$\\mathbit{\\Tau}$', +u'\U0001d74a': '$\\mathbit{\\Upsilon}$', +u'\U0001d74b': '$\\mathbit{\\Phi}$', +u'\U0001d74c': '$\\mathbit{\\Chi}$', +u'\U0001d74d': '$\\mathbit{\\Psi}$', +u'\U0001d74e': '$\\mathbit{\\Omega}$', +u'\U0001d74f': '$\\partial$', +u'\U0001d750': '$\\in$', +u'\U0001d751': '{\\mathbit{\\vartheta}}', +u'\U0001d752': '{\\mathbit{\\varkappa}}', +u'\U0001d753': '{\\mathbit{\\phi}}', +u'\U0001d754': '{\\mathbit{\\varrho}}', +u'\U0001d755': '{\\mathbit{\\varpi}}', +u'\U0001d756': '$\\mathsfbf{\\Alpha}$', +u'\U0001d757': '$\\mathsfbf{\\Beta}$', +u'\U0001d758': '$\\mathsfbf{\\Gamma}$', +u'\U0001d759': '$\\mathsfbf{\\Delta}$', +u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', +u'\U0001d75c': '$\\mathsfbf{\\Eta}$', +u'\U0001d75d': '$\\mathsfbf{\\Theta}$', +u'\U0001d75e': '$\\mathsfbf{\\Iota}$', +u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', +u'\U0001d760': '$\\mathsfbf{\\Lambda}$', +u'\U0001d761': '$M$', +u'\U0001d762': '$N$', +u'\U0001d763': '$\\mathsfbf{\\Xi}$', +u'\U0001d764': '$O$', +u'\U0001d765': '$\\mathsfbf{\\Pi}$', +u'\U0001d766': '$\\mathsfbf{\\Rho}$', +u'\U0001d767': '{\\mathsfbf{\\vartheta}}', +u'\U0001d768': '$\\mathsfbf{\\Sigma}$', +u'\U0001d769': '$\\mathsfbf{\\Tau}$', +u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d76b': '$\\mathsfbf{\\Phi}$', +u'\U0001d76c': '$\\mathsfbf{\\Chi}$', +u'\U0001d76d': '$\\mathsfbf{\\Psi}$', +u'\U0001d76e': '$\\mathsfbf{\\Omega}$', +u'\U0001d76f': '$\\mathsfbf{\\nabla}$', +u'\U0001d770': '$\\mathsfbf{\\Alpha}$', +u'\U0001d771': '$\\mathsfbf{\\Beta}$', +u'\U0001d772': '$\\mathsfbf{\\Gamma}$', +u'\U0001d773': '$\\mathsfbf{\\Delta}$', +u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d775': '$\\mathsfbf{\\Zeta}$', +u'\U0001d776': '$\\mathsfbf{\\Eta}$', +u'\U0001d777': '$\\mathsfbf{\\Theta}$', +u'\U0001d778': '$\\mathsfbf{\\Iota}$', +u'\U0001d779': '$\\mathsfbf{\\Kappa}$', +u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', +u'\U0001d77b': '$M$', +u'\U0001d77c': '$N$', +u'\U0001d77d': '$\\mathsfbf{\\Xi}$', +u'\U0001d77e': '$O$', +u'\U0001d77f': '$\\mathsfbf{\\Pi}$', +u'\U0001d780': '$\\mathsfbf{\\Rho}$', +u'\U0001d781': '$\\mathsfbf{\\varsigma}$', +u'\U0001d782': '$\\mathsfbf{\\Sigma}$', +u'\U0001d783': '$\\mathsfbf{\\Tau}$', +u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d785': '$\\mathsfbf{\\Phi}$', +u'\U0001d786': '$\\mathsfbf{\\Chi}$', +u'\U0001d787': '$\\mathsfbf{\\Psi}$', +u'\U0001d788': '$\\mathsfbf{\\Omega}$', +u'\U0001d789': '$\\partial$', +u'\U0001d78a': '$\\in$', +u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', +u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', +u'\U0001d78d': '{\\mathsfbf{\\phi}}', +u'\U0001d78e': '{\\mathsfbf{\\varrho}}', +u'\U0001d78f': '{\\mathsfbf{\\varpi}}', +u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d79b': '$M$', +u'\U0001d79c': '$N$', +u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d79e': '$O$', +u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', +u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d7b5': '$M$', +u'\U0001d7b6': '$N$', +u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d7b8': '$O$', +u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', +u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7c3': '$\\partial$', +u'\U0001d7c4': '$\\in$', +u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', +u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', +u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', +u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', +u'\U0001d7ce': '$\\mathbf{0}$', +u'\U0001d7cf': '$\\mathbf{1}$', +u'\U0001d7d0': '$\\mathbf{2}$', +u'\U0001d7d1': '$\\mathbf{3}$', +u'\U0001d7d2': '$\\mathbf{4}$', +u'\U0001d7d3': '$\\mathbf{5}$', +u'\U0001d7d4': '$\\mathbf{6}$', +u'\U0001d7d5': '$\\mathbf{7}$', +u'\U0001d7d6': '$\\mathbf{8}$', +u'\U0001d7d7': '$\\mathbf{9}$', +u'\U0001d7d8': '$\\mathbb{0}$', +u'\U0001d7d9': '$\\mathbb{1}$', +u'\U0001d7da': '$\\mathbb{2}$', +u'\U0001d7db': '$\\mathbb{3}$', +u'\U0001d7dc': '$\\mathbb{4}$', +u'\U0001d7dd': '$\\mathbb{5}$', +u'\U0001d7de': '$\\mathbb{6}$', +u'\U0001d7df': '$\\mathbb{7}$', +u'\U0001d7e0': '$\\mathbb{8}$', +u'\U0001d7e1': '$\\mathbb{9}$', +u'\U0001d7e2': '$\\mathsf{0}$', +u'\U0001d7e3': '$\\mathsf{1}$', +u'\U0001d7e4': '$\\mathsf{2}$', +u'\U0001d7e5': '$\\mathsf{3}$', +u'\U0001d7e6': '$\\mathsf{4}$', +u'\U0001d7e7': '$\\mathsf{5}$', +u'\U0001d7e8': '$\\mathsf{6}$', +u'\U0001d7e9': '$\\mathsf{7}$', +u'\U0001d7ea': '$\\mathsf{8}$', +u'\U0001d7eb': '$\\mathsf{9}$', +u'\U0001d7ec': '$\\mathsfbf{0}$', +u'\U0001d7ed': '$\\mathsfbf{1}$', +u'\U0001d7ee': '$\\mathsfbf{2}$', +u'\U0001d7ef': '$\\mathsfbf{3}$', +u'\U0001d7f0': '$\\mathsfbf{4}$', +u'\U0001d7f1': '$\\mathsfbf{5}$', +u'\U0001d7f2': '$\\mathsfbf{6}$', +u'\U0001d7f3': '$\\mathsfbf{7}$', +u'\U0001d7f4': '$\\mathsfbf{8}$', +u'\U0001d7f5': '$\\mathsfbf{9}$', +u'\U0001d7f6': '$\\mathtt{0}$', +u'\U0001d7f7': '$\\mathtt{1}$', +u'\U0001d7f8': '$\\mathtt{2}$', +u'\U0001d7f9': '$\\mathtt{3}$', +u'\U0001d7fa': '$\\mathtt{4}$', +u'\U0001d7fb': '$\\mathtt{5}$', +u'\U0001d7fc': '$\\mathtt{6}$', +u'\U0001d7fd': '$\\mathtt{7}$', +u'\U0001d7fe': '$\\mathtt{8}$', +u'\U0001d7ff': '$\\mathtt{9}$'} diff --git a/docutils/writers/support/pep_html/pep.css b/docutils/writers/support/pep_html/pep.css new file mode 100644 index 000000000..a687ee8c8 --- /dev/null +++ b/docutils/writers/support/pep_html/pep.css @@ -0,0 +1,349 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date$ +:version: $Revision$ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the PEP HTML output of Docutils. +*/ + +/* "! important" is used here to override other ``margin-top`` and + ``margin-bottom`` styles that are later in the stylesheet or + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ +.first { + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +.navigation { + width: 100% ; + background: #99ccff ; + margin-top: 0px ; + margin-bottom: 0px } + +.navigation .navicon { + width: 150px ; + height: 35px } + +.navigation .textlinks { + padding-left: 1em ; + text-align: left } + +.navigation td, .navigation th { + padding-left: 0em ; + padding-right: 0em ; + vertical-align: middle } + +.rfc2822 { + margin-top: 0.5em ; + margin-left: 0.5em ; + margin-right: 0.5em ; + margin-bottom: 0em } + +.rfc2822 td { + text-align: left } + +.rfc2822 th.field-name { + text-align: right ; + font-family: sans-serif ; + padding-right: 0.5em ; + font-weight: bold ; + margin-bottom: 0em } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +body { + margin: 0px ; + margin-bottom: 1em ; + padding: 0px } + +dl.docutils dd { + margin-bottom: 0.5em } + +div.section { + margin-left: 1em ; + margin-right: 1em ; + margin-bottom: 1.5em } + +div.section div.section { + margin-left: 0em ; + margin-right: 0em ; + margin-top: 1.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.footer { + margin-left: 1em ; + margin-right: 1em } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1 { + font-family: sans-serif ; + font-size: large } + +h2 { + font-family: sans-serif ; + font-size: medium } + +h3 { + font-family: sans-serif ; + font-size: small } + +h4 { + font-family: sans-serif ; + font-style: italic ; + font-size: small } + +h5 { + font-family: sans-serif; + font-size: x-small } + +h6 { + font-family: sans-serif; + font-style: italic ; + font-size: x-small } + +hr.docutils { + width: 75% } + +img.align-left { + clear: left } + +img.align-right { + clear: right } + +img.borderless { + border: 0 } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-family: sans-serif ; + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid thin gray } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid thin black } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +td.num { + text-align: right } + +th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } diff --git a/docutils/writers/support/pep_html/template.txt b/docutils/writers/support/pep_html/template.txt new file mode 100644 index 000000000..6f96977e8 --- /dev/null +++ b/docutils/writers/support/pep_html/template.txt @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="%(encoding)s" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<!-- +This HTML is auto-generated. DO NOT EDIT THIS FILE! If you are writing a new +PEP, see http://www.python.org/peps/pep-0001.html for instructions and links +to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! +--> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" /> + <meta name="generator" content="Docutils %(version)s: http://docutils.sourceforge.net/" /> + <title>PEP %(pep)s -- %(title)s + %(stylesheet)s + +
    list table with integral header
    + + +
    +%(body)s +%(body_suffix)s diff --git a/docutils/writers/support/unicode_latex.py b/docutils/writers/support/unicode_latex.py deleted file mode 100644 index 2998178f4..000000000 --- a/docutils/writers/support/unicode_latex.py +++ /dev/null @@ -1,2371 +0,0 @@ -# Author: Felix Wiemann -# Contact: Felix_Wiemann@ososo.de -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This file has been placed in the public domain. - -# This is a mapping of Unicode characters to LaTeX equivalents. -# The information has been extracted from -# , written by -# David Carlisle and Sebastian Rahtz. -# -# The extraction has been done by the "create_unimap.py" script -# located at . - -unicode_map = {u'\xa0': '$~$', -u'\xa1': '{\\textexclamdown}', -u'\xa2': '{\\textcent}', -u'\xa3': '{\\textsterling}', -u'\xa4': '{\\textcurrency}', -u'\xa5': '{\\textyen}', -u'\xa6': '{\\textbrokenbar}', -u'\xa7': '{\\textsection}', -u'\xa8': '{\\textasciidieresis}', -u'\xa9': '{\\textcopyright}', -u'\xaa': '{\\textordfeminine}', -u'\xab': '{\\guillemotleft}', -u'\xac': '$\\lnot$', -u'\xad': '$\\-$', -u'\xae': '{\\textregistered}', -u'\xaf': '{\\textasciimacron}', -u'\xb0': '{\\textdegree}', -u'\xb1': '$\\pm$', -u'\xb2': '${^2}$', -u'\xb3': '${^3}$', -u'\xb4': '{\\textasciiacute}', -u'\xb5': '$\\mathrm{\\mu}$', -u'\xb6': '{\\textparagraph}', -u'\xb7': '$\\cdot$', -u'\xb8': '{\\c{}}', -u'\xb9': '${^1}$', -u'\xba': '{\\textordmasculine}', -u'\xbb': '{\\guillemotright}', -u'\xbc': '{\\textonequarter}', -u'\xbd': '{\\textonehalf}', -u'\xbe': '{\\textthreequarters}', -u'\xbf': '{\\textquestiondown}', -u'\xc0': '{\\`{A}}', -u'\xc1': "{\\'{A}}", -u'\xc2': '{\\^{A}}', -u'\xc3': '{\\~{A}}', -u'\xc4': '{\\"{A}}', -u'\xc5': '{\\AA}', -u'\xc6': '{\\AE}', -u'\xc7': '{\\c{C}}', -u'\xc8': '{\\`{E}}', -u'\xc9': "{\\'{E}}", -u'\xca': '{\\^{E}}', -u'\xcb': '{\\"{E}}', -u'\xcc': '{\\`{I}}', -u'\xcd': "{\\'{I}}", -u'\xce': '{\\^{I}}', -u'\xcf': '{\\"{I}}', -u'\xd0': '{\\DH}', -u'\xd1': '{\\~{N}}', -u'\xd2': '{\\`{O}}', -u'\xd3': "{\\'{O}}", -u'\xd4': '{\\^{O}}', -u'\xd5': '{\\~{O}}', -u'\xd6': '{\\"{O}}', -u'\xd7': '{\\texttimes}', -u'\xd8': '{\\O}', -u'\xd9': '{\\`{U}}', -u'\xda': "{\\'{U}}", -u'\xdb': '{\\^{U}}', -u'\xdc': '{\\"{U}}', -u'\xdd': "{\\'{Y}}", -u'\xde': '{\\TH}', -u'\xdf': '{\\ss}', -u'\xe0': '{\\`{a}}', -u'\xe1': "{\\'{a}}", -u'\xe2': '{\\^{a}}', -u'\xe3': '{\\~{a}}', -u'\xe4': '{\\"{a}}', -u'\xe5': '{\\aa}', -u'\xe6': '{\\ae}', -u'\xe7': '{\\c{c}}', -u'\xe8': '{\\`{e}}', -u'\xe9': "{\\'{e}}", -u'\xea': '{\\^{e}}', -u'\xeb': '{\\"{e}}', -u'\xec': '{\\`{\\i}}', -u'\xed': "{\\'{\\i}}", -u'\xee': '{\\^{\\i}}', -u'\xef': '{\\"{\\i}}', -u'\xf0': '{\\dh}', -u'\xf1': '{\\~{n}}', -u'\xf2': '{\\`{o}}', -u'\xf3': "{\\'{o}}", -u'\xf4': '{\\^{o}}', -u'\xf5': '{\\~{o}}', -u'\xf6': '{\\"{o}}', -u'\xf7': '$\\div$', -u'\xf8': '{\\o}', -u'\xf9': '{\\`{u}}', -u'\xfa': "{\\'{u}}", -u'\xfb': '{\\^{u}}', -u'\xfc': '{\\"{u}}', -u'\xfd': "{\\'{y}}", -u'\xfe': '{\\th}', -u'\xff': '{\\"{y}}', -u'\u0100': '{\\={A}}', -u'\u0101': '{\\={a}}', -u'\u0102': '{\\u{A}}', -u'\u0103': '{\\u{a}}', -u'\u0104': '{\\k{A}}', -u'\u0105': '{\\k{a}}', -u'\u0106': "{\\'{C}}", -u'\u0107': "{\\'{c}}", -u'\u0108': '{\\^{C}}', -u'\u0109': '{\\^{c}}', -u'\u010a': '{\\.{C}}', -u'\u010b': '{\\.{c}}', -u'\u010c': '{\\v{C}}', -u'\u010d': '{\\v{c}}', -u'\u010e': '{\\v{D}}', -u'\u010f': '{\\v{d}}', -u'\u0110': '{\\DJ}', -u'\u0111': '{\\dj}', -u'\u0112': '{\\={E}}', -u'\u0113': '{\\={e}}', -u'\u0114': '{\\u{E}}', -u'\u0115': '{\\u{e}}', -u'\u0116': '{\\.{E}}', -u'\u0117': '{\\.{e}}', -u'\u0118': '{\\k{E}}', -u'\u0119': '{\\k{e}}', -u'\u011a': '{\\v{E}}', -u'\u011b': '{\\v{e}}', -u'\u011c': '{\\^{G}}', -u'\u011d': '{\\^{g}}', -u'\u011e': '{\\u{G}}', -u'\u011f': '{\\u{g}}', -u'\u0120': '{\\.{G}}', -u'\u0121': '{\\.{g}}', -u'\u0122': '{\\c{G}}', -u'\u0123': '{\\c{g}}', -u'\u0124': '{\\^{H}}', -u'\u0125': '{\\^{h}}', -u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', -u'\u0127': '$\\Elzxh$', -u'\u0128': '{\\~{I}}', -u'\u0129': '{\\~{\\i}}', -u'\u012a': '{\\={I}}', -u'\u012b': '{\\={\\i}}', -u'\u012c': '{\\u{I}}', -u'\u012d': '{\\u{\\i}}', -u'\u012e': '{\\k{I}}', -u'\u012f': '{\\k{i}}', -u'\u0130': '{\\.{I}}', -u'\u0131': '{\\i}', -u'\u0132': '{IJ}', -u'\u0133': '{ij}', -u'\u0134': '{\\^{J}}', -u'\u0135': '{\\^{\\j}}', -u'\u0136': '{\\c{K}}', -u'\u0137': '{\\c{k}}', -u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', -u'\u0139': "{\\'{L}}", -u'\u013a': "{\\'{l}}", -u'\u013b': '{\\c{L}}', -u'\u013c': '{\\c{l}}', -u'\u013d': '{\\v{L}}', -u'\u013e': '{\\v{l}}', -u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', -u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', -u'\u0141': '{\\L}', -u'\u0142': '{\\l}', -u'\u0143': "{\\'{N}}", -u'\u0144': "{\\'{n}}", -u'\u0145': '{\\c{N}}', -u'\u0146': '{\\c{n}}', -u'\u0147': '{\\v{N}}', -u'\u0148': '{\\v{n}}', -u'\u0149': "{'n}", -u'\u014a': '{\\NG}', -u'\u014b': '{\\ng}', -u'\u014c': '{\\={O}}', -u'\u014d': '{\\={o}}', -u'\u014e': '{\\u{O}}', -u'\u014f': '{\\u{o}}', -u'\u0150': '{\\H{O}}', -u'\u0151': '{\\H{o}}', -u'\u0152': '{\\OE}', -u'\u0153': '{\\oe}', -u'\u0154': "{\\'{R}}", -u'\u0155': "{\\'{r}}", -u'\u0156': '{\\c{R}}', -u'\u0157': '{\\c{r}}', -u'\u0158': '{\\v{R}}', -u'\u0159': '{\\v{r}}', -u'\u015a': "{\\'{S}}", -u'\u015b': "{\\'{s}}", -u'\u015c': '{\\^{S}}', -u'\u015d': '{\\^{s}}', -u'\u015e': '{\\c{S}}', -u'\u015f': '{\\c{s}}', -u'\u0160': '{\\v{S}}', -u'\u0161': '{\\v{s}}', -u'\u0162': '{\\c{T}}', -u'\u0163': '{\\c{t}}', -u'\u0164': '{\\v{T}}', -u'\u0165': '{\\v{t}}', -u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', -u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', -u'\u0168': '{\\~{U}}', -u'\u0169': '{\\~{u}}', -u'\u016a': '{\\={U}}', -u'\u016b': '{\\={u}}', -u'\u016c': '{\\u{U}}', -u'\u016d': '{\\u{u}}', -u'\u016e': '{\\r{U}}', -u'\u016f': '{\\r{u}}', -u'\u0170': '{\\H{U}}', -u'\u0171': '{\\H{u}}', -u'\u0172': '{\\k{U}}', -u'\u0173': '{\\k{u}}', -u'\u0174': '{\\^{W}}', -u'\u0175': '{\\^{w}}', -u'\u0176': '{\\^{Y}}', -u'\u0177': '{\\^{y}}', -u'\u0178': '{\\"{Y}}', -u'\u0179': "{\\'{Z}}", -u'\u017a': "{\\'{z}}", -u'\u017b': '{\\.{Z}}', -u'\u017c': '{\\.{z}}', -u'\u017d': '{\\v{Z}}', -u'\u017e': '{\\v{z}}', -u'\u0192': '$f$', -u'\u0195': '{\\texthvlig}', -u'\u019e': '{\\textnrleg}', -u'\u01aa': '$\\eth$', -u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', -u'\u01c2': '{\\textdoublepipe}', -u'\u01f5': "{\\'{g}}", -u'\u0250': '$\\Elztrna$', -u'\u0252': '$\\Elztrnsa$', -u'\u0254': '$\\Elzopeno$', -u'\u0256': '$\\Elzrtld$', -u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', -u'\u0259': '$\\Elzschwa$', -u'\u025b': '$\\varepsilon$', -u'\u0261': '{g}', -u'\u0263': '$\\Elzpgamma$', -u'\u0264': '$\\Elzpbgam$', -u'\u0265': '$\\Elztrnh$', -u'\u026c': '$\\Elzbtdl$', -u'\u026d': '$\\Elzrtll$', -u'\u026f': '$\\Elztrnm$', -u'\u0270': '$\\Elztrnmlr$', -u'\u0271': '$\\Elzltlmr$', -u'\u0272': '{\\Elzltln}', -u'\u0273': '$\\Elzrtln$', -u'\u0277': '$\\Elzclomeg$', -u'\u0278': '{\\textphi}', -u'\u0279': '$\\Elztrnr$', -u'\u027a': '$\\Elztrnrl$', -u'\u027b': '$\\Elzrttrnr$', -u'\u027c': '$\\Elzrl$', -u'\u027d': '$\\Elzrtlr$', -u'\u027e': '$\\Elzfhr$', -u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', -u'\u0282': '$\\Elzrtls$', -u'\u0283': '$\\Elzesh$', -u'\u0287': '$\\Elztrnt$', -u'\u0288': '$\\Elzrtlt$', -u'\u028a': '$\\Elzpupsil$', -u'\u028b': '$\\Elzpscrv$', -u'\u028c': '$\\Elzinvv$', -u'\u028d': '$\\Elzinvw$', -u'\u028e': '$\\Elztrny$', -u'\u0290': '$\\Elzrtlz$', -u'\u0292': '$\\Elzyogh$', -u'\u0294': '$\\Elzglst$', -u'\u0295': '$\\Elzreglst$', -u'\u0296': '$\\Elzinglst$', -u'\u029e': '{\\textturnk}', -u'\u02a4': '$\\Elzdyogh$', -u'\u02a7': '$\\Elztesh$', -u'\u02bc': "{'}", -u'\u02c7': '{\\textasciicaron}', -u'\u02c8': '$\\Elzverts$', -u'\u02cc': '$\\Elzverti$', -u'\u02d0': '$\\Elzlmrk$', -u'\u02d1': '$\\Elzhlmrk$', -u'\u02d2': '$\\Elzsbrhr$', -u'\u02d3': '$\\Elzsblhr$', -u'\u02d4': '$\\Elzrais$', -u'\u02d5': '$\\Elzlow$', -u'\u02d8': '{\\textasciibreve}', -u'\u02d9': '{\\textperiodcentered}', -u'\u02da': '{\\r{}}', -u'\u02db': '{\\k{}}', -u'\u02dc': '{\\texttildelow}', -u'\u02dd': '{\\H{}}', -u'\u02e5': '{\\tone{55}}', -u'\u02e6': '{\\tone{44}}', -u'\u02e7': '{\\tone{33}}', -u'\u02e8': '{\\tone{22}}', -u'\u02e9': '{\\tone{11}}', -u'\u0300': '{\\`}', -u'\u0301': "{\\'}", -u'\u0302': '{\\^}', -u'\u0303': '{\\~}', -u'\u0304': '{\\=}', -u'\u0306': '{\\u}', -u'\u0307': '{\\.}', -u'\u0308': '{\\"}', -u'\u030a': '{\\r}', -u'\u030b': '{\\H}', -u'\u030c': '{\\v}', -u'\u030f': '{\\cyrchar\\C}', -u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', -u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', -u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', -u'\u0321': '$\\Elzpalh$', -u'\u0322': '{\\Elzrh}', -u'\u0327': '{\\c}', -u'\u0328': '{\\k}', -u'\u032a': '$\\Elzsbbrg$', -u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', -u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', -u'\u0335': '{\\Elzxl}', -u'\u0336': '{\\Elzbar}', -u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', -u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', -u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', -u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', -u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', -u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', -u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', -u'\u0386': "{\\'{A}}", -u'\u0388': "{\\'{E}}", -u'\u0389': "{\\'{H}}", -u'\u038a': "{\\'{}{I}}", -u'\u038c': "{\\'{}O}", -u'\u038e': "$\\mathrm{'Y}$", -u'\u038f': "$\\mathrm{'\\Omega}$", -u'\u0390': '$\\acute{\\ddot{\\iota}}$', -u'\u0391': '$\\Alpha$', -u'\u0392': '$\\Beta$', -u'\u0393': '$\\Gamma$', -u'\u0394': '$\\Delta$', -u'\u0395': '$\\Epsilon$', -u'\u0396': '$\\Zeta$', -u'\u0397': '$\\Eta$', -u'\u0398': '$\\Theta$', -u'\u0399': '$\\Iota$', -u'\u039a': '$\\Kappa$', -u'\u039b': '$\\Lambda$', -u'\u039c': '$M$', -u'\u039d': '$N$', -u'\u039e': '$\\Xi$', -u'\u039f': '$O$', -u'\u03a0': '$\\Pi$', -u'\u03a1': '$\\Rho$', -u'\u03a3': '$\\Sigma$', -u'\u03a4': '$\\Tau$', -u'\u03a5': '$\\Upsilon$', -u'\u03a6': '$\\Phi$', -u'\u03a7': '$\\Chi$', -u'\u03a8': '$\\Psi$', -u'\u03a9': '$\\Omega$', -u'\u03aa': '$\\mathrm{\\ddot{I}}$', -u'\u03ab': '$\\mathrm{\\ddot{Y}}$', -u'\u03ac': "{\\'{$\\alpha$}}", -u'\u03ad': '$\\acute{\\epsilon}$', -u'\u03ae': '$\\acute{\\eta}$', -u'\u03af': '$\\acute{\\iota}$', -u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', -u'\u03b1': '$\\alpha$', -u'\u03b2': '$\\beta$', -u'\u03b3': '$\\gamma$', -u'\u03b4': '$\\delta$', -u'\u03b5': '$\\epsilon$', -u'\u03b6': '$\\zeta$', -u'\u03b7': '$\\eta$', -u'\u03b8': '{\\texttheta}', -u'\u03b9': '$\\iota$', -u'\u03ba': '$\\kappa$', -u'\u03bb': '$\\lambda$', -u'\u03bc': '$\\mu$', -u'\u03bd': '$\\nu$', -u'\u03be': '$\\xi$', -u'\u03bf': '$o$', -u'\u03c0': '$\\pi$', -u'\u03c1': '$\\rho$', -u'\u03c2': '$\\varsigma$', -u'\u03c3': '$\\sigma$', -u'\u03c4': '$\\tau$', -u'\u03c5': '$\\upsilon$', -u'\u03c6': '$\\varphi$', -u'\u03c7': '$\\chi$', -u'\u03c8': '$\\psi$', -u'\u03c9': '$\\omega$', -u'\u03ca': '$\\ddot{\\iota}$', -u'\u03cb': '$\\ddot{\\upsilon}$', -u'\u03cc': "{\\'{o}}", -u'\u03cd': '$\\acute{\\upsilon}$', -u'\u03ce': '$\\acute{\\omega}$', -u'\u03d0': '{\\Pisymbol{ppi022}{87}}', -u'\u03d1': '{\\textvartheta}', -u'\u03d2': '$\\Upsilon$', -u'\u03d5': '$\\phi$', -u'\u03d6': '$\\varpi$', -u'\u03da': '$\\Stigma$', -u'\u03dc': '$\\Digamma$', -u'\u03dd': '$\\digamma$', -u'\u03de': '$\\Koppa$', -u'\u03e0': '$\\Sampi$', -u'\u03f0': '$\\varkappa$', -u'\u03f1': '$\\varrho$', -u'\u03f4': '{\\textTheta}', -u'\u03f6': '$\\backepsilon$', -u'\u0401': '{\\cyrchar\\CYRYO}', -u'\u0402': '{\\cyrchar\\CYRDJE}', -u'\u0403': "{\\cyrchar{\\'\\CYRG}}", -u'\u0404': '{\\cyrchar\\CYRIE}', -u'\u0405': '{\\cyrchar\\CYRDZE}', -u'\u0406': '{\\cyrchar\\CYRII}', -u'\u0407': '{\\cyrchar\\CYRYI}', -u'\u0408': '{\\cyrchar\\CYRJE}', -u'\u0409': '{\\cyrchar\\CYRLJE}', -u'\u040a': '{\\cyrchar\\CYRNJE}', -u'\u040b': '{\\cyrchar\\CYRTSHE}', -u'\u040c': "{\\cyrchar{\\'\\CYRK}}", -u'\u040e': '{\\cyrchar\\CYRUSHRT}', -u'\u040f': '{\\cyrchar\\CYRDZHE}', -u'\u0410': '{\\cyrchar\\CYRA}', -u'\u0411': '{\\cyrchar\\CYRB}', -u'\u0412': '{\\cyrchar\\CYRV}', -u'\u0413': '{\\cyrchar\\CYRG}', -u'\u0414': '{\\cyrchar\\CYRD}', -u'\u0415': '{\\cyrchar\\CYRE}', -u'\u0416': '{\\cyrchar\\CYRZH}', -u'\u0417': '{\\cyrchar\\CYRZ}', -u'\u0418': '{\\cyrchar\\CYRI}', -u'\u0419': '{\\cyrchar\\CYRISHRT}', -u'\u041a': '{\\cyrchar\\CYRK}', -u'\u041b': '{\\cyrchar\\CYRL}', -u'\u041c': '{\\cyrchar\\CYRM}', -u'\u041d': '{\\cyrchar\\CYRN}', -u'\u041e': '{\\cyrchar\\CYRO}', -u'\u041f': '{\\cyrchar\\CYRP}', -u'\u0420': '{\\cyrchar\\CYRR}', -u'\u0421': '{\\cyrchar\\CYRS}', -u'\u0422': '{\\cyrchar\\CYRT}', -u'\u0423': '{\\cyrchar\\CYRU}', -u'\u0424': '{\\cyrchar\\CYRF}', -u'\u0425': '{\\cyrchar\\CYRH}', -u'\u0426': '{\\cyrchar\\CYRC}', -u'\u0427': '{\\cyrchar\\CYRCH}', -u'\u0428': '{\\cyrchar\\CYRSH}', -u'\u0429': '{\\cyrchar\\CYRSHCH}', -u'\u042a': '{\\cyrchar\\CYRHRDSN}', -u'\u042b': '{\\cyrchar\\CYRERY}', -u'\u042c': '{\\cyrchar\\CYRSFTSN}', -u'\u042d': '{\\cyrchar\\CYREREV}', -u'\u042e': '{\\cyrchar\\CYRYU}', -u'\u042f': '{\\cyrchar\\CYRYA}', -u'\u0430': '{\\cyrchar\\cyra}', -u'\u0431': '{\\cyrchar\\cyrb}', -u'\u0432': '{\\cyrchar\\cyrv}', -u'\u0433': '{\\cyrchar\\cyrg}', -u'\u0434': '{\\cyrchar\\cyrd}', -u'\u0435': '{\\cyrchar\\cyre}', -u'\u0436': '{\\cyrchar\\cyrzh}', -u'\u0437': '{\\cyrchar\\cyrz}', -u'\u0438': '{\\cyrchar\\cyri}', -u'\u0439': '{\\cyrchar\\cyrishrt}', -u'\u043a': '{\\cyrchar\\cyrk}', -u'\u043b': '{\\cyrchar\\cyrl}', -u'\u043c': '{\\cyrchar\\cyrm}', -u'\u043d': '{\\cyrchar\\cyrn}', -u'\u043e': '{\\cyrchar\\cyro}', -u'\u043f': '{\\cyrchar\\cyrp}', -u'\u0440': '{\\cyrchar\\cyrr}', -u'\u0441': '{\\cyrchar\\cyrs}', -u'\u0442': '{\\cyrchar\\cyrt}', -u'\u0443': '{\\cyrchar\\cyru}', -u'\u0444': '{\\cyrchar\\cyrf}', -u'\u0445': '{\\cyrchar\\cyrh}', -u'\u0446': '{\\cyrchar\\cyrc}', -u'\u0447': '{\\cyrchar\\cyrch}', -u'\u0448': '{\\cyrchar\\cyrsh}', -u'\u0449': '{\\cyrchar\\cyrshch}', -u'\u044a': '{\\cyrchar\\cyrhrdsn}', -u'\u044b': '{\\cyrchar\\cyrery}', -u'\u044c': '{\\cyrchar\\cyrsftsn}', -u'\u044d': '{\\cyrchar\\cyrerev}', -u'\u044e': '{\\cyrchar\\cyryu}', -u'\u044f': '{\\cyrchar\\cyrya}', -u'\u0451': '{\\cyrchar\\cyryo}', -u'\u0452': '{\\cyrchar\\cyrdje}', -u'\u0453': "{\\cyrchar{\\'\\cyrg}}", -u'\u0454': '{\\cyrchar\\cyrie}', -u'\u0455': '{\\cyrchar\\cyrdze}', -u'\u0456': '{\\cyrchar\\cyrii}', -u'\u0457': '{\\cyrchar\\cyryi}', -u'\u0458': '{\\cyrchar\\cyrje}', -u'\u0459': '{\\cyrchar\\cyrlje}', -u'\u045a': '{\\cyrchar\\cyrnje}', -u'\u045b': '{\\cyrchar\\cyrtshe}', -u'\u045c': "{\\cyrchar{\\'\\cyrk}}", -u'\u045e': '{\\cyrchar\\cyrushrt}', -u'\u045f': '{\\cyrchar\\cyrdzhe}', -u'\u0460': '{\\cyrchar\\CYROMEGA}', -u'\u0461': '{\\cyrchar\\cyromega}', -u'\u0462': '{\\cyrchar\\CYRYAT}', -u'\u0464': '{\\cyrchar\\CYRIOTE}', -u'\u0465': '{\\cyrchar\\cyriote}', -u'\u0466': '{\\cyrchar\\CYRLYUS}', -u'\u0467': '{\\cyrchar\\cyrlyus}', -u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', -u'\u0469': '{\\cyrchar\\cyriotlyus}', -u'\u046a': '{\\cyrchar\\CYRBYUS}', -u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', -u'\u046d': '{\\cyrchar\\cyriotbyus}', -u'\u046e': '{\\cyrchar\\CYRKSI}', -u'\u046f': '{\\cyrchar\\cyrksi}', -u'\u0470': '{\\cyrchar\\CYRPSI}', -u'\u0471': '{\\cyrchar\\cyrpsi}', -u'\u0472': '{\\cyrchar\\CYRFITA}', -u'\u0474': '{\\cyrchar\\CYRIZH}', -u'\u0478': '{\\cyrchar\\CYRUK}', -u'\u0479': '{\\cyrchar\\cyruk}', -u'\u047a': '{\\cyrchar\\CYROMEGARND}', -u'\u047b': '{\\cyrchar\\cyromegarnd}', -u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', -u'\u047d': '{\\cyrchar\\cyromegatitlo}', -u'\u047e': '{\\cyrchar\\CYROT}', -u'\u047f': '{\\cyrchar\\cyrot}', -u'\u0480': '{\\cyrchar\\CYRKOPPA}', -u'\u0481': '{\\cyrchar\\cyrkoppa}', -u'\u0482': '{\\cyrchar\\cyrthousands}', -u'\u0488': '{\\cyrchar\\cyrhundredthousands}', -u'\u0489': '{\\cyrchar\\cyrmillions}', -u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', -u'\u048d': '{\\cyrchar\\cyrsemisftsn}', -u'\u048e': '{\\cyrchar\\CYRRTICK}', -u'\u048f': '{\\cyrchar\\cyrrtick}', -u'\u0490': '{\\cyrchar\\CYRGUP}', -u'\u0491': '{\\cyrchar\\cyrgup}', -u'\u0492': '{\\cyrchar\\CYRGHCRS}', -u'\u0493': '{\\cyrchar\\cyrghcrs}', -u'\u0494': '{\\cyrchar\\CYRGHK}', -u'\u0495': '{\\cyrchar\\cyrghk}', -u'\u0496': '{\\cyrchar\\CYRZHDSC}', -u'\u0497': '{\\cyrchar\\cyrzhdsc}', -u'\u0498': '{\\cyrchar\\CYRZDSC}', -u'\u0499': '{\\cyrchar\\cyrzdsc}', -u'\u049a': '{\\cyrchar\\CYRKDSC}', -u'\u049b': '{\\cyrchar\\cyrkdsc}', -u'\u049c': '{\\cyrchar\\CYRKVCRS}', -u'\u049d': '{\\cyrchar\\cyrkvcrs}', -u'\u049e': '{\\cyrchar\\CYRKHCRS}', -u'\u049f': '{\\cyrchar\\cyrkhcrs}', -u'\u04a0': '{\\cyrchar\\CYRKBEAK}', -u'\u04a1': '{\\cyrchar\\cyrkbeak}', -u'\u04a2': '{\\cyrchar\\CYRNDSC}', -u'\u04a3': '{\\cyrchar\\cyrndsc}', -u'\u04a4': '{\\cyrchar\\CYRNG}', -u'\u04a5': '{\\cyrchar\\cyrng}', -u'\u04a6': '{\\cyrchar\\CYRPHK}', -u'\u04a7': '{\\cyrchar\\cyrphk}', -u'\u04a8': '{\\cyrchar\\CYRABHHA}', -u'\u04a9': '{\\cyrchar\\cyrabhha}', -u'\u04aa': '{\\cyrchar\\CYRSDSC}', -u'\u04ab': '{\\cyrchar\\cyrsdsc}', -u'\u04ac': '{\\cyrchar\\CYRTDSC}', -u'\u04ad': '{\\cyrchar\\cyrtdsc}', -u'\u04ae': '{\\cyrchar\\CYRY}', -u'\u04af': '{\\cyrchar\\cyry}', -u'\u04b0': '{\\cyrchar\\CYRYHCRS}', -u'\u04b1': '{\\cyrchar\\cyryhcrs}', -u'\u04b2': '{\\cyrchar\\CYRHDSC}', -u'\u04b3': '{\\cyrchar\\cyrhdsc}', -u'\u04b4': '{\\cyrchar\\CYRTETSE}', -u'\u04b5': '{\\cyrchar\\cyrtetse}', -u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', -u'\u04b7': '{\\cyrchar\\cyrchrdsc}', -u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', -u'\u04b9': '{\\cyrchar\\cyrchvcrs}', -u'\u04ba': '{\\cyrchar\\CYRSHHA}', -u'\u04bb': '{\\cyrchar\\cyrshha}', -u'\u04bc': '{\\cyrchar\\CYRABHCH}', -u'\u04bd': '{\\cyrchar\\cyrabhch}', -u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', -u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', -u'\u04c0': '{\\cyrchar\\CYRpalochka}', -u'\u04c3': '{\\cyrchar\\CYRKHK}', -u'\u04c4': '{\\cyrchar\\cyrkhk}', -u'\u04c7': '{\\cyrchar\\CYRNHK}', -u'\u04c8': '{\\cyrchar\\cyrnhk}', -u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', -u'\u04cc': '{\\cyrchar\\cyrchldsc}', -u'\u04d4': '{\\cyrchar\\CYRAE}', -u'\u04d5': '{\\cyrchar\\cyrae}', -u'\u04d8': '{\\cyrchar\\CYRSCHWA}', -u'\u04d9': '{\\cyrchar\\cyrschwa}', -u'\u04e0': '{\\cyrchar\\CYRABHDZE}', -u'\u04e1': '{\\cyrchar\\cyrabhdze}', -u'\u04e8': '{\\cyrchar\\CYROTLD}', -u'\u04e9': '{\\cyrchar\\cyrotld}', -u'\u2002': '{\\hspace{0.6em}}', -u'\u2003': '{\\hspace{1em}}', -u'\u2004': '{\\hspace{0.33em}}', -u'\u2005': '{\\hspace{0.25em}}', -u'\u2006': '{\\hspace{0.166em}}', -u'\u2007': '{\\hphantom{0}}', -u'\u2008': '{\\hphantom{,}}', -u'\u2009': '{\\hspace{0.167em}}', -u'\u200a': '$\\mkern1mu$', -u'\u2010': '{-}', -u'\u2013': '{\\textendash}', -u'\u2014': '{\\textemdash}', -u'\u2015': '{\\rule{1em}{1pt}}', -u'\u2016': '$\\Vert$', -u'\u2018': '{`}', -u'\u2019': "{'}", -u'\u201a': '{,}', -u'\u201b': '$\\Elzreapos$', -u'\u201c': '{\\textquotedblleft}', -u'\u201d': '{\\textquotedblright}', -u'\u201e': '{,,}', -u'\u2020': '{\\textdagger}', -u'\u2021': '{\\textdaggerdbl}', -u'\u2022': '{\\textbullet}', -u'\u2024': '{.}', -u'\u2025': '{..}', -u'\u2026': '{\\ldots}', -u'\u2030': '{\\textperthousand}', -u'\u2031': '{\\textpertenthousand}', -u'\u2032': "${'}$", -u'\u2033': "${''}$", -u'\u2034': "${'''}$", -u'\u2035': '$\\backprime$', -u'\u2039': '{\\guilsinglleft}', -u'\u203a': '{\\guilsinglright}', -u'\u2057': "$''''$", -u'\u205f': '{\\mkern4mu}', -u'\u2060': '{\\nolinebreak}', -u'\u20a7': '{\\ensuremath{\\Elzpes}}', -u'\u20ac': '{\\mbox{\\texteuro}}', -u'\u20db': '$\\dddot$', -u'\u20dc': '$\\ddddot$', -u'\u2102': '$\\mathbb{C}$', -u'\u210a': '{\\mathscr{g}}', -u'\u210b': '$\\mathscr{H}$', -u'\u210c': '$\\mathfrak{H}$', -u'\u210d': '$\\mathbb{H}$', -u'\u210f': '$\\hslash$', -u'\u2110': '$\\mathscr{I}$', -u'\u2111': '$\\mathfrak{I}$', -u'\u2112': '$\\mathscr{L}$', -u'\u2113': '$\\mathscr{l}$', -u'\u2115': '$\\mathbb{N}$', -u'\u2116': '{\\cyrchar\\textnumero}', -u'\u2118': '$\\wp$', -u'\u2119': '$\\mathbb{P}$', -u'\u211a': '$\\mathbb{Q}$', -u'\u211b': '$\\mathscr{R}$', -u'\u211c': '$\\mathfrak{R}$', -u'\u211d': '$\\mathbb{R}$', -u'\u211e': '$\\Elzxrat$', -u'\u2122': '{\\texttrademark}', -u'\u2124': '$\\mathbb{Z}$', -u'\u2126': '$\\Omega$', -u'\u2127': '$\\mho$', -u'\u2128': '$\\mathfrak{Z}$', -u'\u2129': '$\\ElsevierGlyph{2129}$', -u'\u212b': '{\\AA}', -u'\u212c': '$\\mathscr{B}$', -u'\u212d': '$\\mathfrak{C}$', -u'\u212f': '$\\mathscr{e}$', -u'\u2130': '$\\mathscr{E}$', -u'\u2131': '$\\mathscr{F}$', -u'\u2133': '$\\mathscr{M}$', -u'\u2134': '$\\mathscr{o}$', -u'\u2135': '$\\aleph$', -u'\u2136': '$\\beth$', -u'\u2137': '$\\gimel$', -u'\u2138': '$\\daleth$', -u'\u2153': '$\\textfrac{1}{3}$', -u'\u2154': '$\\textfrac{2}{3}$', -u'\u2155': '$\\textfrac{1}{5}$', -u'\u2156': '$\\textfrac{2}{5}$', -u'\u2157': '$\\textfrac{3}{5}$', -u'\u2158': '$\\textfrac{4}{5}$', -u'\u2159': '$\\textfrac{1}{6}$', -u'\u215a': '$\\textfrac{5}{6}$', -u'\u215b': '$\\textfrac{1}{8}$', -u'\u215c': '$\\textfrac{3}{8}$', -u'\u215d': '$\\textfrac{5}{8}$', -u'\u215e': '$\\textfrac{7}{8}$', -u'\u2190': '$\\leftarrow$', -u'\u2191': '$\\uparrow$', -u'\u2192': '$\\rightarrow$', -u'\u2193': '$\\downarrow$', -u'\u2194': '$\\leftrightarrow$', -u'\u2195': '$\\updownarrow$', -u'\u2196': '$\\nwarrow$', -u'\u2197': '$\\nearrow$', -u'\u2198': '$\\searrow$', -u'\u2199': '$\\swarrow$', -u'\u219a': '$\\nleftarrow$', -u'\u219b': '$\\nrightarrow$', -u'\u219c': '$\\arrowwaveright$', -u'\u219d': '$\\arrowwaveright$', -u'\u219e': '$\\twoheadleftarrow$', -u'\u21a0': '$\\twoheadrightarrow$', -u'\u21a2': '$\\leftarrowtail$', -u'\u21a3': '$\\rightarrowtail$', -u'\u21a6': '$\\mapsto$', -u'\u21a9': '$\\hookleftarrow$', -u'\u21aa': '$\\hookrightarrow$', -u'\u21ab': '$\\looparrowleft$', -u'\u21ac': '$\\looparrowright$', -u'\u21ad': '$\\leftrightsquigarrow$', -u'\u21ae': '$\\nleftrightarrow$', -u'\u21b0': '$\\Lsh$', -u'\u21b1': '$\\Rsh$', -u'\u21b3': '$\\ElsevierGlyph{21B3}$', -u'\u21b6': '$\\curvearrowleft$', -u'\u21b7': '$\\curvearrowright$', -u'\u21ba': '$\\circlearrowleft$', -u'\u21bb': '$\\circlearrowright$', -u'\u21bc': '$\\leftharpoonup$', -u'\u21bd': '$\\leftharpoondown$', -u'\u21be': '$\\upharpoonright$', -u'\u21bf': '$\\upharpoonleft$', -u'\u21c0': '$\\rightharpoonup$', -u'\u21c1': '$\\rightharpoondown$', -u'\u21c2': '$\\downharpoonright$', -u'\u21c3': '$\\downharpoonleft$', -u'\u21c4': '$\\rightleftarrows$', -u'\u21c5': '$\\dblarrowupdown$', -u'\u21c6': '$\\leftrightarrows$', -u'\u21c7': '$\\leftleftarrows$', -u'\u21c8': '$\\upuparrows$', -u'\u21c9': '$\\rightrightarrows$', -u'\u21ca': '$\\downdownarrows$', -u'\u21cb': '$\\leftrightharpoons$', -u'\u21cc': '$\\rightleftharpoons$', -u'\u21cd': '$\\nLeftarrow$', -u'\u21ce': '$\\nLeftrightarrow$', -u'\u21cf': '$\\nRightarrow$', -u'\u21d0': '$\\Leftarrow$', -u'\u21d1': '$\\Uparrow$', -u'\u21d2': '$\\Rightarrow$', -u'\u21d3': '$\\Downarrow$', -u'\u21d4': '$\\Leftrightarrow$', -u'\u21d5': '$\\Updownarrow$', -u'\u21da': '$\\Lleftarrow$', -u'\u21db': '$\\Rrightarrow$', -u'\u21dd': '$\\rightsquigarrow$', -u'\u21f5': '$\\DownArrowUpArrow$', -u'\u2200': '$\\forall$', -u'\u2201': '$\\complement$', -u'\u2202': '$\\partial$', -u'\u2203': '$\\exists$', -u'\u2204': '$\\nexists$', -u'\u2205': '$\\varnothing$', -u'\u2207': '$\\nabla$', -u'\u2208': '$\\in$', -u'\u2209': '$\\not\\in$', -u'\u220b': '$\\ni$', -u'\u220c': '$\\not\\ni$', -u'\u220f': '$\\prod$', -u'\u2210': '$\\coprod$', -u'\u2211': '$\\sum$', -u'\u2212': '{-}', -u'\u2213': '$\\mp$', -u'\u2214': '$\\dotplus$', -u'\u2216': '$\\setminus$', -u'\u2217': '${_\\ast}$', -u'\u2218': '$\\circ$', -u'\u2219': '$\\bullet$', -u'\u221a': '$\\surd$', -u'\u221d': '$\\propto$', -u'\u221e': '$\\infty$', -u'\u221f': '$\\rightangle$', -u'\u2220': '$\\angle$', -u'\u2221': '$\\measuredangle$', -u'\u2222': '$\\sphericalangle$', -u'\u2223': '$\\mid$', -u'\u2224': '$\\nmid$', -u'\u2225': '$\\parallel$', -u'\u2226': '$\\nparallel$', -u'\u2227': '$\\wedge$', -u'\u2228': '$\\vee$', -u'\u2229': '$\\cap$', -u'\u222a': '$\\cup$', -u'\u222b': '$\\int$', -u'\u222c': '$\\int\\!\\int$', -u'\u222d': '$\\int\\!\\int\\!\\int$', -u'\u222e': '$\\oint$', -u'\u222f': '$\\surfintegral$', -u'\u2230': '$\\volintegral$', -u'\u2231': '$\\clwintegral$', -u'\u2232': '$\\ElsevierGlyph{2232}$', -u'\u2233': '$\\ElsevierGlyph{2233}$', -u'\u2234': '$\\therefore$', -u'\u2235': '$\\because$', -u'\u2237': '$\\Colon$', -u'\u2238': '$\\ElsevierGlyph{2238}$', -u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', -u'\u223b': '$\\homothetic$', -u'\u223c': '$\\sim$', -u'\u223d': '$\\backsim$', -u'\u223e': '$\\lazysinv$', -u'\u2240': '$\\wr$', -u'\u2241': '$\\not\\sim$', -u'\u2242': '$\\ElsevierGlyph{2242}$', -u'\u2243': '$\\simeq$', -u'\u2244': '$\\not\\simeq$', -u'\u2245': '$\\cong$', -u'\u2246': '$\\approxnotequal$', -u'\u2247': '$\\not\\cong$', -u'\u2248': '$\\approx$', -u'\u2249': '$\\not\\approx$', -u'\u224a': '$\\approxeq$', -u'\u224b': '$\\tildetrpl$', -u'\u224c': '$\\allequal$', -u'\u224d': '$\\asymp$', -u'\u224e': '$\\Bumpeq$', -u'\u224f': '$\\bumpeq$', -u'\u2250': '$\\doteq$', -u'\u2251': '$\\doteqdot$', -u'\u2252': '$\\fallingdotseq$', -u'\u2253': '$\\risingdotseq$', -u'\u2254': '{:=}', -u'\u2255': '$=:$', -u'\u2256': '$\\eqcirc$', -u'\u2257': '$\\circeq$', -u'\u2259': '$\\estimates$', -u'\u225a': '$\\ElsevierGlyph{225A}$', -u'\u225b': '$\\starequal$', -u'\u225c': '$\\triangleq$', -u'\u225f': '$\\ElsevierGlyph{225F}$', -u'\u2260': '$\\not =$', -u'\u2261': '$\\equiv$', -u'\u2262': '$\\not\\equiv$', -u'\u2264': '$\\leq$', -u'\u2265': '$\\geq$', -u'\u2266': '$\\leqq$', -u'\u2267': '$\\geqq$', -u'\u2268': '$\\lneqq$', -u'\u2269': '$\\gneqq$', -u'\u226a': '$\\ll$', -u'\u226b': '$\\gg$', -u'\u226c': '$\\between$', -u'\u226d': '$\\not\\kern-0.3em\\times$', -u'\u226e': '$\\not<$', -u'\u226f': '$\\not>$', -u'\u2270': '$\\not\\leq$', -u'\u2271': '$\\not\\geq$', -u'\u2272': '$\\lessequivlnt$', -u'\u2273': '$\\greaterequivlnt$', -u'\u2274': '$\\ElsevierGlyph{2274}$', -u'\u2275': '$\\ElsevierGlyph{2275}$', -u'\u2276': '$\\lessgtr$', -u'\u2277': '$\\gtrless$', -u'\u2278': '$\\notlessgreater$', -u'\u2279': '$\\notgreaterless$', -u'\u227a': '$\\prec$', -u'\u227b': '$\\succ$', -u'\u227c': '$\\preccurlyeq$', -u'\u227d': '$\\succcurlyeq$', -u'\u227e': '$\\precapprox$', -u'\u227f': '$\\succapprox$', -u'\u2280': '$\\not\\prec$', -u'\u2281': '$\\not\\succ$', -u'\u2282': '$\\subset$', -u'\u2283': '$\\supset$', -u'\u2284': '$\\not\\subset$', -u'\u2285': '$\\not\\supset$', -u'\u2286': '$\\subseteq$', -u'\u2287': '$\\supseteq$', -u'\u2288': '$\\not\\subseteq$', -u'\u2289': '$\\not\\supseteq$', -u'\u228a': '$\\subsetneq$', -u'\u228b': '$\\supsetneq$', -u'\u228e': '$\\uplus$', -u'\u228f': '$\\sqsubset$', -u'\u2290': '$\\sqsupset$', -u'\u2291': '$\\sqsubseteq$', -u'\u2292': '$\\sqsupseteq$', -u'\u2293': '$\\sqcap$', -u'\u2294': '$\\sqcup$', -u'\u2295': '$\\oplus$', -u'\u2296': '$\\ominus$', -u'\u2297': '$\\otimes$', -u'\u2298': '$\\oslash$', -u'\u2299': '$\\odot$', -u'\u229a': '$\\circledcirc$', -u'\u229b': '$\\circledast$', -u'\u229d': '$\\circleddash$', -u'\u229e': '$\\boxplus$', -u'\u229f': '$\\boxminus$', -u'\u22a0': '$\\boxtimes$', -u'\u22a1': '$\\boxdot$', -u'\u22a2': '$\\vdash$', -u'\u22a3': '$\\dashv$', -u'\u22a4': '$\\top$', -u'\u22a5': '$\\perp$', -u'\u22a7': '$\\truestate$', -u'\u22a8': '$\\forcesextra$', -u'\u22a9': '$\\Vdash$', -u'\u22aa': '$\\Vvdash$', -u'\u22ab': '$\\VDash$', -u'\u22ac': '$\\nvdash$', -u'\u22ad': '$\\nvDash$', -u'\u22ae': '$\\nVdash$', -u'\u22af': '$\\nVDash$', -u'\u22b2': '$\\vartriangleleft$', -u'\u22b3': '$\\vartriangleright$', -u'\u22b4': '$\\trianglelefteq$', -u'\u22b5': '$\\trianglerighteq$', -u'\u22b6': '$\\original$', -u'\u22b7': '$\\image$', -u'\u22b8': '$\\multimap$', -u'\u22b9': '$\\hermitconjmatrix$', -u'\u22ba': '$\\intercal$', -u'\u22bb': '$\\veebar$', -u'\u22be': '$\\rightanglearc$', -u'\u22c0': '$\\ElsevierGlyph{22C0}$', -u'\u22c1': '$\\ElsevierGlyph{22C1}$', -u'\u22c2': '$\\bigcap$', -u'\u22c3': '$\\bigcup$', -u'\u22c4': '$\\diamond$', -u'\u22c5': '$\\cdot$', -u'\u22c6': '$\\star$', -u'\u22c7': '$\\divideontimes$', -u'\u22c8': '$\\bowtie$', -u'\u22c9': '$\\ltimes$', -u'\u22ca': '$\\rtimes$', -u'\u22cb': '$\\leftthreetimes$', -u'\u22cc': '$\\rightthreetimes$', -u'\u22cd': '$\\backsimeq$', -u'\u22ce': '$\\curlyvee$', -u'\u22cf': '$\\curlywedge$', -u'\u22d0': '$\\Subset$', -u'\u22d1': '$\\Supset$', -u'\u22d2': '$\\Cap$', -u'\u22d3': '$\\Cup$', -u'\u22d4': '$\\pitchfork$', -u'\u22d6': '$\\lessdot$', -u'\u22d7': '$\\gtrdot$', -u'\u22d8': '$\\verymuchless$', -u'\u22d9': '$\\verymuchgreater$', -u'\u22da': '$\\lesseqgtr$', -u'\u22db': '$\\gtreqless$', -u'\u22de': '$\\curlyeqprec$', -u'\u22df': '$\\curlyeqsucc$', -u'\u22e2': '$\\not\\sqsubseteq$', -u'\u22e3': '$\\not\\sqsupseteq$', -u'\u22e5': '$\\Elzsqspne$', -u'\u22e6': '$\\lnsim$', -u'\u22e7': '$\\gnsim$', -u'\u22e8': '$\\precedesnotsimilar$', -u'\u22e9': '$\\succnsim$', -u'\u22ea': '$\\ntriangleleft$', -u'\u22eb': '$\\ntriangleright$', -u'\u22ec': '$\\ntrianglelefteq$', -u'\u22ed': '$\\ntrianglerighteq$', -u'\u22ee': '$\\vdots$', -u'\u22ef': '$\\cdots$', -u'\u22f0': '$\\upslopeellipsis$', -u'\u22f1': '$\\downslopeellipsis$', -u'\u2305': '{\\barwedge}', -u'\u2306': '$\\perspcorrespond$', -u'\u2308': '$\\lceil$', -u'\u2309': '$\\rceil$', -u'\u230a': '$\\lfloor$', -u'\u230b': '$\\rfloor$', -u'\u2315': '$\\recorder$', -u'\u2316': '$\\mathchar"2208$', -u'\u231c': '$\\ulcorner$', -u'\u231d': '$\\urcorner$', -u'\u231e': '$\\llcorner$', -u'\u231f': '$\\lrcorner$', -u'\u2322': '$\\frown$', -u'\u2323': '$\\smile$', -u'\u2329': '$\\langle$', -u'\u232a': '$\\rangle$', -u'\u233d': '$\\ElsevierGlyph{E838}$', -u'\u23a3': '$\\Elzdlcorn$', -u'\u23b0': '$\\lmoustache$', -u'\u23b1': '$\\rmoustache$', -u'\u2423': '{\\textvisiblespace}', -u'\u2460': '{\\ding{172}}', -u'\u2461': '{\\ding{173}}', -u'\u2462': '{\\ding{174}}', -u'\u2463': '{\\ding{175}}', -u'\u2464': '{\\ding{176}}', -u'\u2465': '{\\ding{177}}', -u'\u2466': '{\\ding{178}}', -u'\u2467': '{\\ding{179}}', -u'\u2468': '{\\ding{180}}', -u'\u2469': '{\\ding{181}}', -u'\u24c8': '$\\circledS$', -u'\u2506': '$\\Elzdshfnc$', -u'\u2519': '$\\Elzsqfnw$', -u'\u2571': '$\\diagup$', -u'\u25a0': '{\\ding{110}}', -u'\u25a1': '$\\square$', -u'\u25aa': '$\\blacksquare$', -u'\u25ad': '$\\fbox{~~}$', -u'\u25af': '$\\Elzvrecto$', -u'\u25b1': '$\\ElsevierGlyph{E381}$', -u'\u25b2': '{\\ding{115}}', -u'\u25b3': '$\\bigtriangleup$', -u'\u25b4': '$\\blacktriangle$', -u'\u25b5': '$\\vartriangle$', -u'\u25b8': '$\\blacktriangleright$', -u'\u25b9': '$\\triangleright$', -u'\u25bc': '{\\ding{116}}', -u'\u25bd': '$\\bigtriangledown$', -u'\u25be': '$\\blacktriangledown$', -u'\u25bf': '$\\triangledown$', -u'\u25c2': '$\\blacktriangleleft$', -u'\u25c3': '$\\triangleleft$', -u'\u25c6': '{\\ding{117}}', -u'\u25ca': '$\\lozenge$', -u'\u25cb': '$\\bigcirc$', -u'\u25cf': '{\\ding{108}}', -u'\u25d0': '$\\Elzcirfl$', -u'\u25d1': '$\\Elzcirfr$', -u'\u25d2': '$\\Elzcirfb$', -u'\u25d7': '{\\ding{119}}', -u'\u25d8': '$\\Elzrvbull$', -u'\u25e7': '$\\Elzsqfl$', -u'\u25e8': '$\\Elzsqfr$', -u'\u25ea': '$\\Elzsqfse$', -u'\u25ef': '$\\bigcirc$', -u'\u2605': '{\\ding{72}}', -u'\u2606': '{\\ding{73}}', -u'\u260e': '{\\ding{37}}', -u'\u261b': '{\\ding{42}}', -u'\u261e': '{\\ding{43}}', -u'\u263e': '{\\rightmoon}', -u'\u263f': '{\\mercury}', -u'\u2640': '{\\venus}', -u'\u2642': '{\\male}', -u'\u2643': '{\\jupiter}', -u'\u2644': '{\\saturn}', -u'\u2645': '{\\uranus}', -u'\u2646': '{\\neptune}', -u'\u2647': '{\\pluto}', -u'\u2648': '{\\aries}', -u'\u2649': '{\\taurus}', -u'\u264a': '{\\gemini}', -u'\u264b': '{\\cancer}', -u'\u264c': '{\\leo}', -u'\u264d': '{\\virgo}', -u'\u264e': '{\\libra}', -u'\u264f': '{\\scorpio}', -u'\u2650': '{\\sagittarius}', -u'\u2651': '{\\capricornus}', -u'\u2652': '{\\aquarius}', -u'\u2653': '{\\pisces}', -u'\u2660': '{\\ding{171}}', -u'\u2662': '$\\diamond$', -u'\u2663': '{\\ding{168}}', -u'\u2665': '{\\ding{170}}', -u'\u2666': '{\\ding{169}}', -u'\u2669': '{\\quarternote}', -u'\u266a': '{\\eighthnote}', -u'\u266d': '$\\flat$', -u'\u266e': '$\\natural$', -u'\u266f': '$\\sharp$', -u'\u2701': '{\\ding{33}}', -u'\u2702': '{\\ding{34}}', -u'\u2703': '{\\ding{35}}', -u'\u2704': '{\\ding{36}}', -u'\u2706': '{\\ding{38}}', -u'\u2707': '{\\ding{39}}', -u'\u2708': '{\\ding{40}}', -u'\u2709': '{\\ding{41}}', -u'\u270c': '{\\ding{44}}', -u'\u270d': '{\\ding{45}}', -u'\u270e': '{\\ding{46}}', -u'\u270f': '{\\ding{47}}', -u'\u2710': '{\\ding{48}}', -u'\u2711': '{\\ding{49}}', -u'\u2712': '{\\ding{50}}', -u'\u2713': '{\\ding{51}}', -u'\u2714': '{\\ding{52}}', -u'\u2715': '{\\ding{53}}', -u'\u2716': '{\\ding{54}}', -u'\u2717': '{\\ding{55}}', -u'\u2718': '{\\ding{56}}', -u'\u2719': '{\\ding{57}}', -u'\u271a': '{\\ding{58}}', -u'\u271b': '{\\ding{59}}', -u'\u271c': '{\\ding{60}}', -u'\u271d': '{\\ding{61}}', -u'\u271e': '{\\ding{62}}', -u'\u271f': '{\\ding{63}}', -u'\u2720': '{\\ding{64}}', -u'\u2721': '{\\ding{65}}', -u'\u2722': '{\\ding{66}}', -u'\u2723': '{\\ding{67}}', -u'\u2724': '{\\ding{68}}', -u'\u2725': '{\\ding{69}}', -u'\u2726': '{\\ding{70}}', -u'\u2727': '{\\ding{71}}', -u'\u2729': '{\\ding{73}}', -u'\u272a': '{\\ding{74}}', -u'\u272b': '{\\ding{75}}', -u'\u272c': '{\\ding{76}}', -u'\u272d': '{\\ding{77}}', -u'\u272e': '{\\ding{78}}', -u'\u272f': '{\\ding{79}}', -u'\u2730': '{\\ding{80}}', -u'\u2731': '{\\ding{81}}', -u'\u2732': '{\\ding{82}}', -u'\u2733': '{\\ding{83}}', -u'\u2734': '{\\ding{84}}', -u'\u2735': '{\\ding{85}}', -u'\u2736': '{\\ding{86}}', -u'\u2737': '{\\ding{87}}', -u'\u2738': '{\\ding{88}}', -u'\u2739': '{\\ding{89}}', -u'\u273a': '{\\ding{90}}', -u'\u273b': '{\\ding{91}}', -u'\u273c': '{\\ding{92}}', -u'\u273d': '{\\ding{93}}', -u'\u273e': '{\\ding{94}}', -u'\u273f': '{\\ding{95}}', -u'\u2740': '{\\ding{96}}', -u'\u2741': '{\\ding{97}}', -u'\u2742': '{\\ding{98}}', -u'\u2743': '{\\ding{99}}', -u'\u2744': '{\\ding{100}}', -u'\u2745': '{\\ding{101}}', -u'\u2746': '{\\ding{102}}', -u'\u2747': '{\\ding{103}}', -u'\u2748': '{\\ding{104}}', -u'\u2749': '{\\ding{105}}', -u'\u274a': '{\\ding{106}}', -u'\u274b': '{\\ding{107}}', -u'\u274d': '{\\ding{109}}', -u'\u274f': '{\\ding{111}}', -u'\u2750': '{\\ding{112}}', -u'\u2751': '{\\ding{113}}', -u'\u2752': '{\\ding{114}}', -u'\u2756': '{\\ding{118}}', -u'\u2758': '{\\ding{120}}', -u'\u2759': '{\\ding{121}}', -u'\u275a': '{\\ding{122}}', -u'\u275b': '{\\ding{123}}', -u'\u275c': '{\\ding{124}}', -u'\u275d': '{\\ding{125}}', -u'\u275e': '{\\ding{126}}', -u'\u2761': '{\\ding{161}}', -u'\u2762': '{\\ding{162}}', -u'\u2763': '{\\ding{163}}', -u'\u2764': '{\\ding{164}}', -u'\u2765': '{\\ding{165}}', -u'\u2766': '{\\ding{166}}', -u'\u2767': '{\\ding{167}}', -u'\u2776': '{\\ding{182}}', -u'\u2777': '{\\ding{183}}', -u'\u2778': '{\\ding{184}}', -u'\u2779': '{\\ding{185}}', -u'\u277a': '{\\ding{186}}', -u'\u277b': '{\\ding{187}}', -u'\u277c': '{\\ding{188}}', -u'\u277d': '{\\ding{189}}', -u'\u277e': '{\\ding{190}}', -u'\u277f': '{\\ding{191}}', -u'\u2780': '{\\ding{192}}', -u'\u2781': '{\\ding{193}}', -u'\u2782': '{\\ding{194}}', -u'\u2783': '{\\ding{195}}', -u'\u2784': '{\\ding{196}}', -u'\u2785': '{\\ding{197}}', -u'\u2786': '{\\ding{198}}', -u'\u2787': '{\\ding{199}}', -u'\u2788': '{\\ding{200}}', -u'\u2789': '{\\ding{201}}', -u'\u278a': '{\\ding{202}}', -u'\u278b': '{\\ding{203}}', -u'\u278c': '{\\ding{204}}', -u'\u278d': '{\\ding{205}}', -u'\u278e': '{\\ding{206}}', -u'\u278f': '{\\ding{207}}', -u'\u2790': '{\\ding{208}}', -u'\u2791': '{\\ding{209}}', -u'\u2792': '{\\ding{210}}', -u'\u2793': '{\\ding{211}}', -u'\u2794': '{\\ding{212}}', -u'\u2798': '{\\ding{216}}', -u'\u2799': '{\\ding{217}}', -u'\u279a': '{\\ding{218}}', -u'\u279b': '{\\ding{219}}', -u'\u279c': '{\\ding{220}}', -u'\u279d': '{\\ding{221}}', -u'\u279e': '{\\ding{222}}', -u'\u279f': '{\\ding{223}}', -u'\u27a0': '{\\ding{224}}', -u'\u27a1': '{\\ding{225}}', -u'\u27a2': '{\\ding{226}}', -u'\u27a3': '{\\ding{227}}', -u'\u27a4': '{\\ding{228}}', -u'\u27a5': '{\\ding{229}}', -u'\u27a6': '{\\ding{230}}', -u'\u27a7': '{\\ding{231}}', -u'\u27a8': '{\\ding{232}}', -u'\u27a9': '{\\ding{233}}', -u'\u27aa': '{\\ding{234}}', -u'\u27ab': '{\\ding{235}}', -u'\u27ac': '{\\ding{236}}', -u'\u27ad': '{\\ding{237}}', -u'\u27ae': '{\\ding{238}}', -u'\u27af': '{\\ding{239}}', -u'\u27b1': '{\\ding{241}}', -u'\u27b2': '{\\ding{242}}', -u'\u27b3': '{\\ding{243}}', -u'\u27b4': '{\\ding{244}}', -u'\u27b5': '{\\ding{245}}', -u'\u27b6': '{\\ding{246}}', -u'\u27b7': '{\\ding{247}}', -u'\u27b8': '{\\ding{248}}', -u'\u27b9': '{\\ding{249}}', -u'\u27ba': '{\\ding{250}}', -u'\u27bb': '{\\ding{251}}', -u'\u27bc': '{\\ding{252}}', -u'\u27bd': '{\\ding{253}}', -u'\u27be': '{\\ding{254}}', -u'\u27f5': '$\\longleftarrow$', -u'\u27f6': '$\\longrightarrow$', -u'\u27f7': '$\\longleftrightarrow$', -u'\u27f8': '$\\Longleftarrow$', -u'\u27f9': '$\\Longrightarrow$', -u'\u27fa': '$\\Longleftrightarrow$', -u'\u27fc': '$\\longmapsto$', -u'\u27ff': '$\\sim\\joinrel\\leadsto$', -u'\u2905': '$\\ElsevierGlyph{E212}$', -u'\u2912': '$\\UpArrowBar$', -u'\u2913': '$\\DownArrowBar$', -u'\u2923': '$\\ElsevierGlyph{E20C}$', -u'\u2924': '$\\ElsevierGlyph{E20D}$', -u'\u2925': '$\\ElsevierGlyph{E20B}$', -u'\u2926': '$\\ElsevierGlyph{E20A}$', -u'\u2927': '$\\ElsevierGlyph{E211}$', -u'\u2928': '$\\ElsevierGlyph{E20E}$', -u'\u2929': '$\\ElsevierGlyph{E20F}$', -u'\u292a': '$\\ElsevierGlyph{E210}$', -u'\u2933': '$\\ElsevierGlyph{E21C}$', -u'\u2936': '$\\ElsevierGlyph{E21A}$', -u'\u2937': '$\\ElsevierGlyph{E219}$', -u'\u2940': '$\\Elolarr$', -u'\u2941': '$\\Elorarr$', -u'\u2942': '$\\ElzRlarr$', -u'\u2944': '$\\ElzrLarr$', -u'\u2947': '$\\Elzrarrx$', -u'\u294e': '$\\LeftRightVector$', -u'\u294f': '$\\RightUpDownVector$', -u'\u2950': '$\\DownLeftRightVector$', -u'\u2951': '$\\LeftUpDownVector$', -u'\u2952': '$\\LeftVectorBar$', -u'\u2953': '$\\RightVectorBar$', -u'\u2954': '$\\RightUpVectorBar$', -u'\u2955': '$\\RightDownVectorBar$', -u'\u2956': '$\\DownLeftVectorBar$', -u'\u2957': '$\\DownRightVectorBar$', -u'\u2958': '$\\LeftUpVectorBar$', -u'\u2959': '$\\LeftDownVectorBar$', -u'\u295a': '$\\LeftTeeVector$', -u'\u295b': '$\\RightTeeVector$', -u'\u295c': '$\\RightUpTeeVector$', -u'\u295d': '$\\RightDownTeeVector$', -u'\u295e': '$\\DownLeftTeeVector$', -u'\u295f': '$\\DownRightTeeVector$', -u'\u2960': '$\\LeftUpTeeVector$', -u'\u2961': '$\\LeftDownTeeVector$', -u'\u296e': '$\\UpEquilibrium$', -u'\u296f': '$\\ReverseUpEquilibrium$', -u'\u2970': '$\\RoundImplies$', -u'\u297c': '$\\ElsevierGlyph{E214}$', -u'\u297d': '$\\ElsevierGlyph{E215}$', -u'\u2980': '$\\Elztfnc$', -u'\u2985': '$\\ElsevierGlyph{3018}$', -u'\u2986': '$\\Elroang$', -u'\u2993': '$<\\kern-0.58em($', -u'\u2994': '$\\ElsevierGlyph{E291}$', -u'\u2999': '$\\Elzddfnc$', -u'\u299c': '$\\Angle$', -u'\u29a0': '$\\Elzlpargt$', -u'\u29b5': '$\\ElsevierGlyph{E260}$', -u'\u29b6': '$\\ElsevierGlyph{E61B}$', -u'\u29ca': '$\\ElzLap$', -u'\u29cb': '$\\Elzdefas$', -u'\u29cf': '$\\LeftTriangleBar$', -u'\u29d0': '$\\RightTriangleBar$', -u'\u29dc': '$\\ElsevierGlyph{E372}$', -u'\u29eb': '$\\blacklozenge$', -u'\u29f4': '$\\RuleDelayed$', -u'\u2a04': '$\\Elxuplus$', -u'\u2a05': '$\\ElzThr$', -u'\u2a06': '$\\Elxsqcup$', -u'\u2a07': '$\\ElzInf$', -u'\u2a08': '$\\ElzSup$', -u'\u2a0d': '$\\ElzCint$', -u'\u2a0f': '$\\clockoint$', -u'\u2a10': '$\\ElsevierGlyph{E395}$', -u'\u2a16': '$\\sqrint$', -u'\u2a25': '$\\ElsevierGlyph{E25A}$', -u'\u2a2a': '$\\ElsevierGlyph{E25B}$', -u'\u2a2d': '$\\ElsevierGlyph{E25C}$', -u'\u2a2e': '$\\ElsevierGlyph{E25D}$', -u'\u2a2f': '$\\ElzTimes$', -u'\u2a34': '$\\ElsevierGlyph{E25E}$', -u'\u2a35': '$\\ElsevierGlyph{E25E}$', -u'\u2a3c': '$\\ElsevierGlyph{E259}$', -u'\u2a3f': '$\\amalg$', -u'\u2a53': '$\\ElzAnd$', -u'\u2a54': '$\\ElzOr$', -u'\u2a55': '$\\ElsevierGlyph{E36E}$', -u'\u2a56': '$\\ElOr$', -u'\u2a5e': '$\\perspcorrespond$', -u'\u2a5f': '$\\Elzminhat$', -u'\u2a63': '$\\ElsevierGlyph{225A}$', -u'\u2a6e': '$\\stackrel{*}{=}$', -u'\u2a75': '$\\Equal$', -u'\u2a7d': '$\\leqslant$', -u'\u2a7e': '$\\geqslant$', -u'\u2a85': '$\\lessapprox$', -u'\u2a86': '$\\gtrapprox$', -u'\u2a87': '$\\lneq$', -u'\u2a88': '$\\gneq$', -u'\u2a89': '$\\lnapprox$', -u'\u2a8a': '$\\gnapprox$', -u'\u2a8b': '$\\lesseqqgtr$', -u'\u2a8c': '$\\gtreqqless$', -u'\u2a95': '$\\eqslantless$', -u'\u2a96': '$\\eqslantgtr$', -u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', -u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', -u'\u2aa1': '$\\NestedLessLess$', -u'\u2aa2': '$\\NestedGreaterGreater$', -u'\u2aaf': '$\\preceq$', -u'\u2ab0': '$\\succeq$', -u'\u2ab5': '$\\precneqq$', -u'\u2ab6': '$\\succneqq$', -u'\u2ab7': '$\\precapprox$', -u'\u2ab8': '$\\succapprox$', -u'\u2ab9': '$\\precnapprox$', -u'\u2aba': '$\\succnapprox$', -u'\u2ac5': '$\\subseteqq$', -u'\u2ac6': '$\\supseteqq$', -u'\u2acb': '$\\subsetneqq$', -u'\u2acc': '$\\supsetneqq$', -u'\u2aeb': '$\\ElsevierGlyph{E30D}$', -u'\u2af6': '$\\Elztdcol$', -u'\u2afd': '${{/}\\!\\!{/}}$', -u'\u300a': '$\\ElsevierGlyph{300A}$', -u'\u300b': '$\\ElsevierGlyph{300B}$', -u'\u3018': '$\\ElsevierGlyph{3018}$', -u'\u3019': '$\\ElsevierGlyph{3019}$', -u'\u301a': '$\\openbracketleft$', -u'\u301b': '$\\openbracketright$', -u'\ufb00': '{ff}', -u'\ufb01': '{fi}', -u'\ufb02': '{fl}', -u'\ufb03': '{ffi}', -u'\ufb04': '{ffl}', -u'\U0001d400': '$\\mathbf{A}$', -u'\U0001d401': '$\\mathbf{B}$', -u'\U0001d402': '$\\mathbf{C}$', -u'\U0001d403': '$\\mathbf{D}$', -u'\U0001d404': '$\\mathbf{E}$', -u'\U0001d405': '$\\mathbf{F}$', -u'\U0001d406': '$\\mathbf{G}$', -u'\U0001d407': '$\\mathbf{H}$', -u'\U0001d408': '$\\mathbf{I}$', -u'\U0001d409': '$\\mathbf{J}$', -u'\U0001d40a': '$\\mathbf{K}$', -u'\U0001d40b': '$\\mathbf{L}$', -u'\U0001d40c': '$\\mathbf{M}$', -u'\U0001d40d': '$\\mathbf{N}$', -u'\U0001d40e': '$\\mathbf{O}$', -u'\U0001d40f': '$\\mathbf{P}$', -u'\U0001d410': '$\\mathbf{Q}$', -u'\U0001d411': '$\\mathbf{R}$', -u'\U0001d412': '$\\mathbf{S}$', -u'\U0001d413': '$\\mathbf{T}$', -u'\U0001d414': '$\\mathbf{U}$', -u'\U0001d415': '$\\mathbf{V}$', -u'\U0001d416': '$\\mathbf{W}$', -u'\U0001d417': '$\\mathbf{X}$', -u'\U0001d418': '$\\mathbf{Y}$', -u'\U0001d419': '$\\mathbf{Z}$', -u'\U0001d41a': '$\\mathbf{a}$', -u'\U0001d41b': '$\\mathbf{b}$', -u'\U0001d41c': '$\\mathbf{c}$', -u'\U0001d41d': '$\\mathbf{d}$', -u'\U0001d41e': '$\\mathbf{e}$', -u'\U0001d41f': '$\\mathbf{f}$', -u'\U0001d420': '$\\mathbf{g}$', -u'\U0001d421': '$\\mathbf{h}$', -u'\U0001d422': '$\\mathbf{i}$', -u'\U0001d423': '$\\mathbf{j}$', -u'\U0001d424': '$\\mathbf{k}$', -u'\U0001d425': '$\\mathbf{l}$', -u'\U0001d426': '$\\mathbf{m}$', -u'\U0001d427': '$\\mathbf{n}$', -u'\U0001d428': '$\\mathbf{o}$', -u'\U0001d429': '$\\mathbf{p}$', -u'\U0001d42a': '$\\mathbf{q}$', -u'\U0001d42b': '$\\mathbf{r}$', -u'\U0001d42c': '$\\mathbf{s}$', -u'\U0001d42d': '$\\mathbf{t}$', -u'\U0001d42e': '$\\mathbf{u}$', -u'\U0001d42f': '$\\mathbf{v}$', -u'\U0001d430': '$\\mathbf{w}$', -u'\U0001d431': '$\\mathbf{x}$', -u'\U0001d432': '$\\mathbf{y}$', -u'\U0001d433': '$\\mathbf{z}$', -u'\U0001d434': '$\\mathsl{A}$', -u'\U0001d435': '$\\mathsl{B}$', -u'\U0001d436': '$\\mathsl{C}$', -u'\U0001d437': '$\\mathsl{D}$', -u'\U0001d438': '$\\mathsl{E}$', -u'\U0001d439': '$\\mathsl{F}$', -u'\U0001d43a': '$\\mathsl{G}$', -u'\U0001d43b': '$\\mathsl{H}$', -u'\U0001d43c': '$\\mathsl{I}$', -u'\U0001d43d': '$\\mathsl{J}$', -u'\U0001d43e': '$\\mathsl{K}$', -u'\U0001d43f': '$\\mathsl{L}$', -u'\U0001d440': '$\\mathsl{M}$', -u'\U0001d441': '$\\mathsl{N}$', -u'\U0001d442': '$\\mathsl{O}$', -u'\U0001d443': '$\\mathsl{P}$', -u'\U0001d444': '$\\mathsl{Q}$', -u'\U0001d445': '$\\mathsl{R}$', -u'\U0001d446': '$\\mathsl{S}$', -u'\U0001d447': '$\\mathsl{T}$', -u'\U0001d448': '$\\mathsl{U}$', -u'\U0001d449': '$\\mathsl{V}$', -u'\U0001d44a': '$\\mathsl{W}$', -u'\U0001d44b': '$\\mathsl{X}$', -u'\U0001d44c': '$\\mathsl{Y}$', -u'\U0001d44d': '$\\mathsl{Z}$', -u'\U0001d44e': '$\\mathsl{a}$', -u'\U0001d44f': '$\\mathsl{b}$', -u'\U0001d450': '$\\mathsl{c}$', -u'\U0001d451': '$\\mathsl{d}$', -u'\U0001d452': '$\\mathsl{e}$', -u'\U0001d453': '$\\mathsl{f}$', -u'\U0001d454': '$\\mathsl{g}$', -u'\U0001d456': '$\\mathsl{i}$', -u'\U0001d457': '$\\mathsl{j}$', -u'\U0001d458': '$\\mathsl{k}$', -u'\U0001d459': '$\\mathsl{l}$', -u'\U0001d45a': '$\\mathsl{m}$', -u'\U0001d45b': '$\\mathsl{n}$', -u'\U0001d45c': '$\\mathsl{o}$', -u'\U0001d45d': '$\\mathsl{p}$', -u'\U0001d45e': '$\\mathsl{q}$', -u'\U0001d45f': '$\\mathsl{r}$', -u'\U0001d460': '$\\mathsl{s}$', -u'\U0001d461': '$\\mathsl{t}$', -u'\U0001d462': '$\\mathsl{u}$', -u'\U0001d463': '$\\mathsl{v}$', -u'\U0001d464': '$\\mathsl{w}$', -u'\U0001d465': '$\\mathsl{x}$', -u'\U0001d466': '$\\mathsl{y}$', -u'\U0001d467': '$\\mathsl{z}$', -u'\U0001d468': '$\\mathbit{A}$', -u'\U0001d469': '$\\mathbit{B}$', -u'\U0001d46a': '$\\mathbit{C}$', -u'\U0001d46b': '$\\mathbit{D}$', -u'\U0001d46c': '$\\mathbit{E}$', -u'\U0001d46d': '$\\mathbit{F}$', -u'\U0001d46e': '$\\mathbit{G}$', -u'\U0001d46f': '$\\mathbit{H}$', -u'\U0001d470': '$\\mathbit{I}$', -u'\U0001d471': '$\\mathbit{J}$', -u'\U0001d472': '$\\mathbit{K}$', -u'\U0001d473': '$\\mathbit{L}$', -u'\U0001d474': '$\\mathbit{M}$', -u'\U0001d475': '$\\mathbit{N}$', -u'\U0001d476': '$\\mathbit{O}$', -u'\U0001d477': '$\\mathbit{P}$', -u'\U0001d478': '$\\mathbit{Q}$', -u'\U0001d479': '$\\mathbit{R}$', -u'\U0001d47a': '$\\mathbit{S}$', -u'\U0001d47b': '$\\mathbit{T}$', -u'\U0001d47c': '$\\mathbit{U}$', -u'\U0001d47d': '$\\mathbit{V}$', -u'\U0001d47e': '$\\mathbit{W}$', -u'\U0001d47f': '$\\mathbit{X}$', -u'\U0001d480': '$\\mathbit{Y}$', -u'\U0001d481': '$\\mathbit{Z}$', -u'\U0001d482': '$\\mathbit{a}$', -u'\U0001d483': '$\\mathbit{b}$', -u'\U0001d484': '$\\mathbit{c}$', -u'\U0001d485': '$\\mathbit{d}$', -u'\U0001d486': '$\\mathbit{e}$', -u'\U0001d487': '$\\mathbit{f}$', -u'\U0001d488': '$\\mathbit{g}$', -u'\U0001d489': '$\\mathbit{h}$', -u'\U0001d48a': '$\\mathbit{i}$', -u'\U0001d48b': '$\\mathbit{j}$', -u'\U0001d48c': '$\\mathbit{k}$', -u'\U0001d48d': '$\\mathbit{l}$', -u'\U0001d48e': '$\\mathbit{m}$', -u'\U0001d48f': '$\\mathbit{n}$', -u'\U0001d490': '$\\mathbit{o}$', -u'\U0001d491': '$\\mathbit{p}$', -u'\U0001d492': '$\\mathbit{q}$', -u'\U0001d493': '$\\mathbit{r}$', -u'\U0001d494': '$\\mathbit{s}$', -u'\U0001d495': '$\\mathbit{t}$', -u'\U0001d496': '$\\mathbit{u}$', -u'\U0001d497': '$\\mathbit{v}$', -u'\U0001d498': '$\\mathbit{w}$', -u'\U0001d499': '$\\mathbit{x}$', -u'\U0001d49a': '$\\mathbit{y}$', -u'\U0001d49b': '$\\mathbit{z}$', -u'\U0001d49c': '$\\mathscr{A}$', -u'\U0001d49e': '$\\mathscr{C}$', -u'\U0001d49f': '$\\mathscr{D}$', -u'\U0001d4a2': '$\\mathscr{G}$', -u'\U0001d4a5': '$\\mathscr{J}$', -u'\U0001d4a6': '$\\mathscr{K}$', -u'\U0001d4a9': '$\\mathscr{N}$', -u'\U0001d4aa': '$\\mathscr{O}$', -u'\U0001d4ab': '$\\mathscr{P}$', -u'\U0001d4ac': '$\\mathscr{Q}$', -u'\U0001d4ae': '$\\mathscr{S}$', -u'\U0001d4af': '$\\mathscr{T}$', -u'\U0001d4b0': '$\\mathscr{U}$', -u'\U0001d4b1': '$\\mathscr{V}$', -u'\U0001d4b2': '$\\mathscr{W}$', -u'\U0001d4b3': '$\\mathscr{X}$', -u'\U0001d4b4': '$\\mathscr{Y}$', -u'\U0001d4b5': '$\\mathscr{Z}$', -u'\U0001d4b6': '$\\mathscr{a}$', -u'\U0001d4b7': '$\\mathscr{b}$', -u'\U0001d4b8': '$\\mathscr{c}$', -u'\U0001d4b9': '$\\mathscr{d}$', -u'\U0001d4bb': '$\\mathscr{f}$', -u'\U0001d4bd': '$\\mathscr{h}$', -u'\U0001d4be': '$\\mathscr{i}$', -u'\U0001d4bf': '$\\mathscr{j}$', -u'\U0001d4c0': '$\\mathscr{k}$', -u'\U0001d4c1': '$\\mathscr{l}$', -u'\U0001d4c2': '$\\mathscr{m}$', -u'\U0001d4c3': '$\\mathscr{n}$', -u'\U0001d4c5': '$\\mathscr{p}$', -u'\U0001d4c6': '$\\mathscr{q}$', -u'\U0001d4c7': '$\\mathscr{r}$', -u'\U0001d4c8': '$\\mathscr{s}$', -u'\U0001d4c9': '$\\mathscr{t}$', -u'\U0001d4ca': '$\\mathscr{u}$', -u'\U0001d4cb': '$\\mathscr{v}$', -u'\U0001d4cc': '$\\mathscr{w}$', -u'\U0001d4cd': '$\\mathscr{x}$', -u'\U0001d4ce': '$\\mathscr{y}$', -u'\U0001d4cf': '$\\mathscr{z}$', -u'\U0001d4d0': '$\\mathmit{A}$', -u'\U0001d4d1': '$\\mathmit{B}$', -u'\U0001d4d2': '$\\mathmit{C}$', -u'\U0001d4d3': '$\\mathmit{D}$', -u'\U0001d4d4': '$\\mathmit{E}$', -u'\U0001d4d5': '$\\mathmit{F}$', -u'\U0001d4d6': '$\\mathmit{G}$', -u'\U0001d4d7': '$\\mathmit{H}$', -u'\U0001d4d8': '$\\mathmit{I}$', -u'\U0001d4d9': '$\\mathmit{J}$', -u'\U0001d4da': '$\\mathmit{K}$', -u'\U0001d4db': '$\\mathmit{L}$', -u'\U0001d4dc': '$\\mathmit{M}$', -u'\U0001d4dd': '$\\mathmit{N}$', -u'\U0001d4de': '$\\mathmit{O}$', -u'\U0001d4df': '$\\mathmit{P}$', -u'\U0001d4e0': '$\\mathmit{Q}$', -u'\U0001d4e1': '$\\mathmit{R}$', -u'\U0001d4e2': '$\\mathmit{S}$', -u'\U0001d4e3': '$\\mathmit{T}$', -u'\U0001d4e4': '$\\mathmit{U}$', -u'\U0001d4e5': '$\\mathmit{V}$', -u'\U0001d4e6': '$\\mathmit{W}$', -u'\U0001d4e7': '$\\mathmit{X}$', -u'\U0001d4e8': '$\\mathmit{Y}$', -u'\U0001d4e9': '$\\mathmit{Z}$', -u'\U0001d4ea': '$\\mathmit{a}$', -u'\U0001d4eb': '$\\mathmit{b}$', -u'\U0001d4ec': '$\\mathmit{c}$', -u'\U0001d4ed': '$\\mathmit{d}$', -u'\U0001d4ee': '$\\mathmit{e}$', -u'\U0001d4ef': '$\\mathmit{f}$', -u'\U0001d4f0': '$\\mathmit{g}$', -u'\U0001d4f1': '$\\mathmit{h}$', -u'\U0001d4f2': '$\\mathmit{i}$', -u'\U0001d4f3': '$\\mathmit{j}$', -u'\U0001d4f4': '$\\mathmit{k}$', -u'\U0001d4f5': '$\\mathmit{l}$', -u'\U0001d4f6': '$\\mathmit{m}$', -u'\U0001d4f7': '$\\mathmit{n}$', -u'\U0001d4f8': '$\\mathmit{o}$', -u'\U0001d4f9': '$\\mathmit{p}$', -u'\U0001d4fa': '$\\mathmit{q}$', -u'\U0001d4fb': '$\\mathmit{r}$', -u'\U0001d4fc': '$\\mathmit{s}$', -u'\U0001d4fd': '$\\mathmit{t}$', -u'\U0001d4fe': '$\\mathmit{u}$', -u'\U0001d4ff': '$\\mathmit{v}$', -u'\U0001d500': '$\\mathmit{w}$', -u'\U0001d501': '$\\mathmit{x}$', -u'\U0001d502': '$\\mathmit{y}$', -u'\U0001d503': '$\\mathmit{z}$', -u'\U0001d504': '$\\mathfrak{A}$', -u'\U0001d505': '$\\mathfrak{B}$', -u'\U0001d507': '$\\mathfrak{D}$', -u'\U0001d508': '$\\mathfrak{E}$', -u'\U0001d509': '$\\mathfrak{F}$', -u'\U0001d50a': '$\\mathfrak{G}$', -u'\U0001d50d': '$\\mathfrak{J}$', -u'\U0001d50e': '$\\mathfrak{K}$', -u'\U0001d50f': '$\\mathfrak{L}$', -u'\U0001d510': '$\\mathfrak{M}$', -u'\U0001d511': '$\\mathfrak{N}$', -u'\U0001d512': '$\\mathfrak{O}$', -u'\U0001d513': '$\\mathfrak{P}$', -u'\U0001d514': '$\\mathfrak{Q}$', -u'\U0001d516': '$\\mathfrak{S}$', -u'\U0001d517': '$\\mathfrak{T}$', -u'\U0001d518': '$\\mathfrak{U}$', -u'\U0001d519': '$\\mathfrak{V}$', -u'\U0001d51a': '$\\mathfrak{W}$', -u'\U0001d51b': '$\\mathfrak{X}$', -u'\U0001d51c': '$\\mathfrak{Y}$', -u'\U0001d51e': '$\\mathfrak{a}$', -u'\U0001d51f': '$\\mathfrak{b}$', -u'\U0001d520': '$\\mathfrak{c}$', -u'\U0001d521': '$\\mathfrak{d}$', -u'\U0001d522': '$\\mathfrak{e}$', -u'\U0001d523': '$\\mathfrak{f}$', -u'\U0001d524': '$\\mathfrak{g}$', -u'\U0001d525': '$\\mathfrak{h}$', -u'\U0001d526': '$\\mathfrak{i}$', -u'\U0001d527': '$\\mathfrak{j}$', -u'\U0001d528': '$\\mathfrak{k}$', -u'\U0001d529': '$\\mathfrak{l}$', -u'\U0001d52a': '$\\mathfrak{m}$', -u'\U0001d52b': '$\\mathfrak{n}$', -u'\U0001d52c': '$\\mathfrak{o}$', -u'\U0001d52d': '$\\mathfrak{p}$', -u'\U0001d52e': '$\\mathfrak{q}$', -u'\U0001d52f': '$\\mathfrak{r}$', -u'\U0001d530': '$\\mathfrak{s}$', -u'\U0001d531': '$\\mathfrak{t}$', -u'\U0001d532': '$\\mathfrak{u}$', -u'\U0001d533': '$\\mathfrak{v}$', -u'\U0001d534': '$\\mathfrak{w}$', -u'\U0001d535': '$\\mathfrak{x}$', -u'\U0001d536': '$\\mathfrak{y}$', -u'\U0001d537': '$\\mathfrak{z}$', -u'\U0001d538': '$\\mathbb{A}$', -u'\U0001d539': '$\\mathbb{B}$', -u'\U0001d53b': '$\\mathbb{D}$', -u'\U0001d53c': '$\\mathbb{E}$', -u'\U0001d53d': '$\\mathbb{F}$', -u'\U0001d53e': '$\\mathbb{G}$', -u'\U0001d540': '$\\mathbb{I}$', -u'\U0001d541': '$\\mathbb{J}$', -u'\U0001d542': '$\\mathbb{K}$', -u'\U0001d543': '$\\mathbb{L}$', -u'\U0001d544': '$\\mathbb{M}$', -u'\U0001d546': '$\\mathbb{O}$', -u'\U0001d54a': '$\\mathbb{S}$', -u'\U0001d54b': '$\\mathbb{T}$', -u'\U0001d54c': '$\\mathbb{U}$', -u'\U0001d54d': '$\\mathbb{V}$', -u'\U0001d54e': '$\\mathbb{W}$', -u'\U0001d54f': '$\\mathbb{X}$', -u'\U0001d550': '$\\mathbb{Y}$', -u'\U0001d552': '$\\mathbb{a}$', -u'\U0001d553': '$\\mathbb{b}$', -u'\U0001d554': '$\\mathbb{c}$', -u'\U0001d555': '$\\mathbb{d}$', -u'\U0001d556': '$\\mathbb{e}$', -u'\U0001d557': '$\\mathbb{f}$', -u'\U0001d558': '$\\mathbb{g}$', -u'\U0001d559': '$\\mathbb{h}$', -u'\U0001d55a': '$\\mathbb{i}$', -u'\U0001d55b': '$\\mathbb{j}$', -u'\U0001d55c': '$\\mathbb{k}$', -u'\U0001d55d': '$\\mathbb{l}$', -u'\U0001d55e': '$\\mathbb{m}$', -u'\U0001d55f': '$\\mathbb{n}$', -u'\U0001d560': '$\\mathbb{o}$', -u'\U0001d561': '$\\mathbb{p}$', -u'\U0001d562': '$\\mathbb{q}$', -u'\U0001d563': '$\\mathbb{r}$', -u'\U0001d564': '$\\mathbb{s}$', -u'\U0001d565': '$\\mathbb{t}$', -u'\U0001d566': '$\\mathbb{u}$', -u'\U0001d567': '$\\mathbb{v}$', -u'\U0001d568': '$\\mathbb{w}$', -u'\U0001d569': '$\\mathbb{x}$', -u'\U0001d56a': '$\\mathbb{y}$', -u'\U0001d56b': '$\\mathbb{z}$', -u'\U0001d56c': '$\\mathslbb{A}$', -u'\U0001d56d': '$\\mathslbb{B}$', -u'\U0001d56e': '$\\mathslbb{C}$', -u'\U0001d56f': '$\\mathslbb{D}$', -u'\U0001d570': '$\\mathslbb{E}$', -u'\U0001d571': '$\\mathslbb{F}$', -u'\U0001d572': '$\\mathslbb{G}$', -u'\U0001d573': '$\\mathslbb{H}$', -u'\U0001d574': '$\\mathslbb{I}$', -u'\U0001d575': '$\\mathslbb{J}$', -u'\U0001d576': '$\\mathslbb{K}$', -u'\U0001d577': '$\\mathslbb{L}$', -u'\U0001d578': '$\\mathslbb{M}$', -u'\U0001d579': '$\\mathslbb{N}$', -u'\U0001d57a': '$\\mathslbb{O}$', -u'\U0001d57b': '$\\mathslbb{P}$', -u'\U0001d57c': '$\\mathslbb{Q}$', -u'\U0001d57d': '$\\mathslbb{R}$', -u'\U0001d57e': '$\\mathslbb{S}$', -u'\U0001d57f': '$\\mathslbb{T}$', -u'\U0001d580': '$\\mathslbb{U}$', -u'\U0001d581': '$\\mathslbb{V}$', -u'\U0001d582': '$\\mathslbb{W}$', -u'\U0001d583': '$\\mathslbb{X}$', -u'\U0001d584': '$\\mathslbb{Y}$', -u'\U0001d585': '$\\mathslbb{Z}$', -u'\U0001d586': '$\\mathslbb{a}$', -u'\U0001d587': '$\\mathslbb{b}$', -u'\U0001d588': '$\\mathslbb{c}$', -u'\U0001d589': '$\\mathslbb{d}$', -u'\U0001d58a': '$\\mathslbb{e}$', -u'\U0001d58b': '$\\mathslbb{f}$', -u'\U0001d58c': '$\\mathslbb{g}$', -u'\U0001d58d': '$\\mathslbb{h}$', -u'\U0001d58e': '$\\mathslbb{i}$', -u'\U0001d58f': '$\\mathslbb{j}$', -u'\U0001d590': '$\\mathslbb{k}$', -u'\U0001d591': '$\\mathslbb{l}$', -u'\U0001d592': '$\\mathslbb{m}$', -u'\U0001d593': '$\\mathslbb{n}$', -u'\U0001d594': '$\\mathslbb{o}$', -u'\U0001d595': '$\\mathslbb{p}$', -u'\U0001d596': '$\\mathslbb{q}$', -u'\U0001d597': '$\\mathslbb{r}$', -u'\U0001d598': '$\\mathslbb{s}$', -u'\U0001d599': '$\\mathslbb{t}$', -u'\U0001d59a': '$\\mathslbb{u}$', -u'\U0001d59b': '$\\mathslbb{v}$', -u'\U0001d59c': '$\\mathslbb{w}$', -u'\U0001d59d': '$\\mathslbb{x}$', -u'\U0001d59e': '$\\mathslbb{y}$', -u'\U0001d59f': '$\\mathslbb{z}$', -u'\U0001d5a0': '$\\mathsf{A}$', -u'\U0001d5a1': '$\\mathsf{B}$', -u'\U0001d5a2': '$\\mathsf{C}$', -u'\U0001d5a3': '$\\mathsf{D}$', -u'\U0001d5a4': '$\\mathsf{E}$', -u'\U0001d5a5': '$\\mathsf{F}$', -u'\U0001d5a6': '$\\mathsf{G}$', -u'\U0001d5a7': '$\\mathsf{H}$', -u'\U0001d5a8': '$\\mathsf{I}$', -u'\U0001d5a9': '$\\mathsf{J}$', -u'\U0001d5aa': '$\\mathsf{K}$', -u'\U0001d5ab': '$\\mathsf{L}$', -u'\U0001d5ac': '$\\mathsf{M}$', -u'\U0001d5ad': '$\\mathsf{N}$', -u'\U0001d5ae': '$\\mathsf{O}$', -u'\U0001d5af': '$\\mathsf{P}$', -u'\U0001d5b0': '$\\mathsf{Q}$', -u'\U0001d5b1': '$\\mathsf{R}$', -u'\U0001d5b2': '$\\mathsf{S}$', -u'\U0001d5b3': '$\\mathsf{T}$', -u'\U0001d5b4': '$\\mathsf{U}$', -u'\U0001d5b5': '$\\mathsf{V}$', -u'\U0001d5b6': '$\\mathsf{W}$', -u'\U0001d5b7': '$\\mathsf{X}$', -u'\U0001d5b8': '$\\mathsf{Y}$', -u'\U0001d5b9': '$\\mathsf{Z}$', -u'\U0001d5ba': '$\\mathsf{a}$', -u'\U0001d5bb': '$\\mathsf{b}$', -u'\U0001d5bc': '$\\mathsf{c}$', -u'\U0001d5bd': '$\\mathsf{d}$', -u'\U0001d5be': '$\\mathsf{e}$', -u'\U0001d5bf': '$\\mathsf{f}$', -u'\U0001d5c0': '$\\mathsf{g}$', -u'\U0001d5c1': '$\\mathsf{h}$', -u'\U0001d5c2': '$\\mathsf{i}$', -u'\U0001d5c3': '$\\mathsf{j}$', -u'\U0001d5c4': '$\\mathsf{k}$', -u'\U0001d5c5': '$\\mathsf{l}$', -u'\U0001d5c6': '$\\mathsf{m}$', -u'\U0001d5c7': '$\\mathsf{n}$', -u'\U0001d5c8': '$\\mathsf{o}$', -u'\U0001d5c9': '$\\mathsf{p}$', -u'\U0001d5ca': '$\\mathsf{q}$', -u'\U0001d5cb': '$\\mathsf{r}$', -u'\U0001d5cc': '$\\mathsf{s}$', -u'\U0001d5cd': '$\\mathsf{t}$', -u'\U0001d5ce': '$\\mathsf{u}$', -u'\U0001d5cf': '$\\mathsf{v}$', -u'\U0001d5d0': '$\\mathsf{w}$', -u'\U0001d5d1': '$\\mathsf{x}$', -u'\U0001d5d2': '$\\mathsf{y}$', -u'\U0001d5d3': '$\\mathsf{z}$', -u'\U0001d5d4': '$\\mathsfbf{A}$', -u'\U0001d5d5': '$\\mathsfbf{B}$', -u'\U0001d5d6': '$\\mathsfbf{C}$', -u'\U0001d5d7': '$\\mathsfbf{D}$', -u'\U0001d5d8': '$\\mathsfbf{E}$', -u'\U0001d5d9': '$\\mathsfbf{F}$', -u'\U0001d5da': '$\\mathsfbf{G}$', -u'\U0001d5db': '$\\mathsfbf{H}$', -u'\U0001d5dc': '$\\mathsfbf{I}$', -u'\U0001d5dd': '$\\mathsfbf{J}$', -u'\U0001d5de': '$\\mathsfbf{K}$', -u'\U0001d5df': '$\\mathsfbf{L}$', -u'\U0001d5e0': '$\\mathsfbf{M}$', -u'\U0001d5e1': '$\\mathsfbf{N}$', -u'\U0001d5e2': '$\\mathsfbf{O}$', -u'\U0001d5e3': '$\\mathsfbf{P}$', -u'\U0001d5e4': '$\\mathsfbf{Q}$', -u'\U0001d5e5': '$\\mathsfbf{R}$', -u'\U0001d5e6': '$\\mathsfbf{S}$', -u'\U0001d5e7': '$\\mathsfbf{T}$', -u'\U0001d5e8': '$\\mathsfbf{U}$', -u'\U0001d5e9': '$\\mathsfbf{V}$', -u'\U0001d5ea': '$\\mathsfbf{W}$', -u'\U0001d5eb': '$\\mathsfbf{X}$', -u'\U0001d5ec': '$\\mathsfbf{Y}$', -u'\U0001d5ed': '$\\mathsfbf{Z}$', -u'\U0001d5ee': '$\\mathsfbf{a}$', -u'\U0001d5ef': '$\\mathsfbf{b}$', -u'\U0001d5f0': '$\\mathsfbf{c}$', -u'\U0001d5f1': '$\\mathsfbf{d}$', -u'\U0001d5f2': '$\\mathsfbf{e}$', -u'\U0001d5f3': '$\\mathsfbf{f}$', -u'\U0001d5f4': '$\\mathsfbf{g}$', -u'\U0001d5f5': '$\\mathsfbf{h}$', -u'\U0001d5f6': '$\\mathsfbf{i}$', -u'\U0001d5f7': '$\\mathsfbf{j}$', -u'\U0001d5f8': '$\\mathsfbf{k}$', -u'\U0001d5f9': '$\\mathsfbf{l}$', -u'\U0001d5fa': '$\\mathsfbf{m}$', -u'\U0001d5fb': '$\\mathsfbf{n}$', -u'\U0001d5fc': '$\\mathsfbf{o}$', -u'\U0001d5fd': '$\\mathsfbf{p}$', -u'\U0001d5fe': '$\\mathsfbf{q}$', -u'\U0001d5ff': '$\\mathsfbf{r}$', -u'\U0001d600': '$\\mathsfbf{s}$', -u'\U0001d601': '$\\mathsfbf{t}$', -u'\U0001d602': '$\\mathsfbf{u}$', -u'\U0001d603': '$\\mathsfbf{v}$', -u'\U0001d604': '$\\mathsfbf{w}$', -u'\U0001d605': '$\\mathsfbf{x}$', -u'\U0001d606': '$\\mathsfbf{y}$', -u'\U0001d607': '$\\mathsfbf{z}$', -u'\U0001d608': '$\\mathsfsl{A}$', -u'\U0001d609': '$\\mathsfsl{B}$', -u'\U0001d60a': '$\\mathsfsl{C}$', -u'\U0001d60b': '$\\mathsfsl{D}$', -u'\U0001d60c': '$\\mathsfsl{E}$', -u'\U0001d60d': '$\\mathsfsl{F}$', -u'\U0001d60e': '$\\mathsfsl{G}$', -u'\U0001d60f': '$\\mathsfsl{H}$', -u'\U0001d610': '$\\mathsfsl{I}$', -u'\U0001d611': '$\\mathsfsl{J}$', -u'\U0001d612': '$\\mathsfsl{K}$', -u'\U0001d613': '$\\mathsfsl{L}$', -u'\U0001d614': '$\\mathsfsl{M}$', -u'\U0001d615': '$\\mathsfsl{N}$', -u'\U0001d616': '$\\mathsfsl{O}$', -u'\U0001d617': '$\\mathsfsl{P}$', -u'\U0001d618': '$\\mathsfsl{Q}$', -u'\U0001d619': '$\\mathsfsl{R}$', -u'\U0001d61a': '$\\mathsfsl{S}$', -u'\U0001d61b': '$\\mathsfsl{T}$', -u'\U0001d61c': '$\\mathsfsl{U}$', -u'\U0001d61d': '$\\mathsfsl{V}$', -u'\U0001d61e': '$\\mathsfsl{W}$', -u'\U0001d61f': '$\\mathsfsl{X}$', -u'\U0001d620': '$\\mathsfsl{Y}$', -u'\U0001d621': '$\\mathsfsl{Z}$', -u'\U0001d622': '$\\mathsfsl{a}$', -u'\U0001d623': '$\\mathsfsl{b}$', -u'\U0001d624': '$\\mathsfsl{c}$', -u'\U0001d625': '$\\mathsfsl{d}$', -u'\U0001d626': '$\\mathsfsl{e}$', -u'\U0001d627': '$\\mathsfsl{f}$', -u'\U0001d628': '$\\mathsfsl{g}$', -u'\U0001d629': '$\\mathsfsl{h}$', -u'\U0001d62a': '$\\mathsfsl{i}$', -u'\U0001d62b': '$\\mathsfsl{j}$', -u'\U0001d62c': '$\\mathsfsl{k}$', -u'\U0001d62d': '$\\mathsfsl{l}$', -u'\U0001d62e': '$\\mathsfsl{m}$', -u'\U0001d62f': '$\\mathsfsl{n}$', -u'\U0001d630': '$\\mathsfsl{o}$', -u'\U0001d631': '$\\mathsfsl{p}$', -u'\U0001d632': '$\\mathsfsl{q}$', -u'\U0001d633': '$\\mathsfsl{r}$', -u'\U0001d634': '$\\mathsfsl{s}$', -u'\U0001d635': '$\\mathsfsl{t}$', -u'\U0001d636': '$\\mathsfsl{u}$', -u'\U0001d637': '$\\mathsfsl{v}$', -u'\U0001d638': '$\\mathsfsl{w}$', -u'\U0001d639': '$\\mathsfsl{x}$', -u'\U0001d63a': '$\\mathsfsl{y}$', -u'\U0001d63b': '$\\mathsfsl{z}$', -u'\U0001d63c': '$\\mathsfbfsl{A}$', -u'\U0001d63d': '$\\mathsfbfsl{B}$', -u'\U0001d63e': '$\\mathsfbfsl{C}$', -u'\U0001d63f': '$\\mathsfbfsl{D}$', -u'\U0001d640': '$\\mathsfbfsl{E}$', -u'\U0001d641': '$\\mathsfbfsl{F}$', -u'\U0001d642': '$\\mathsfbfsl{G}$', -u'\U0001d643': '$\\mathsfbfsl{H}$', -u'\U0001d644': '$\\mathsfbfsl{I}$', -u'\U0001d645': '$\\mathsfbfsl{J}$', -u'\U0001d646': '$\\mathsfbfsl{K}$', -u'\U0001d647': '$\\mathsfbfsl{L}$', -u'\U0001d648': '$\\mathsfbfsl{M}$', -u'\U0001d649': '$\\mathsfbfsl{N}$', -u'\U0001d64a': '$\\mathsfbfsl{O}$', -u'\U0001d64b': '$\\mathsfbfsl{P}$', -u'\U0001d64c': '$\\mathsfbfsl{Q}$', -u'\U0001d64d': '$\\mathsfbfsl{R}$', -u'\U0001d64e': '$\\mathsfbfsl{S}$', -u'\U0001d64f': '$\\mathsfbfsl{T}$', -u'\U0001d650': '$\\mathsfbfsl{U}$', -u'\U0001d651': '$\\mathsfbfsl{V}$', -u'\U0001d652': '$\\mathsfbfsl{W}$', -u'\U0001d653': '$\\mathsfbfsl{X}$', -u'\U0001d654': '$\\mathsfbfsl{Y}$', -u'\U0001d655': '$\\mathsfbfsl{Z}$', -u'\U0001d656': '$\\mathsfbfsl{a}$', -u'\U0001d657': '$\\mathsfbfsl{b}$', -u'\U0001d658': '$\\mathsfbfsl{c}$', -u'\U0001d659': '$\\mathsfbfsl{d}$', -u'\U0001d65a': '$\\mathsfbfsl{e}$', -u'\U0001d65b': '$\\mathsfbfsl{f}$', -u'\U0001d65c': '$\\mathsfbfsl{g}$', -u'\U0001d65d': '$\\mathsfbfsl{h}$', -u'\U0001d65e': '$\\mathsfbfsl{i}$', -u'\U0001d65f': '$\\mathsfbfsl{j}$', -u'\U0001d660': '$\\mathsfbfsl{k}$', -u'\U0001d661': '$\\mathsfbfsl{l}$', -u'\U0001d662': '$\\mathsfbfsl{m}$', -u'\U0001d663': '$\\mathsfbfsl{n}$', -u'\U0001d664': '$\\mathsfbfsl{o}$', -u'\U0001d665': '$\\mathsfbfsl{p}$', -u'\U0001d666': '$\\mathsfbfsl{q}$', -u'\U0001d667': '$\\mathsfbfsl{r}$', -u'\U0001d668': '$\\mathsfbfsl{s}$', -u'\U0001d669': '$\\mathsfbfsl{t}$', -u'\U0001d66a': '$\\mathsfbfsl{u}$', -u'\U0001d66b': '$\\mathsfbfsl{v}$', -u'\U0001d66c': '$\\mathsfbfsl{w}$', -u'\U0001d66d': '$\\mathsfbfsl{x}$', -u'\U0001d66e': '$\\mathsfbfsl{y}$', -u'\U0001d66f': '$\\mathsfbfsl{z}$', -u'\U0001d670': '$\\mathtt{A}$', -u'\U0001d671': '$\\mathtt{B}$', -u'\U0001d672': '$\\mathtt{C}$', -u'\U0001d673': '$\\mathtt{D}$', -u'\U0001d674': '$\\mathtt{E}$', -u'\U0001d675': '$\\mathtt{F}$', -u'\U0001d676': '$\\mathtt{G}$', -u'\U0001d677': '$\\mathtt{H}$', -u'\U0001d678': '$\\mathtt{I}$', -u'\U0001d679': '$\\mathtt{J}$', -u'\U0001d67a': '$\\mathtt{K}$', -u'\U0001d67b': '$\\mathtt{L}$', -u'\U0001d67c': '$\\mathtt{M}$', -u'\U0001d67d': '$\\mathtt{N}$', -u'\U0001d67e': '$\\mathtt{O}$', -u'\U0001d67f': '$\\mathtt{P}$', -u'\U0001d680': '$\\mathtt{Q}$', -u'\U0001d681': '$\\mathtt{R}$', -u'\U0001d682': '$\\mathtt{S}$', -u'\U0001d683': '$\\mathtt{T}$', -u'\U0001d684': '$\\mathtt{U}$', -u'\U0001d685': '$\\mathtt{V}$', -u'\U0001d686': '$\\mathtt{W}$', -u'\U0001d687': '$\\mathtt{X}$', -u'\U0001d688': '$\\mathtt{Y}$', -u'\U0001d689': '$\\mathtt{Z}$', -u'\U0001d68a': '$\\mathtt{a}$', -u'\U0001d68b': '$\\mathtt{b}$', -u'\U0001d68c': '$\\mathtt{c}$', -u'\U0001d68d': '$\\mathtt{d}$', -u'\U0001d68e': '$\\mathtt{e}$', -u'\U0001d68f': '$\\mathtt{f}$', -u'\U0001d690': '$\\mathtt{g}$', -u'\U0001d691': '$\\mathtt{h}$', -u'\U0001d692': '$\\mathtt{i}$', -u'\U0001d693': '$\\mathtt{j}$', -u'\U0001d694': '$\\mathtt{k}$', -u'\U0001d695': '$\\mathtt{l}$', -u'\U0001d696': '$\\mathtt{m}$', -u'\U0001d697': '$\\mathtt{n}$', -u'\U0001d698': '$\\mathtt{o}$', -u'\U0001d699': '$\\mathtt{p}$', -u'\U0001d69a': '$\\mathtt{q}$', -u'\U0001d69b': '$\\mathtt{r}$', -u'\U0001d69c': '$\\mathtt{s}$', -u'\U0001d69d': '$\\mathtt{t}$', -u'\U0001d69e': '$\\mathtt{u}$', -u'\U0001d69f': '$\\mathtt{v}$', -u'\U0001d6a0': '$\\mathtt{w}$', -u'\U0001d6a1': '$\\mathtt{x}$', -u'\U0001d6a2': '$\\mathtt{y}$', -u'\U0001d6a3': '$\\mathtt{z}$', -u'\U0001d6a8': '$\\mathbf{\\Alpha}$', -u'\U0001d6a9': '$\\mathbf{\\Beta}$', -u'\U0001d6aa': '$\\mathbf{\\Gamma}$', -u'\U0001d6ab': '$\\mathbf{\\Delta}$', -u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', -u'\U0001d6ad': '$\\mathbf{\\Zeta}$', -u'\U0001d6ae': '$\\mathbf{\\Eta}$', -u'\U0001d6af': '$\\mathbf{\\Theta}$', -u'\U0001d6b0': '$\\mathbf{\\Iota}$', -u'\U0001d6b1': '$\\mathbf{\\Kappa}$', -u'\U0001d6b2': '$\\mathbf{\\Lambda}$', -u'\U0001d6b3': '$M$', -u'\U0001d6b4': '$N$', -u'\U0001d6b5': '$\\mathbf{\\Xi}$', -u'\U0001d6b6': '$O$', -u'\U0001d6b7': '$\\mathbf{\\Pi}$', -u'\U0001d6b8': '$\\mathbf{\\Rho}$', -u'\U0001d6b9': '{\\mathbf{\\vartheta}}', -u'\U0001d6ba': '$\\mathbf{\\Sigma}$', -u'\U0001d6bb': '$\\mathbf{\\Tau}$', -u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', -u'\U0001d6bd': '$\\mathbf{\\Phi}$', -u'\U0001d6be': '$\\mathbf{\\Chi}$', -u'\U0001d6bf': '$\\mathbf{\\Psi}$', -u'\U0001d6c0': '$\\mathbf{\\Omega}$', -u'\U0001d6c1': '$\\mathbf{\\nabla}$', -u'\U0001d6c2': '$\\mathbf{\\Alpha}$', -u'\U0001d6c3': '$\\mathbf{\\Beta}$', -u'\U0001d6c4': '$\\mathbf{\\Gamma}$', -u'\U0001d6c5': '$\\mathbf{\\Delta}$', -u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', -u'\U0001d6c7': '$\\mathbf{\\Zeta}$', -u'\U0001d6c8': '$\\mathbf{\\Eta}$', -u'\U0001d6c9': '$\\mathbf{\\theta}$', -u'\U0001d6ca': '$\\mathbf{\\Iota}$', -u'\U0001d6cb': '$\\mathbf{\\Kappa}$', -u'\U0001d6cc': '$\\mathbf{\\Lambda}$', -u'\U0001d6cd': '$M$', -u'\U0001d6ce': '$N$', -u'\U0001d6cf': '$\\mathbf{\\Xi}$', -u'\U0001d6d0': '$O$', -u'\U0001d6d1': '$\\mathbf{\\Pi}$', -u'\U0001d6d2': '$\\mathbf{\\Rho}$', -u'\U0001d6d3': '$\\mathbf{\\varsigma}$', -u'\U0001d6d4': '$\\mathbf{\\Sigma}$', -u'\U0001d6d5': '$\\mathbf{\\Tau}$', -u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', -u'\U0001d6d7': '$\\mathbf{\\Phi}$', -u'\U0001d6d8': '$\\mathbf{\\Chi}$', -u'\U0001d6d9': '$\\mathbf{\\Psi}$', -u'\U0001d6da': '$\\mathbf{\\Omega}$', -u'\U0001d6db': '$\\partial$', -u'\U0001d6dc': '$\\in$', -u'\U0001d6dd': '{\\mathbf{\\vartheta}}', -u'\U0001d6de': '{\\mathbf{\\varkappa}}', -u'\U0001d6df': '{\\mathbf{\\phi}}', -u'\U0001d6e0': '{\\mathbf{\\varrho}}', -u'\U0001d6e1': '{\\mathbf{\\varpi}}', -u'\U0001d6e2': '$\\mathsl{\\Alpha}$', -u'\U0001d6e3': '$\\mathsl{\\Beta}$', -u'\U0001d6e4': '$\\mathsl{\\Gamma}$', -u'\U0001d6e5': '$\\mathsl{\\Delta}$', -u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', -u'\U0001d6e7': '$\\mathsl{\\Zeta}$', -u'\U0001d6e8': '$\\mathsl{\\Eta}$', -u'\U0001d6e9': '$\\mathsl{\\Theta}$', -u'\U0001d6ea': '$\\mathsl{\\Iota}$', -u'\U0001d6eb': '$\\mathsl{\\Kappa}$', -u'\U0001d6ec': '$\\mathsl{\\Lambda}$', -u'\U0001d6ed': '$M$', -u'\U0001d6ee': '$N$', -u'\U0001d6ef': '$\\mathsl{\\Xi}$', -u'\U0001d6f0': '$O$', -u'\U0001d6f1': '$\\mathsl{\\Pi}$', -u'\U0001d6f2': '$\\mathsl{\\Rho}$', -u'\U0001d6f3': '{\\mathsl{\\vartheta}}', -u'\U0001d6f4': '$\\mathsl{\\Sigma}$', -u'\U0001d6f5': '$\\mathsl{\\Tau}$', -u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', -u'\U0001d6f7': '$\\mathsl{\\Phi}$', -u'\U0001d6f8': '$\\mathsl{\\Chi}$', -u'\U0001d6f9': '$\\mathsl{\\Psi}$', -u'\U0001d6fa': '$\\mathsl{\\Omega}$', -u'\U0001d6fb': '$\\mathsl{\\nabla}$', -u'\U0001d6fc': '$\\mathsl{\\Alpha}$', -u'\U0001d6fd': '$\\mathsl{\\Beta}$', -u'\U0001d6fe': '$\\mathsl{\\Gamma}$', -u'\U0001d6ff': '$\\mathsl{\\Delta}$', -u'\U0001d700': '$\\mathsl{\\Epsilon}$', -u'\U0001d701': '$\\mathsl{\\Zeta}$', -u'\U0001d702': '$\\mathsl{\\Eta}$', -u'\U0001d703': '$\\mathsl{\\Theta}$', -u'\U0001d704': '$\\mathsl{\\Iota}$', -u'\U0001d705': '$\\mathsl{\\Kappa}$', -u'\U0001d706': '$\\mathsl{\\Lambda}$', -u'\U0001d707': '$M$', -u'\U0001d708': '$N$', -u'\U0001d709': '$\\mathsl{\\Xi}$', -u'\U0001d70a': '$O$', -u'\U0001d70b': '$\\mathsl{\\Pi}$', -u'\U0001d70c': '$\\mathsl{\\Rho}$', -u'\U0001d70d': '$\\mathsl{\\varsigma}$', -u'\U0001d70e': '$\\mathsl{\\Sigma}$', -u'\U0001d70f': '$\\mathsl{\\Tau}$', -u'\U0001d710': '$\\mathsl{\\Upsilon}$', -u'\U0001d711': '$\\mathsl{\\Phi}$', -u'\U0001d712': '$\\mathsl{\\Chi}$', -u'\U0001d713': '$\\mathsl{\\Psi}$', -u'\U0001d714': '$\\mathsl{\\Omega}$', -u'\U0001d715': '$\\partial$', -u'\U0001d716': '$\\in$', -u'\U0001d717': '{\\mathsl{\\vartheta}}', -u'\U0001d718': '{\\mathsl{\\varkappa}}', -u'\U0001d719': '{\\mathsl{\\phi}}', -u'\U0001d71a': '{\\mathsl{\\varrho}}', -u'\U0001d71b': '{\\mathsl{\\varpi}}', -u'\U0001d71c': '$\\mathbit{\\Alpha}$', -u'\U0001d71d': '$\\mathbit{\\Beta}$', -u'\U0001d71e': '$\\mathbit{\\Gamma}$', -u'\U0001d71f': '$\\mathbit{\\Delta}$', -u'\U0001d720': '$\\mathbit{\\Epsilon}$', -u'\U0001d721': '$\\mathbit{\\Zeta}$', -u'\U0001d722': '$\\mathbit{\\Eta}$', -u'\U0001d723': '$\\mathbit{\\Theta}$', -u'\U0001d724': '$\\mathbit{\\Iota}$', -u'\U0001d725': '$\\mathbit{\\Kappa}$', -u'\U0001d726': '$\\mathbit{\\Lambda}$', -u'\U0001d727': '$M$', -u'\U0001d728': '$N$', -u'\U0001d729': '$\\mathbit{\\Xi}$', -u'\U0001d72a': '$O$', -u'\U0001d72b': '$\\mathbit{\\Pi}$', -u'\U0001d72c': '$\\mathbit{\\Rho}$', -u'\U0001d72d': '{\\mathbit{O}}', -u'\U0001d72e': '$\\mathbit{\\Sigma}$', -u'\U0001d72f': '$\\mathbit{\\Tau}$', -u'\U0001d730': '$\\mathbit{\\Upsilon}$', -u'\U0001d731': '$\\mathbit{\\Phi}$', -u'\U0001d732': '$\\mathbit{\\Chi}$', -u'\U0001d733': '$\\mathbit{\\Psi}$', -u'\U0001d734': '$\\mathbit{\\Omega}$', -u'\U0001d735': '$\\mathbit{\\nabla}$', -u'\U0001d736': '$\\mathbit{\\Alpha}$', -u'\U0001d737': '$\\mathbit{\\Beta}$', -u'\U0001d738': '$\\mathbit{\\Gamma}$', -u'\U0001d739': '$\\mathbit{\\Delta}$', -u'\U0001d73a': '$\\mathbit{\\Epsilon}$', -u'\U0001d73b': '$\\mathbit{\\Zeta}$', -u'\U0001d73c': '$\\mathbit{\\Eta}$', -u'\U0001d73d': '$\\mathbit{\\Theta}$', -u'\U0001d73e': '$\\mathbit{\\Iota}$', -u'\U0001d73f': '$\\mathbit{\\Kappa}$', -u'\U0001d740': '$\\mathbit{\\Lambda}$', -u'\U0001d741': '$M$', -u'\U0001d742': '$N$', -u'\U0001d743': '$\\mathbit{\\Xi}$', -u'\U0001d744': '$O$', -u'\U0001d745': '$\\mathbit{\\Pi}$', -u'\U0001d746': '$\\mathbit{\\Rho}$', -u'\U0001d747': '$\\mathbit{\\varsigma}$', -u'\U0001d748': '$\\mathbit{\\Sigma}$', -u'\U0001d749': '$\\mathbit{\\Tau}$', -u'\U0001d74a': '$\\mathbit{\\Upsilon}$', -u'\U0001d74b': '$\\mathbit{\\Phi}$', -u'\U0001d74c': '$\\mathbit{\\Chi}$', -u'\U0001d74d': '$\\mathbit{\\Psi}$', -u'\U0001d74e': '$\\mathbit{\\Omega}$', -u'\U0001d74f': '$\\partial$', -u'\U0001d750': '$\\in$', -u'\U0001d751': '{\\mathbit{\\vartheta}}', -u'\U0001d752': '{\\mathbit{\\varkappa}}', -u'\U0001d753': '{\\mathbit{\\phi}}', -u'\U0001d754': '{\\mathbit{\\varrho}}', -u'\U0001d755': '{\\mathbit{\\varpi}}', -u'\U0001d756': '$\\mathsfbf{\\Alpha}$', -u'\U0001d757': '$\\mathsfbf{\\Beta}$', -u'\U0001d758': '$\\mathsfbf{\\Gamma}$', -u'\U0001d759': '$\\mathsfbf{\\Delta}$', -u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', -u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', -u'\U0001d75c': '$\\mathsfbf{\\Eta}$', -u'\U0001d75d': '$\\mathsfbf{\\Theta}$', -u'\U0001d75e': '$\\mathsfbf{\\Iota}$', -u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', -u'\U0001d760': '$\\mathsfbf{\\Lambda}$', -u'\U0001d761': '$M$', -u'\U0001d762': '$N$', -u'\U0001d763': '$\\mathsfbf{\\Xi}$', -u'\U0001d764': '$O$', -u'\U0001d765': '$\\mathsfbf{\\Pi}$', -u'\U0001d766': '$\\mathsfbf{\\Rho}$', -u'\U0001d767': '{\\mathsfbf{\\vartheta}}', -u'\U0001d768': '$\\mathsfbf{\\Sigma}$', -u'\U0001d769': '$\\mathsfbf{\\Tau}$', -u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', -u'\U0001d76b': '$\\mathsfbf{\\Phi}$', -u'\U0001d76c': '$\\mathsfbf{\\Chi}$', -u'\U0001d76d': '$\\mathsfbf{\\Psi}$', -u'\U0001d76e': '$\\mathsfbf{\\Omega}$', -u'\U0001d76f': '$\\mathsfbf{\\nabla}$', -u'\U0001d770': '$\\mathsfbf{\\Alpha}$', -u'\U0001d771': '$\\mathsfbf{\\Beta}$', -u'\U0001d772': '$\\mathsfbf{\\Gamma}$', -u'\U0001d773': '$\\mathsfbf{\\Delta}$', -u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', -u'\U0001d775': '$\\mathsfbf{\\Zeta}$', -u'\U0001d776': '$\\mathsfbf{\\Eta}$', -u'\U0001d777': '$\\mathsfbf{\\Theta}$', -u'\U0001d778': '$\\mathsfbf{\\Iota}$', -u'\U0001d779': '$\\mathsfbf{\\Kappa}$', -u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', -u'\U0001d77b': '$M$', -u'\U0001d77c': '$N$', -u'\U0001d77d': '$\\mathsfbf{\\Xi}$', -u'\U0001d77e': '$O$', -u'\U0001d77f': '$\\mathsfbf{\\Pi}$', -u'\U0001d780': '$\\mathsfbf{\\Rho}$', -u'\U0001d781': '$\\mathsfbf{\\varsigma}$', -u'\U0001d782': '$\\mathsfbf{\\Sigma}$', -u'\U0001d783': '$\\mathsfbf{\\Tau}$', -u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', -u'\U0001d785': '$\\mathsfbf{\\Phi}$', -u'\U0001d786': '$\\mathsfbf{\\Chi}$', -u'\U0001d787': '$\\mathsfbf{\\Psi}$', -u'\U0001d788': '$\\mathsfbf{\\Omega}$', -u'\U0001d789': '$\\partial$', -u'\U0001d78a': '$\\in$', -u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', -u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', -u'\U0001d78d': '{\\mathsfbf{\\phi}}', -u'\U0001d78e': '{\\mathsfbf{\\varrho}}', -u'\U0001d78f': '{\\mathsfbf{\\varpi}}', -u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', -u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', -u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', -u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', -u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', -u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', -u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', -u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', -u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', -u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', -u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', -u'\U0001d79b': '$M$', -u'\U0001d79c': '$N$', -u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', -u'\U0001d79e': '$O$', -u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', -u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', -u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', -u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', -u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', -u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', -u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', -u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', -u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', -u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', -u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', -u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', -u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', -u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', -u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', -u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', -u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', -u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', -u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', -u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', -u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', -u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', -u'\U0001d7b5': '$M$', -u'\U0001d7b6': '$N$', -u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', -u'\U0001d7b8': '$O$', -u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', -u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', -u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', -u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', -u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', -u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', -u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', -u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', -u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', -u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', -u'\U0001d7c3': '$\\partial$', -u'\U0001d7c4': '$\\in$', -u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', -u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', -u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', -u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', -u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', -u'\U0001d7ce': '$\\mathbf{0}$', -u'\U0001d7cf': '$\\mathbf{1}$', -u'\U0001d7d0': '$\\mathbf{2}$', -u'\U0001d7d1': '$\\mathbf{3}$', -u'\U0001d7d2': '$\\mathbf{4}$', -u'\U0001d7d3': '$\\mathbf{5}$', -u'\U0001d7d4': '$\\mathbf{6}$', -u'\U0001d7d5': '$\\mathbf{7}$', -u'\U0001d7d6': '$\\mathbf{8}$', -u'\U0001d7d7': '$\\mathbf{9}$', -u'\U0001d7d8': '$\\mathbb{0}$', -u'\U0001d7d9': '$\\mathbb{1}$', -u'\U0001d7da': '$\\mathbb{2}$', -u'\U0001d7db': '$\\mathbb{3}$', -u'\U0001d7dc': '$\\mathbb{4}$', -u'\U0001d7dd': '$\\mathbb{5}$', -u'\U0001d7de': '$\\mathbb{6}$', -u'\U0001d7df': '$\\mathbb{7}$', -u'\U0001d7e0': '$\\mathbb{8}$', -u'\U0001d7e1': '$\\mathbb{9}$', -u'\U0001d7e2': '$\\mathsf{0}$', -u'\U0001d7e3': '$\\mathsf{1}$', -u'\U0001d7e4': '$\\mathsf{2}$', -u'\U0001d7e5': '$\\mathsf{3}$', -u'\U0001d7e6': '$\\mathsf{4}$', -u'\U0001d7e7': '$\\mathsf{5}$', -u'\U0001d7e8': '$\\mathsf{6}$', -u'\U0001d7e9': '$\\mathsf{7}$', -u'\U0001d7ea': '$\\mathsf{8}$', -u'\U0001d7eb': '$\\mathsf{9}$', -u'\U0001d7ec': '$\\mathsfbf{0}$', -u'\U0001d7ed': '$\\mathsfbf{1}$', -u'\U0001d7ee': '$\\mathsfbf{2}$', -u'\U0001d7ef': '$\\mathsfbf{3}$', -u'\U0001d7f0': '$\\mathsfbf{4}$', -u'\U0001d7f1': '$\\mathsfbf{5}$', -u'\U0001d7f2': '$\\mathsfbf{6}$', -u'\U0001d7f3': '$\\mathsfbf{7}$', -u'\U0001d7f4': '$\\mathsfbf{8}$', -u'\U0001d7f5': '$\\mathsfbf{9}$', -u'\U0001d7f6': '$\\mathtt{0}$', -u'\U0001d7f7': '$\\mathtt{1}$', -u'\U0001d7f8': '$\\mathtt{2}$', -u'\U0001d7f9': '$\\mathtt{3}$', -u'\U0001d7fa': '$\\mathtt{4}$', -u'\U0001d7fb': '$\\mathtt{5}$', -u'\U0001d7fc': '$\\mathtt{6}$', -u'\U0001d7fd': '$\\mathtt{7}$', -u'\U0001d7fe': '$\\mathtt{8}$', -u'\U0001d7ff': '$\\mathtt{9}$'} diff --git a/setup.py b/setup.py index 49b399f9e..24caa593c 100755 --- a/setup.py +++ b/setup.py @@ -50,16 +50,33 @@ what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 'platforms': 'OS-independent', 'cmdclass': {'install_data': smart_install_data}, 'package_dir': {'docutils': 'docutils', '': 'extras'}, - 'packages': ['docutils', 'docutils.languages', - 'docutils.parsers', 'docutils.parsers.rst', + 'packages': ['docutils', + 'docutils.languages', + 'docutils.parsers', + 'docutils.parsers.rst', 'docutils.parsers.rst.directives', 'docutils.parsers.rst.languages', - 'docutils.readers', 'docutils.readers.python', + 'docutils.readers', + 'docutils.readers.python', 'docutils.transforms', - 'docutils.writers',], + 'docutils.writers', + 'docutils.writers.support', + 'docutils.writers.support.newlatex2e'], 'data_files': [('docutils/parsers/rst/include', - glob.glob('docutils/parsers/rst/include/*.txt'))], - 'scripts' : ['tools/rst2html.py','tools/rst2latex.py'],} + glob.glob('docutils/parsers/rst/include/*.txt')), + ('docutils/writers/support', + ['docutils/writers/support/html4css1.css', + 'docutils/writers/support/latex2e.tex']), + ('docutils/writers/support/newlatex2e', + ['docutils/writers/support/newlatex2e/base.tex']), + ('docutils/writers/support/pep_html', + ['docutils/writers/support/pep_html/pep.css', + 'docutils/writers/support/pep_html/template.txt']),], + 'scripts' : ['tools/rst2html.py', + 'tools/rst2latex.py', + 'tools/rst2newlatex.py', + 'tools/rst2xml.py', + 'tools/rst2pseudoxml.py'],} """Distutils setup parameters.""" classifiers = [ diff --git a/test/functional/tests/misc_rst_html4css1.py b/test/functional/tests/misc_rst_html4css1.py index d90f3453c..861a9e9c5 100644 --- a/test/functional/tests/misc_rst_html4css1.py +++ b/test/functional/tests/misc_rst_html4css1.py @@ -10,3 +10,5 @@ writer_name = "html4css1" # Settings # test for encoded attribute value: settings_overrides['stylesheet'] = 'foo&bar.css' +settings_overrides['stylesheet_path'] = '' +settings_overrides['embed_stylesheet'] = 0 diff --git a/test/functional/tests/pep_html.py b/test/functional/tests/pep_html.py index efb067ac4..fde5a0cd5 100644 --- a/test/functional/tests/pep_html.py +++ b/test/functional/tests/pep_html.py @@ -8,9 +8,10 @@ parser_name = "rst" writer_name = "pep_html" # Settings -settings_overrides['stylesheet'] = None -settings_overrides['stylesheet_path'] = "../tools/stylesheets/pep.css" -settings_overrides['template'] = "../tools/pep-html-template" +# settings_overrides['stylesheet'] = None +settings_overrides['stylesheet_path'] = ( + "../docutils/writers/support/pep_html/pep.css") +# settings_overrides['template'] = "../tools/pep-html-template" settings_overrides['python_home'] = "http://www.python.org" settings_overrides['pep_home'] = "http://www.python.org/peps" settings_overrides['no_random'] = 1 diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 3e08d32c4..1df84de15 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -26,7 +26,8 @@ def suite(): totest = {} -totest['Title promotion'] = ({}, [ +totest['Title promotion'] = ({'stylesheet_path': '', + 'embed_stylesheet': 0}, [ ["""\ Simple String """, @@ -186,7 +187,9 @@ Some stuff """] ]) -totest['No title promotion'] = ({'doctitle_xform' : 0}, [ +totest['No title promotion'] = ({'doctitle_xform' : 0, + 'stylesheet_path': '', + 'embed_stylesheet': 0}, [ ["""\ Simple String """, diff --git a/tools/docutils.conf b/tools/docutils.conf index 92392c2ed..f696f0013 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -7,10 +7,4 @@ embed-stylesheet: no [html4css1 writer] # These entries affect HTML output: -stylesheet-path: stylesheets/default.css field-name-limit: 20 - -[pep_html writer] -# These entries affect reStructuredText-style PEPs: -template: pep-html-template -stylesheet-path: stylesheets/pep.css diff --git a/tools/pep-html-template b/tools/pep-html-template deleted file mode 100644 index 6f96977e8..000000000 --- a/tools/pep-html-template +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - PEP %(pep)s -- %(title)s - %(stylesheet)s - - - - -
    -%(body)s -%(body_suffix)s diff --git a/tools/rst2html.py b/tools/rst2html.py index 7fa3aebc4..35e5558aa 100755 --- a/tools/rst2html.py +++ b/tools/rst2html.py @@ -22,5 +22,4 @@ from docutils.core import publish_cmdline, default_description description = ('Generates (X)HTML documents from standalone reStructuredText ' 'sources. ' + default_description) -publish_cmdline(writer_name='html', description=description, - settings_overrides={'_stylesheet_required': 1}) +publish_cmdline(writer_name='html', description=description) diff --git a/tools/stylesheets/default.css b/tools/stylesheets/default.css deleted file mode 100644 index a418a7a00..000000000 --- a/tools/stylesheets/default.css +++ /dev/null @@ -1,276 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:Date: $Date$ -:Revision: $Revision$ -:Copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. - -See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to -customize this style sheet. -*/ - -/* "! important" is used here to override other ``margin-top`` and - ``margin-bottom`` styles that are later in the stylesheet or - more specific. See http://www.w3.org/TR/CSS1#the-cascade */ -.first { - margin-top: 0 ! important } - -.last, .with-subtitle { - margin-bottom: 0 ! important } - -.hidden { - display: none } - -a.toc-backref { - text-decoration: none ; - color: black } - -blockquote.epigraph { - margin: 2em 5em ; } - -dl.docutils dd { - margin-bottom: 0.5em } - -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - clear: both; - font-size: smaller } - -div.line-block { - display: block ; - margin-top: 1em ; - margin-bottom: 1em } - -div.line-block div.line-block { - margin-top: 0 ; - margin-bottom: 0 ; - margin-left: 1.5em } - -div.sidebar { - margin-left: 1em ; - border: medium outset ; - padding: 1em ; - background-color: #ffffee ; - width: 40% ; - float: right ; - clear: right } - -div.sidebar p.rubric { - font-family: sans-serif ; - font-size: medium } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr.docutils { - width: 75% } - -img.align-left { - clear: left } - -img.align-right { - clear: right } - -img.borderless { - border: 0 } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.attribution { - text-align: right ; - margin-left: 50% } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.label { - white-space: nowrap } - -p.rubric { - font-weight: bold ; - font-size: larger ; - color: maroon ; - text-align: center } - -p.sidebar-title { - font-family: sans-serif ; - font-weight: bold ; - font-size: larger } - -p.sidebar-subtitle { - font-family: sans-serif ; - font-weight: bold } - -p.topic-title { - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option { - white-space: nowrap } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -span.section-subtitle { - /* font-size relative to parent (h1..h6 element) */ - font-size: 80% } - -table.citation { - border-left: solid thin gray } - -table.docinfo { - margin: 2em 4em } - -table.docutils { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.footnote { - border-left: solid thin black } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap ; - padding-left: 0 } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100% } - -tt.docutils { - background-color: #eeeeee } - -ul.auto-toc { - list-style-type: none } diff --git a/tools/stylesheets/latex.tex b/tools/stylesheets/latex.tex deleted file mode 100644 index 231f3911f..000000000 --- a/tools/stylesheets/latex.tex +++ /dev/null @@ -1,1108 +0,0 @@ -\makeatletter - -% Development notes at -% http://docutils.python-hosting.com/wiki/NewLatex - - -\providecommand{\Dprinting}{false} - - -\providecommand{\DSearly}{} -\providecommand{\DSlate}{} - -\providecommand{\Ddocumentclass}{scrartcl} -\providecommand{\Ddocumentoptions}{a4paper} - -\documentclass[\Ddocumentoptions]{\Ddocumentclass} - -\DSearly - - -\providecommand{\DSfontencoding}{ - % Set up font encoding. - % AE is a T1-emulation. It provides most characters and features - % as T1-encoded fonts but doesn't use ugly bitmap fonts. - \usepackage{ae} - % Provide the characters not contained in AE from EC bitmap fonts. - \usepackage{aecompl} - % Guillemets ("<<", ">>") in AE. - \usepackage{aeguill} -} - - -\providecommand{\DSsymbols}{% - % Fix up symbols. - % The Euro symbol in Computer Modern looks, um, funny. Let's get a - % proper Euro symbol. - \RequirePackage{eurosym}% - \renewcommand{\texteuro}{\euro}% -} - - -% Taken from -% -% and modified. Used with permission. -\providecommand{\Dprovidelength}[2]{% - \begingroup% - \escapechar\m@ne% - \xdef\@gtempa{{\string#1}}% - \endgroup% - \expandafter\@ifundefined\@gtempa% - {\newlength{#1}\setlength{#1}{#2}}% - {}% -} - -\providecommand{\Dprovidecounter}[1]{% - % Like \newcounter except that it doesn't crash if the counter - % already exists. - \@ifundefined{c@#1}{\newcounter{#1}}{} -} - -\Dprovidelength{\Dboxparindent}{\parindent} -\providecommand{\Dmakeboxminipage}[1]{% - % Make minipage for use in a box created by \Dmakefbox. - \begin{minipage}[t]{0.9\linewidth}% - \setlength{\parindent}{\Dboxparindent}% - #1% - \end{minipage}% -} -\providecommand{\Dmakefbox}[1]{% - % Make a centered, framed box. Useful e.g. for admonitions. - \vspace{0.4\baselineskip}% - \begin{center}% - \fbox{\Dmakeboxminipage{#1}}% - \end{center}% - \vspace{0.4\baselineskip}% -} -\providecommand{\Dmakebox}[1]{% - % Make a centered, frameless box. Useful e.g. for block quotes. - % Do not use minipages here, but create pseudo-lists to allow - % page-breaking. (Don't use KOMA-script's addmargin environment - % because it messes up bullet lists.) - \Dmakelistenvironment{}{}{% - \setlength{\parskip}{0pt}% - \setlength{\parindent}{\Dboxparindent}% - \item{#1}% - }% -} - - -\RequirePackage{ifthen} -\providecommand{\Dfrenchspacing}{true} -\ifthenelse{\equal{\Dfrenchspacing}{true}}{\frenchspacing}{} - - -\Dprovidelength{\Dblocklevelvspace}{% - % Space between block-level elements other than paragraphs. - 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% -} -\providecommand{\Dauxiliaryspace}{% - \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% - \par\noindent% -} -\providecommand{\Dparagraphspace}{\par} -\providecommand{\Dneedvspace}{true} - - -\providecommand{\DSlinks}{ - % Targets and references. - \RequirePackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} - - \providecommand{\Draisedlink}[1]{\Hy@raisedlink{##1}} - - % References. - % We're assuming here that the "refid" and "refuri" attributes occur - % only in inline context (in TextElements). - \providecommand{\DArefid}[5]{% - \ifthenelse{\equal{##4}{reference}}{% - \Dexplicitreference{\###3}{##5}% - }{% - % If this is not a target node (targets with refids are - % uninteresting and should be silently dropped). - \ifthenelse{\not\equal{##4}{target}}{% - % If this is a footnote reference, call special macro. - \ifthenelse{\equal{##4}{footnotereference}}{% - \Dimplicitfootnotereference{\###3}{##5}% - }{% - \ifthenelse{\equal{##4}{citationreference}}{% - \Dimplicitcitationreference{\###3}{##5}% - }{% - \Dimplicitreference{\###3}{##5}% - }% - }% - }{}% - }% - } - \providecommand{\DArefuri}[5]{% - \ifthenelse{\equal{##4}{target}}{% - % Hyperlink targets can (and should be) ignored because they are - % invisible. - }{% - % We only have explicit URI references, so one macro suffices. - \Durireference{##3}{##5}% - }% - } - % Targets. - \providecommand{\DAids}[5]{% - \label{##3}% - \ifthenelse{\equal{##4}{footnotereference}}{% - {% - \renewcommand{\HyperRaiseLinkDefault}{% - % Dirty hack to make backrefs to footnote references work. - % For some reason, \baselineskip is 0pt in fn references. - 0.5\Doriginalbaselineskip% - }% - \Draisedlink{\hypertarget{##3}{}}##5% - }% - }{% - \Draisedlink{\hypertarget{##3}{}}##5% - }% - } - % Color in references. - \RequirePackage{color} - \providecommand{\Dimplicitreference}[2]{% - % Create implicit reference to ID. Implicit references occur - % e.g. in TOC-backlinks of section titles. Parameters: - % 1. Target. - % 2. Link text. - \href{##1}{##2}% - } - \providecommand{\Dimplicitfootnotereference}[2]{% - % Ditto, but for the special case of footnotes. - % We want them to be rendered like explicit references. - \Dexplicitreference{##1}{##2}% - } - \providecommand{\Dimplicitcitationreference}[2]{% - % Ditto for citation references. - \Dimplicitfootnotereference{##1}{##2}% - } - \ifthenelse{\equal{\Dprinting}{true}}{ - \providecommand{\Dexplicitreferencecolor}{black} - }{ - \providecommand{\Dexplicitreferencecolor}{blue} - } - \providecommand{\Dexplicitreference}[2]{% - % Create explicit reference to ID, e.g. created with "foo_". - % Parameters: - % 1. Target. - % 2. Link text. - \href{##1}{{\color{\Dexplicitreferencecolor}##2}}% - } - \providecommand{\Durireferencecolor}{\Dexplicitreferencecolor} - \providecommand{\Durireference}[2]{% - % Create reference to URI. Parameters: - % 1. Target. - % 2. Link text. - \href{##1}{{\color{\Durireferencecolor}##2}}% - } -} - - -\providecommand{\DSlanguage}{% - % Set up babel. - \ifthenelse{\equal{\Dlanguagebabel}{}}{}{ - \RequirePackage[\Dlanguagebabel]{babel} - } -} - - - - -\providecommand{\DAclasses}[5]{% - \Difdefined{DN#4C#3}{% - % Pass only contents, nothing else! - \csname DN#4C#3\endcsname{#5}% - }{% - \Difdefined{DC#3}{% - \csname DC#3\endcsname{#5}% - }{% - #5% - }% - }% -} - -\providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}} - -\providecommand{\Dattr}[5]{% - % Global attribute dispatcher. - % Parameters: - % 1. Attribute number. - % 2. Attribute name. - % 3. Attribute value. - % 4. Node name. - % 5. Node contents. - \Difdefined{DN#4A#2V#3}{% - \csname DN#4A#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% - }{\Difdefined{DN#4A#2}{% - \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% - }{\Difdefined{DA#2V#3}{% - \csname DA#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% - }{\Difdefined{DA#2}{% - \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}% - }{#5% - }}}}% -} - -\providecommand{\DNparagraph}[1]{% - \ifthenelse{\equal{\Dparagraphindented}{true}}{\indent}{\noindent}% - #1% -} -\providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} -\providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} -\providecommand{\Dtopictitle}[1]{% - \Difinsidetoc{\vspace{1em}\par}{}% - \noindent\Dformatboxtitle{#1}% - \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% - \par% -} -\providecommand{\Dtopicsubtitle}[1]{% - \noindent\Dformatboxsubtitle{#1}% - \vspace{1em}% - \par% -} -\providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}} -\providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}} -\providecommand{\Ddocumenttitle}[1]{% - \begin{center}{\Huge#1}\end{center}% - \ifthenelse{\equal{\Dhassubtitle}{true}}{\vspace{0.1cm}}{\vspace{1cm}}% -} -\providecommand{\Ddocumentsubtitle}[1]{% - \begin{center}{\huge#1}\end{center}% - \vspace{1cm}% -} -% Can be overwritten by user stylesheet. -\providecommand{\Dformatsectiontitle}[1]{#1} -\providecommand{\Dformatsectionsubtitle}[1]{\Dformatsectiontitle{#1}} -\providecommand{\Dbookmarksectiontitle}[1]{% - % Return text suitable for use in \section*, \subsection*, etc., - % containing a PDF bookmark. Parameter: The title (as node tree). - \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% - #1% -} -\providecommand{\Dsectiontitlehook}[1]{#1} -\providecommand{\Dsectiontitle}[1]{% - \Dsectiontitlehook{% - \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% - }% -} -\providecommand{\Ddispatchsectiontitle}[1]{% - \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% - \Ddeepsectiontitle{#1}% - }{% - \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% - }% -} -\providecommand{\Ddispatchsectionsubtitle}[1]{% - \Ddispatchsectiontitle{#1}% -} -\providecommand{\Dsectiontitlei}[1]{\section*{#1}} -\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} -\providecommand{\Ddeepsectiontitle}[1]{% - % Anything below \subsubsection (like \paragraph or \subparagraph) - % is useless because it uses the same font. The only way to - % (visually) distinguish such deeply nested sections is to use - % section numbering. - \subsubsection*{#1}% -} -\providecommand{\Dsectionsubtitlehook}[1]{#1} -\Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} -\providecommand{\Dsectionsubtitlescaling}{0.85} -\providecommand{\Dsectionsubtitle}[1]{% - \Dsectionsubtitlehook{% - % Move the subtitle nearer to the title. - \vspace{-\Dsectionsubtitleraisedistance}% - % Don't create a PDF bookmark. - \Ddispatchsectionsubtitle{% - \Dformatsectionsubtitle{\scalebox{\Dsectionsubtitlescaling}{#1}}% - }% - }% -} -% Boolean variable. -\providecommand{\Dhassubtitle}{false} -\providecommand{\DNtitle}[1]{% - \csname D\Dparent title\endcsname{#1}% -} -\providecommand{\DNsubtitle}[1]{% - \csname D\Dparent subtitle\endcsname{#1}% -} -\newcounter{Dpdfbookmarkid} -\setcounter{Dpdfbookmarkid}{0} -\providecommand{\Dpdfbookmark}[1]{% - % Temporarily decrement Desctionlevel counter. - \addtocounter{Dsectionlevel}{-1}% - %\typeout{\arabic{Dsectionlevel}}% - %\typeout{#1}% - %\typeout{docutils\roman{Dpdfbookmarkid}}% - %\typeout{}% - \pdfbookmark[\arabic{Dsectionlevel}]{#1}{docutils\arabic{Dpdfbookmarkid}}% - \addtocounter{Dsectionlevel}{1}% - \addtocounter{Dpdfbookmarkid}{1}% -} - -%\providecommand{\DNliteralblock}[1]{\begin{quote}\ttfamily\raggedright#1\end{quote}} -\providecommand{\DNliteralblock}[1]{% - \Dmakelistenvironment{}{% - \ifthenelse{\equal{\Dinsidetabular}{true}}{% - \setlength{\leftmargin}{0pt}% - }{}% - \setlength{\rightmargin}{0pt}% - }{% - \raggedright\item\noindent\nohyphens{\textnhtt{#1\Dfinalstrut}}% - }% -} -\providecommand{\DNdoctestblock}[1]{% - % Treat doctest blocks the same as literal blocks. - \DNliteralblock{#1}% -} -\RequirePackage{hyphenat} -\providecommand{\DNliteral}[1]{\textnhtt{#1}} -\providecommand{\DNemphasis}[1]{\emph{#1}} -\providecommand{\DNstrong}[1]{\textbf{#1}} -\providecommand{\Dvisitdocument}{\begin{document}\noindent} -\providecommand{\Ddepartdocument}{\end{document}} -\providecommand{\DNtopic}[1]{% - \ifthenelse{\equal{\DcurrentNtopicAcontents}{1}}{% - \addtocounter{Dtoclevel}{1}% - \par\noindent% - #1% - \addtocounter{Dtoclevel}{-1}% - }{% - \par\noindent% - \Dmakebox{#1}% - }% -} -\providecommand{\Dformatrubric}[1]{\textbf{#1}} -\Dprovidelength{\Dprerubricspace}{0.3em} -\providecommand{\DNrubric}[1]{% - \vspace{\Dprerubricspace}\par\noindent\Dformatrubric{#1}\par% -} - -\providecommand{\Dbullet}{} -\providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} -\providecommand{\DNbulletlist}[1]{% - \Difinsidetoc{% - \Dtocbulletlist{#1}% - }{% - \Dmakelistenvironment{\Dbullet}{}{#1}% - }% -} -\renewcommand{\@pnumwidth}{2.2em} -\providecommand{\DNlistitem}[1]{% - \Difinsidetoc{% - \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{% - {% - \par\addvspace{1em}\noindent% - \sectfont% - #1\hfill\pageref{\DcurrentNlistitemAtocrefid}% - }% - }{% - \@dottedtocline{0}{\Dtocindent}{0em}{#1}{% - \pageref{\DcurrentNlistitemAtocrefid}% - }% - }% - }{% - \item{#1}% - }% -} -\providecommand{\DNenumeratedlist}[1]{#1} -\newcounter{Dsectionlevel} -\providecommand{\Dvisitsectionhook}{} -\providecommand{\Ddepartsectionhook}{} -\providecommand{\Dvisitsection}{% - \addtocounter{Dsectionlevel}{1}% - \Dvisitsectionhook% -} -\providecommand{\Ddepartsection}{% - \Ddepartsectionhook% - \addtocounter{Dsectionlevel}{-1}% -} - -% Using \_ will cause hyphenation after _ even in \textnhtt-typewriter -% because the hyphenat package redefines \_. So we use -% \textunderscore here. -\providecommand{\Dtextunderscore}{\textunderscore} - -\providecommand{\Dtextinlineliteralfirstspace}{{ }} -\providecommand{\Dtextinlineliteralsecondspace}{{~}} - -\Dprovidelength{\Dlistspacing}{0.8\baselineskip} - -\providecommand{\Dsetlistrightmargin}{% - \ifthenelse{\lengthtest{\linewidth>12em}}{% - % Equal margins. - \setlength{\rightmargin}{\leftmargin}% - }{% - % If the line is narrower than 10em, we don't remove any further - % space from the right. - \setlength{\rightmargin}{0pt}% - }% -} -\providecommand{\Dresetlistdepth}{false} -\Dprovidelength{\Doriginallabelsep}{\labelsep} -\providecommand{\Dmakelistenvironment}[3]{% - % Make list environment with support for unlimited nesting and with - % reasonable default lengths. Parameters: - % 1. Label (same as in list environment). - % 2. Spacing (same as in list environment). - % 3. List contents (contents of list environment). - \ifthenelse{\equal{\Dinsidetabular}{true}}{% - % Unfortunately, vertical spacing doesn't work correctly when - % using lists inside tabular environments, so we use a minipage. - \begin{minipage}[t]{\linewidth}% - }{}% - {% - \renewcommand{\Dneedvspace}{false}% - % \parsep0.5\baselineskip - \renewcommand{\Dresetlistdepth}{false}% - \ifnum \@listdepth>5% - \protect\renewcommand{\Dresetlistdepth}{true}% - \@listdepth=5% - \fi% - \begin{list}{% - #1% - }{% - \setlength{\itemsep}{0pt}% - \setlength{\partopsep}{0pt}% - \setlength{\topsep}{0pt}% - % List should take 90% of total width. - \setlength{\leftmargin}{0.05\linewidth}% - \ifthenelse{\lengthtest{\leftmargin<1.8em}}{% - \setlength{\leftmargin}{1.8em}% - }{}% - \setlength{\labelsep}{\Doriginallabelsep}% - \Dsetlistrightmargin% - #2% - }{% - #3% - }% - \end{list}% - \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% - }% - \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% -} -\providecommand{\Dfinalstrut}{\@finalstrut\@arstrutbox} -\providecommand{\DAlastitem}[5]{#5\Dfinalstrut} - -\Dprovidelength{\Ditemsep}{0pt} -\providecommand{\Dmakeenumeratedlist}[6]{% - % Make enumerated list. - % Parameters: - % - prefix - % - type (\arabic, \roman, ...) - % - suffix - % - suggested counter name - % - start number - 1 - % - list contents - \newcounter{#4}% - \Dmakelistenvironment{#1#2{#4}#3}{% - % Use as much space as needed for the label. - \setlength{\labelwidth}{10em}% - % Reserve enough space so that the label doesn't go beyond the - % left margin of preceding paragraphs. Like that: - % - % A paragraph. - % - % 1. First item. - \setlength{\leftmargin}{2.5em}% - \Dsetlistrightmargin% - \setlength{\itemsep}{\Ditemsep}% - % Use counter recommended by Python module. - \usecounter{#4}% - % Set start value. - \addtocounter{#4}{#5}% - }{% - % The list contents. - #6% - }% -} - - -% Single quote in literal mode. \textquotesingle from package -% textcomp has wrong width when using package ae, so we use a normal -% single curly quote here. -\providecommand{\Dtextliteralsinglequote}{'} - - -% "Tabular lists" are field lists and options lists (not definition -% lists because there the term always appears on its own line). We'll -% use the terminology of field lists now ("field", "field name", -% "field body"), but the same is also analogously applicable to option -% lists. -% -% We want these lists to be breakable across pages. We cannot -% automatically get the narrowest possible size for the left column -% (i.e. the field names or option groups) because tabularx does not -% support multi-page tables, ltxtable needs to have the table in an -% external file and we don't want to clutter the user's directories -% with auxiliary files created by the filecontents environment, and -% ltablex is not included in teTeX. -% -% Thus we set a fixed length for the left column and use list -% environments. This also has the nice side effect that breaking is -% now possible anywhere, not just between fields. -% -% Note that we are creating a distinct list environment for each -% field. There is no macro for a whole tabular list! -\Dprovidelength{\Dtabularlistfieldnamewidth}{6em} -\Dprovidelength{\Dtabularlistfieldnamesep}{0.5em} -\providecommand{\Dinsidetabular}{false} -\providecommand{\Dsavefieldname}{} -\providecommand{\Dsavefieldbody}{} -\Dprovidelength{\Dusedfieldnamewidth}{0pt} -\Dprovidelength{\Drealfieldnamewidth}{0pt} -\providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}} -\providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}} -\Dprovidelength{\Dparskiptemp}{0pt} -\providecommand{\Dtabularlistfield}[1]{% - {% - % This only saves field name and field body in \Dsavefieldname and - % \Dsavefieldbody, resp. It does not insert any text into the - % document. - #1% - % Recalculate the real field name width everytime we encounter a - % tabular list field because it may have been changed using a - % "raw" node. - \setlength{\Drealfieldnamewidth}{\Dtabularlistfieldnamewidth}% - \addtolength{\Drealfieldnamewidth}{\Dtabularlistfieldnamesep}% - \Dmakelistenvironment{% - \makebox[\Drealfieldnamewidth][l]{\Dsavefieldname}% - }{% - \setlength{\labelwidth}{\Drealfieldnamewidth}% - \setlength{\leftmargin}{\Drealfieldnamewidth}% - \setlength{\rightmargin}{0pt}% - \setlength{\labelsep}{0pt}% - }{% - \item% - \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}% - \setlength{\Dparskiptemp}{\parskip}% - \ifthenelse{% - \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% - }{% - \mbox{}\par% - \setlength{\parskip}{0pt}% - }{}% - \Dsavefieldbody% - \setlength{\parskip}{\Dparskiptemp}% - %XXX Why did we need this? - %\@finalstrut\@arstrutbox% - }% - \par% - }% -} - -\providecommand{\Dformatfieldname}[1]{\textbf{#1:}} -\providecommand{\DNfieldlist}[1]{#1} -\providecommand{\DNfield}[1]{\Dtabularlistfield{#1}} -\providecommand{\DNfieldname}[1]{% - \Dtabularlistfieldname{% - \Dformatfieldname{#1}% - }% -} -\providecommand{\DNfieldbody}[1]{\Dtabularlistfieldbody{#1}} - -\providecommand{\Dformatoptiongroup}[1]{% - % Format option group, e.g. "-f file, --input file". - \texttt{#1}% -} -\providecommand{\Dformatoption}[1]{% - % Format option, e.g. "-f file". - % Put into mbox to avoid line-breaking at spaces. - \mbox{#1}% -} -\providecommand{\Dformatoptionstring}[1]{% - % Format option string, e.g. "-f". - #1% -} -\providecommand{\Dformatoptionargument}[1]{% - % Format option argument, e.g. "file". - \textsl{#1}% -} -\providecommand{\Dformatoptiondescription}[1]{% - % Format option description, e.g. - % "\DNparagraph{Read input data from file.}" - #1% -} -\providecommand{\DNoptionlist}[1]{#1} -\providecommand{\Doptiongroupjoiner}{,{ }} -\providecommand{\Disfirstoption}{% - % Auxiliary macro indicating if a given option is the first child - % of its option group (if it's not, it has to preceded by - % \Doptiongroupjoiner). - false% -} -\providecommand{\DNoptionlistitem}[1]{% - \Dtabularlistfield{#1}% -} -\providecommand{\DNoptiongroup}[1]{% - \renewcommand{\Disfirstoption}{true}% - \Dtabularlistfieldname{\Dformatoptiongroup{#1}}% -} -\providecommand{\DNoption}[1]{% - % If this is not the first option in this option group, add a - % joiner. - \ifthenelse{\equal{\Disfirstoption}{true}}{% - \renewcommand{\Disfirstoption}{false}% - }{% - \Doptiongroupjoiner% - }% - \Dformatoption{#1}% -} -\providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}} -\providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}} -\providecommand{\DNdescription}[1]{% - \Dtabularlistfieldbody{\Dformatoptiondescription{#1}}% -} - -\providecommand{\DNdefinitionlist}[1]{% - \begin{description}% - \parskip0pt% - #1% - \end{description}% -} -\providecommand{\DNdefinitionlistitem}[1]{% - % LaTeX expects the label in square brackets; we provide an empty - % label. - \item[]#1% -} -\providecommand{\Dformatterm}[1]{#1} -\providecommand{\DNterm}[1]{\hspace{-5pt}\Dformatterm{#1}} -% I'm still not sure what's the best rendering for classifiers. The -% colon syntax is used by reStructuredText, so it's at least WYSIWYG. -% Use slanted text because italic would cause too much emphasis. -\providecommand{\Dformatclassifier}[1]{\textsl{#1}} -\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} -\providecommand{\Dformatdefinition}[1]{#1} -\providecommand{\DNdefinition}[1]{\par\Dformatdefinition{#1}} - -\providecommand{\Dlineblockindentation}{2.5em} -\providecommand{\DNlineblock}[1]{% - \Dmakelistenvironment{}{% - \ifthenelse{\equal{\Dparent}{lineblock}}{% - % Parent is a line block, so indent. - \setlength{\leftmargin}{\Dlineblockindentation}% - }{% - % At top level; don't indent. - \setlength{\leftmargin}{0pt}% - }% - \setlength{\rightmargin}{0pt}% - \setlength{\parsep}{0pt}% - }{% - #1% - }% -} -\providecommand{\DNline}[1]{\item#1} - - -\providecommand{\DNtransition}{% - \raisebox{0.25em}{\parbox{\linewidth}{\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}}}% -} - - -\providecommand{\Dformatblockquote}[1]{% - % Format contents of block quote. - % This occurs in block-level context, so we cannot use \textsl. - {\slshape#1}% -} -\providecommand{\Dformatattribution}[1]{---\textup{#1}} -\providecommand{\DNblockquote}[1]{% - \Dmakebox{% - \Dformatblockquote{#1} - }% -} -\providecommand{\DNattribution}[1]{% - \par% - \begin{flushright}\Dformatattribution{#1}\end{flushright}% -} - - -% Sidebars: -\RequirePackage{picins} -% Vertical and horizontal margins. -\Dprovidelength{\Dsidebarvmargin}{0.5em} -\Dprovidelength{\Dsidebarhmargin}{1em} -% Padding (space between contents and frame). -\Dprovidelength{\Dsidebarpadding}{1em} -% Frame width. -\Dprovidelength{\Dsidebarframewidth}{2\fboxrule} -% Position ("l" or "r"). -\providecommand{\Dsidebarposition}{r} -% Width. -\Dprovidelength{\Dsidebarwidth}{0.45\linewidth} -\providecommand{\DNsidebar}[1]{ - \parpic[\Dsidebarposition]{% - \begin{minipage}[t]{\Dsidebarwidth}% - % Doing this with nested minipages is ugly, but I haven't found - % another way to place vertical space before and after the fbox. - \vspace{\Dsidebarvmargin}% - {% - \setlength{\fboxrule}{\Dsidebarframewidth}% - \setlength{\fboxsep}{\Dsidebarpadding}% - \fbox{% - \begin{minipage}[t]{\linewidth}% - \setlength{\parindent}{\Dboxparindent}% - #1% - \end{minipage}% - }% - }% - \vspace{\Dsidebarvmargin}% - \end{minipage}% - }% -} - - -% Citations and footnotes. -\providecommand{\Dformatfootnote}[1]{% - % Format footnote. - {% - \footnotesize#1% - % \par is necessary for LaTeX to adjust baselineskip to the - % changed font size. - \par% - }% -} -\providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}} -\Dprovidelength{\Doriginalbaselineskip}{0pt} -\providecommand{\DNfootnotereference}[1]{% - {% - % \baselineskip is 0pt in \textsuperscript, so we save it here. - \setlength{\Doriginalbaselineskip}{\baselineskip}% - \textsuperscript{#1}% - }% -} -\providecommand{\DNcitationreference}[1]{{[}#1{]}} -\Dprovidelength{\Dfootnotesep}{3.5pt} -\providecommand{\Dsetfootnotespacing}{% - % Spacing commands executed at the beginning of footnotes. - \setlength{\parindent}{0pt}% - \hspace{1em}% -} -\providecommand{\DNfootnote}[1]{% - % See ltfloat.dtx for details. - {% - \insert\footins{% - \vspace{\Dfootnotesep}% - \Dsetfootnotespacing% - \Dformatfootnote{#1}% - }% - }% -} -\providecommand{\DNcitation}[1]{\DNfootnote{#1}} -\providecommand{\Dformatfootnotelabel}[1]{% - % Keep \footnotesize in footnote labels (\textsuperscript would - % reduce the font size even more). - \textsuperscript{\footnotesize#1{ }}% -} -\providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }} -\providecommand{\Dformatmultiplebackrefs}[1]{% - % If in printing mode, do not write out multiple backrefs. - \ifthenelse{\equal{\Dprinting}{true}}{}{\textsl{#1}}% -} -\providecommand{\Dthislabel}{} -\providecommand{\DNlabel}[1]{% - \renewcommand{\Dthislabel}{#1} - \ifthenelse{\not\equal{\Dsinglebackref}{}}{% - \let\Doriginallabel=\Dthislabel% - \def\Dthislabel{% - \Dsinglefootnotebacklink{\Dsinglebackref}{\Doriginallabel}% - }% - }{}% - \ifthenelse{\equal{\Dparent}{footnote}}{% - % Footnote label. - \Dformatfootnotelabel{\Dthislabel}% - }{% - \ifthenelse{\equal{\Dparent}{citation}}{% - % Citation label. - \Dformatcitationlabel{\Dthislabel}% - }{}% - }% - % If there are multiple backrefs, add them now. - \Dformatmultiplebackrefs{\Dmultiplebackrefs}% -} -\providecommand{\Dsinglefootnotebacklink}[2]{% - % Create normal backlink of a footnote label. Parameters: - % 1. ID. - % 2. Link text. - % Treat like a footnote reference. - \Dimplicitfootnotereference{\##1}{#2}% -} -\providecommand{\Dmultifootnotebacklink}[2]{% - % Create generated backlink, as in (1, 2). Parameters: - % 1. ID. - % 2. Link text. - % Treat like a footnote reference. - \Dimplicitfootnotereference{\##1}{#2}% -} -\providecommand{\Dsinglecitationbacklink}[2]{\Dsinglefootnotebacklink{#1}{#2}} -\providecommand{\Dmulticitationbacklink}[2]{\Dmultifootnotebacklink{#1}{#2}} - - -\RequirePackage{longtable} -\providecommand{\Dmaketable}[2]{% - % Make table. Parameters: - % 1. Table spec (like "|p|p|"). - % 2. Table contents. - {% - \ifthenelse{\equal{\Dinsidetabular}{true}}{% - % Inside longtable; we cannot have nested longtables. - \begin{tabular}{#1}% - \hline% - #2% - \end{tabular}% - }{% - \renewcommand{\Dinsidetabular}{true}% - \begin{longtable}{#1}% - \hline% - #2% - \end{longtable}% - }% - }% -} -\providecommand{\DNthead}[1]{% - #1% - \endhead% -} -\providecommand{\DNrow}[1]{% - #1\tabularnewline% - \hline% -} -\providecommand{\Dinsidemulticolumn}{false} -\providecommand{\Dcompensatingmulticol}[3]{% - \multicolumn{#1}{#2}{% - {% - \renewcommand{\Dinsidemulticolumn}{true}% - % Compensate for weird missing vertical space at top of paragraph. - \raisebox{-2.5pt}{#3}% - }% - }% -} -\providecommand{\Dcolspan}[2]{% - % Take care of the morecols attribute (but incremented by 1). - &% - \Dcompensatingmulticol{#1}{l|}{#2}% -} -\providecommand{\Dcolspanleft}[2]{% - % Like \Dmorecols, but called for the leftmost entries in a table - % row. - \Dcompensatingmulticol{#1}{|l|}{#2}% -} -\providecommand{\Dsubsequententry}[1]{% - % -} -\providecommand{\DNentry}[1]{% - % The following sequence adds minimal vertical space above the top - % lines of the first cell paragraph, so that vertical space is - % balanced at the top and bottom of table cells. - \ifthenelse{\equal{\Dinsidemulticolumn}{false}}{% - \vspace{-1em}\vspace{-\parskip}\par% - }{}% - #1% - % No need to add an ampersand ("&"); that's done by \Dsubsequententry. -} -\providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} -\providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} - - -\providecommand{\DNsystemmessage}[1]{% - {% - \ifthenelse{\equal{\Dprinting}{false}}{\color{red}}{}% - \bfseries% - #1% - }% -} - - -\providecommand{\Dinsidehalign}{false} -\newsavebox{\Dalignedimagebox} -\Dprovidelength{\Dalignedimagewidth}{0pt} -\providecommand{\Dhalign}[2]{% - % Horizontally align the contents to the left or right so that the - % text flows around it. - % Parameters: - % 1. l or r - % 2. Contents. - \renewcommand{\Dinsidehalign}{true}% - % For some obscure reason \parpic consumes some vertical space. - \vspace{-3pt}% - % Now we do something *really* ugly, but this enables us to wrap the - % image in a minipage while still allowing tight frames when - % class=border (see \DNimageCborder). - \sbox{\Dalignedimagebox}{#2}% - \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}% - \parpic[#1]{% - \begin{minipage}[b]{\Dalignedimagewidth}% - % Compensate for previously added space, but not entirely. - \vspace*{2.0pt}% - \vspace*{\Dfloatimagetopmargin}% - \usebox{\Dalignedimagebox}% - \vspace*{1.5pt}% - \vspace*{\Dfloatimagebottommargin}% - \end{minipage}% - }% - \renewcommand{\Dinsidehalign}{false}% -} - - -\RequirePackage{graphicx} -% Maximum width of an image. -\providecommand{\Dimagemaxwidth}{\linewidth} -\providecommand{\Dfloatimagemaxwidth}{0.5\linewidth} -% Auxiliary variable. -\Dprovidelength{\Dcurrentimagewidth}{0pt} -\providecommand{\DNimageAalign}[5]{% - \ifthenelse{\equal{#3}{left}}{% - \Dhalign{l}{#5}% - }{% - \ifthenelse{\equal{#3}{right}}{% - \Dhalign{r}{#5}% - }{% - \ifthenelse{\equal{#3}{center}}{% - % Text floating around centered figures is a bad idea. Thus - % we use a center environment. Note that no extra space is - % added by the writer, so the space added by the center - % environment is fine. - \begin{center}#5\end{center}% - }{% - #5% - }% - }% - }% -} -% Base path for images. -\providecommand{\Dimagebase}{} -% Auxiliary command. Current image path. -\providecommand{\Dimagepath}{} -\providecommand{\DNimageAuri}[5]{% - % Insert image. We treat the URI like a path here. - \renewcommand{\Dimagepath}{\Dimagebase#3}% - \Difdefined{DcurrentNimageAwidth}{% - \Dwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% - }{% - \Dsimpleimage{\Dimagepath}% - }% -} -\Dprovidelength{\Dfloatimagevmargin}{0pt} -\providecommand{\Dfloatimagetopmargin}{\Dfloatimagevmargin} -\providecommand{\Dfloatimagebottommargin}{\Dfloatimagevmargin} -\providecommand{\Dwidthimage}[2]{% - % Image with specified width. - % Parameters: - % 1. Image width. - % 2. Image path. - % Need to make bottom-alignment dependent on align attribute (add - % functional test first). Need to observe height attribute. - %\begin{minipage}[b]{#1}% - \includegraphics[width=#1,height=\textheight,keepaspectratio]{#2}% - %\end{minipage}% -} -\providecommand{\Dcurrentimagemaxwidth}{} -\providecommand{\Dsimpleimage}[1]{% - % Insert image, without much parametrization. - \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}% - \ifthenelse{\equal{\Dinsidehalign}{true}}{% - \renewcommand{\Dcurrentimagemaxwidth}{\Dfloatimagemaxwidth}% - }{% - \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}% - }% - \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{% - \Dwidthimage{\Dcurrentimagemaxwidth}{#1}% - }{% - \Dwidthimage{\Dcurrentimagewidth}{#1}% - }% -} -\providecommand{\Dwidthimage}[2]{% - % Image with specified width. - % Parameters: - % 1. Image width. - % 2. Image path. - \Dwidthimage{#1}{#2}% -} - -% Figures. -\providecommand{\DNfigureAalign}[5]{% - % Hack to make it work Right Now. - %\def\DcurrentNimageAwidth{\DcurrentNfigureAwidth}% - % - %\def\DcurrentNimageAwidth{\linewidth}% - \DNimageAalign{#1}{#2}{#3}{#4}{% - \begin{minipage}[b]{0.4\linewidth}#5\end{minipage}}% - %\let\DcurrentNimageAwidth=\relax% - % - %\let\DcurrentNimageAwidth=\relax% -} -\providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}} -\providecommand{\DNlegend}[1]{\Dauxiliaryspace#1} - -\providecommand{\DCborder}[1]{\fbox{#1}} -% No padding between image and border. -\providecommand{\DNimageCborder}[1]{\frame{#1}} - - -% Need to replace with language-specific stuff. Maybe look at -% csquotes.sty and ask the author for permission to use parts of it. -\providecommand{\Dtextleftdblquote}{``} -\providecommand{\Dtextrightdblquote}{''} - -% Table of contents: -\Dprovidelength{\Dtocininitialsectnumwidth}{2.4em} -\Dprovidelength{\Dtocadditionalsectnumwidth}{0.7em} -% Level inside a table of contents. While this is at -1, we are not -% inside a TOC. -\Dprovidecounter{Dtoclevel}% -\setcounter{Dtoclevel}{-1} -\providecommand{\Dlocaltoc}{false}% -\providecommand{\DNtopicClocal}[1]{% - \renewcommand{\Dlocaltoc}{true}% - \addtolength{\Dtocsectnumwidth}{2\Dtocadditionalsectnumwidth}% - \addtolength{\Dtocindent}{-2\Dtocadditionalsectnumwidth}% - #1% - \addtolength{\Dtocindent}{2\Dtocadditionalsectnumwidth}% - \addtolength{\Dtocsectnumwidth}{-2\Dtocadditionalsectnumwidth}% - \renewcommand{\Dlocaltoc}{false}% -} -\Dprovidelength{\Dtocindent}{0pt}% -\Dprovidelength{\Dtocsectnumwidth}{\Dtocininitialsectnumwidth} -% Compensate for one additional TOC indentation space so that the -% top-level is unindented. -\addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth} -\addtolength{\Dtocindent}{-\Dtocsectnumwidth} -\providecommand{\Difinsidetoc}[2]{% - \ifthenelse{\not\equal{\theDtoclevel}{-1}}{#1}{#2}% -} -\providecommand{\DNgeneratedCsectnum}[1]{% - \Difinsidetoc{% - % Section number inside TOC. - \makebox[\Dtocsectnumwidth][l]{#1}% - }{% - % Section number inside section title. - #1\quad% - }% -} -\providecommand{\Dtocbulletlist}[1]{% - \addtocounter{Dtoclevel}{1}% - \addtolength{\Dtocindent}{\Dtocsectnumwidth}% - \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% - #1% - \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% - \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% - \addtocounter{Dtoclevel}{-1}% -} - - -% For \Dpixelunit, the length value is pre-multiplied with 0.75, so by -% specifying "pt" we get the same notion of "pixel" as graphicx. -\providecommand{\Dpixelunit}{pt} -% Normally lengths are relative to the current linewidth. -\providecommand{\Drelativeunit}{\linewidth} - - -%\RequirePackage{fixmath} -%\RequirePackage{amsmath} - - -\DSfontencoding -\DSlanguage -\DSlinks -\DSsymbols -\DSlate - -\makeatother diff --git a/tools/stylesheets/pep.css b/tools/stylesheets/pep.css deleted file mode 100644 index a687ee8c8..000000000 --- a/tools/stylesheets/pep.css +++ /dev/null @@ -1,349 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date$ -:version: $Revision$ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the PEP HTML output of Docutils. -*/ - -/* "! important" is used here to override other ``margin-top`` and - ``margin-bottom`` styles that are later in the stylesheet or - more specific. See http://www.w3.org/TR/CSS1#the-cascade */ -.first { - margin-top: 0 ! important } - -.last, .with-subtitle { - margin-bottom: 0 ! important } - -.hidden { - display: none } - -.navigation { - width: 100% ; - background: #99ccff ; - margin-top: 0px ; - margin-bottom: 0px } - -.navigation .navicon { - width: 150px ; - height: 35px } - -.navigation .textlinks { - padding-left: 1em ; - text-align: left } - -.navigation td, .navigation th { - padding-left: 0em ; - padding-right: 0em ; - vertical-align: middle } - -.rfc2822 { - margin-top: 0.5em ; - margin-left: 0.5em ; - margin-right: 0.5em ; - margin-bottom: 0em } - -.rfc2822 td { - text-align: left } - -.rfc2822 th.field-name { - text-align: right ; - font-family: sans-serif ; - padding-right: 0.5em ; - font-weight: bold ; - margin-bottom: 0em } - -a.toc-backref { - text-decoration: none ; - color: black } - -blockquote.epigraph { - margin: 2em 5em ; } - -body { - margin: 0px ; - margin-bottom: 1em ; - padding: 0px } - -dl.docutils dd { - margin-bottom: 0.5em } - -div.section { - margin-left: 1em ; - margin-right: 1em ; - margin-bottom: 1.5em } - -div.section div.section { - margin-left: 0em ; - margin-right: 0em ; - margin-top: 1.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - clear: both; - font-size: smaller } - -div.footer { - margin-left: 1em ; - margin-right: 1em } - -div.line-block { - display: block ; - margin-top: 1em ; - margin-bottom: 1em } - -div.line-block div.line-block { - margin-top: 0 ; - margin-bottom: 0 ; - margin-left: 1.5em } - -div.sidebar { - margin-left: 1em ; - border: medium outset ; - padding: 1em ; - background-color: #ffffee ; - width: 40% ; - float: right ; - clear: right } - -div.sidebar p.rubric { - font-family: sans-serif ; - font-size: medium } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em } - -h1 { - font-family: sans-serif ; - font-size: large } - -h2 { - font-family: sans-serif ; - font-size: medium } - -h3 { - font-family: sans-serif ; - font-size: small } - -h4 { - font-family: sans-serif ; - font-style: italic ; - font-size: small } - -h5 { - font-family: sans-serif; - font-size: x-small } - -h6 { - font-family: sans-serif; - font-style: italic ; - font-size: x-small } - -hr.docutils { - width: 75% } - -img.align-left { - clear: left } - -img.align-right { - clear: right } - -img.borderless { - border: 0 } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.attribution { - text-align: right ; - margin-left: 50% } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.label { - white-space: nowrap } - -p.rubric { - font-weight: bold ; - font-size: larger ; - color: maroon ; - text-align: center } - -p.sidebar-title { - font-family: sans-serif ; - font-weight: bold ; - font-size: larger } - -p.sidebar-subtitle { - font-family: sans-serif ; - font-weight: bold } - -p.topic-title { - font-family: sans-serif ; - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option { - white-space: nowrap } - -span.option-argument { - font-style: italic } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -span.section-subtitle { - /* font-size relative to parent (h1..h6 element) */ - font-size: 80% } - -table.citation { - border-left: solid thin gray } - -table.docinfo { - margin: 2em 4em } - -table.docutils { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.footnote { - border-left: solid thin black } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -td.num { - text-align: right } - -th.field-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap ; - padding-left: 0 } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100% } - -tt.docutils { - background-color: #eeeeee } - -ul.auto-toc { - list-style-type: none } diff --git a/tools/stylesheets/style.tex b/tools/stylesheets/style.tex deleted file mode 100644 index 6e041a14b..000000000 --- a/tools/stylesheets/style.tex +++ /dev/null @@ -1,74 +0,0 @@ -% latex include file for docutils latex writer -% -------------------------------------------- -% -% CVS: $Id$ -% -% This is included at the end of the latex header in the generated file, -% to allow overwriting defaults, although this could get hairy. -% Generated files should process well standalone too, LaTeX might give a -% message about a missing file. - -% donot indent first line of paragraph. -\setlength{\parindent}{0pt} -\setlength{\parskip}{5pt plus 2pt minus 1pt} - -% sloppy -% ------ -% Less strict (opposite to default fussy) space size between words. Therefore -% less hyphenation. -\sloppy - -% fonts -% ----- -% times for pdf generation, gives smaller pdf files. -% -% But in standard postscript fonts: courier and times/helvetica do not fit. -% Maybe use pslatex. -\usepackage{times} - -% pagestyle -% --------- -% headings might put section titles in the page heading, but not if -% the table of contents is done by docutils. -% If pagestyle{headings} is used, \geometry{headheight=10pt,headsep=1pt} -% should be set too. -%\pagestyle{plain} -% -% or use fancyhdr (untested !) -%\usepackage{fancyhdr} -%\pagestyle{fancy} -%\addtolength{\headheight}{\\baselineskip} -%\renewcommand{\sectionmark}[1]{\markboth{#1}{}} -%\renewcommand{\subsectionmark}[1]{\markright{#1}} -%\fancyhf{} -%\fancyhead[LE,RO]{\\bfseries\\textsf{\Large\\thepage}} -%\fancyhead[LO]{\\textsf{\\footnotesize\\rightmark}} -%\fancyhead[RE]{\\textsc{\\textsf{\\footnotesize\leftmark}}} -%\\fancyfoot[LE,RO]{\\bfseries\\textsf{\scriptsize Docutils}} -%\fancyfoot[RE,LO]{\\textsf{\scriptsize\\today}} - -% geometry -% -------- -% = papersizes and margins -%\geometry{a4paper,twoside,tmargin=1.5cm, -% headheight=1cm,headsep=0.75cm} - -% Do section number display -% ------------------------- -%\makeatletter -%\def\@seccntformat#1{} -%\makeatother -% no numbers in toc -%\renewcommand{\numberline}[1]{} - - -% change maketitle -% ---------------- -%\renewcommand{\maketitle}{ -% \begin{titlepage} -% \begin{center} -% \textsf{TITLE \@title} \\ -% Date: \today -% \end{center} -% \end{titlepage} -%} -- cgit v1.2.1 From bc4e4dd67fb0eab710abe1b8db863e206bf07b49 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 26 Sep 2005 00:42:41 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3902 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++++ docs/dev/todo.txt | 17 ----------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index df87608d1..6f93d99f3 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -128,6 +128,11 @@ Changes Since 0.3.9 * docutils/writers/support/: Directory added to project. Modules and data files that support writers have been moved here. + The stylesheets are now installed along with the code, the code now + knows where to find them, and the default is now to use (actually, + to embed) the built-in stylesheets. Some adjustments to + configuration files may be necessary. + * docutils/writers/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e4d8186d4..c54eb4a9f 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -72,23 +72,6 @@ for inclusion in the Python standard library. General ======= -* Move the following _`support files` to docutils/writers/support: - - - tools/stylesheets/pep.css (renamed to pep_html/pep.css) - - tools/stylesheets/default.css (renamed to html4css1.css) - - tools/stylesheets/style.tex (renamed to latex2e.tex) & latex.tex - (renamed or newlatex2e/base.tex). - - tools/pep-html-template (renamed pep_html/template.txt) - - Rename docutils/writers/support/unicode_latex.py to - newlatex2e/unicode_map.py. - - Add to docs: - - Keep the basenames (e.g. "pep_html") of support files consistent - with the writer names. If there are multiple support files, - create a subdirectory whose name matches the writer. - * Move some general-interest sandboxes out of individuals' directories, into subprojects? -- cgit v1.2.1 From bc9ce2a9a1a519ee4d16c898fead56d6ae891ae1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Sep 2005 17:17:33 +0000 Subject: updated expected output of functional test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3903 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/pep_html.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index 92b6772ab..277b2e6ca 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -10,7 +10,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! PEP 100 -- Test PEP - + Date: Mon, 26 Sep 2005 17:54:39 +0000 Subject: moved pruning docutils.conf up the tree so that template.txt isn't processed by buildhtml.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3904 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/docutils.conf | 5 +++++ docutils/parsers/rst/include/docutils.conf | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 docutils/docutils.conf delete mode 100644 docutils/parsers/rst/include/docutils.conf diff --git a/docutils/docutils.conf b/docutils/docutils.conf new file mode 100644 index 000000000..cdce8d629 --- /dev/null +++ b/docutils/docutils.conf @@ -0,0 +1,5 @@ +# This configuration file is to prevent tools/buildhtml.py from +# processing text files in and below this directory. + +[buildhtml application] +prune: . diff --git a/docutils/parsers/rst/include/docutils.conf b/docutils/parsers/rst/include/docutils.conf deleted file mode 100644 index cdce8d629..000000000 --- a/docutils/parsers/rst/include/docutils.conf +++ /dev/null @@ -1,5 +0,0 @@ -# This configuration file is to prevent tools/buildhtml.py from -# processing text files in and below this directory. - -[buildhtml application] -prune: . -- cgit v1.2.1 From c67b0abf918397b79b68cae23a1d3a9d3e7c9339 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Sep 2005 17:59:51 +0000 Subject: added stylesheet-path entry to docutils.conf because otherwise we get absolute stylesheet links like this on the Docutils website: /home/groups/docutils/htdocs/aux/lib/python/docutils/docutils/writers/support/html4css1.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3905 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/docutils.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/docutils.conf b/tools/docutils.conf index f696f0013..dbe42e14a 100644 --- a/tools/docutils.conf +++ b/tools/docutils.conf @@ -3,8 +3,9 @@ source-link: yes datestamp: %Y-%m-%d %H:%M UTC generator: on -embed-stylesheet: no [html4css1 writer] # These entries affect HTML output: +stylesheet-path: ../docutils/writers/support/html4css1.css +embed-stylesheet: no field-name-limit: 20 -- cgit v1.2.1 From 1ca50e661a08dfb908bc09284e9e984b9c888cd2 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 26 Sep 2005 18:02:55 +0000 Subject: further elaboration on the new default stylesheet behavior; applicable to the release notes git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3906 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 6f93d99f3..db17a90a7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -131,7 +131,9 @@ Changes Since 0.3.9 The stylesheets are now installed along with the code, the code now knows where to find them, and the default is now to use (actually, to embed) the built-in stylesheets. Some adjustments to - configuration files may be necessary. + 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/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. -- cgit v1.2.1 From cee7d04e88cef9ee98b610bb4b18e373564e0363 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 26 Sep 2005 18:03:22 +0000 Subject: added section for release 0.4 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3907 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c54eb4a9f..46cbf4715 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -35,6 +35,26 @@ Please see also the Bugs_ document for a list of bugs in Docutils. .. _bugs: ../../BUGS.html +Release 0.4 +=========== + +We should get Docutils 0.4 out soon. But we shouldn't just cut a +"frozen snapshot" release. Here's a list of features (achievable in +the short term) to include: + +* [DONE in rev. 3901] Move support files to docutils/writers/support. + +* [DONE in rev. 3901] Remove docutils.transforms.html.StylesheetCheck + (no longer needed because of the above change). + +* Incorporate new branch policy into the docs. [DavidG] + ("Development strategy" thread on Docutils-develop) + +* Fix East-Asian `double-width characters`_ issue. [DavidG] + +Anything else? + + Minimum Requirements for Python Standard Library Candidacy ========================================================== -- cgit v1.2.1 From cbbb97aaefad06330b1fda89300eb23f4a9cfd5d Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Sep 2005 18:10:06 +0000 Subject: replaced %r with "%s" to avoid backslashes being doubled on Windows systems git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3908 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 2 +- docutils/writers/pep_html.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index bb3c1789e..4394dded9 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -51,7 +51,7 @@ class Writer(writers.Writer): {'metavar': '', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' 'directory. The path is adjusted relative to the output HTML ' - 'file. Overrides --stylesheet. Default: %r' + 'file. Overrides --stylesheet. Default: "%s"' % default_stylesheet_path, ['--stylesheet-path'], {'metavar': '', 'overrides': 'stylesheet', diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py index 16b305087..1fdc36f30 100644 --- a/docutils/writers/pep_html.py +++ b/docutils/writers/pep_html.py @@ -36,9 +36,9 @@ class Writer(html4css1.Writer): settings_spec = html4css1.Writer.settings_spec + ( 'PEP/HTML-Specific Options', 'The default value for the --stylesheet-path option (defined in ' - 'HTML-Specific Options above) is %r for the PEP/HTML writer.' + 'HTML-Specific Options above) is "%s" for the PEP/HTML writer.' % default_stylesheet_path, - (('Specify a template file. Default is %r.' % default_template_path, + (('Specify a template file. Default is "%s".' % default_template_path, ['--template'], {'default': default_template_path, 'metavar': ''}), ('Python\'s home URL. Default is "http://www.python.org".', -- cgit v1.2.1 From 69fadff9ca4f067b3042b6383989ce638ff4d42d Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 26 Sep 2005 18:17:31 +0000 Subject: renamed Element.substitute to Element.replace_self git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3909 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 4 ++-- docutils/transforms/components.py | 2 +- docutils/transforms/misc.py | 2 +- docutils/transforms/parts.py | 2 +- docutils/transforms/peps.py | 6 +++--- docutils/transforms/references.py | 16 ++++++++-------- docutils/transforms/writer_aux.py | 2 +- test/test_nodes.py | 10 +++++----- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index 0a574d77b..578529556 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -568,9 +568,9 @@ class Element(Node): elif new is not None: self[index:index+1] = new - def substitute(self, new): + def replace_self(self, new): """ - Substitute `new` for `self` node, where `new` is a node or + Replace `self` node with `new`, where `new` is a node or a list of nodes. """ update = new diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py index a31f09fb5..1c3ecbef6 100644 --- a/docutils/transforms/components.py +++ b/docutils/transforms/components.py @@ -49,6 +49,6 @@ class Filter(Transform): format = pending.details['format'] component = self.document.transformer.components[component_type] if component.supports(format): - pending.substitute(pending.details['nodes']) + pending.replace_self(pending.details['nodes']) else: pending.parent.remove(pending) diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py index 18446944d..9567055f9 100644 --- a/docutils/transforms/misc.py +++ b/docutils/transforms/misc.py @@ -66,7 +66,7 @@ class ClassAttribute(Transform): % pending.details['directive'], nodes.literal_block(pending.rawsource, pending.rawsource), line=pending.line) - pending.substitute(error) + pending.replace_self(error) class Transitions(Transform): diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py index b28c44c71..1e275c78a 100644 --- a/docutils/transforms/parts.py +++ b/docutils/transforms/parts.py @@ -97,7 +97,7 @@ class Contents(Transform): self.backlinks = self.document.settings.toc_backlinks contents = self.build_contents(startnode) if len(contents): - self.startnode.substitute(contents) + self.startnode.replace_self(contents) else: self.startnode.parent.parent.remove(self.startnode.parent) diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py index 96c265207..edaba2557 100644 --- a/docutils/transforms/peps.py +++ b/docutils/transforms/peps.py @@ -107,11 +107,11 @@ class Headers(Transform): if name == 'author': for node in para: if isinstance(node, nodes.reference): - node.substitute(mask_email(node)) + node.replace_self(mask_email(node)) elif name == 'discussions-to': for node in para: if isinstance(node, nodes.reference): - node.substitute(mask_email(node, pep)) + node.replace_self(mask_email(node, pep)) elif name in ('replaces', 'replaced-by', 'requires'): newbody = [] space = nodes.Text(' ') @@ -241,7 +241,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor): pass def visit_reference(self, node): - node.substitute(mask_email(node)) + node.replace_self(mask_email(node)) def visit_field_list(self, node): if 'rfc2822' in node['classes']: diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 35dabddd3..2cc83be87 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -127,7 +127,7 @@ class AnonymousHyperlinks(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.substitute(prb) + ref.replace_self(prb) return for ref, target in zip(self.document.anonymous_refs, self.document.anonymous_targets): @@ -281,7 +281,7 @@ class IndirectHyperlinks(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.substitute(prb) + ref.replace_self(prb) target.resolved = 1 def resolve_indirect_references(self, target): @@ -540,7 +540,7 @@ class Footnotes(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.substitute(prb) + ref.replace_self(prb) break ref += nodes.Text(label) id = self.document.nameids[label] @@ -580,7 +580,7 @@ class Footnotes(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.substitute(prb) + ref.replace_self(prb) break footnote = self.document.symbol_footnotes[i] assert len(footnote['ids']) == 1 @@ -674,7 +674,7 @@ class Substitutions(Transform): ref.rawsource, ref.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - ref.substitute(prb) + ref.replace_self(prb) else: subdef = defs[key] parent = ref.parent @@ -691,7 +691,7 @@ class Substitutions(Transform): and isinstance(parent[index + 1], nodes.Text)): parent.replace(parent[index + 1], parent[index + 1].lstrip()) - ref.substitute(subdef.children) + ref.replace_self(subdef.children) self.document.substitution_refs = None # release replaced references @@ -732,7 +732,7 @@ class TargetNotes(Transform): if not notes.has_key(target['refuri']): notes[target['refuri']] = footnote nodelist.append(footnote) - self.startnode.substitute(nodelist) + self.startnode.replace_self(nodelist) def make_target_footnote(self, target, refs, notes): refuri = target['refuri'] @@ -838,7 +838,7 @@ class DanglingReferencesVisitor(nodes.SparseNodeVisitor): node.rawsource, node.rawsource, refid=msgid) prbid = self.document.set_id(prb) msg.add_backref(prbid) - node.substitute(prb) + node.replace_self(prb) else: del node['refname'] node['refid'] = id diff --git a/docutils/transforms/writer_aux.py b/docutils/transforms/writer_aux.py index 99e961243..74ac4d4f6 100644 --- a/docutils/transforms/writer_aux.py +++ b/docutils/transforms/writer_aux.py @@ -49,4 +49,4 @@ class Compound(Transform): else: child['classes'].append('continued') # Substitute children for compound. - compound.substitute(compound[:]) + compound.replace_self(compound[:]) diff --git a/test/test_nodes.py b/test/test_nodes.py index 520abd17a..42a64ad49 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -114,7 +114,7 @@ class ElementTests(unittest.TestCase): # 'test' is not overwritten because it is not a basic attribute. self.assertEquals(element1['test'], ['test1']) - def test_substitute(self): + def test_replace_self(self): parent = nodes.Element(ids=['parent']) child1 = nodes.Element(ids=['child1']) grandchild = nodes.Element(ids=['grandchild']) @@ -136,23 +136,23 @@ class ElementTests(unittest.TestCase): """) # Replace child1 with the grandchild. - child1.substitute(child1[0]) + child1.replace_self(child1[0]) self.assertEquals(parent[0], grandchild) # Assert that 'ids' have been updated. self.assertEquals(grandchild['ids'], ['grandchild', 'child1']) # Replace child2 with its children. - child2.substitute(child2[:]) + child2.replace_self(child2[:]) self.assertEquals(parent[1:3], twins) # Assert that 'ids' have been propagated to first child. self.assertEquals(twins[0]['ids'], ['twin1', 'child2']) self.assertEquals(twins[1]['ids'], ['twin2']) # Replace child3 with new child. newchild = nodes.Element(ids=['newchild']) - child3.substitute(newchild) + child3.replace_self(newchild) self.assertEquals(parent[3], newchild) self.assertEquals(newchild['ids'], ['newchild', 'child3']) # Crazy but possible case: Substitute child4 for itself. - child4.substitute(child4) + child4.replace_self(child4) # Make sure the 'child4' ID hasn't been duplicated. self.assertEquals(child4['ids'], ['child4']) self.assertEquals(len(parent), 5) -- cgit v1.2.1 From 56141f49a0dff5ef21cd29e00479f41c4efd88db Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 28 Sep 2005 13:31:55 +0000 Subject: clarification git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3910 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 2908d4959..f67ea4532 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1551,9 +1551,9 @@ base roles: specified, a "class" option with the directive argument (role name) as the value is implied. See the class_ directive above. -Specific roles may support other options and/or directive content. -See the `reStructuredText Interpreted Text Roles`_ document for -details. +Specific base roles may support other options and/or directive +content. See the `reStructuredText Interpreted Text Roles`_ document +for details. .. _reStructuredText Interpreted Text Roles: roles.html -- cgit v1.2.1 From 4c16652c99cfc1ba8ec7dd2697d606972a98e952 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 29 Sep 2005 13:10:07 +0000 Subject: Added support for "class" directive content. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3912 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/ref/rst/directives.txt | 26 +++++++++++++++++++------- docutils/parsers/rst/directives/misc.py | 24 +++++++++++++++++------- test/test_transforms/test_class.py | 24 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index db17a90a7..3abf18ff2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -50,6 +50,7 @@ Changes Since 0.3.9 - Added the "default-role" and "title" directives. - Added standard data file syntax to the "include" directive. + - Added support for "class" directive content. * docutils/parsers/rst/directives/images.py: diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index f67ea4532..88bcbf570 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1391,14 +1391,16 @@ Class :Directive Arguments: One or more, required (class names / attribute values). :Directive Options: None. -:Directive Content: None. +:Directive Content: Optional. If present, it is interpreted as body + elements. -The "class" directive sets a "class" attribute value on the first -immediately following non-comment element [#]_. For details of the -"class" attribute, see `its entry`__ in `The Docutils Document Tree`_. -The directive argument consists of one or more space-separated class -names, which are converted to lowercase and all non-alphanumeric -characters are converted to hyphens. (For the rationale, see below.) +The "class" directive sets the "class" attribute value on its content +or on the first immediately following non-comment element [#]_. For +details of the "class" attribute, see `its entry`__ in `The Docutils +Document Tree`_. The directive argument consists of one or more +space-separated class names, which are converted to lowercase and all +non-alphanumeric characters are converted to hyphens. (For the +rationale, see below.) __ ../doctree.html#class @@ -1415,6 +1417,12 @@ Examples:: This is an ordinary paragraph. + .. class:: multiple + + First paragraph. + + Second paragraph. + The text above is parsed and transformed into this doctree fragment:: @@ -1424,6 +1432,10 @@ The text above is parsed and transformed into this doctree fragment:: An Exceptional Section This is an ordinary paragraph. + + First paragraph. + + Second paragraph. .. [#] To set a "class" attribute value on a block quote, the "class" directive must be followed by an empty comment:: diff --git a/docutils/parsers/rst/directives/misc.py b/docutils/parsers/rst/directives/misc.py index 71c097b33..0eec557b5 100644 --- a/docutils/parsers/rst/directives/misc.py +++ b/docutils/parsers/rst/directives/misc.py @@ -256,8 +256,9 @@ unicode_comment_pattern = re.compile(r'( |\n|^)\.\. ') def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ - Set a "class" attribute on the next element. - A "pending" element is inserted, and a transform does the work later. + Set a "class" attribute on the directive content or the next element. + When applied to the next element, a "pending" element is inserted, and a + transform does the work later. """ try: class_value = directives.class_option(arguments[0]) @@ -267,11 +268,20 @@ def class_directive(name, arguments, options, content, lineno, % (name, arguments[0]), nodes.literal_block(block_text, block_text), line=lineno) return [error] - pending = nodes.pending(misc.ClassAttribute, - {'class': class_value, 'directive': name}, - block_text) - state_machine.document.note_pending(pending) - return [pending] + node_list = [] + if content: + container = nodes.Element() + state.nested_parse(content, content_offset, container) + for node in container: + node['classes'].extend(class_value) + node_list.extend(container.children) + else: + pending = nodes.pending(misc.ClassAttribute, + {'class': class_value, 'directive': name}, + block_text) + state_machine.document.note_pending(pending) + node_list.append(pending) + return node_list class_directive.arguments = (1, 0, 1) class_directive.content = 1 diff --git a/test/test_transforms/test_class.py b/test/test_transforms/test_class.py index 6fc2b33a5..601272135 100755 --- a/test/test_transforms/test_class.py +++ b/test/test_transforms/test_class.py @@ -78,6 +78,30 @@ Paragraph Paragraph """], ["""\ +.. class:: multiple + + paragraph 1 + + paragraph 2 +""", +"""\ + + + paragraph 1 + + paragraph 2 +"""], +["""\ +.. class:: multiple + + .. Just a comment. It's silly, but possible +""", +"""\ + + + Just a comment. It's silly, but possible +"""], +["""\ .. class:: .. class:: 99 -- cgit v1.2.1 From 239b6dc3e601ada17264833b47c2cd9bbe9a647d Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 30 Sep 2005 13:04:50 +0000 Subject: updated for new stylesheet location; thanks to Michael Foord for pointing this out git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3913 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/howto/html-stylesheets.txt | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/howto/html-stylesheets.txt b/docs/howto/html-stylesheets.txt index 1ae265e5e..1f61bab5d 100644 --- a/docs/howto/html-stylesheets.txt +++ b/docs/howto/html-stylesheets.txt @@ -12,13 +12,16 @@ The look of Docutils' HTML output is customizable via a CSS -stylesheet. The default stylesheet is called ``default.css`` and can -be found in the ``tools/stylesheets/`` directory of the Docutils -distribution tarball. +stylesheet. The default stylesheet is called ``html4css1.css`` and +can be found in the ``writers/support/`` directory of the Docutils +installation. Use the command ``rst2html.py --help`` and look at the +description of the ``--stylesheet-path`` command-line option for the +exact machine-specific location. -To customize the stylesheet, place a new file (e.g. called -``my-docutils.css``) in the same directory as ``default.css`` and use -the following template:: +To customize the stylesheet, first copy ``html4css1.css`` to the same +place as your output HTML files will go. Next, place a new file +(e.g. called ``my-docutils.css``) in the same directory and use the +following template:: /* :Author: Your Name @@ -29,7 +32,7 @@ the following template:: detailed description here.] */ - @import url(default.css); + @import url(html4css1.css); /* Your customizations go here. For example: */ @@ -42,26 +45,26 @@ Style Sheets`__ and, in particular, their `list of CSS1 properties`__. __ http://www.htmlhelp.com/reference/css/ __ http://www.htmlhelp.com/reference/css/all-properties.html -It is important that you do not edit a copy of ``default.css`` -directly because ``default.css`` is frequently updated with each new +It is important that you do not edit a copy of ``html4css1.css`` +directly because ``html4css1.css`` is frequently updated with each new release of Docutils. -Also make sure that you import ``default.css`` (using "``@import -url(default.css);``") because the definitions contained in the default -stylesheet are required for correct rendering (margins, alignment, -etc.). +Also make sure that you import ``html4css1.css`` (using "``@import +url(html4css1.css);``") because the definitions contained in the +default stylesheet are required for correct rendering (margins, +alignment, etc.). If you think your stylesheet is fancy and you would like to let others benefit from your efforts, you are encouraged to post the stylesheet -to the Docutils-users_ mailing list. We can upload it to the Docutils -repository if you would like us to do so. +to the Docutils-users_ mailing list. We can upload it to the +`Docutils repository`__ if you would like us to do so. If you decide to share you stylesheet with other users of Docutils, please keep website-specific customizations not applicable to Docutils' HTML code in a separate stylesheet. .. _Docutils-users: ../user/mailing-lists.html#docutils-users - +__ http://docutils.sourceforge.net/sandbox/stylesheets/ .. -- cgit v1.2.1 From 9e9921fe49c022074aeaa20aff58cfc51828b2c3 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 30 Sep 2005 13:05:06 +0000 Subject: added entry for generic container element git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3914 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 46cbf4715..390273dd2 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -92,6 +92,10 @@ for inclusion in the Python standard library. General ======= +* Add a generic "container" element, equivalent to "inline", to which + a "class" attribute can be attached. Will require a reST directive + also. + * Move some general-interest sandboxes out of individuals' directories, into subprojects? -- cgit v1.2.1 From fa67b65d49e091aec810d2e5e8db5b19fc5be2d5 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 2 Oct 2005 01:06:42 +0000 Subject: 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``. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3915 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 7 +++ docutils/nodes.py | 8 ++- .../expected/standalone_rst_pseudoxml.txt | 72 +++++++++++----------- .../test_rst/test_directives/test_contents.py | 10 +-- .../test_rst/test_directives/test_include.py | 20 +++--- .../test_rst/test_directives/test_unicode.py | 6 +- test/test_parsers/test_rst/test_inline_markup.py | 8 +-- test/test_parsers/test_rst/test_section_headers.py | 46 +++++++------- test/test_parsers/test_rst/test_substitutions.py | 12 ++-- test/test_parsers/test_rst/test_targets.py | 18 +++--- test/test_parsers/test_rst/test_transitions.py | 18 +++--- test/test_publisher.py | 4 +- test/test_transforms/test_class.py | 2 +- test/test_transforms/test_contents.py | 44 ++++++------- test/test_transforms/test_doctitle.py | 16 ++--- test/test_transforms/test_hyperlinks.py | 28 ++++----- test/test_transforms/test_peps.py | 2 +- test/test_transforms/test_sectnum.py | 50 +++++++-------- test/test_transforms/test_substitutions.py | 2 +- test/test_transforms/test_transitions.py | 16 ++--- test/test_writers/test_pseudoxml.py | 2 +- 21 files changed, 201 insertions(+), 190 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 3abf18ff2..fbfa0ef8e 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -34,6 +34,13 @@ Changes Since 0.3.9 - Added ``DocTreeInput`` class, for reprocessing existing documents. - Added support for non-Unicode (e.g. binary) writer output. +* docutils/nodes.py: + + - 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``. + * docutils/parsers/null.py: Added to project; a do-nothing parser. * docutils/parsers/rst/__init__.py: diff --git a/docutils/nodes.py b/docutils/nodes.py index 578529556..9b68f2aec 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -370,7 +370,7 @@ class Element(Node): element = domroot.createElement(self.tagname) for attribute, value in self.attlist(): if isinstance(value, ListType): - value = ' '.join(['%s' % v for v in value]) + value = ' '.join([serial_escape('%s' % v) for v in value]) element.setAttribute(attribute, '%s' % value) for child in self.children: element.appendChild(child._dom_node(domroot)) @@ -413,7 +413,7 @@ class Element(Node): if value is None: # boolean attribute parts.append(name) elif isinstance(value, ListType): - values = ['%s' % v for v in value] + values = [serial_escape('%s' % v) for v in value] parts.append('%s="%s"' % (name, ' '.join(values))) else: parts.append('%s="%s"' % (name, value)) @@ -1732,3 +1732,7 @@ def fully_normalize_name(name): def whitespace_normalize_name(name): """Return a whitespace-normalized name.""" return ' '.join(name.split()) + +def serial_escape(value): + """Escape string values that are elements of a list, for serialization.""" + return value.replace('\\', r'\\').replace(' ', r'\ ') diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index dc7940ee1..179760c86 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1,7 +1,7 @@ - + reStructuredText Test Document - <subtitle ids="examples-of-syntax-constructs subtitle" names="examples of syntax constructs subtitle"> + <subtitle ids="examples-of-syntax-constructs subtitle" names="examples\ of\ syntax\ constructs subtitle"> Examples of Syntax Constructs <decoration> <header> @@ -85,7 +85,7 @@ bibliographic fields (which also require a transform): <meta content="reStructuredText, test, parser" name="keywords"> <meta content="A test document, containing at least one example of each reStructuredText construct." lang="en" name="description"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <bullet_list classes="auto-toc"> @@ -316,21 +316,21 @@ <generated classes="sectnum"> 3    Error Handling - <section ids="structural-elements" names="structural elements"> + <section ids="structural-elements" names="structural\ elements"> <title auto="1" refid="id25"> <generated classes="sectnum"> 1    Structural Elements - <section ids="section-title" names="section title"> + <section ids="section-title" names="section\ title"> <title auto="1" refid="id26"> <generated classes="sectnum"> 1.1    Section Title - <subtitle ids="section-subtitle" names="section subtitle"> + <subtitle ids="section-subtitle" names="section\ subtitle"> Section Subtitle <paragraph> That's it, the text just above this line. - <section ids="empty-section" names="empty section"> + <section ids="empty-section" names="empty\ section"> <title auto="1" refid="id27"> <generated classes="sectnum"> 1.2    @@ -346,7 +346,7 @@ <paragraph> It divides the section. Transitions may also occur between sections: <transition> - <section ids="body-elements" names="body elements"> + <section ids="body-elements" names="body\ elements"> <title auto="1" refid="id29"> <generated classes="sectnum"> 2    @@ -358,7 +358,7 @@ Paragraphs <paragraph> A paragraph. - <section ids="inline-markup" names="inline markup"> + <section ids="inline-markup" names="inline\ markup"> <title auto="1" refid="id31"> <generated classes="sectnum"> 2.1.1    @@ -412,7 +412,7 @@ ), substitution references ( <image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"> ), and - <target ids="inline-hyperlink-targets" names="inline hyperlink targets"> + <target ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets"> inline hyperlink targets (see @@ -483,7 +483,7 @@ --pep-references option was supplied, there should be a live link to PEP 258 here. - <section ids="bullet-lists" names="bullet lists"> + <section ids="bullet-lists" names="bullet\ lists"> <title auto="1" refid="id32"> <generated classes="sectnum"> 2.2    @@ -527,7 +527,7 @@ <target ids="target" names="target"> <comment xml:space="preserve"> Even if this item contains a target and a comment. - <section ids="enumerated-lists" names="enumerated lists"> + <section ids="enumerated-lists" names="enumerated\ lists"> <title auto="1" refid="id33"> <generated classes="sectnum"> 2.3    @@ -576,7 +576,7 @@ <list_item> <paragraph> iv - <section ids="definition-lists" names="definition lists"> + <section ids="definition-lists" names="definition\ lists"> <title auto="1" refid="id34"> <generated classes="sectnum"> 2.4    @@ -614,7 +614,7 @@ <definition> <paragraph> Definition - <section ids="field-lists" names="field lists"> + <section ids="field-lists" names="field\ lists"> <title auto="1" refid="id35"> <generated classes="sectnum"> 2.5    @@ -648,7 +648,7 @@ class set. (This is actually not about credits but just for ensuring that the class attribute doesn't get stripped away.) - <section ids="option-lists" names="option lists"> + <section ids="option-lists" names="option\ lists"> <title auto="1" refid="id36"> <generated classes="sectnum"> 2.6    @@ -761,7 +761,7 @@ <paragraph> There must be at least two spaces between the option and the description. - <section ids="literal-blocks" names="literal blocks"> + <section ids="literal-blocks" names="literal\ blocks"> <title auto="1" refid="id37"> <generated classes="sectnum"> 2.7    @@ -783,7 +783,7 @@ >> Great idea! > > Why didn't I think of that? - <section ids="line-blocks" names="line blocks"> + <section ids="line-blocks" names="line\ blocks"> <title auto="1" refid="id38"> <generated classes="sectnum"> 2.8    @@ -861,7 +861,7 @@ <line> <line> Singing... - <section ids="block-quotes" names="block quotes"> + <section ids="block-quotes" names="block\ quotes"> <title auto="1" refid="id39"> <generated classes="sectnum"> 2.9    @@ -877,7 +877,7 @@ own it, and what it is too. <attribution> Anne Elk (Miss) - <section ids="doctest-blocks" names="doctest blocks"> + <section ids="doctest-blocks" names="doctest\ blocks"> <title auto="1" refid="id40"> <generated classes="sectnum"> 2.10    @@ -972,7 +972,7 @@ citation. <target refid="another-target"> - <section ids="targets another-target" names="targets another target"> + <section ids="targets another-target" names="targets another\ target"> <title auto="1" refid="id43"> <generated classes="sectnum"> 2.13    @@ -1022,7 +1022,7 @@ `hyperlink reference without a target`_ , which generates an error. - <section dupnames="duplicate target names" ids="duplicate-target-names"> + <section dupnames="duplicate\ target\ names" ids="duplicate-target-names"> <title auto="1" refid="id44"> <generated classes="sectnum"> 2.13.1    @@ -1031,7 +1031,7 @@ Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages. - <section dupnames="duplicate target names" ids="id18"> + <section dupnames="duplicate\ target\ names" ids="id18"> <title auto="1" refid="id45"> <generated classes="sectnum"> 2.13.2    @@ -1098,7 +1098,7 @@ <reference refuri="http://docutils.sourceforge.net/docs/ref/rst/directives.html"> http://docutils.sourceforge.net/docs/ref/rst/directives.html . - <section ids="document-parts" names="document parts"> + <section ids="document-parts" names="document\ parts"> <title auto="1" refid="id62"> <generated classes="sectnum"> 2.14.1    @@ -1127,7 +1127,7 @@ <target refid="image-target-1"> <target refid="image-target-2"> <target refid="image-target-3"> - <image ids="image-target-3 image-target-2 image-target-1" names="image target 3 image target 2 image target 1" uri="../../../docs/user/rst/images/title.png"> + <image ids="image-target-3 image-target-2 image-target-1" names="image\ target\ 3 image\ target\ 2 image\ target\ 1" uri="../../../docs/user/rst/images/title.png"> <paragraph> A figure directive: <figure align="right" classes="figclass1 figclass2"> @@ -1255,7 +1255,7 @@ <paragraph> You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> - <section ids="topics-sidebars-and-rubrics" names="topics, sidebars, and rubrics"> + <section ids="topics-sidebars-and-rubrics" names="topics,\ sidebars,\ and\ rubrics"> <title auto="1" refid="id65"> <generated classes="sectnum"> 2.14.4    @@ -1280,18 +1280,18 @@ This is a topic. <rubric> This is a rubric - <section ids="target-footnotes" names="target footnotes"> + <section ids="target-footnotes" names="target\ footnotes"> <title auto="1" refid="id66"> <generated classes="sectnum"> 2.14.5    Target Footnotes - <footnote auto="1" backrefs="id22 id23 id24" ids="id21" names="TARGET_NOTE: id21"> + <footnote auto="1" backrefs="id22 id23 id24" ids="id21" names="TARGET_NOTE:\ id21"> <label> 5 <paragraph> <reference refuri="http://www.python.org/"> http://www.python.org/ - <section ids="replacement-text" names="replacement text"> + <section ids="replacement-text" names="replacement\ text"> <title auto="1" refid="id67"> <generated classes="sectnum"> 2.14.6    @@ -1312,7 +1312,7 @@ <emphasis> the best language around - <section ids="compound-paragraph" names="compound paragraph"> + <section ids="compound-paragraph" names="compound\ paragraph"> <title auto="1" refid="id68"> <generated classes="sectnum"> 2.14.7    @@ -1398,7 +1398,7 @@ Compound 7, a paragraph after the table. <paragraph> Compound 7, another paragraph. - <section ids="substitution-definitions" names="substitution definitions"> + <section ids="substitution-definitions" names="substitution\ definitions"> <title auto="1" refid="id54"> <generated classes="sectnum"> 2.15    @@ -1426,7 +1426,7 @@ Double-dashes -- "--" -- must be escaped somehow in HTML output. <paragraph> (View the HTML source to see the comment.) - <section ids="raw-text" names="raw text"> + <section ids="raw-text" names="raw\ text"> <title auto="1" refid="id56"> <generated classes="sectnum"> 2.17    @@ -1450,7 +1450,7 @@ Fifth test in HTML.<br />Line two. <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. - <section ids="colspanning-tables" names="colspanning tables"> + <section ids="colspanning-tables" names="colspanning\ tables"> <title auto="1" refid="id57"> <generated classes="sectnum"> 2.18    @@ -1521,7 +1521,7 @@ <entry> <paragraph> True - <section ids="rowspanning-tables" names="rowspanning tables"> + <section ids="rowspanning-tables" names="rowspanning\ tables"> <title auto="1" refid="id58"> <generated classes="sectnum"> 2.19    @@ -1573,7 +1573,7 @@ <entry> <paragraph> body row 3 - <section ids="complex-tables" names="complex tables"> + <section ids="complex-tables" names="complex\ tables"> <title auto="1" refid="id59"> <generated classes="sectnum"> 2.20    @@ -1658,7 +1658,7 @@ <literal> --> <entry> - <section ids="list-tables" names="list tables"> + <section ids="list-tables" names="list\ tables"> <title auto="1" refid="id60"> <generated classes="sectnum"> 2.21    @@ -1715,7 +1715,7 @@ <entry> <paragraph> On a stick! - <section ids="error-handling" names="error handling"> + <section ids="error-handling" names="error\ handling"> <title auto="1" refid="id61"> <generated classes="sectnum"> 3    diff --git a/test/test_parsers/test_rst/test_directives/test_contents.py b/test/test_parsers/test_rst/test_directives/test_contents.py index 6d6d0f3e2..cb7bbec0f 100755 --- a/test/test_parsers/test_rst/test_directives/test_contents.py +++ b/test/test_parsers/test_rst/test_directives/test_contents.py @@ -38,7 +38,7 @@ totest['contents'] = [ """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <pending> @@ -52,7 +52,7 @@ totest['contents'] = [ """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <pending> @@ -67,7 +67,7 @@ totest['contents'] = [ """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of @@ -82,7 +82,7 @@ totest['contents'] = [ """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> <emphasis> Table @@ -132,7 +132,7 @@ totest['contents'] = [ """, """\ <document source="test data"> - <topic classes="contents local" ids="table-of-contents" names="table of contents"> + <topic classes="contents local" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <pending> diff --git a/test/test_parsers/test_rst/test_directives/test_include.py b/test/test_parsers/test_rst/test_directives/test_include.py index cf6ada106..f6009b96b 100755 --- a/test/test_parsers/test_rst/test_directives/test_include.py +++ b/test/test_parsers/test_rst/test_directives/test_include.py @@ -51,10 +51,10 @@ A paragraph. """ % include1, """\ <document source="test data"> - <section ids="include-test" names="include test"> + <section ids="include-test" names="include\ test"> <title> Include Test - <section ids="inclusion-1" names="inclusion 1"> + <section ids="inclusion-1" names="inclusion\ 1"> <title> Inclusion 1 <paragraph> @@ -76,7 +76,7 @@ A paragraph. """ % include1, """\ <document source="test data"> - <section ids="include-test" names="include test"> + <section ids="include-test" names="include\ test"> <title> Include Test <literal_block source="%s" xml:space="preserve"> @@ -124,7 +124,7 @@ A paragraph. """, """\ <document source="test data"> - <section ids="include-test" names="include test"> + <section ids="include-test" names="include\ test"> <title> Include Test <system_message level="4" line="4" source="test data" type="SEVERE"> @@ -148,10 +148,10 @@ A paragraph. """ % (include1, include1), """\ <document source="test data"> - <section ids="include-test" names="include test"> + <section ids="include-test" names="include\ test"> <title> Include Test - <section dupnames="inclusion 1" ids="inclusion-1"> + <section dupnames="inclusion\ 1" ids="inclusion-1"> <title> Inclusion 1 <paragraph> @@ -159,7 +159,7 @@ A paragraph. <literal> test_include.py . - <section dupnames="inclusion 1" ids="id1"> + <section dupnames="inclusion\ 1" ids="id1"> <title> Inclusion 1 <system_message backrefs="id1" level="1" line="2" source="%s" type="INFO"> @@ -187,10 +187,10 @@ A paragraph. """ % (include1, include1), """\ <document source="test data"> - <section ids="include-test" names="include test"> + <section ids="include-test" names="include\ test"> <title> Include Test - <section dupnames="inclusion 1" ids="inclusion-1"> + <section dupnames="inclusion\ 1" ids="inclusion-1"> <title> Inclusion 1 <paragraph> @@ -199,7 +199,7 @@ A paragraph. test_include.py . <transition> - <section dupnames="inclusion 1" ids="id1"> + <section dupnames="inclusion\ 1" ids="id1"> <title> Inclusion 1 <system_message backrefs="id1" level="1" line="2" source="%s" type="INFO"> diff --git a/test/test_parsers/test_rst/test_directives/test_unicode.py b/test/test_parsers/test_rst/test_directives/test_unicode.py index 526182a62..bd028cf42 100755 --- a/test/test_parsers/test_rst/test_directives/test_unicode.py +++ b/test/test_parsers/test_rst/test_directives/test_unicode.py @@ -92,9 +92,9 @@ Bad input: Substitution definition "empty too" empty or invalid. <literal_block xml:space="preserve"> .. |empty too| unicode:: .. comment doesn't count as content - <substitution_definition names="not hex"> + <substitution_definition names="not\ hex"> 0xHEX - <substitution_definition names="not all hex"> + <substitution_definition names="not\ all\ hex"> UABCX <system_message level="3" line="8" source="test data" type="ERROR"> <paragraph> @@ -125,7 +125,7 @@ u"""\ . <substitution_definition names="copy"> \u00A9 - <substitution_definition names="BogusMegaCorp (TM)"> + <substitution_definition names="BogusMegaCorp\ (TM)"> BogusMegaCorp \u2122 """], diff --git a/test/test_parsers/test_rst/test_inline_markup.py b/test/test_parsers/test_rst/test_inline_markup.py index 598902370..7185d723d 100755 --- a/test/test_parsers/test_rst/test_inline_markup.py +++ b/test/test_parsers/test_rst/test_inline_markup.py @@ -432,7 +432,7 @@ totest['embedded_URIs'] = [ <paragraph> <reference name="phrase reference" refuri="http://example.com"> phrase reference - <target ids="phrase-reference" names="phrase reference" refuri="http://example.com"> + <target ids="phrase-reference" names="phrase\ reference" refuri="http://example.com"> """], ["""\ `anonymous reference <http://example.com>`__ @@ -560,15 +560,15 @@ _`Here is a TaRgeT` with case and spacial difficulties. target <paragraph> Here is \n\ - <target ids="another-target" names="another target"> + <target ids="another-target" names="another\ target"> another target in some text. And \n\ - <target ids="yet-another-target" names="yet another target"> + <target ids="yet-another-target" names="yet\ another\ target"> yet another target , spanning lines. <paragraph> - <target ids="here-is-a-target" names="here is a target"> + <target ids="here-is-a-target" names="here\ is\ a\ target"> Here is a TaRgeT with case and spacial difficulties. """], diff --git a/test/test_parsers/test_rst/test_section_headers.py b/test/test_parsers/test_rst/test_section_headers.py index e1557fcb9..3c5a21170 100755 --- a/test/test_parsers/test_rst/test_section_headers.py +++ b/test/test_parsers/test_rst/test_section_headers.py @@ -205,7 +205,7 @@ Test long title and space normalization. """, """\ <document source="test data"> - <section ids="long-title" names="long title"> + <section ids="long-title" names="long\ title"> <title> Long Title <system_message level="2" line="1" source="test data" type="WARNING"> @@ -306,22 +306,22 @@ Paragraph 4. <document source="test data"> <comment xml:space="preserve"> Test return to existing, highest-level section (Title 3). - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title> Title 4 <paragraph> @@ -354,22 +354,22 @@ Paragraph 4. <document source="test data"> <paragraph> Test return to existing, highest-level section (Title 3, with overlines). - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title> Title 4 <paragraph> @@ -398,22 +398,22 @@ Paragraph 4. <document source="test data"> <paragraph> Test return to existing, higher-level section (Title 4). - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title> Title 4 <paragraph> @@ -442,17 +442,17 @@ Paragraph 4. <document source="test data"> <paragraph> Test bad subsection order (Title 4). - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> @@ -493,17 +493,17 @@ Paragraph 4. <document source="test data"> <paragraph> Test bad subsection order (Title 4, with overlines). - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> @@ -526,7 +526,7 @@ Paragraph. """, """\ <document source="test data"> - <section ids="title-containing-inline-markup" names="title containing inline markup"> + <section ids="title-containing-inline-markup" names="title\ containing\ inline\ markup"> <title> Title containing \n\ <emphasis> @@ -545,7 +545,7 @@ Paragraph. """, """\ <document source="test data"> - <section ids="numbered-title" names="1. numbered title"> + <section ids="numbered-title" names="1.\ numbered\ title"> <title> 1. Numbered Title <paragraph> @@ -571,7 +571,7 @@ Paragraph. <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> Enumerated list ends without a blank line; unexpected unindent. - <section ids="numbered-title" names="3. numbered title"> + <section ids="numbered-title" names="3.\ numbered\ title"> <title> 3. Numbered Title <paragraph> @@ -850,7 +850,7 @@ Empty Section """, """\ <document source="test data"> - <section ids="empty-section" names="empty section"> + <section ids="empty-section" names="empty\ section"> <title> Empty Section """], diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index d2a5207c9..f949ce187 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -71,11 +71,11 @@ Here's a series of substitution definitions: <document source="test data"> <paragraph> Here's a series of substitution definitions: - <substitution_definition names="symbol 1"> + <substitution_definition names="symbol\ 1"> <image alt="symbol 1" uri="symbol1.png"> - <substitution_definition names="SYMBOL 2"> + <substitution_definition names="SYMBOL\ 2"> <image alt="SYMBOL 2" height="50" uri="symbol2.png" width="100"> - <substitution_definition names="symbol 3"> + <substitution_definition names="symbol\ 3"> <image alt="symbol 3" uri="symbol3.png"> """], ["""\ @@ -84,7 +84,7 @@ Here's a series of substitution definitions: """, """\ <document source="test data"> - <substitution_definition names="very long substitution text, split across lines"> + <substitution_definition names="very\ long\ substitution\ text,\ split\ across\ lines"> <image alt="very long substitution text, split across lines" uri="symbol.png"> """], ["""\ @@ -123,11 +123,11 @@ Followed by a paragraph. """, """\ <document source="test data"> - <substitution_definition names="symbol 1"> + <substitution_definition names="symbol\ 1"> <image alt="symbol 1" uri="symbol.png"> <paragraph> Followed by a paragraph. - <substitution_definition names="symbol 2"> + <substitution_definition names="symbol\ 2"> <image alt="symbol 2" uri="symbol.png"> <comment xml:space="preserve"> <block_quote> diff --git a/test/test_parsers/test_rst/test_targets.py b/test/test_parsers/test_rst/test_targets.py index ef7f8ec76..362bf2cca 100755 --- a/test/test_parsers/test_rst/test_targets.py +++ b/test/test_parsers/test_rst/test_targets.py @@ -36,7 +36,7 @@ totest['targets'] = [ """, """\ <document source="test data"> - <target ids="optional-space-before-colon" names="optional space before colon"> + <target ids="optional-space-before-colon" names="optional\ space\ before\ colon"> """], ["""\ External hyperlink targets: @@ -85,9 +85,9 @@ Indirect hyperlink targets: """, """\ <document source="test data"> - <target ids="a-long-target-name" names="a long target name"> - <target ids="a-target-name-including-a-colon-quoted" names="a target name: including a colon (quoted)"> - <target ids="a-target-name-including-a-colon-escaped" names="a target name: including a colon (escaped)"> + <target ids="a-long-target-name" names="a\ long\ target\ name"> + <target ids="a-target-name-including-a-colon-quoted" names="a\ target\ name:\ including\ a\ colon\ (quoted)"> + <target ids="a-target-name-including-a-colon-escaped" names="a\ target\ name:\ including\ a\ colon\ (escaped)"> """], ["""\ .. _a very long target name, @@ -97,8 +97,8 @@ Indirect hyperlink targets: """, """\ <document source="test data"> - <target ids="a-very-long-target-name-split-across-lines" names="a very long target name, split across lines"> - <target ids="and-another-with-backquotes" names="and another, with backquotes"> + <target ids="a-very-long-target-name-split-across-lines" names="a\ very\ long\ target\ name,\ split\ across\ lines"> + <target ids="and-another-with-backquotes" names="and\ another,\ with\ backquotes"> """], ["""\ External hyperlink: @@ -120,7 +120,7 @@ External hyperlink: """\ <document source="test data"> <target ids="email" names="email" refuri="mailto:jdoe@example.com"> - <target ids="multi-line-email" names="multi-line email" refuri="mailto:jdoe@example.com"> + <target ids="multi-line-email" names="multi-line\ email" refuri="mailto:jdoe@example.com"> """], ["""\ Duplicate external targets (different URIs): @@ -319,8 +319,8 @@ Explicit internal target. <system_message level="2" line="3" source="test data" type="WARNING"> <paragraph> malformed hyperlink target. - <target ids="escaped-colon" names="escaped colon:" refuri="OK"> - <target ids="unescaped-colon-quoted" names="unescaped colon, quoted:" refuri="OK"> + <target ids="escaped-colon" names="escaped\ colon:" refuri="OK"> + <target ids="unescaped-colon-quoted" names="unescaped\ colon,\ quoted:" refuri="OK"> """], ] diff --git a/test/test_parsers/test_rst/test_transitions.py b/test/test_parsers/test_rst/test_transitions.py index 8b143832c..c60a28e96 100755 --- a/test/test_parsers/test_rst/test_transitions.py +++ b/test/test_parsers/test_rst/test_transitions.py @@ -52,7 +52,7 @@ Paragraph 2 in section 2. """, """\ <document source="test data"> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <paragraph> @@ -60,7 +60,7 @@ Paragraph 2 in section 2. <transition> <paragraph> Second text division of section 1. - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <paragraph> @@ -162,14 +162,14 @@ Section 2 <document source="test data"> <paragraph> Sections with transitions at beginning and end. - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <transition> <paragraph> The next transition is legal: <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <transition> @@ -232,16 +232,16 @@ Some text. """, """\ <document source="test data"> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 - <section ids="subsection-1" names="subsection 1"> + <section ids="subsection-1" names="subsection\ 1"> <title> Subsection 1 <paragraph> Some text. <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <paragraph> @@ -264,13 +264,13 @@ Some text. """, """\ <document source="test data"> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <transition> <transition> <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <paragraph> diff --git a/test/test_publisher.py b/test/test_publisher.py index f395eb419..545822bc6 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -26,7 +26,7 @@ Test Document This is a test document with a broken reference: nonexistent_ """ pseudoxml_output = """\ -<document ids="test-document" names="test document" source="<string>" title="Test Document"> +<document ids="test-document" names="test\ document" source="<string>" title="Test Document"> <title> Test Document <paragraph> @@ -41,7 +41,7 @@ pseudoxml_output = """\ Unknown target name: "nonexistent". """ exposed_pseudoxml_output = """\ -<document ids="test-document" internal:refnames="{u\'nonexistent\': [<reference: <#text: u\'nonexistent\'>>]}" names="test document" source="<string>" title="Test Document"> +<document ids="test-document" internal:refnames="{u\'nonexistent\': [<reference: <#text: u\'nonexistent\'>>]}" names="test\ document" source="<string>" title="Test Document"> <title> Test Document <paragraph> diff --git a/test/test_transforms/test_class.py b/test/test_transforms/test_class.py index 601272135..4cd874ea3 100755 --- a/test/test_transforms/test_class.py +++ b/test/test_transforms/test_class.py @@ -71,7 +71,7 @@ Paragraph """, """\ <document source="test data"> - <section classes="four" ids="section-title" names="section title"> + <section classes="four" ids="section-title" names="section\ title"> <title> Section Title <paragraph> diff --git a/test/test_transforms/test_contents.py b/test/test_transforms/test_contents.py index c96764343..19705b5ba 100755 --- a/test/test_transforms/test_contents.py +++ b/test/test_transforms/test_contents.py @@ -70,26 +70,26 @@ Paragraph 4. <paragraph> <reference ids="id4" refid="title-4"> Title 4 - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title refid="id1"> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> <reference name="Title" refname="title"> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title refid="id3"> <target ids="title" names="title"> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title refid="id4"> Title 4 <paragraph> @@ -108,7 +108,7 @@ Paragraph 2. """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <bullet_list> @@ -121,12 +121,12 @@ Paragraph 2. <paragraph> <reference ids="id2" refid="title-2"> Title 2 - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title refid="id1"> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title refid="id2"> Title 2 <paragraph> @@ -147,7 +147,7 @@ Paragraph 2. """, """\ <document source="test data"> - <topic classes="contents" ids="there-s-an-image-in-title-2" names="there's an image in title 2"> + <topic classes="contents" ids="there-s-an-image-in-title-2" names="there's\ an\ image\ in\ title\ 2"> <title> There's an image in Title 2 <bullet_list> @@ -159,17 +159,17 @@ Paragraph 2. <paragraph> <reference ids="id2" refid="title-2"> Title 2 - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title refid="id1"> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title refid="id2"> <image alt="Title 2" uri="title2.png"> <paragraph> Paragraph 2. - <substitution_definition names="Title 2"> + <substitution_definition names="Title\ 2"> <image alt="Title 2" uri="title2.png"> """], # emacs cruft: " ["""\ @@ -211,22 +211,22 @@ Paragraph 4. <paragraph> <reference ids="id3" refid="title-4"> Title 4 - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title refid="id1"> Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title refid="id2"> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title refid="id3"> Title 4 <paragraph> @@ -255,7 +255,7 @@ Paragraph 4. """, """\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <topic classes="contents local" ids="contents" names="contents"> @@ -275,17 +275,17 @@ Paragraph 4. Title 4 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title refid="id1"> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title refid="id2"> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title refid="id3"> Title 4 <paragraph> @@ -396,7 +396,7 @@ Paragraph 3. """, """\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title> Title 1 <paragraph> @@ -415,12 +415,12 @@ Paragraph 3. <paragraph> <reference ids="id2" refid="title-3"> Title 3 - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title refid="id1"> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title refid="id2"> Title 3 <paragraph> diff --git a/test/test_transforms/test_doctitle.py b/test/test_transforms/test_doctitle.py index 22629c45a..3000f53a5 100755 --- a/test/test_transforms/test_doctitle.py +++ b/test/test_transforms/test_doctitle.py @@ -120,7 +120,7 @@ The system_message should move after the document title (it was before the beginning of the section). """, """\ -<document ids="long-title" names="long title" source="test data" title="Long Title"> +<document ids="long-title" names="long\ title" source="test data" title="Long Title"> <title> Long Title <system_message level="2" line="1" source="test data" type="WARNING"> @@ -151,19 +151,19 @@ Title 3 Paragraph 3. """, """\ -<document ids="title-1" names="title 1" source="test data" title="Title 1"> +<document ids="title-1" names="title\ 1" source="test data" title="Title 1"> <title> Title 1 <comment xml:space="preserve"> Test multiple second-level titles. <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title> Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> @@ -185,7 +185,7 @@ substitution_definition. Title <substitution_definition names="foo"> bar - <target ids="invisible-target" names="invisible target"> + <target ids="invisible-target" names="invisible\ target"> <paragraph> This title should be the document title despite the substitution_definition. @@ -212,15 +212,15 @@ Another Subtitle <document source="test data"> <paragraph> (Because of this paragraph, the following is not a doc title.) - <section ids="section-title" names="section title"> + <section ids="section-title" names="section\ title"> <title> Section Title <subtitle ids="subtitle" names="subtitle"> Subtitle - <section ids="another-section" names="another section"> + <section ids="another-section" names="another\ section"> <title> Another Section - <subtitle ids="another-subtitle" names="another subtitle"> + <subtitle ids="another-subtitle" names="another\ subtitle"> Another Subtitle """], ]) diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index d060043cd..1b84a18c4 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -291,7 +291,7 @@ Another reference to the same `embedded URI`_. An \n\ <reference name="embedded uri" refuri="http://direct"> embedded uri - <target ids="embedded-uri" names="embedded uri" refuri="http://direct"> + <target ids="embedded-uri" names="embedded\ uri" refuri="http://direct"> . <paragraph> Another reference to the same \n\ @@ -357,7 +357,7 @@ By this `internal hyperlink`_ reference. """\ <document source="test data"> <target refid="internal-hyperlink"> - <paragraph ids="internal-hyperlink" names="internal hyperlink"> + <paragraph ids="internal-hyperlink" names="internal\ hyperlink"> This paragraph referenced. <paragraph> By this \n\ @@ -380,7 +380,7 @@ The results of the transform are not visible at the XML level. <document source="test data"> <target refid="chained"> <target refid="internal-hyperlink"> - <paragraph ids="internal-hyperlink chained" names="internal hyperlink chained"> + <paragraph ids="internal-hyperlink chained" names="internal\ hyperlink chained"> This paragraph referenced. <paragraph> By this \n\ @@ -488,7 +488,7 @@ a_\ b_ """, """\ <document source="test data"> - <target ids="external-hyperlink" names="external hyperlink" refuri="http://uri"> + <target ids="external-hyperlink" names="external\ hyperlink" refuri="http://uri"> <paragraph> <reference name="External hyperlink" refuri="http://uri"> External hyperlink @@ -500,8 +500,8 @@ a_\ b_ """, """\ <document source="test data"> - <target ids="external-hyperlink" names="external hyperlink" refuri="http://uri"> - <target ids="indirect-target" names="indirect target" refuri="http://uri"> + <target ids="external-hyperlink" names="external\ hyperlink" refuri="http://uri"> + <target ids="indirect-target" names="indirect\ target" refuri="http://uri"> <system_message level="1" line="2" source="test data" type="INFO"> <paragraph> Hyperlink target "indirect target" is not referenced. @@ -516,7 +516,7 @@ and a chained_ reference too. """\ <document source="test data"> <target refid="chained"> - <target ids="external-hyperlink chained" names="external hyperlink chained" refuri="http://uri"> + <target ids="external-hyperlink chained" names="external\ hyperlink chained" refuri="http://uri"> <paragraph> <reference name="External hyperlink" refuri="http://uri"> External hyperlink @@ -534,8 +534,8 @@ and a chained_ reference too. """, """\ <document source="test data"> - <target ids="external-hyperlink" names="external hyperlink" refuri="http://uri"> - <target ids="indirect-hyperlink" names="indirect hyperlink" refuri="http://uri"> + <target ids="external-hyperlink" names="external\ hyperlink" refuri="http://uri"> + <target ids="indirect-hyperlink" names="indirect\ hyperlink" refuri="http://uri"> <paragraph> <reference name="Indirect hyperlink" refuri="http://uri"> Indirect hyperlink @@ -550,9 +550,9 @@ Chained_ `indirect hyperlink`_ reference. """, """\ <document source="test data"> - <target ids="external-hyperlink" names="external hyperlink" refuri="http://uri"> + <target ids="external-hyperlink" names="external\ hyperlink" refuri="http://uri"> <target refuri="http://uri"> - <target ids="indirect-hyperlink chained" names="indirect hyperlink chained" refuri="http://uri"> + <target ids="indirect-hyperlink chained" names="indirect\ hyperlink chained" refuri="http://uri"> <paragraph> <reference name="Chained" refuri="http://uri"> Chained @@ -700,7 +700,7 @@ Testing an `indirect reference to the table of contents`_. """, """\ <document source="test data"> - <topic classes="contents" ids="table-of-contents" names="table of contents"> + <topic classes="contents" ids="table-of-contents" names="table\ of\ contents"> <title> Table of Contents <bullet_list> @@ -708,7 +708,7 @@ Testing an `indirect reference to the table of contents`_. <paragraph> <reference ids="id1" refid="section"> Section - <target ids="indirect-reference-to-the-table-of-contents" names="indirect reference to the table of contents" refid="table-of-contents"> + <target ids="indirect-reference-to-the-table-of-contents" names="indirect\ reference\ to\ the\ table\ of\ contents" refid="table-of-contents"> <section ids="section" names="section"> <title refid="id1"> Section @@ -729,7 +729,7 @@ Let's reference it (`explicit target`_) to avoid an irrelevant error. """\ <document source="test data"> <target refid="explicit-target"> - <section ids="title explicit-target" names="title explicit target"> + <section ids="title explicit-target" names="title explicit\ target"> <title> Title <paragraph> diff --git a/test/test_transforms/test_peps.py b/test/test_transforms/test_peps.py index 5ab57be50..5e34aea80 100755 --- a/test/test_transforms/test_peps.py +++ b/test/test_transforms/test_peps.py @@ -54,7 +54,7 @@ A "References" section should be generated. <section ids="id1"> <title> References - <footnote auto="1" ids="id2" names="TARGET_NOTE: id2"> + <footnote auto="1" ids="id2" names="TARGET_NOTE:\ id2"> <paragraph> <reference refuri="http://www.example.org"> http://www.example.org diff --git a/test/test_transforms/test_sectnum.py b/test/test_transforms/test_sectnum.py index 514ae419f..60237cea1 100755 --- a/test/test_transforms/test_sectnum.py +++ b/test/test_transforms/test_sectnum.py @@ -46,28 +46,28 @@ Paragraph 4. """, u"""\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1"> <generated classes="sectnum"> 1\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1"> <generated classes="sectnum"> 1.1\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title auto="1"> <generated classes="sectnum"> 1.1.1\u00a0\u00a0\u00a0 Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1"> <generated classes="sectnum"> 1.2\u00a0\u00a0\u00a0 @@ -84,7 +84,7 @@ Paragraph 1. """, u"""\ <document source="test data"> - <section ids="bold-title" names="bold title"> + <section ids="bold-title" names="bold\ title"> <title auto="1"> <generated classes="sectnum"> 1\u00a0\u00a0\u00a0 @@ -114,26 +114,26 @@ Paragraph 4. """, u"""\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1"> <generated classes="sectnum"> 1\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1"> <generated classes="sectnum"> 1.1\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1"> <generated classes="sectnum"> 1.2\u00a0\u00a0\u00a0 @@ -191,26 +191,26 @@ u"""\ <generated classes="sectnum"> 1.2\u00a0\u00a0\u00a0 Title 4 - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1" refid="id1"> <generated classes="sectnum"> 1\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1" refid="id2"> <generated classes="sectnum"> 1.1\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title refid="id3"> Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1" refid="id4"> <generated classes="sectnum"> 1.2\u00a0\u00a0\u00a0 @@ -240,28 +240,28 @@ Paragraph 4. """, u"""\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1"> <generated classes="sectnum"> Arbitrary-1\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1"> <generated classes="sectnum"> Arbitrary-1.1\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title auto="1"> <generated classes="sectnum"> Arbitrary-1.1.1\u00a0\u00a0\u00a0 Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1"> <generated classes="sectnum"> Arbitrary-1.2\u00a0\u00a0\u00a0 @@ -291,28 +291,28 @@ Paragraph 4. """, u"""\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1"> <generated classes="sectnum"> 3\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1"> <generated classes="sectnum"> 3.1\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title auto="1"> <generated classes="sectnum"> 3.1.1\u00a0\u00a0\u00a0 Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1"> <generated classes="sectnum"> 3.2\u00a0\u00a0\u00a0 @@ -344,28 +344,28 @@ Paragraph 4. """, u"""\ <document source="test data"> - <section ids="title-1" names="title 1"> + <section ids="title-1" names="title\ 1"> <title auto="1"> <generated classes="sectnum"> (5.9.3)\u00a0\u00a0\u00a0 Title 1 <paragraph> Paragraph 1. - <section ids="title-2" names="title 2"> + <section ids="title-2" names="title\ 2"> <title auto="1"> <generated classes="sectnum"> (5.9.3.1)\u00a0\u00a0\u00a0 Title 2 <paragraph> Paragraph 2. - <section ids="title-3" names="title 3"> + <section ids="title-3" names="title\ 3"> <title auto="1"> <generated classes="sectnum"> (5.9.3.1.1)\u00a0\u00a0\u00a0 Title 3 <paragraph> Paragraph 3. - <section ids="title-4" names="title 4"> + <section ids="title-4" names="title\ 4"> <title auto="1"> <generated classes="sectnum"> (5.9.3.2)\u00a0\u00a0\u00a0 diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 19534a486..723f01473 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -209,7 +209,7 @@ u"""\ . <substitution_definition names="copy"> \u00a9 - <substitution_definition names="BogusMegaCorp (TM)"> + <substitution_definition names="BogusMegaCorp\ (TM)"> BogusMegaCorp \u2122 """], diff --git a/test/test_transforms/test_transitions.py b/test/test_transforms/test_transitions.py index 24a69bb52..e450ddff7 100755 --- a/test/test_transforms/test_transitions.py +++ b/test/test_transforms/test_transitions.py @@ -42,16 +42,16 @@ Some text. """, """\ <document source="test data"> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 - <section ids="subsection-1" names="subsection 1"> + <section ids="subsection-1" names="subsection\ 1"> <title> Subsection 1 <paragraph> Some text. <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <paragraph> @@ -72,7 +72,7 @@ Paragraph. <paragraph> A paragraph. <transition> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <paragraph> @@ -146,7 +146,7 @@ Section 2 <document source="test data"> <paragraph> Sections with transitions at beginning and end. - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <system_message level="3" line="6" source="test data" type="ERROR"> @@ -156,7 +156,7 @@ Section 2 <paragraph> The next transition is legal: <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <system_message level="3" line="15" source="test data" type="ERROR"> @@ -239,7 +239,7 @@ Some text. """, """\ <document source="test data"> - <section ids="section-1" names="section 1"> + <section ids="section-1" names="section\ 1"> <title> Section 1 <system_message level="3" line="4" source="test data" type="ERROR"> @@ -254,7 +254,7 @@ Some text. <paragraph> At least one body element must separate transitions; adjacent transitions are not allowed. <transition> - <section ids="section-2" names="section 2"> + <section ids="section-2" names="section\ 2"> <title> Section 2 <paragraph> diff --git a/test/test_writers/test_pseudoxml.py b/test/test_writers/test_pseudoxml.py index 45b320b8b..db8bed7cb 100755 --- a/test/test_writers/test_pseudoxml.py +++ b/test/test_writers/test_pseudoxml.py @@ -41,7 +41,7 @@ Foo. <transition> <paragraph> This is another paragraph. - <section ids="a-section" names="a section"> + <section ids="a-section" names="a\ section"> <title> A Section <paragraph> -- cgit v1.2.1 From 7d8c53e396f1ff64640cd8f2f9f093186504f727 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 2 Oct 2005 01:09:01 +0000 Subject: Updated for plural attributes "classes", "ids", "names", "dupnames". git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3916 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 10 +++++++ docs/ref/doctree.txt | 72 ++++++++++++++++++++++++++------------------------- docs/ref/docutils.dtd | 8 +++--- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index fbfa0ef8e..4fa70197b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -151,6 +151,16 @@ Changes Since 0.3.9 * docs/dev/hacking.txt: Added to project; guide for developers. +* docs/ref/doctree.txt: + + - Updated for plural attributes "classes", "ids", "names", + "dupnames". + +* docs/ref/docutils.dtd: + + - Updated for plural attributes "classes", "ids", "names", + "dupnames". + * docs/user/links.txt: Added to project; lists of Docutils-related links. diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index 68bfb408f..e6cd509de 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -4421,25 +4421,25 @@ system_message_ elements (via the `%backrefs.att;`_ parameter entity). The ``bullet`` attribute is used in the bullet_list_ element. -``class`` -========= +``classes`` +=========== `Attribute type`_: ``NMTOKENS``. Default value: none. -The ``class`` attribute contains one or more names used to classify an -element. The purpose of the attribute is to indicate an "is-a" -variant relationship, to allow an extensible way of defining +The ``classes`` attribute is a list containing one or more names used +to classify an element. The purpose of the attribute is to indicate +an "is-a" variant relationship, to allow an extensible way of defining sub-classes of existing elements. It can be used to carry context forward between a Docutils Reader and Writer, when a custom structure is reduced to a standardized document tree. One common use is in conjunction with stylesheets, to add selection criteria. It should not be used to carry formatting instructions or arbitrary content. -The ``class`` attribute's contents should be ignorable. Writers that +The ``classes`` attribute's contents should be ignorable. Writers that are not familiar with the variant expressed should be able to ignore the attribute. -``class`` is one of the `common attributes`_, shared by all Docutils +``classes`` is one of the `common attributes`_, shared by all Docutils elements. @@ -4451,17 +4451,17 @@ elements. The ``delimiter`` attribute is used in the option_argument_ element. -``dupname`` -=========== +``dupnames`` +============ -`Attribute type`_: ``NMTOKENS``. Default value: none. +`Attribute type`_: ``CDATA``. Default value: none. -The ``dupname`` attribute contains the name of an element when there -has been a naming conflict. The contents of the ``dupname`` attribute -would have been transferred from the `name`_ attribute. An element -may have at most one of the ``name`` or ``dupname`` attributes, but -not both. ``dupname`` is one of the `common attributes`_, shared by -all Docutils elements. +The ``dupnames`` attribute is a list containing the names of an +element when there has been a naming conflict. The contents of the +``dupnames`` attribute would have been transferred from the `names`_ +attribute. An element may have at most one of the ``names`` or +``dupnames`` attributes, but not both. ``dupnames`` is one of the +`common attributes`_, shared by all Docutils elements. ``enumtype`` @@ -4473,27 +4473,29 @@ all Docutils elements. The ``enumtype`` attribute is used in the enumerated_list_ element. -``id`` -====== +``ids`` +======= -`Attribute type`_: ``ID``. Default value: none. +`Attribute type`_: ``NMTOKENS``. Default value: none. -The ``id`` attribute contains a unique identifier key. ``id`` is one -of the `common attributes`_, shared by all Docutils elements. +The ``ids`` attribute is a list containing one or more unique +identifier keys. ``ids`` is one of the `common attributes`_, shared +by all Docutils elements. -``name`` -======== +``names`` +========= -`Attribute type`_: ``NMTOKENS``. Default value: none. +`Attribute type`_: ``CDATA``. Default value: none. -The ``name`` attribute contains the name of an element, typically -originating from the element's title or content. ``name`` must be -unique; if there are name conflicts (two or more elements want to the -same name), the contents will be transferred to the `dupname`_ -attribute on the duplicate elements. An element may have at most one -of the ``name`` or ``dupname`` attributes, but not both. ``name`` is -one of the `common attributes`_, shared by all Docutils elements. +The ``names`` attribute is a list containing the names of an element, +typically originating from the element's title or content. Each name +in ``names`` must be unique; if there are name conflicts (two or more +elements want to the same name), the contents will be transferred to +the `dupnames`_ attribute on the duplicate elements. An element may +have at most one of the ``names`` or ``dupnames`` attributes, but not +both. ``names`` is one of the `common attributes`_, shared by all +Docutils elements. ``prefix`` @@ -4668,11 +4670,11 @@ Entity definition: .. parsed-literal:: - id_ ID #IMPLIED - name_ NMTOKENS #IMPLIED - dupname_ NMTOKENS #IMPLIED + ids_ NMTOKENS #IMPLIED + names_ CDATA #IMPLIED + dupnames_ CDATA #IMPLIED source_ CDATA #IMPLIED - class_ NMTOKENS #IMPLIED + classes_ NMTOKENS #IMPLIED %additional.basic.atts; The ``%additional.basic.atts;`` parameter entity can be used by diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index f6628684a..c2024391f 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -53,11 +53,11 @@ Attributes shared by all elements in this DTD: - `class` is used to transmit individuality information forward. --> <!ENTITY % basic.atts - " id ID #IMPLIED - name CDATA #IMPLIED - dupname CDATA #IMPLIED + " ids NMTOKENS #IMPLIED + names CDATA #IMPLIED + dupnames CDATA #IMPLIED source CDATA #IMPLIED - class NMTOKENS #IMPLIED + classes NMTOKENS #IMPLIED %additional.basic.atts; "> <!-- External reference to a URI/URL. --> -- cgit v1.2.1 From 5ba8d0c43d40007f043459bdf0f842ca52d9add7 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 2 Oct 2005 04:39:00 +0000 Subject: fixed references git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3917 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 148 +++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index e6cd509de..caffc3a89 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -340,8 +340,8 @@ Content Model `%text.model;`_ :Attributes: - The ``address`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus `xml:space`_. + The ``address`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus `xml:space`_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -413,7 +413,7 @@ Content Model :Attributes: The ``admonition`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -480,7 +480,7 @@ Content Model :Attributes: The ``attention`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -542,7 +542,7 @@ Content Model :Attributes: The ``author`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -608,7 +608,7 @@ Content Model :Attributes: The ``authors`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -686,7 +686,7 @@ Content Model :Attributes: The ``block_quote`` element contains only the `common - attributes`_: id_, name_, dupname_, source_, and class_. + attributes`_: ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -760,7 +760,7 @@ Content Model :Attributes: The ``bullet_list`` element contains the `common attributes`_ - (id_, name_, dupname_, source_, and class_), plus bullet_. + (ids_, names_, dupnames_, source_, and classes_), plus bullet_. ``bullet`` is used to record the style of bullet from the input data. In documents processed from reStructuredText_, it contains @@ -844,7 +844,7 @@ Content Model :Attributes: The ``caution`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -915,7 +915,7 @@ Content Model :Attributes: The ``classifier`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -1005,7 +1005,7 @@ Content Model :Attributes: The ``contact`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -1071,7 +1071,7 @@ Content Model :Attributes: The ``copyright`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -1142,7 +1142,7 @@ Content Model :Attributes: The ``danger`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -1199,7 +1199,7 @@ Content Model :Attributes: The ``date`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -1270,7 +1270,7 @@ empty ``decoration`` elements are ever created. :Attributes: The ``decoration`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -1329,7 +1329,7 @@ Content Model :Attributes: The ``definition`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -1380,7 +1380,7 @@ Content Model :Attributes: The ``definition_list`` element contains only the `common - attributes`_: id_, name_, dupname_, source_, and class_. + attributes`_: ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -1462,7 +1462,7 @@ Content Model :Attributes: The ``definition_list_item`` element contains only the `common - attributes`_: id_, name_, dupname_, source_, and class_. + attributes`_: ids_, names_, dupnames_, source_, and classes_. Examples @@ -1542,7 +1542,7 @@ Content Model :Attributes: The ``description`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -1600,7 +1600,7 @@ Content Model :Attributes: The ``docinfo`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -1706,7 +1706,7 @@ Content Model :Attributes: The ``doctest_block`` element contains the `common attributes`_ - (id_, name_, dupname_, source_, and class_), plus `xml:space`_. + (ids_, names_, dupnames_, source_, and classes_), plus `xml:space`_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -1785,8 +1785,8 @@ See the `%structure.model;`_ parameter entity for details of the body of a ``document``. :Attributes: - The ``document`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus an optional title__ + The ``document`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus an optional title__ attribute which stores the document title metadata. __ `title (attribute)`_ @@ -1873,7 +1873,7 @@ Content Model :Attributes: The ``enumerated_list`` element contains the `common attributes`_ - (id_, name_, dupname_, source_, and class_), plus enumtype_, + (ids_, names_, dupnames_, source_, and classes_), plus enumtype_, prefix_, suffix_, and start_. ``enumtype`` is used to record the intended enumeration sequence, @@ -1980,8 +1980,8 @@ Content Model (`%body.elements;`_)+ :Attributes: - The ``error`` element contains only the `common attributes`_: id_, - name_, dupname_, source_, and class_. + The ``error`` element contains only the `common attributes`_: ids_, + names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2040,7 +2040,7 @@ Content Model :Attributes: The ``field`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -2088,7 +2088,7 @@ Content Model :Attributes: The ``field_body`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -2142,7 +2142,7 @@ Content Model :Attributes: The ``field_list`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2224,7 +2224,7 @@ Content Model :Attributes: The ``field_name`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -2276,7 +2276,7 @@ Content Model :Attributes: The ``footer`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -2356,7 +2356,7 @@ Content Model :Attributes: The ``header`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -2416,8 +2416,8 @@ Content Model (`%body.elements;`_)+ :Attributes: - The ``hint`` element contains only the `common attributes`_: id_, - name_, dupname_, source_, and class_. + The ``hint`` element contains only the `common attributes`_: ids_, + names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2486,7 +2486,7 @@ Content Model :Attributes: The ``important`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2577,8 +2577,8 @@ Content Model `%text.model;`_ :Attributes: - The ``line`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus `xml:space`_. + The ``line`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus `xml:space`_. Examples @@ -2632,8 +2632,8 @@ Content Model (line_ | line_block_)+ :Attributes: - The ``line_block`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus `xml:space`_. + The ``line_block`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus `xml:space`_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2740,7 +2740,7 @@ Content Model :Attributes: The ``list_item`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -2825,7 +2825,7 @@ Content Model :Attributes: The ``literal_block`` element contains the `common attributes`_ - (id_, name_, dupname_, source_, and class_), plus `xml:space`_. + (ids_, names_, dupnames_, source_, and classes_), plus `xml:space`_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2896,8 +2896,8 @@ Content Model (`%body.elements;`_)+ :Attributes: - The ``note`` element contains only the `common attributes`_: id_, - name_, dupname_, source_, and class_. + The ``note`` element contains only the `common attributes`_: ids_, + names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -2957,7 +2957,7 @@ Content Model :Attributes: The ``option`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3004,8 +3004,8 @@ Content Model (#PCDATA) :Attributes: - The ``option_argument`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus delimiter_. + The ``option_argument`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus delimiter_. ``delimiter`` contains the text preceding the ``option_argument``: either the text separating it from the option_string_ (typically @@ -3060,7 +3060,7 @@ Content Model :Attributes: The ``option_group`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3111,7 +3111,7 @@ Content Model :Attributes: The ``option_list`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -3197,7 +3197,7 @@ Content Model :Attributes: The ``option_list_item`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3242,7 +3242,7 @@ Content Model :Attributes: The ``option_string`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3288,7 +3288,7 @@ Content Model :Attributes: The ``organization`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -3354,7 +3354,7 @@ Content Model :Attributes: The ``paragraph`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -3437,7 +3437,7 @@ Content Model :Attributes: The ``revision`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -3533,7 +3533,7 @@ of a ``section``. :Attributes: The ``section`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%section.elements;`_ parameter entity directly includes @@ -3639,7 +3639,7 @@ Content Model :Attributes: The ``sidebar`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%structure.model;`_ parameter entity directly includes @@ -3705,7 +3705,7 @@ Content Model :Attributes: The ``status`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -3795,7 +3795,7 @@ Content Model :Attributes: The ``subtitle`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3824,7 +3824,7 @@ Complete pseudo-XML_ result after parsing and applying transforms:: Note how two section levels have collapsed, promoting their titles to become the document's title and subtitle. Since there is only one -structural element (document), the subsection's ``id`` and ``name`` +structural element (document), the subsection's ``ids`` and ``names`` attributes are stored in the ``subtitle`` element. @@ -3894,7 +3894,7 @@ Content Model :Attributes: The ``term`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. Examples @@ -3955,8 +3955,8 @@ Content Model (`%body.elements;`_)+ :Attributes: - The ``tip`` element contains only the `common attributes`_: id_, - name_, dupname_, source_, and class_. + The ``tip`` element contains only the `common attributes`_: ids_, + names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes ``tip``. @@ -4013,8 +4013,8 @@ Content Model `%text.model;`_ :Attributes: - The ``title`` element contains the `common attributes`_ (id_, - name_, dupname_, source_, and class_), plus refid_ and auto_. + The ``title`` element contains the `common attributes`_ (ids_, + names_, dupnames_, source_, and classes_), plus refid_ and auto_. ``refid`` is used as a backlink to a table of contents entry. @@ -4089,7 +4089,7 @@ Content Model :Attributes: The ``topic`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%structure.model;`_ parameter entity directly includes @@ -4174,7 +4174,7 @@ The ``transition`` element has no content; it is a "point element". :Attributes: The ``transition`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%structure.model;`_ parameter entity directly includes @@ -4240,7 +4240,7 @@ Content Model :Attributes: The ``version`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%bibliographic.elements;`_ parameter entity directly includes @@ -4310,7 +4310,7 @@ Content Model :Attributes: The ``warning`` element contains only the `common attributes`_: - id_, name_, dupname_, source_, and class_. + ids_, names_, dupnames_, source_, and classes_. :Parameter Entities: The `%body.elements;`_ parameter entity directly includes @@ -4340,8 +4340,8 @@ Pseudo-XML_ fragment from simple parsing:: :depth: 1 _`Common Attributes`: Through the `%basic.atts;`_ parameter entity, -all elements contain the following attributes: id_, name_, dupname_, -source_, and class_. +all elements contain the following attributes: ids_, names_, dupnames_, +source_, and classes_. .. _attribute type: @@ -4408,7 +4408,7 @@ footnote_, footnote_reference_ and title_ elements (via the `Attribute type`_: ``IDREFS``. Default value: none. -The ``backrefs`` attribute contains a space-separated list of id_ +The ``backrefs`` attribute contains a space-separated list of ids_ references, used for backlinks from footnote_, citation_, and system_message_ elements (via the `%backrefs.att;`_ parameter entity). @@ -4511,7 +4511,7 @@ The ``prefix`` attribute is used in the enumerated_list_ element. `Attribute type`_: ``IDREF``. Default value: none. -The ``refid`` attribute contains references to `id`_ attributes in +The ``refid`` attribute contains references to `ids`_ attributes in other elements. It is used by the target_, reference_, footnote_reference_, citation_reference_, title_ and problematic_ elements (via the `%refid.att;`_ and `%reference.atts;`_ parameter @@ -4524,7 +4524,7 @@ entities). `Attribute type`_: ``NMTOKENS``. Default value: none. The ``refname`` attribute contains an internal reference to the -`name`_ attribute of another element. On a `target`_ element, +`names`_ attribute of another element. On a `target`_ element, ``refname`` indicates an indirect target which may resolve to either an internal or external reference. ``refname`` is used by the target_, reference_, footnote_reference_, citation_reference_, and @@ -4817,7 +4817,7 @@ their attribute lists. ================ The ``%refid.att;`` parameter entity contains the refid_ attribute, an -internal reference to the `id`_ attribute of another element. +internal reference to the `ids`_ attribute of another element. Entity definition: @@ -4837,7 +4837,7 @@ footnote_reference_, reference_, and target_ elements. ================= The ``%refname.att;`` parameter entity contains the refname_ -attribute, an internal reference to the `name`_ attribute of another +attribute, an internal reference to the `names`_ attribute of another element. On a `target`_ element, ``refname`` indicates an indirect target which may resolve to either an internal or external reference. -- cgit v1.2.1 From 6a2fee95236a9e35897b8e321897ac358605e330 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 3 Oct 2005 13:11:40 +0000 Subject: added SimpleTable bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3918 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 20 ++++++++++++++++++++ test/test_parsers/test_rst/test_SimpleTableParser.py | 14 ++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index f74933efa..b64074eca 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -277,6 +277,26 @@ Also see the `SourceForge Bug Tracker`_. the HTML output at ``test/functional/expected/standalone_rst_html4css1.html``. +* Blank first columns in simple tables with explicit row separators + silently swallow their input. They should at least produce system + error messages. But, with explicit row separators, the meaning is + unambiguous and ought to be supported:: + + ============== ========== + Table with row separators + ============== ========== + and blank + -------------- ---------- + entries + -------------- ---------- + in first + -------------- ---------- + columns. + ============== ========== + + Added a commented-out test case to + test/test_parsers/test_rst/test_SimpleTableParser.py. + .. Local Variables: diff --git a/test/test_parsers/test_rst/test_SimpleTableParser.py b/test/test_parsers/test_rst/test_SimpleTableParser.py index ba6f1b2e0..aee037206 100755 --- a/test/test_parsers/test_rst/test_SimpleTableParser.py +++ b/test/test_parsers/test_rst/test_SimpleTableParser.py @@ -101,6 +101,20 @@ That's bad. [], [[[0, 0, 1, []], [0, 0, 1, []]]])], +# ["""\ +# ============== ========== +# Table with row separators +# ============== ========== +# and blank +# -------------- ---------- +# entries +# -------------- ---------- +# in first +# -------------- ---------- +# columns. +# ============== ========== +# """, +# ''] ] -- cgit v1.2.1 From e6715dd1ba80e7f59f70006387eb1d8726d6fa77 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 3 Oct 2005 18:33:46 +0000 Subject: added correct link to stylesheet path for visual checkability of HTML output git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3919 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/expected/standalone_rst_html4css1.html | 2 +- test/functional/tests/dangerous.py | 3 +-- test/functional/tests/field_name_limit.py | 3 +-- test/functional/tests/pep_html.py | 2 -- test/functional/tests/standalone_rst_html4css1.py | 3 +-- 7 files changed, 6 insertions(+), 11 deletions(-) diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 89e86864b..8eb626e62 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -5,7 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" /> <title> - +
    diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index 736b8b98b..81bc6dc3a 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 032e37a47..0d61313d9 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -14,7 +14,7 @@ - +
    diff --git a/test/functional/tests/dangerous.py b/test/functional/tests/dangerous.py index 5611268eb..b2faca07a 100644 --- a/test/functional/tests/dangerous.py +++ b/test/functional/tests/dangerous.py @@ -10,5 +10,4 @@ writer_name = "html" # Settings settings_overrides['file_insertion_enabled'] = 0 settings_overrides['raw_enabled'] = 0 -settings_overrides['stylesheet'] = None -settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" +settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" diff --git a/test/functional/tests/field_name_limit.py b/test/functional/tests/field_name_limit.py index 86ad59a46..27c5c296e 100644 --- a/test/functional/tests/field_name_limit.py +++ b/test/functional/tests/field_name_limit.py @@ -10,5 +10,4 @@ writer_name = "html" # Settings settings_overrides['field_name_limit'] = 0 # no limit settings_overrides['docinfo_xform'] = 0 -settings_overrides['stylesheet'] = None -settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" +settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" diff --git a/test/functional/tests/pep_html.py b/test/functional/tests/pep_html.py index fde5a0cd5..5a292b207 100644 --- a/test/functional/tests/pep_html.py +++ b/test/functional/tests/pep_html.py @@ -8,10 +8,8 @@ parser_name = "rst" writer_name = "pep_html" # Settings -# settings_overrides['stylesheet'] = None settings_overrides['stylesheet_path'] = ( "../docutils/writers/support/pep_html/pep.css") -# settings_overrides['template'] = "../tools/pep-html-template" settings_overrides['python_home'] = "http://www.python.org" settings_overrides['pep_home'] = "http://www.python.org/peps" settings_overrides['no_random'] = 1 diff --git a/test/functional/tests/standalone_rst_html4css1.py b/test/functional/tests/standalone_rst_html4css1.py index 54252e83f..874deada5 100644 --- a/test/functional/tests/standalone_rst_html4css1.py +++ b/test/functional/tests/standalone_rst_html4css1.py @@ -8,5 +8,4 @@ test_destination = "standalone_rst_html4css1.html" writer_name = "html4css1" # Settings. -settings_overrides['stylesheet'] = None -settings_overrides['stylesheet_path'] = "../tools/stylesheets/default.css" +settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" -- cgit v1.2.1 From b7ea575d30a73cdb3efae6c1bb1d875a62e461fc Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 3 Oct 2005 19:18:04 +0000 Subject: fixed bug with center-alignment of image; added test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3920 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 18 ++++++++++++++---- test/functional/expected/standalone_rst_html4css1.html | 6 ++++++ test/functional/expected/standalone_rst_latex.tex | 12 ++++++++++++ test/functional/expected/standalone_rst_pseudoxml.txt | 9 +++++++++ test/functional/input/data/standard.txt | 15 +++++++++++++++ 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 4394dded9..14d0424da 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -975,9 +975,6 @@ class HTMLTranslator(nodes.NodeVisitor): if style: atts['style'] = ' '.join(style) atts['alt'] = node.get('alt', atts['src']) - if node.has_key('align'): - atts['align'] = self.attval(node['align']) - atts['class'] = 'align-%s' % atts['align'] if (isinstance(node.parent, nodes.TextElement) or (isinstance(node.parent, nodes.reference) and not isinstance(node.parent.parent, nodes.TextElement))): @@ -985,10 +982,23 @@ class HTMLTranslator(nodes.NodeVisitor): suffix = '' else: suffix = '\n' + if node.has_key('align'): + if node['align'] == 'center': + # "align" attribute is set in surrounding "div" element. + self.body.append('
    ') + self.context.append('
    \n') + suffix = '' + else: + # "align" attribute is set in "img" element. + atts['align'] = node['align'] + self.context.append('') + atts['class'] = 'align-%s' % node['align'] + else: + self.context.append('') self.body.append(self.emptytag(node, 'img', suffix, **atts)) def depart_image(self, node): - pass + self.body.append(self.context.pop()) def visit_important(self, node): self.visit_admonition(node, 'important') diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 0d61313d9..3f6014854 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -549,6 +549,12 @@ document (a document-wide table o ../../../docs/user/rst/images/title.png

    Image with multiple IDs:

    ../../../docs/user/rst/images/title.png +

    A centered image:

    +
    ../../../docs/user/rst/images/biohazard.png
    +

    A left-aligned image:

    +../../../docs/user/rst/images/biohazard.png +

    A right-aligned image:

    +../../../docs/user/rst/images/biohazard.png

    A figure directive:

    reStructuredText, the markup syntax diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index aa03b5dc0..4e36fc61f 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -869,6 +869,18 @@ Image with multiple IDs: \includegraphics{../../../docs/user/rst/images/title.png} +A centered image: + +{\hfill\includegraphics{../../../docs/user/rst/images/biohazard.png}\hfill} + +A left-aligned image: + +{\includegraphics{../../../docs/user/rst/images/biohazard.png}\hfill} + +A right-aligned image: + +{\hfill\includegraphics{../../../docs/user/rst/images/biohazard.png}} + A figure directive: \begin{figure}[htbp]\begin{center} diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 179760c86..f47750eb5 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1128,6 +1128,15 @@ + + A centered image: + + + A left-aligned image: + + + A right-aligned image: + A figure directive:
    diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 85016529f..0ce3020ef 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -434,6 +434,21 @@ Image with multiple IDs: .. _image target 3: .. image:: ../../../docs/user/rst/images/title.png +A centered image: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :align: center + +A left-aligned image: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :align: left + +A right-aligned image: + +.. image:: ../../../docs/user/rst/images/biohazard.png + :align: right + A figure directive: .. figure:: ../../../docs/user/rst/images/biohazard.png -- cgit v1.2.1 From 0880f518d78dc87baddd465adbaf500a2654b6d3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 4 Oct 2005 17:26:33 +0000 Subject: added test for parsed literal block git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3922 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../expected/standalone_rst_html4css1.html | 224 ++++++++++--------- test/functional/expected/standalone_rst_latex.tex | 34 ++- .../expected/standalone_rst_pseudoxml.txt | 246 ++++++++++++--------- test/functional/input/data/standard.txt | 12 + 4 files changed, 300 insertions(+), 216 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 3f6014854..8a8def5e9 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -88,67 +88,68 @@ They are transformed from section titles after parsing. -->

    Table of Contents

    -

    1   Structural Elements

    +

    1   Structural Elements

    -

    1.1   Section Title

    +

    1.1   Section Title

    Section Subtitle

    That's it, the text just above this line.

    -

    1.3   Transitions

    +

    1.3   Transitions

    Here's a transition:


    It divides the section. Transitions may also occur between sections:

    @@ -156,24 +157,24 @@ They are transformed from section titles after parsing. -->

    -

    2   Body Elements

    +

    2   Body Elements

    -

    2.1   Paragraphs

    +

    2.1   Paragraphs

    A paragraph.

    -

    2.1.1   Inline Markup

    +

    2.1.1   Inline Markup

    Paragraphs contain text and may contain inline markup: emphasis, strong emphasis, inline literals, standalone hyperlinks -(http://www.python.org), external hyperlinks (Python [5]), internal +(http://www.python.org), external hyperlinks (Python [5]), internal cross-references (example), external hyperlinks with embedded URIs (Python web site), footnote references (manually numbered [1], anonymous auto-numbered [3], labeled auto-numbered [2], or symbolic [*]), citation references ([CIT2002]), substitution references (EXAMPLE), and inline -hyperlink targets (see Targets below for a reference back to here). +hyperlink targets (see Targets below for a reference back to here). Character-level inline markup is also possible (although exceedingly ugly!) in reStructuredText. Problems are indicated by -|problematic| text (generated by processing errors; this one is +|problematic| text (generated by processing errors; this one is intentional). Here is a reference to the doctitle and the subtitle.

    The default role for interpreted text is Title Reference. Here are some explicit interpreted text roles: a PEP reference (PEP 287); an @@ -192,7 +193,7 @@ live link to PEP 258 here.

    -

    2.2   Bullet Lists

    +

    2.2   Bullet Lists

    • A bullet list

        @@ -217,7 +218,7 @@ live link to PEP 258 here.

    -

    2.3   Enumerated Lists

    +

    2.3   Enumerated Lists

    1. Arabic numerals.

        @@ -250,7 +251,7 @@ live link to PEP 258 here.

    -

    2.4   Definition Lists

    +

    2.4   Definition Lists

    Term
    Definition
    @@ -265,7 +266,7 @@ live link to PEP 258 here.

    @@ -289,7 +290,7 @@ doesn't get stripped away.)

    -

    2.6   Option Lists

    +

    2.6   Option Lists

    For listing command-line options:

    @@ -335,7 +336,7 @@ regardless of where it starts.

    description.

    -

    2.7   Literal Blocks

    +

    2.7   Literal Blocks

    Literal blocks are indicated with a double-colon ("::") at the end of the preceding paragraph (over there -->). They can be indented:

    @@ -352,7 +353,7 @@ if literal_block:
     
    -

    2.8   Line Blocks

    +

    2.8   Line Blocks

    This section tests line blocks. Line blocks are body elements which consist of lines and other line blocks. Nested line blocks cause indentation.

    @@ -411,7 +412,7 @@ the left edge of the text above it.
    -

    2.9   Block Quotes

    +

    2.9   Block Quotes

    Block quotes consist of indented body elements:

    My theory by A. Elk. Brackets Miss, brackets. This theory goes @@ -423,7 +424,7 @@ own it, and what it is too.

    -

    2.10   Doctest Blocks

    +

    2.10   Doctest Blocks

     >>> print 'Python-specific usage examples; begun with ">>>"'
     Python-specific usage examples; begun with ">>>"
    @@ -432,11 +433,11 @@ Python-specific usage examples; begun with ">>>"
     
    - @@ -479,12 +480,12 @@ Here's a reference to the next footnote: +nonexistent footnote: [5]_.
    [1](1, 2)

    A footnote contains body elements, consistently indented by at +

    [1](1, 2, 3)

    A footnote contains body elements, consistently indented by at least 3 spaces.

    This is the footnote's second paragraph.

    [4]Here's an unreferenced footnote, with a reference to a -nonexistent footnote: [5]_.
    -

    2.12   Citations

    +

    2.12   Citations

    @@ -492,59 +493,60 @@ nonexistent footnote: [CIT2002], and a [nonexistent]_ +

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    -

    2.13   Targets

    +

    2.13   Targets

    This paragraph is pointed to by the explicit "example" target. A reference can be found under Inline Markup, above. Inline hyperlink targets are also possible.

    Section headers are implicit targets, referred to by name. See -Targets, which is a subsection of Body Elements.

    +Targets, which is a subsection of Body Elements.

    Explicit external targets are interpolated into references such as -"Python [5]".

    -

    Targets may be indirect and anonymous. Thus this phrase may also -refer to the Targets section.

    -

    Here's a `hyperlink reference without a target`_, which generates an +"Python [5]".

    +

    Targets may be indirect and anonymous. Thus this phrase may also +refer to the Targets section.

    +

    Here's a `hyperlink reference without a target`_, which generates an error.

    -

    2.13.1   Duplicate Target Names

    +

    2.13.1   Duplicate Target Names

    Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages.

    -

    2.13.2   Duplicate Target Names

    +

    2.13.2   Duplicate Target Names

    Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: `Duplicate Target Names`_), an error is generated.

    +this: `Duplicate Target Names`_), an error is generated.

    -

    2.14   Directives

    +

    2.14   Directives

    These are just a sample of the many reStructuredText Directives. For others, please see http://docutils.sourceforge.net/docs/ref/rst/directives.html.

    -

    2.14.1   Document Parts

    +

    2.14.1   Document Parts

    An example of the "contents" directive can be seen above this section (a local, untitled table of contents) and at the beginning of the document (a document-wide table of contents).

    -

    2.14.2   Images

    +

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png

    Image with multiple IDs:

    @@ -612,7 +614,7 @@ document (a document-wide table o ../../../docs/user/rst/images/biohazard.png
    -

    2.14.3   Admonitions

    +

    2.14.3   Admonitions

    Attention!

    Directives at large.

    @@ -661,7 +663,7 @@ Reader discretion is strongly advised.

    -

    2.14.4   Topics, Sidebars, and Rubrics

    +

    2.14.4   Topics, Sidebars, and Rubrics

    +

    2.14.5   Target Footnotes

    +
    - +
    [5](1, 2, 3) http://www.python.org/
    [5](1, 2, 3) http://www.python.org/
    -

    2.14.7   Compound Paragraph

    +

    2.14.7   Compound Paragraph

    Compound 1, paragraph 1.

    Compound 1, paragraph 2.

    @@ -758,14 +760,24 @@ paragraph.

    Compound 7, another paragraph.

    +
    +

    2.14.8   Parsed Literal Blocks

    +
    +This is a parsed literal block.
    +    This line is indented.  The next line is blank.
    +
    +Inline markup is supported, e.g. emphasis, strong, literal
    +text, footnotes [1], targets, and references.
    +
    +
    -

    2.15   Substitution Definitions

    +

    2.15   Substitution Definitions

    An inline image (EXAMPLE) example:

    (Substitution definitions are not visible in the HTML source.)

    -

    2.16   Comments

    +

    2.16   Comments

    Here's one:

    (View the HTML source to see the comment.)

    -

    2.17   Raw text

    +

    2.17   Raw text

    This does not necessarily look nice, because there may be missing white space.

    It's just there to freeze the behavior.

    A test.Second test.
    Another test with myclass set.

    This is the fourth test with myrawroleclass set.

    Fifth test in HTML.
    Line two.
    -

    2.18   Colspanning tables

    +

    2.18   Colspanning tables

    This table has a cell spanning two columns:

    @@ -819,7 +831,7 @@ Fifth test in HTML.
    Line two.
    -

    2.19   Rowspanning tables

    +

    2.19   Rowspanning tables

    Here's a table with cells spanning several rows:

    @@ -852,7 +864,7 @@ cell.
    -

    2.20   Complex tables

    +

    2.20   Complex tables

    Here's a complex table, which should test all features.

    @@ -901,7 +913,7 @@ empty: -->
    -

    2.21   List Tables

    +

    2.21   List Tables

    Here's a list table exercising all features:

    @@ -935,7 +947,7 @@ crunchy, now would it?
    -

    3   Error Handling

    +

    3   Error Handling

    Any errors caught during processing will generate system messages.

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    @@ -943,20 +955,20 @@ section, "Docutils System Messages":

    Docutils System Messages

    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 100); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 100); backlink

    Undefined substitution referenced: "problematic".
    -
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 354); backlink

    +
    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 354); backlink

    Unknown target name: "5".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 363); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 363); backlink

    Unknown target name: "nonexistent".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 390); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 390); backlink

    Unknown target name: "hyperlink reference without a target".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 403); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 403); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 4e36fc61f..0a5aec391 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -198,6 +198,8 @@ reStructuredText construct. \item {} \href{\#compound-paragraph}{2.14.7~~~Compound Paragraph} +\item {} \href{\#parsed-literal-blocks}{2.14.8~~~Parsed Literal Blocks} + \end{list} \item {} \href{\#substitution-definitions}{2.15~~~Substitution Definitions} @@ -296,13 +298,13 @@ A paragraph. Paragraphs contain text and may contain inline markup: \emph{emphasis}, \textbf{strong emphasis}, \texttt{inline literals}, standalone hyperlinks -(\href{http://www.python.org}{http://www.python.org}), external hyperlinks (\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id21}{5}}), internal +(\href{http://www.python.org}{http://www.python.org}), external hyperlinks (\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}), internal cross-references (\href{\#example}{example}), external hyperlinks with embedded URIs (\href{http://www.python.org}{Python web site}), footnote references (manually numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id6}{1}}, anonymous auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id9}{3}}, labeled auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{label}{2}}, or symbolic\raisebox{.5em}[0em]{\scriptsize\hyperlink{id10}{*}}), citation references ([\hyperlink{cit2002}{CIT2002}]), substitution references (\includegraphics{../../../docs/user/rst/images/biohazard.png}), and \hypertarget{inline-hyperlink-targets}{inline -hyperlink targets} (see \href{\#targets}{Targets} below for a reference back to here). +hyperlink targets} (see \href{\#id20}{Targets} below for a reference back to here). Character-level inline markup is also possible (although exceedingly ugly!) in \emph{re}\texttt{Structured}\emph{Text}. Problems are indicated by {\color{red}\bfseries{}{\textbar}problematic{\textbar}} text (generated by processing errors; this one is @@ -784,13 +786,13 @@ reference can be found under \href{\#inline-markup}{Inline Markup}, above. \href hyperlink targets} are also possible. Section headers are implicit targets, referred to by name. See -\href{\#targets}{Targets}, which is a subsection of \href{\#body-elements}{Body Elements}. +\href{\#id20}{Targets}, which is a subsection of \href{\#body-elements}{Body Elements}. Explicit external targets are interpolated into references such as -``\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id21}{5}}''. +``\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}''. -Targets may be indirect and anonymous. Thus \href{\#targets}{this phrase} may also -refer to the \href{\#targets}{Targets} section. +Targets may be indirect and anonymous. Thus \href{\#id20}{this phrase} may also +refer to the \href{\#id20}{Targets} section. Here's a {\color{red}\bfseries{}`hyperlink reference without a target`{\_}}, which generates an error. @@ -838,6 +840,8 @@ this: {\color{red}\bfseries{}`Duplicate Target Names`{\_}}), an error is generat \item {} \href{\#compound-paragraph}{2.14.7~~~Compound Paragraph} +\item {} \href{\#parsed-literal-blocks}{2.14.8~~~Parsed Literal Blocks} + \end{list} @@ -1105,7 +1109,7 @@ This is a topic. \hypertarget{target-footnotes}{} \pdfbookmark[2]{2.14.5~~~Target Footnotes}{target-footnotes} \subsubsection*{2.14.5~~~Target Footnotes} -\begin{figure}[b]\hypertarget{id21}$^{5}$ +\begin{figure}[b]\hypertarget{id23}$^{5}$ \href{http://www.python.org/}{http://www.python.org/} \end{figure} @@ -1116,7 +1120,7 @@ This is a topic. \pdfbookmark[2]{2.14.6~~~Replacement Text}{replacement-text} \subsubsection*{2.14.6~~~Replacement Text} -I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id21}{5}}. +I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}. %___________________________________________________________________________ @@ -1193,6 +1197,20 @@ Compound 7, a paragraph after the table. Compound 7, another paragraph. +%___________________________________________________________________________ + +\hypertarget{parsed-literal-blocks}{} +\pdfbookmark[2]{2.14.8~~~Parsed Literal Blocks}{parsed-literal-blocks} +\subsubsection*{2.14.8~~~Parsed Literal Blocks} +\begin{quote}{\ttfamily \raggedright \noindent +This~is~a~parsed~literal~block.~\\ +~~~~This~line~is~indented.~~The~next~line~is~blank.~\\ +~\\ +Inline~markup~is~supported,~e.g.~\emph{emphasis},~\textbf{strong},~\texttt{literal~\\ +text},~footnotes\raisebox{.5em}[0em]{\scriptsize\hyperlink{id6}{1}},~\hypertarget{id20}{targets},~and~\href{http://www.python.org/}{references}. +}\end{quote} + + %___________________________________________________________________________ \hypertarget{substitution-definitions}{} diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index f47750eb5..ac3fc98a7 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -91,238 +91,244 @@ - + 1    Structural Elements - + 1.1    Section Title - + 1.2    Empty Section - + 1.3    Transitions - + 2    Body Elements - + 2.1    Paragraphs - + 2.1.1    Inline Markup - + 2.2    Bullet Lists - + 2.3    Enumerated Lists - + 2.4    Definition Lists - + 2.5    Field Lists - + 2.6    Option Lists - + 2.7    Literal Blocks - + 2.8    Line Blocks - + 2.9    Block Quotes - + 2.10    Doctest Blocks - + 2.11    Footnotes - + 2.12    Citations - + 2.13    Targets - + 2.13.1    Duplicate Target Names - + 2.13.2    Duplicate Target Names - + 2.14    Directives - + 2.14.1    Document Parts - + 2.14.2    Images - + 2.14.3    Admonitions - + 2.14.4    Topics, Sidebars, and Rubrics - + 2.14.5    Target Footnotes - + 2.14.6    Replacement Text - + 2.14.7    Compound Paragraph + + + + + 2.14.8    + Parsed Literal Blocks - + 2.15    Substitution Definitions - + 2.16    Comments - + 2.17    Raw text - + 2.18    Colspanning tables - + 2.19    Rowspanning tables - + 2.20    Complex tables - + 2.21    List Tables - + 3    Error Handling
    - + <title auto="1" refid="id27"> <generated classes="sectnum"> 1    Structural Elements <section ids="section-title" names="section\ title"> - <title auto="1" refid="id26"> + <title auto="1" refid="id28"> <generated classes="sectnum"> 1.1    Section Title @@ -331,12 +337,12 @@ <paragraph> That's it, the text just above this line. <section ids="empty-section" names="empty\ section"> - <title auto="1" refid="id27"> + <title auto="1" refid="id29"> <generated classes="sectnum"> 1.2    Empty Section <section ids="transitions" names="transitions"> - <title auto="1" refid="id28"> + <title auto="1" refid="id30"> <generated classes="sectnum"> 1.3    Transitions @@ -347,19 +353,19 @@ It divides the section. Transitions may also occur between sections: <transition> <section ids="body-elements" names="body\ elements"> - <title auto="1" refid="id29"> + <title auto="1" refid="id31"> <generated classes="sectnum"> 2    Body Elements <section ids="paragraphs" names="paragraphs"> - <title auto="1" refid="id30"> + <title auto="1" refid="id32"> <generated classes="sectnum"> 2.1    Paragraphs <paragraph> A paragraph. <section ids="inline-markup" names="inline\ markup"> - <title auto="1" refid="id31"> + <title auto="1" refid="id33"> <generated classes="sectnum"> 2.1.1    Inline Markup @@ -381,7 +387,7 @@ <reference name="Python" refuri="http://www.python.org/"> Python - <footnote_reference auto="1" ids="id22" refid="id21"> + <footnote_reference auto="1" ids="id24" refid="id23"> 5 ), internal cross-references ( @@ -416,7 +422,7 @@ inline hyperlink targets (see - <reference name="Targets" refid="targets"> + <reference name="Targets" refid="id20"> Targets below for a reference back to here). Character-level inline markup is also possible (although exceedingly @@ -428,7 +434,7 @@ <emphasis> Text . Problems are indicated by - <problematic ids="id20" refid="id19"> + <problematic ids="id22" refid="id21"> |problematic| text (generated by processing errors; this one is intentional). Here is a reference to the @@ -484,7 +490,7 @@ option was supplied, there should be a live link to PEP 258 here. <section ids="bullet-lists" names="bullet\ lists"> - <title auto="1" refid="id32"> + <title auto="1" refid="id34"> <generated classes="sectnum"> 2.2    Bullet Lists @@ -528,7 +534,7 @@ <comment xml:space="preserve"> Even if this item contains a target and a comment. <section ids="enumerated-lists" names="enumerated\ lists"> - <title auto="1" refid="id33"> + <title auto="1" refid="id35"> <generated classes="sectnum"> 2.3    Enumerated Lists @@ -577,7 +583,7 @@ <paragraph> iv <section ids="definition-lists" names="definition\ lists"> - <title auto="1" refid="id34"> + <title auto="1" refid="id36"> <generated classes="sectnum"> 2.4    Definition Lists @@ -615,7 +621,7 @@ <paragraph> Definition <section ids="field-lists" names="field\ lists"> - <title auto="1" refid="id35"> + <title auto="1" refid="id37"> <generated classes="sectnum"> 2.5    Field Lists @@ -649,7 +655,7 @@ about credits but just for ensuring that the class attribute doesn't get stripped away.) <section ids="option-lists" names="option\ lists"> - <title auto="1" refid="id36"> + <title auto="1" refid="id38"> <generated classes="sectnum"> 2.6    Option Lists @@ -762,7 +768,7 @@ There must be at least two spaces between the option and the description. <section ids="literal-blocks" names="literal\ blocks"> - <title auto="1" refid="id37"> + <title auto="1" refid="id39"> <generated classes="sectnum"> 2.7    Literal Blocks @@ -784,7 +790,7 @@ > > Why didn't I think of that? <section ids="line-blocks" names="line\ blocks"> - <title auto="1" refid="id38"> + <title auto="1" refid="id40"> <generated classes="sectnum"> 2.8    Line Blocks @@ -862,7 +868,7 @@ <line> Singing... <section ids="block-quotes" names="block\ quotes"> - <title auto="1" refid="id39"> + <title auto="1" refid="id41"> <generated classes="sectnum"> 2.9    Block Quotes @@ -878,7 +884,7 @@ <attribution> Anne Elk (Miss) <section ids="doctest-blocks" names="doctest\ blocks"> - <title auto="1" refid="id40"> + <title auto="1" refid="id42"> <generated classes="sectnum"> 2.10    Doctest Blocks @@ -888,11 +894,11 @@ >>> print '(cut and pasted from interactive Python sessions)' (cut and pasted from interactive Python sessions) <section ids="footnotes" names="footnotes"> - <title auto="1" refid="id41"> + <title auto="1" refid="id43"> <generated classes="sectnum"> 2.11    Footnotes - <footnote backrefs="id1 id7" ids="id6" names="1"> + <footnote backrefs="id1 id7 id19" ids="id6" names="1"> <label> 1 <paragraph> @@ -948,11 +954,11 @@ <paragraph> Here's an unreferenced footnote, with a reference to a nonexistent footnote: - <problematic ids="id70 id14" refid="id69"> + <problematic ids="id74 id14" refid="id73"> [5]_ . <section ids="citations" names="citations"> - <title auto="1" refid="id42"> + <title auto="1" refid="id44"> <generated classes="sectnum"> 2.12    Citations @@ -967,13 +973,13 @@ <citation_reference ids="id15" refid="cit2002"> CIT2002 , and a - <problematic ids="id72 id16" refid="id71"> + <problematic ids="id76 id16" refid="id75"> [nonexistent]_ citation. <target refid="another-target"> - <section ids="targets another-target" names="targets another\ target"> - <title auto="1" refid="id43"> + <section dupnames="targets" ids="targets another-target" names="another\ target"> + <title auto="1" refid="id45"> <generated classes="sectnum"> 2.13    Targets @@ -990,7 +996,7 @@ are also possible. <paragraph> Section headers are implicit targets, referred to by name. See - <reference name="Targets" refid="targets"> + <reference name="Targets" refid="id20"> Targets , which is a subsection of <reference name="Body Elements" refid="body-elements"> @@ -1002,28 +1008,28 @@ <reference name="Python" refuri="http://www.python.org/"> Python - <footnote_reference auto="1" ids="id23" refid="id21"> + <footnote_reference auto="1" ids="id25" refid="id23"> 5 ". <target ids="python" names="python" refuri="http://www.python.org/"> <paragraph> Targets may be indirect and anonymous. Thus - <reference anonymous="1" name="this phrase" refid="targets"> + <reference anonymous="1" name="this phrase" refid="id20"> this phrase may also refer to the - <reference name="Targets" refid="targets"> + <reference name="Targets" refid="id20"> Targets section. - <target anonymous="1" ids="id17" refid="targets"> + <target anonymous="1" ids="id17" refid="id20"> <paragraph> Here's a - <problematic ids="id74" refid="id73"> + <problematic ids="id78" refid="id77"> `hyperlink reference without a target`_ , which generates an error. <section dupnames="duplicate\ target\ names" ids="duplicate-target-names"> - <title auto="1" refid="id44"> + <title auto="1" refid="id46"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names @@ -1032,7 +1038,7 @@ generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages. <section dupnames="duplicate\ target\ names" ids="id18"> - <title auto="1" refid="id45"> + <title auto="1" refid="id47"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names @@ -1040,11 +1046,11 @@ Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: - <problematic ids="id76" refid="id75"> + <problematic ids="id80" refid="id79"> `Duplicate Target Names`_ ), an error is generated. <section ids="directives" names="directives"> - <title auto="1" refid="id46"> + <title auto="1" refid="id48"> <generated classes="sectnum"> 2.14    Directives @@ -1052,46 +1058,52 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id62" refid="document-parts"> + <reference ids="id65" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id63" refid="images"> + <reference ids="id66" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id64" refid="admonitions"> + <reference ids="id67" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id65" refid="topics-sidebars-and-rubrics"> + <reference ids="id68" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id66" refid="target-footnotes"> + <reference ids="id69" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id67" refid="replacement-text"> + <reference ids="id70" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id68" refid="compound-paragraph"> + <reference ids="id71" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph + <list_item> + <paragraph> + <reference ids="id72" refid="parsed-literal-blocks"> + <generated classes="sectnum"> + 2.14.8    + Parsed Literal Blocks <paragraph> These are just a sample of the many reStructuredText Directives. For others, please see @@ -1099,7 +1111,7 @@ http://docutils.sourceforge.net/docs/ref/rst/directives.html . <section ids="document-parts" names="document\ parts"> - <title auto="1" refid="id62"> + <title auto="1" refid="id65"> <generated classes="sectnum"> 2.14.1    Document Parts @@ -1114,7 +1126,7 @@ table of contents ). <section ids="images" names="images"> - <title auto="1" refid="id63"> + <title auto="1" refid="id66"> <generated classes="sectnum"> 2.14.2    Images @@ -1215,7 +1227,7 @@ An image 3 cm high: <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> - <title auto="1" refid="id64"> + <title auto="1" refid="id67"> <generated classes="sectnum"> 2.14.3    Admonitions @@ -1265,7 +1277,7 @@ You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> <section ids="topics-sidebars-and-rubrics" names="topics,\ sidebars,\ and\ rubrics"> - <title auto="1" refid="id65"> + <title auto="1" refid="id68"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics @@ -1290,18 +1302,18 @@ <rubric> This is a rubric <section ids="target-footnotes" names="target\ footnotes"> - <title auto="1" refid="id66"> + <title auto="1" refid="id69"> <generated classes="sectnum"> 2.14.5    Target Footnotes - <footnote auto="1" backrefs="id22 id23 id24" ids="id21" names="TARGET_NOTE:\ id21"> + <footnote auto="1" backrefs="id24 id25 id26" ids="id23" names="TARGET_NOTE:\ id23"> <label> 5 <paragraph> <reference refuri="http://www.python.org/"> http://www.python.org/ <section ids="replacement-text" names="replacement\ text"> - <title auto="1" refid="id67"> + <title auto="1" refid="id70"> <generated classes="sectnum"> 2.14.6    Replacement Text @@ -1313,7 +1325,7 @@ the best language around - <footnote_reference auto="1" ids="id24" refid="id21"> + <footnote_reference auto="1" ids="id26" refid="id23"> 5 . <substitution_definition names="Python"> @@ -1322,7 +1334,7 @@ the best language around <section ids="compound-paragraph" names="compound\ paragraph"> - <title auto="1" refid="id68"> + <title auto="1" refid="id71"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1407,8 +1419,38 @@ Compound 7, a paragraph after the table. <paragraph> Compound 7, another paragraph. + <section ids="parsed-literal-blocks" names="parsed\ literal\ blocks"> + <title auto="1" refid="id72"> + <generated classes="sectnum"> + 2.14.8    + Parsed Literal Blocks + <literal_block xml:space="preserve"> + This is a parsed literal block. + This line is indented. The next line is blank. + + Inline markup is supported, e.g. + <emphasis> + emphasis + , + <strong> + strong + , + <literal> + literal + text + , footnotes + <footnote_reference ids="id19" refid="id6"> + 1 + , + <target ids="id20" names="targets"> + targets + , and + <reference name="references" refuri="http://www.python.org/"> + references + <target ids="references" names="references" refuri="http://www.python.org/"> + . <section ids="substitution-definitions" names="substitution\ definitions"> - <title auto="1" refid="id54"> + <title auto="1" refid="id57"> <generated classes="sectnum"> 2.15    Substitution Definitions @@ -1421,7 +1463,7 @@ <paragraph> (Substitution definitions are not visible in the HTML source.) <section ids="comments" names="comments"> - <title auto="1" refid="id55"> + <title auto="1" refid="id58"> <generated classes="sectnum"> 2.16    Comments @@ -1436,7 +1478,7 @@ <paragraph> (View the HTML source to see the comment.) <section ids="raw-text" names="raw\ text"> - <title auto="1" refid="id56"> + <title auto="1" refid="id59"> <generated classes="sectnum"> 2.17    Raw text @@ -1460,7 +1502,7 @@ <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. <section ids="colspanning-tables" names="colspanning\ tables"> - <title auto="1" refid="id57"> + <title auto="1" refid="id60"> <generated classes="sectnum"> 2.18    Colspanning tables @@ -1531,7 +1573,7 @@ <paragraph> True <section ids="rowspanning-tables" names="rowspanning\ tables"> - <title auto="1" refid="id58"> + <title auto="1" refid="id61"> <generated classes="sectnum"> 2.19    Rowspanning tables @@ -1583,7 +1625,7 @@ <paragraph> body row 3 <section ids="complex-tables" names="complex\ tables"> - <title auto="1" refid="id59"> + <title auto="1" refid="id62"> <generated classes="sectnum"> 2.20    Complex tables @@ -1668,7 +1710,7 @@ --> <entry> <section ids="list-tables" names="list\ tables"> - <title auto="1" refid="id60"> + <title auto="1" refid="id63"> <generated classes="sectnum"> 2.21    List Tables @@ -1725,7 +1767,7 @@ <paragraph> On a stick! <section ids="error-handling" names="error\ handling"> - <title auto="1" refid="id61"> + <title auto="1" refid="id64"> <generated classes="sectnum"> 3    Error Handling @@ -1739,18 +1781,18 @@ <section classes="system-messages"> <title> Docutils System Messages - <system_message backrefs="id20" ids="id19" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id22" ids="id21" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id70" ids="id69" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id74" ids="id73" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id72" ids="id71" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id76" ids="id75" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id74" ids="id73" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id78" ids="id77" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id76" ids="id75" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id80" ids="id79" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index 0ce3020ef..ccb5ddbeb 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -659,6 +659,18 @@ meaningful. Compound 7, another paragraph. +Parsed Literal Blocks +````````````````````` + +.. parsed-literal:: + + This is a parsed literal block. + This line is indented. The next line is blank. + + Inline markup is supported, e.g. *emphasis*, **strong**, ``literal + text``, footnotes [1]_, _`targets`, and `references + <http://www.python.org/>`_. + Substitution Definitions ------------------------ -- cgit v1.2.1 From c54c65baf381ec76c7041b10d14ba19531f6e604 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 4 Oct 2005 18:33:57 +0000 Subject: added to do list entry about "raw-wrapped" base role git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3923 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 390273dd2..6541d41ca 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1357,6 +1357,36 @@ any knowledge of the Python-Reader origin of these elements. * Implement roles: + - "_`raw-wrapped`" (or "_`raw-wrap`"): Base role to wrap raw text + around role contents. + + For example, the following reStructuredText source ... :: + + .. role:: red(raw-formatting) + :prefix: + :html: <font color="red"> + :latex: {\color{red} + :suffix: + :html: </font> + :latex: } + + colored :red:`text` + + ... will yield the following document fragment:: + + <paragraph> + colored + <inline classes="red"> + <raw format="html"> + <font color="red"> + <raw format="latex"> + {\color{red} + text + <raw format="html"> + </font> + <raw format="latex"> + } + - "acronym" and "abbreviation": Associate the full text with a short form. Jason Diamond's description: -- cgit v1.2.1 From 641669c1961739317cead6b48445e972e70b6e71 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 5 Oct 2005 01:45:59 +0000 Subject: added entry about --strip-comments option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3924 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 6541d41ca..c45a26dfc 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -92,6 +92,12 @@ for inclusion in the Python standard library. General ======= +* Add a --strip-comments command-line option (& strip_comments runtime + setting), declared in docutils/frontend.py, and implemented as a + transform. This feature isn't specific to rst2html.py, or to the + HTML Writer, or to the reST parser; it applies to Docutils as a + whole. See <http://thread.gmane.org/gmane.text.docutils.devel/3216>. + * Add a generic "container" element, equivalent to "inline", to which a "class" attribute can be attached. Will require a reST directive also. -- cgit v1.2.1 From eabdac6b7d7561c4325f483b7d94eb307504ff73 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 5 Oct 2005 01:50:28 +0000 Subject: added entry about indirect citation/footnote links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3925 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c45a26dfc..1a9fd1d98 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -660,6 +660,16 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* Add indirect links via citation references & footnote references. + Example:: + + `Goodger (2005)`_ is helpful. + + .. _Goodger (2005): [goodger2005]_ + .. [goodger2005] citation text + + See <http://thread.gmane.org/gmane.text.docutils.user/2499>. + * Allow multiple block quotes, only separated by attributions (http://article.gmane.org/gmane.text.docutils.devel/2985), e.g.:: -- cgit v1.2.1 From 5fdf1c828e5736b03feb375654f2735bfd8b395a Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 5 Oct 2005 16:00:44 +0000 Subject: Changed emacs support to avoid touching the kill-ring. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3926 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index e0c0a1c0f..b03e7cbf8 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -249,7 +249,8 @@ have been seen. ;; For all the preferred decorations... (let* ( - ;; If 'prev' is given, reorder the list to start searching after the match. + ;; If 'prev' is given, reorder the list to start searching after the + ;; match. (fplist (cdr (rest-get-decoration-match rest-preferred-decorations prev))) @@ -270,6 +271,9 @@ have been seen. (copy-list (car curpotential)) )) +(defun rest-delete-line () + "A version of kill-line that does not use the kill-ring." + (delete-region (line-beginning-position) (+ 1 (line-end-position)))) (defun rest-update-section (char style &optional indent) "Unconditionally updates the style of a section decoration @@ -311,14 +315,14 @@ have been seen. ;; Avoid removing the underline of a title right above us. (save-excursion (forward-line -1) (not (looking-at rest-section-text-regexp))) - (kill-line 1))) + (rest-delete-line))) ;; Remove following line if it consists only of a single repeated ;; character (save-excursion (forward-line +1) (and (rest-line-homogeneous-p 1) - (kill-line 1)) + (rest-delete-line)) ;; Add a newline if we're at the end of the buffer, for the subsequence ;; inserting of the underline (if (= (point) (buffer-end 1)) @@ -1088,7 +1092,7 @@ cand replace with char: ") (setq p (1+ (point))) (beginning-of-line) (setq l (- p (point))) - (kill-line) + (rest-delete-line) (insert-char tochar l)) (search-failed (message (format "%d lines replaced." found))))))) -- cgit v1.2.1 From 5b8e4a4676301f3de183f5683c04e3ba3d4d5131 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 8 Oct 2005 20:22:52 +0000 Subject: added "Local Variables" block because most blocks are wrapped at column 78 but Emacs uses column 70 by default git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3927 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index 9b68f2aec..df470dbec 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1736,3 +1736,10 @@ def whitespace_normalize_name(name): def serial_escape(value): """Escape string values that are elements of a list, for serialization.""" return value.replace('\\', r'\\').replace(' ', r'\ ') + +# +# +# Local Variables: +# indent-tabs-mode: nil +# sentence-end-double-space: t +# fill-column: 78 -- cgit v1.2.1 From 2d16e5e0ca1bbd86a2f0ba8873079751ee2ece47 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 8 Oct 2005 21:02:39 +0000 Subject: improved documentation about state transition table git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3928 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docutils/nodes.py b/docutils/nodes.py index df470dbec..9fa84b140 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -911,7 +911,8 @@ class document(Root, Structural, Element): The following state transition table shows how `self.nameids` ("ids") and `self.nametypes` ("types") change with new input (a call to this - method), and what actions are performed: + method), and what actions are performed ("implicit"-type system + messages are INFO/1, and "explicit"-type system messages are ERROR/3): ==== ===== ======== ======== ======= ==== ===== ===== Old State Input Action New State Notes -- cgit v1.2.1 From fb06bc04fd8b7dd1b1fbbc235ed0d6876f0f5129 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 8 Oct 2005 23:45:44 +0000 Subject: added reference to newlatex2e/base.tex git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3929 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/newlatex2e.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py index 6845a7b72..e3d0a738b 100644 --- a/docutils/writers/newlatex2e.py +++ b/docutils/writers/newlatex2e.py @@ -30,6 +30,12 @@ class Writer(writers.Writer): supported = ('newlatex', 'newlatex2e') """Formats this writer supports.""" + default_stylesheet = 'base.tex' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(writers.support_path, 'newlatex2e', default_stylesheet)) + settings_spec = ( 'LaTeX-Specific Options', 'Note that this LaTeX writer is still EXPERIMENTAL. ' @@ -42,9 +48,11 @@ class Writer(writers.Writer): {'default': '', 'metavar': '<file>', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' - 'directory. Overrides --stylesheet.', + 'directory. Overrides --stylesheet. Default: "%s"' + % default_stylesheet_path, ['--stylesheet-path'], - {'metavar': '<file>', 'overrides': 'stylesheet'}), + {'metavar': '<file>', 'overrides': 'stylesheet', + 'default': default_stylesheet_path}), ('Specify a user stylesheet file. See --stylesheet.', ['--user-stylesheet'], {'default': '', 'metavar': '<file>', -- cgit v1.2.1 From aebbc5cf69dddc4ccae38c8577ef2ae389a3447e Mon Sep 17 00:00:00 2001 From: grubert <grubert@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 10 Oct 2005 07:59:49 +0000 Subject: Fix: do not escape citekeys in latex citations. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3930 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 4 ++++ docutils/writers/latex2e.py | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index 4fa70197b..c2e04b927 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,6 +14,10 @@ Changes Since 0.3.9 =================== +* docutils/writers/latex2e-py: + + Fix underscores in citekeys must not be escaped. + * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 824946204..78d8f1e35 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1196,7 +1196,9 @@ class LaTeXTranslator(nodes.NodeVisitor): widest_label = bi[0] self.body.append('\n\\begin{thebibliography}{%s}\n'%widest_label) for bi in self._bibitems: - self.body.append('\\bibitem[%s]{%s}{%s}\n' % (bi[0], bi[0], bi[1])) + # cite_key: underscores must not be escaped + cite_key = bi[0].replace(r"{\_}","_") + self.body.append('\\bibitem[%s]{%s}{%s}\n' % (bi[0], cite_key, bi[1])) self.body.append('\\end{thebibliography}\n') self.body_suffix.append('\\end{document}\n') -- cgit v1.2.1 From ad01b501da1019d3953f0956d65dae3b72a4a1c8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 13:14:06 +0000 Subject: added OS X clipboard note git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3931 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/README.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index d4359213b..366a826da 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -79,13 +79,18 @@ here are some useful resources for Emacs users in the Unicode world: (set-frame-font "fontset-monaco") + - To enable cooperation between the system clipboard and the Emacs + kill ring, add this line:: + + (set-clipboard-coding-system 'mac-roman) + Other useful resources are in `Andrew Choi's Emacs 21 for Mac OS X FAQ <http://members.shaw.ca/akochoi-emacs/stories/faq.html>`__. No matter what platform (or editor) you're using, I recommend the ProFont__ programmer's font. It's monospaced, small but readable, -similar characters are visually distinctive (like "1lI|", "0O", "ao", -and ".,"), and free. +similar characters are visually distinctive (like "I1l|", "0O", "ao", +and ".,:;"), and free. __ http://www.tobias-jung.de/seekingprofont/ .. _reStructuredText: http://docutils.sf.net/rst.html -- cgit v1.2.1 From 554fd14a2991750dd134aee52d40c6806aa0e8ad Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 13:14:13 +0000 Subject: clarified row separators in simple tables git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3932 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index ed6056e96..921ac31a4 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -1390,7 +1390,8 @@ Simple tables are described with horizontal borders made up of "=" and "-" characters. The equals sign ("=") is used for top and bottom table borders, and to separate optional header rows from the table body. The hyphen ("-") is used to indicate column spans in a single -row by underlining the joined columns. +row by underlining the joined columns, and may optionally be used to +explicitly and/or visually separate rows. A simple table begins with a top border of equals signs with one or more spaces at each column boundary (two or more spaces recommended). -- cgit v1.2.1 From 8caecfa4637c4690054d994722b629f5dba32721 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 17:51:38 +0000 Subject: disallow targets inside substitution definitions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3933 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 + docutils/nodes.py | 1 - docutils/parsers/rst/states.py | 53 ++++++++++++++---------- test/test_parsers/test_rst/test_substitutions.py | 15 +++++++ test/test_transforms/test_substitutions.py | 24 +++++++++++ 5 files changed, 71 insertions(+), 24 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index c2e04b927..aea0d6fc8 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -56,6 +56,8 @@ Changes Since 0.3.9 - Fixed bug with escaped colons indicating a literal block. - Fixed bug with enumerated lists (SF#1254145). + - Targets (implicit and explicit) inside of substitution definitions + are now disallowed. * docutils/parsers/rst/directives/misc.py: diff --git a/docutils/nodes.py b/docutils/nodes.py index 9fa84b140..e02273d9f 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1049,7 +1049,6 @@ class document(Root, Structural, Element): def note_substitution_def(self, subdef, def_name, msgnode=None): name = whitespace_normalize_name(def_name) - subdef['names'].append(name) if self.substitution_defs.has_key(name): msg = self.reporter.error( 'Duplicate substitution definition name: "%s".' % name, diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index d72a96e0c..e9fa14d40 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1910,34 +1910,41 @@ class Body(RSTState): subname = subdefmatch.group('name') substitution_node = nodes.substitution_definition(blocktext) substitution_node.line = lineno - self.document.note_substitution_def( - substitution_node,subname, self.parent) - if block: - block[0] = block[0].strip() - new_abs_offset, blank_finish = self.nested_list_parse( - block, input_offset=offset, node=substitution_node, - initial_state='SubstitutionDef', blank_finish=blank_finish) - i = 0 - for node in substitution_node[:]: - if not (isinstance(node, nodes.Inline) or - isinstance(node, nodes.Text)): - self.parent += substitution_node[i] - del substitution_node[i] - else: - i += 1 - if len(substitution_node) == 0: + if not block: + msg = self.reporter.warning( + 'Substitution definition "%s" missing contents.' % subname, + nodes.literal_block(blocktext, blocktext), line=lineno) + return [msg], blank_finish + block[0] = block[0].strip() + substitution_node['names'].append( + nodes.whitespace_normalize_name(subname)) + new_abs_offset, blank_finish = self.nested_list_parse( + block, input_offset=offset, node=substitution_node, + initial_state='SubstitutionDef', blank_finish=blank_finish) + i = 0 + for node in substitution_node[:]: + if not (isinstance(node, nodes.Inline) or + isinstance(node, nodes.Text)): + self.parent += substitution_node[i] + del substitution_node[i] + else: + i += 1 + for node in substitution_node.traverse(nodes.Element): + if node['ids']: msg = self.reporter.warning( - 'Substitution definition "%s" empty or invalid.' - % subname, - nodes.literal_block(blocktext, blocktext), line=lineno) + 'Substitution definitions may not contain targets.', + nodes.literal_block(blocktext, blocktext), + line=lineno) return [msg], blank_finish - else: - return [substitution_node], blank_finish - else: + if len(substitution_node) == 0: msg = self.reporter.warning( - 'Substitution definition "%s" missing contents.' % subname, + 'Substitution definition "%s" empty or invalid.' + % subname, nodes.literal_block(blocktext, blocktext), line=lineno) return [msg], blank_finish + self.document.note_substitution_def( + substitution_node, subname, self.parent) + return [substitution_node], blank_finish def directive(self, match, **option_presets): """Returns a 2-tuple: list of nodes, and a "blank finish" boolean.""" diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index f949ce187..7210819b0 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -255,6 +255,21 @@ No blank line after. <comment xml:space="preserve"> | """], +["""\ +Substitution definition with a target: + +.. |target| replace:: _`target` +""", +"""\ +<document source="test data"> + <paragraph> + Substitution definition with a target: + <system_message level="2" line="3" source="test data" type="WARNING"> + <paragraph> + Substitution definitions may not contain targets. + <literal_block xml:space="preserve"> + .. |target| replace:: _`target` +"""], ] diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 723f01473..8a09fe109 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -236,6 +236,30 @@ u"""\ <substitution_definition ltrim="1" names="TM"> \u2122 """], +["""\ +Substitution definition with a target: + +.. |target| replace:: _`target` + +Make sure this substitution definition is not registered: |target| +""", +"""\ +<document source="test data"> + <paragraph> + Substitution definition with a target: + <system_message level="2" line="3" source="test data" type="WARNING"> + <paragraph> + Substitution definitions may not contain targets. + <literal_block xml:space="preserve"> + .. |target| replace:: _`target` + <paragraph> + Make sure this substitution definition is not registered: \n\ + <problematic ids="id2" refid="id1"> + |target| + <system_message backrefs="id2" ids="id1" level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Undefined substitution referenced: "target". +"""], ]) -- cgit v1.2.1 From 340274a5ac7f0f0212928245da73116fc5a0daf0 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 19:26:35 +0000 Subject: removed now-fixed "targets inside substitution definitions" bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3934 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index b64074eca..8a31d43cd 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -176,22 +176,6 @@ Also see the `SourceForge Bug Tracker`_. all IDs from definitions after the first substitution reference is processed. - * _`Targets inside substitution definitions` cause duplicate IDs:: - - $ rst2pseudoxml.py - .. |target| replace:: _`foo` - - |target|\ |target| - <document source="<stdin>"> - <substitution_definition names="target"> - <target ids="foo" names="foo"> - foo - <paragraph> - <target ids="foo" names="foo"> - foo - <target ids="foo" names="foo"> - foo - * Footnote label "5" should be "4" when processing the following input:: -- cgit v1.2.1 From 8ca484acd7f7fbc2990475a22fb1089b022e5571 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 19:34:52 +0000 Subject: added Node.deepcopy(); fixed bug with doubly-indirect substitutions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3935 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 8 --- HISTORY.txt | 2 + docutils/nodes.py | 19 +++++-- docutils/transforms/references.py | 79 ++++++++++++++------------- test/test_nodes.py | 22 ++++++++ test/test_transforms/test_substitutions.py | 88 +++++++++++++++--------------- 6 files changed, 120 insertions(+), 98 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 8a31d43cd..c162064a5 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -151,14 +151,6 @@ Also see the `SourceForge Bug Tracker`_. "Active" content inside of substitution definitions does not work. This bug becomes manifest in the following cases: - * There's a bug with _`doubly-indirect substitutions` but only when - there's multiple references and in certain cases. See the - commented-out test case in test_transforms/test_substitutions.py - (line 104 on, in revision 3808) which fails. - - This is tricky. Substitution definitions have to propagate back - completely, through multiple levels of references. - * .. _substitutions and references: Another bug from David Abrahams (run with ``rst2html.py --traceback``):: diff --git a/HISTORY.txt b/HISTORY.txt index aea0d6fc8..7286ffa42 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -44,6 +44,7 @@ Changes Since 0.3.9 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. * docutils/parsers/null.py: Added to project; a do-nothing parser. @@ -93,6 +94,7 @@ Changes Since 0.3.9 - Added references.DanglingReferences transform, extracted from universal.FinalChecks. + - Fixed bug with doubly-indirect substitutions. * docutils/transforms/universal.py: diff --git a/docutils/nodes.py b/docutils/nodes.py index e02273d9f..17ef75e99 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -82,6 +82,10 @@ class Node: """Return a copy of self.""" raise NotImplementedError + def deepcopy(self): + """Return a deep copy of self (also copying children).""" + raise NotImplementedError + def setup_child(self, child): child.parent = self if self.document: @@ -288,6 +292,9 @@ class Text(Node, UserString): def copy(self): return self.__class__(self.data) + def deepcopy(self): + return self.copy() + def pformat(self, indent=' ', level=0): result = [] indent = indent * level @@ -639,6 +646,11 @@ class Element(Node): def copy(self): return self.__class__(**self.attributes) + def deepcopy(self): + copy = self.copy() + copy.extend([child.deepcopy() for child in self.children]) + return copy + def set_class(self, name): """Add a new class to the "classes" attribute.""" warnings.warn('docutils.nodes.Element.set_class deprecated; ' @@ -816,10 +828,6 @@ class document(Root, Structural, Element): self.ids = {} """Mapping of ids to nodes.""" - self.substitution_refs = {} - """Mapping of substitution names to lists of substitution_reference - nodes.""" - self.footnote_refs = {} """Mapping of footnote labels to lists of footnote_reference nodes.""" @@ -1063,8 +1071,7 @@ class document(Root, Structural, Element): self.substitution_names[fully_normalize_name(name)] = name def note_substitution_ref(self, subref, refname): - name = subref['refname'] = whitespace_normalize_name(refname) - self.substitution_refs.setdefault(name, []).append(subref) + subref['refname'] = whitespace_normalize_name(refname) def note_pending(self, pending, priority=None): self.transformer.add_pending(pending, priority) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index 2cc83be87..d7ad9376f 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -654,45 +654,46 @@ class Substitutions(Transform): def apply(self): defs = self.document.substitution_defs normed = self.document.substitution_names - subreflist = self.document.substitution_refs.items() - subreflist.sort() - for refname, refs in subreflist: - for ref in refs: - key = None - if defs.has_key(refname): - key = refname - else: - normed_name = refname.lower() - if normed.has_key(normed_name): - 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 (subdef.attributes.has_key('ltrim') - or subdef.attributes.has_key('trim')): - if index > 0 and isinstance(parent[index - 1], - nodes.Text): - parent.replace(parent[index - 1], - parent[index - 1].rstrip()) - if (subdef.attributes.has_key('rtrim') - or subdef.attributes.has_key('trim')): - if (len(parent) > index + 1 - and isinstance(parent[index + 1], nodes.Text)): - parent.replace(parent[index + 1], - parent[index + 1].lstrip()) - ref.replace_self(subdef.children) - self.document.substitution_refs = None # release replaced references + subreflist = self.document.traverse(nodes.substitution_reference) + for ref in subreflist: + refname = ref['refname'] + key = None + if defs.has_key(refname): + key = refname + else: + normed_name = refname.lower() + if normed.has_key(normed_name): + 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 (subdef.attributes.has_key('ltrim') + or subdef.attributes.has_key('trim')): + if index > 0 and isinstance(parent[index - 1], + nodes.Text): + parent.replace(parent[index - 1], + parent[index - 1].rstrip()) + if (subdef.attributes.has_key('rtrim') + or subdef.attributes.has_key('trim')): + 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() + # Take care of nested substitution references. + subreflist.extend(subdef_copy.traverse(nodes.substitution_reference)) + ref.replace_self(subdef_copy.children) class TargetNotes(Transform): diff --git a/test/test_nodes.py b/test/test_nodes.py index 42a64ad49..4471b3a15 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -242,6 +242,28 @@ class MiscTests(unittest.TestCase): def not_in_testlist(self, x): return x not in self.testlist + def test_copy(self): + grandchild = nodes.Text('rawsource') + child = nodes.emphasis('rawsource', grandchild, att='child') + e = nodes.Element('rawsource', child, att='e') + # Shallow copy: + e_copy = e.copy() + self.assert_(e is not e_copy) + # Internal attributes (like `rawsource`) are not copied. + self.assertEquals(e.rawsource, 'rawsource') + self.assertEquals(e_copy.rawsource, '') + self.assertEquals(e_copy['att'], 'e') + # Children are not copied. + self.assertEquals(len(e_copy), 0) + # Deep copy: + e_deepcopy = e.deepcopy() + self.assertEquals(e_deepcopy.rawsource, '') + self.assertEquals(e_deepcopy['att'], 'e') + # Children are copied recursively. + self.assertEquals(e_deepcopy[0][0], grandchild) + self.assert_(e_deepcopy[0][0] is not grandchild) + self.assertEquals(e_deepcopy[0]['att'], 'child') + class TreeCopyVisitorTests(unittest.TestCase): diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index 8a09fe109..ba98e1aa1 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -101,51 +101,49 @@ u"""\ <substitution_definition names="replace"> swap """], -#["""\ -#.. |l| unicode:: U+00AB .. left chevron -#.. |r| unicode:: U+00BB .. right chevron -#.. |.| replace:: |l|\ ``.``\ |r| -# -#.. Delete either of the following lines, and there is no error. -# -#Regular expression |.| will match any character -# -#.. Note:: Note that |.| matches *exactly* one character -#""", -#u"""\ -#<document source="test data"> -# <substitution_definition names="l"> -# \xab -# <substitution_definition names="r"> -# \xbb -# <substitution_definition names="."> -# <substitution_reference refname="l"> -# l -# <literal> -# . -# <substitution_reference refname="r"> -# r -# <comment xml:space="preserve"> -# Delete either of the following lines, and there is no error. -# <paragraph> -# Regular expression \n\ -# \xab -# <literal> -# . -# \xbb -# will match any character -# <note> -# <paragraph> -# Note that \n\ -# \xab -# <literal> -# . -# \xbb -# matches \n\ -# <emphasis> -# exactly -# one character -#"""], +["""\ +.. |l| unicode:: U+00AB .. left chevron +.. |r| unicode:: U+00BB .. right chevron +.. |.| replace:: |l|\ ``.``\ |r| + +.. Delete either of the following lines, and there is no error. + +Regular expression |.| will match any character + +.. Note:: Note that |.| matches *exactly* one character +""", +u"""\ +<document source="test data"> + <substitution_definition names="l"> + \xab + <substitution_definition names="r"> + \xbb + <substitution_definition names="."> + \xab + <literal> + . + \xbb + <comment xml:space="preserve"> + Delete either of the following lines, and there is no error. + <paragraph> + Regular expression \n\ + \xab + <literal> + . + \xbb + will match any character + <note> + <paragraph> + Note that \n\ + \xab + <literal> + . + \xbb + matches \n\ + <emphasis> + exactly + one character +"""], ]) totest['unicode'] = ((Substitutions,), [ -- cgit v1.2.1 From b9f4da7cb726b00a563ec3e72497de9c8d127412 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 19:59:43 +0000 Subject: added bug with circular substitutions (found by David) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3936 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index c162064a5..34dceb78b 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -168,6 +168,10 @@ Also see the `SourceForge Bug Tracker`_. all IDs from definitions after the first substitution reference is processed. +* _`Circular substitutions` cause Docutils to hang:: + + .. |sub| replace:: |sub| + * Footnote label "5" should be "4" when processing the following input:: -- cgit v1.2.1 From 7068fae26ee297f883adf5f884fd64b0892b2a70 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 20:40:41 +0000 Subject: disallow anonymous hyperlink references and auto-numbered footnotes inside of substitution definitions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3937 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 22 ------------------- HISTORY.txt | 13 ++++++----- docutils/parsers/rst/states.py | 17 ++++++++++---- test/test_parsers/test_rst/test_substitutions.py | 28 ++++++++++++++++++++---- test/test_transforms/test_substitutions.py | 11 ++++++---- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index 34dceb78b..89b5998df 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -146,28 +146,6 @@ Also see the `SourceForge Bug Tracker`_. Quite a few nodes are getting a "None" source attribute as well. In particular, see the bodies of definition lists. -* .. _substitutions: - - "Active" content inside of substitution definitions does not work. - This bug becomes manifest in the following cases: - - * .. _substitutions and references: - - Another bug from David Abrahams (run with ``rst2html.py --traceback``):: - - |substitution| and again a |substitution|. - - .. |substitution| replace:: ref__ - - __ a.html - __ b.html - - Change the references.Substitutions tranform's priority from 220 to - 680, so it happens after reference resolution? Then we have to deal - with multiple IDs. Perhaps the Substitution transform should remove - all IDs from definitions after the first substitution reference is - processed. - * _`Circular substitutions` cause Docutils to hang:: .. |sub| replace:: |sub| diff --git a/HISTORY.txt b/HISTORY.txt index 7286ffa42..57d7a2319 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,10 +14,6 @@ Changes Since 0.3.9 =================== -* docutils/writers/latex2e-py: - - Fix underscores in citekeys must not be escaped. - * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. @@ -57,8 +53,9 @@ Changes Since 0.3.9 - Fixed bug with escaped colons indicating a literal block. - Fixed bug with enumerated lists (SF#1254145). - - Targets (implicit and explicit) inside of substitution definitions - are now disallowed. + - Targets (implicit and explicit), anonymous hyperlink references + and auto-numbered footnote references inside of substitution + definitions are now disallowed. * docutils/parsers/rst/directives/misc.py: @@ -141,6 +138,10 @@ Changes Since 0.3.9 - Made cloaking of email addresses with ``--cloak-email-addresses`` less obtrusive. +* docutils/writers/latex2e.py: + + - Underscores in citekeys are no longer escaped. + * docutils/writers/support/: Directory added to project. Modules and data files that support writers have been moved here. diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index e9fa14d40..db19c34b6 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1930,10 +1930,11 @@ class Body(RSTState): else: i += 1 for node in substitution_node.traverse(nodes.Element): - if node['ids']: - msg = self.reporter.warning( - 'Substitution definitions may not contain targets.', - nodes.literal_block(blocktext, blocktext), + if self.disallowed_inside_substitution_definitions(node): + pformat = nodes.literal_block('', node.pformat().rstrip()) + msg = self.reporter.error( + 'Substitution definition contains illegal element:', + pformat, nodes.literal_block(blocktext, blocktext), line=lineno) return [msg], blank_finish if len(substitution_node) == 0: @@ -1946,6 +1947,14 @@ class Body(RSTState): substitution_node, subname, self.parent) return [substitution_node], blank_finish + def disallowed_inside_substitution_definitions(self, node): + if (node['ids'] or + isinstance(node, nodes.reference) and node.get('anonymous') or + isinstance(node, nodes.footnote_reference) and node.get('auto')): + return 1 + else: + return 0 + def directive(self, match, **option_presets): """Returns a 2-tuple: list of nodes, and a "blank finish" boolean.""" type_name = match.group(1) diff --git a/test/test_parsers/test_rst/test_substitutions.py b/test/test_parsers/test_rst/test_substitutions.py index 7210819b0..fb8af4c2d 100755 --- a/test/test_parsers/test_rst/test_substitutions.py +++ b/test/test_parsers/test_rst/test_substitutions.py @@ -256,19 +256,39 @@ No blank line after. | """], ["""\ -Substitution definition with a target: +Elements that are prohibited inside of substitution definitions: .. |target| replace:: _`target` +.. |reference| replace:: anonymous__ +.. |auto-numbered footnote| replace:: [#]_ """, """\ <document source="test data"> <paragraph> - Substitution definition with a target: - <system_message level="2" line="3" source="test data" type="WARNING"> + Elements that are prohibited inside of substitution definitions: + <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - Substitution definitions may not contain targets. + Substitution definition contains illegal element: + <literal_block xml:space="preserve"> + <target ids="target" names="target"> + target <literal_block xml:space="preserve"> .. |target| replace:: _`target` + <system_message level="3" line="4" source="test data" type="ERROR"> + <paragraph> + Substitution definition contains illegal element: + <literal_block xml:space="preserve"> + <reference anonymous="1" name="anonymous"> + anonymous + <literal_block xml:space="preserve"> + .. |reference| replace:: anonymous__ + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Substitution definition contains illegal element: + <literal_block xml:space="preserve"> + <footnote_reference auto="1" ids="id1"> + <literal_block xml:space="preserve"> + .. |auto-numbered footnote| replace:: [#]_ """], ] diff --git a/test/test_transforms/test_substitutions.py b/test/test_transforms/test_substitutions.py index ba98e1aa1..aa3a7c6f6 100755 --- a/test/test_transforms/test_substitutions.py +++ b/test/test_transforms/test_substitutions.py @@ -235,7 +235,7 @@ u"""\ \u2122 """], ["""\ -Substitution definition with a target: +Substitution definition with an illegal element: .. |target| replace:: _`target` @@ -244,10 +244,13 @@ Make sure this substitution definition is not registered: |target| """\ <document source="test data"> <paragraph> - Substitution definition with a target: - <system_message level="2" line="3" source="test data" type="WARNING"> + Substitution definition with an illegal element: + <system_message level="3" line="3" source="test data" type="ERROR"> <paragraph> - Substitution definitions may not contain targets. + Substitution definition contains illegal element: + <literal_block xml:space="preserve"> + <target ids="target" names="target"> + target <literal_block xml:space="preserve"> .. |target| replace:: _`target` <paragraph> -- cgit v1.2.1 From c8c683761645534bb45877a851b966451f490024 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 21:22:01 +0000 Subject: added a functional test for target footnotes for anonymous targets git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3938 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- .../expected/standalone_rst_html4css1.html | 266 ++++++++++--------- test/functional/expected/standalone_rst_latex.tex | 56 ++-- .../expected/standalone_rst_pseudoxml.txt | 292 +++++++++++---------- test/functional/input/data/standard.txt | 22 +- 4 files changed, 334 insertions(+), 302 deletions(-) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index 8a8def5e9..e14d5a72d 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -88,68 +88,68 @@ They are transformed from section titles after parsing. --> <div class="contents topic"> <p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of Contents</a></p> <ul class="auto-toc simple"> -<li><a class="reference" href="#structural-elements" id="id27" name="id27">1   Structural Elements</a><ul class="auto-toc"> -<li><a class="reference" href="#section-title" id="id28" name="id28">1.1   Section Title</a></li> -<li><a class="reference" href="#empty-section" id="id29" name="id29">1.2   Empty Section</a></li> -<li><a class="reference" href="#transitions" id="id30" name="id30">1.3   Transitions</a></li> +<li><a class="reference" href="#structural-elements" id="id32" name="id32">1   Structural Elements</a><ul class="auto-toc"> +<li><a class="reference" href="#section-title" id="id33" name="id33">1.1   Section Title</a></li> +<li><a class="reference" href="#empty-section" id="id34" name="id34">1.2   Empty Section</a></li> +<li><a class="reference" href="#transitions" id="id35" name="id35">1.3   Transitions</a></li> </ul> </li> -<li><a class="reference" href="#body-elements" id="id31" name="id31">2   Body Elements</a><ul class="auto-toc"> -<li><a class="reference" href="#paragraphs" id="id32" name="id32">2.1   Paragraphs</a><ul class="auto-toc"> -<li><a class="reference" href="#inline-markup" id="id33" name="id33">2.1.1   Inline Markup</a></li> +<li><a class="reference" href="#body-elements" id="id36" name="id36">2   Body Elements</a><ul class="auto-toc"> +<li><a class="reference" href="#paragraphs" id="id37" name="id37">2.1   Paragraphs</a><ul class="auto-toc"> +<li><a class="reference" href="#inline-markup" id="id38" name="id38">2.1.1   Inline Markup</a></li> </ul> </li> -<li><a class="reference" href="#bullet-lists" id="id34" name="id34">2.2   Bullet Lists</a></li> -<li><a class="reference" href="#enumerated-lists" id="id35" name="id35">2.3   Enumerated Lists</a></li> -<li><a class="reference" href="#definition-lists" id="id36" name="id36">2.4   Definition Lists</a></li> -<li><a class="reference" href="#field-lists" id="id37" name="id37">2.5   Field Lists</a></li> -<li><a class="reference" href="#option-lists" id="id38" name="id38">2.6   Option Lists</a></li> -<li><a class="reference" href="#literal-blocks" id="id39" name="id39">2.7   Literal Blocks</a></li> -<li><a class="reference" href="#line-blocks" id="id40" name="id40">2.8   Line Blocks</a></li> -<li><a class="reference" href="#block-quotes" id="id41" name="id41">2.9   Block Quotes</a></li> -<li><a class="reference" href="#doctest-blocks" id="id42" name="id42">2.10   Doctest Blocks</a></li> -<li><a class="reference" href="#footnotes" id="id43" name="id43">2.11   Footnotes</a></li> -<li><a class="reference" href="#citations" id="id44" name="id44">2.12   Citations</a></li> -<li><a class="reference" href="#targets" id="id45" name="id45">2.13   Targets</a><ul class="auto-toc"> -<li><a class="reference" href="#duplicate-target-names" id="id46" name="id46">2.13.1   Duplicate Target Names</a></li> -<li><a class="reference" href="#id18" id="id47" name="id47">2.13.2   Duplicate Target Names</a></li> +<li><a class="reference" href="#bullet-lists" id="id39" name="id39">2.2   Bullet Lists</a></li> +<li><a class="reference" href="#enumerated-lists" id="id40" name="id40">2.3   Enumerated Lists</a></li> +<li><a class="reference" href="#definition-lists" id="id41" name="id41">2.4   Definition Lists</a></li> +<li><a class="reference" href="#field-lists" id="id42" name="id42">2.5   Field Lists</a></li> +<li><a class="reference" href="#option-lists" id="id43" name="id43">2.6   Option Lists</a></li> +<li><a class="reference" href="#literal-blocks" id="id44" name="id44">2.7   Literal Blocks</a></li> +<li><a class="reference" href="#line-blocks" id="id45" name="id45">2.8   Line Blocks</a></li> +<li><a class="reference" href="#block-quotes" id="id46" name="id46">2.9   Block Quotes</a></li> +<li><a class="reference" href="#doctest-blocks" id="id47" name="id47">2.10   Doctest Blocks</a></li> +<li><a class="reference" href="#footnotes" id="id48" name="id48">2.11   Footnotes</a></li> +<li><a class="reference" href="#citations" id="id49" name="id49">2.12   Citations</a></li> +<li><a class="reference" href="#targets" id="id50" name="id50">2.13   Targets</a><ul class="auto-toc"> +<li><a class="reference" href="#duplicate-target-names" id="id51" name="id51">2.13.1   Duplicate Target Names</a></li> +<li><a class="reference" href="#id20" id="id52" name="id52">2.13.2   Duplicate Target Names</a></li> </ul> </li> -<li><a class="reference" href="#directives" id="id48" name="id48">2.14   Directives</a><ul class="auto-toc"> -<li><a class="reference" href="#document-parts" id="id49" name="id49">2.14.1   Document Parts</a></li> -<li><a class="reference" href="#images" id="id50" name="id50">2.14.2   Images</a></li> -<li><a class="reference" href="#admonitions" id="id51" name="id51">2.14.3   Admonitions</a></li> -<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id52" name="id52">2.14.4   Topics, Sidebars, and Rubrics</a></li> -<li><a class="reference" href="#target-footnotes" id="id53" name="id53">2.14.5   Target Footnotes</a></li> -<li><a class="reference" href="#replacement-text" id="id54" name="id54">2.14.6   Replacement Text</a></li> -<li><a class="reference" href="#compound-paragraph" id="id55" name="id55">2.14.7   Compound Paragraph</a></li> -<li><a class="reference" href="#parsed-literal-blocks" id="id56" name="id56">2.14.8   Parsed Literal Blocks</a></li> +<li><a class="reference" href="#directives" id="id53" name="id53">2.14   Directives</a><ul class="auto-toc"> +<li><a class="reference" href="#document-parts" id="id54" name="id54">2.14.1   Document Parts</a></li> +<li><a class="reference" href="#images" id="id55" name="id55">2.14.2   Images</a></li> +<li><a class="reference" href="#admonitions" id="id56" name="id56">2.14.3   Admonitions</a></li> +<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id57" name="id57">2.14.4   Topics, Sidebars, and Rubrics</a></li> +<li><a class="reference" href="#target-footnotes" id="id58" name="id58">2.14.5   Target Footnotes</a></li> +<li><a class="reference" href="#replacement-text" id="id59" name="id59">2.14.6   Replacement Text</a></li> +<li><a class="reference" href="#compound-paragraph" id="id60" name="id60">2.14.7   Compound Paragraph</a></li> +<li><a class="reference" href="#parsed-literal-blocks" id="id61" name="id61">2.14.8   Parsed Literal Blocks</a></li> </ul> </li> -<li><a class="reference" href="#substitution-definitions" id="id57" name="id57">2.15   Substitution Definitions</a></li> -<li><a class="reference" href="#comments" id="id58" name="id58">2.16   Comments</a></li> -<li><a class="reference" href="#raw-text" id="id59" name="id59">2.17   Raw text</a></li> -<li><a class="reference" href="#colspanning-tables" id="id60" name="id60">2.18   Colspanning tables</a></li> -<li><a class="reference" href="#rowspanning-tables" id="id61" name="id61">2.19   Rowspanning tables</a></li> -<li><a class="reference" href="#complex-tables" id="id62" name="id62">2.20   Complex tables</a></li> -<li><a class="reference" href="#list-tables" id="id63" name="id63">2.21   List Tables</a></li> +<li><a class="reference" href="#substitution-definitions" id="id62" name="id62">2.15   Substitution Definitions</a></li> +<li><a class="reference" href="#comments" id="id63" name="id63">2.16   Comments</a></li> +<li><a class="reference" href="#raw-text" id="id64" name="id64">2.17   Raw text</a></li> +<li><a class="reference" href="#colspanning-tables" id="id65" name="id65">2.18   Colspanning tables</a></li> +<li><a class="reference" href="#rowspanning-tables" id="id66" name="id66">2.19   Rowspanning tables</a></li> +<li><a class="reference" href="#complex-tables" id="id67" name="id67">2.20   Complex tables</a></li> +<li><a class="reference" href="#list-tables" id="id68" name="id68">2.21   List Tables</a></li> </ul> </li> -<li><a class="reference" href="#error-handling" id="id64" name="id64">3   Error Handling</a></li> +<li><a class="reference" href="#error-handling" id="id69" name="id69">3   Error Handling</a></li> </ul> </div> <div class="section"> -<h1><a class="toc-backref" href="#id27" id="structural-elements" name="structural-elements">1   Structural Elements</a></h1> +<h1><a class="toc-backref" href="#id32" id="structural-elements" name="structural-elements">1   Structural Elements</a></h1> <div class="section"> -<h2 class="with-subtitle"><a class="toc-backref" href="#id28" id="section-title" name="section-title">1.1   Section Title</a></h2> +<h2 class="with-subtitle"><a class="toc-backref" href="#id33" id="section-title" name="section-title">1.1   Section Title</a></h2> <h2 class="section-subtitle" id="section-subtitle"><span class="section-subtitle">Section Subtitle</span></h2> <p>That's it, the text just above this line.</p> </div> <div class="section"> -<h2><a class="toc-backref" href="#id29" id="empty-section" name="empty-section">1.2   Empty Section</a></h2> +<h2><a class="toc-backref" href="#id34" id="empty-section" name="empty-section">1.2   Empty Section</a></h2> </div> <div class="section"> -<h2><a class="toc-backref" href="#id30" id="transitions" name="transitions">1.3   Transitions</a></h2> +<h2><a class="toc-backref" href="#id35" id="transitions" name="transitions">1.3   Transitions</a></h2> <p>Here's a transition:</p> <hr class="docutils" /> <p>It divides the section. Transitions may also occur between sections:</p> @@ -157,25 +157,25 @@ They are transformed from section titles after parsing. --> </div> <hr class="docutils" /> <div class="section"> -<h1><a class="toc-backref" href="#id31" id="body-elements" name="body-elements">2   Body Elements</a></h1> +<h1><a class="toc-backref" href="#id36" id="body-elements" name="body-elements">2   Body Elements</a></h1> <div class="section"> -<h2><a class="toc-backref" href="#id32" id="paragraphs" name="paragraphs">2.1   Paragraphs</a></h2> +<h2><a class="toc-backref" href="#id37" id="paragraphs" name="paragraphs">2.1   Paragraphs</a></h2> <p>A paragraph.</p> <div class="section"> -<h3><a class="toc-backref" href="#id33" id="inline-markup" name="inline-markup">2.1.1   Inline Markup</a></h3> +<h3><a class="toc-backref" href="#id38" id="inline-markup" name="inline-markup">2.1.1   Inline Markup</a></h3> <p>Paragraphs contain text and may contain inline markup: <em>emphasis</em>, <strong>strong emphasis</strong>, <tt class="docutils literal"><span class="pre">inline</span> <span class="pre">literals</span></tt>, standalone hyperlinks -(<a class="reference" href="http://www.python.org">http://www.python.org</a>), external hyperlinks (<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id23" id="id24" name="id24">[5]</a>), internal +(<a class="reference" href="http://www.python.org">http://www.python.org</a>), external hyperlinks (<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id25" id="id26" name="id26">[5]</a>), internal cross-references (<a class="reference" href="#example">example</a>), external hyperlinks with embedded URIs -(<a class="reference" href="http://www.python.org">Python web site</a>), footnote references -(manually numbered <a class="footnote-reference" href="#id6" id="id1" name="id1">[1]</a>, anonymous auto-numbered <a class="footnote-reference" href="#id9" id="id2" name="id2">[3]</a>, labeled -auto-numbered <a class="footnote-reference" href="#label" id="id3" name="id3">[2]</a>, or symbolic <a class="footnote-reference" href="#id10" id="id4" name="id4">[*]</a>), citation references -(<a class="citation-reference" href="#cit2002" id="id5" name="id5">[CIT2002]</a>), substitution references (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" />), and <span class="target" id="inline-hyperlink-targets">inline -hyperlink targets</span> (see <a class="reference" href="#id20">Targets</a> below for a reference back to here). -Character-level inline markup is also possible (although exceedingly -ugly!) in <em>re</em><tt class="docutils literal"><span class="pre">Structured</span></tt><em>Text</em>. Problems are indicated by -<a href="#id21" name="id22"><span class="problematic" id="id22">|problematic|</span></a> text (generated by processing errors; this one is -intentional). Here is a reference to the <a class="reference" href="#doctitle">doctitle</a> and the <a class="reference" href="#subtitle">subtitle</a>.</p> +(<a class="reference" href="http://www.python.org">Python web site</a>), <a class="reference" href="http://www.python.org/">anonymous hyperlink +references</a> <a class="footnote-reference" href="#id25" id="id29" name="id29">[5]</a> (<a class="reference" href="http://docutils.sourceforge.net/">a second reference</a> <a class="footnote-reference" href="#id30" id="id31" name="id31">[6]</a>), footnote references (manually +numbered <a class="footnote-reference" href="#id8" id="id1" name="id1">[1]</a>, anonymous auto-numbered <a class="footnote-reference" href="#id11" id="id2" name="id2">[3]</a>, labeled auto-numbered +<a class="footnote-reference" href="#label" id="id3" name="id3">[2]</a>, or symbolic <a class="footnote-reference" href="#id12" id="id4" name="id4">[*]</a>), citation references (<a class="citation-reference" href="#cit2002" id="id5" name="id5">[CIT2002]</a>), +substitution references (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" />), and <span class="target" id="inline-hyperlink-targets">inline hyperlink targets</span> +(see <a class="reference" href="#id22">Targets</a> below for a reference back to here). Character-level +inline markup is also possible (although exceedingly ugly!) in <em>re</em><tt class="docutils literal"><span class="pre">Structured</span></tt><em>Text</em>. Problems are indicated by <a href="#id23" name="id24"><span class="problematic" id="id24">|problematic|</span></a> text +(generated by processing errors; this one is intentional). Here is a +reference to the <a class="reference" href="#doctitle">doctitle</a> and the <a class="reference" href="#subtitle">subtitle</a>.</p> <p>The default role for interpreted text is <cite>Title Reference</cite>. Here are some explicit interpreted text roles: a PEP reference (<a class="reference" href="http://www.python.org/peps/pep-0287.html">PEP 287</a>); an RFC reference (<a class="reference" href="http://www.faqs.org/rfcs/rfc2822.html">RFC 2822</a>); a <sub>subscript</sub>; a <sup>superscript</sup>; @@ -193,7 +193,7 @@ live link to PEP 258 here.</p> </div> </div> <div class="section"> -<h2><a class="toc-backref" href="#id34" id="bullet-lists" name="bullet-lists">2.2   Bullet Lists</a></h2> +<h2><a class="toc-backref" href="#id39" id="bullet-lists" name="bullet-lists">2.2   Bullet Lists</a></h2> <ul> <li><p class="first">A bullet list</p> <ul class="simple"> @@ -218,7 +218,7 @@ live link to PEP 258 here.</p> </ul> </div> <div class="section"> -<h2><a class="toc-backref" href="#id35" id="enumerated-lists" name="enumerated-lists">2.3   Enumerated Lists</a></h2> +<h2><a class="toc-backref" href="#id40" id="enumerated-lists" name="enumerated-lists">2.3   Enumerated Lists</a></h2> <ol class="arabic"> <li><p class="first">Arabic numerals.</p> <ol class="loweralpha simple"> @@ -251,7 +251,7 @@ live link to PEP 258 here.</p> </ol> </div> <div class="section"> -<h2><a class="toc-backref" href="#id36" id="definition-lists" name="definition-lists">2.4   Definition Lists</a></h2> +<h2><a class="toc-backref" href="#id41" id="definition-lists" name="definition-lists">2.4   Definition Lists</a></h2> <dl class="docutils"> <dt>Term</dt> <dd>Definition</dd> @@ -266,7 +266,7 @@ live link to PEP 258 here.</p> </dl> </div> <div class="section"> -<h2><a class="toc-backref" href="#id37" id="field-lists" name="field-lists">2.5   Field Lists</a></h2> +<h2><a class="toc-backref" href="#id42" id="field-lists" name="field-lists">2.5   Field Lists</a></h2> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> @@ -290,7 +290,7 @@ doesn't get stripped away.)</p> </table> </div> <div class="section"> -<h2><a class="toc-backref" href="#id38" id="option-lists" name="option-lists">2.6   Option Lists</a></h2> +<h2><a class="toc-backref" href="#id43" id="option-lists" name="option-lists">2.6   Option Lists</a></h2> <p>For listing command-line options:</p> <table class="docutils option-list" frame="void" rules="none"> <col class="option" /> @@ -336,7 +336,7 @@ regardless of where it starts.</p> description.</p> </div> <div class="section"> -<h2><a class="toc-backref" href="#id39" id="literal-blocks" name="literal-blocks">2.7   Literal Blocks</a></h2> +<h2><a class="toc-backref" href="#id44" id="literal-blocks" name="literal-blocks">2.7   Literal Blocks</a></h2> <p>Literal blocks are indicated with a double-colon ("::") at the end of the preceding paragraph (over there <tt class="docutils literal"><span class="pre">--></span></tt>). They can be indented:</p> <pre class="literal-block"> @@ -353,7 +353,7 @@ if literal_block: </pre> </div> <div class="section"> -<h2><a class="toc-backref" href="#id40" id="line-blocks" name="line-blocks">2.8   Line Blocks</a></h2> +<h2><a class="toc-backref" href="#id45" id="line-blocks" name="line-blocks">2.8   Line Blocks</a></h2> <p>This section tests line blocks. Line blocks are body elements which consist of lines and other line blocks. Nested line blocks cause indentation.</p> @@ -412,7 +412,7 @@ the left edge of the text above it.</div> </blockquote> </div> <div class="section"> -<h2><a class="toc-backref" href="#id41" id="block-quotes" name="block-quotes">2.9   Block Quotes</a></h2> +<h2><a class="toc-backref" href="#id46" id="block-quotes" name="block-quotes">2.9   Block Quotes</a></h2> <p>Block quotes consist of indented body elements:</p> <blockquote> <p>My theory by A. Elk. Brackets Miss, brackets. This theory goes @@ -424,7 +424,7 @@ own it, and what it is too.</p> </blockquote> </div> <div class="section"> -<h2><a class="toc-backref" href="#id42" id="doctest-blocks" name="doctest-blocks">2.10   Doctest Blocks</a></h2> +<h2><a class="toc-backref" href="#id47" id="doctest-blocks" name="doctest-blocks">2.10   Doctest Blocks</a></h2> <pre class="doctest-block"> >>> print 'Python-specific usage examples; begun with ">>>"' Python-specific usage examples; begun with ">>>" @@ -433,11 +433,11 @@ Python-specific usage examples; begun with ">>>" </pre> </div> <div class="section"> -<h2><a class="toc-backref" href="#id43" id="footnotes" name="footnotes">2.11   Footnotes</a></h2> -<table class="docutils footnote" frame="void" id="id6" rules="none"> +<h2><a class="toc-backref" href="#id48" id="footnotes" name="footnotes">2.11   Footnotes</a></h2> +<table class="docutils footnote" frame="void" id="id8" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a name="id6">[1]</a></td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id7">2</a>, <a class="fn-backref" href="#id19">3</a>)</em> <p>A footnote contains body elements, consistently indented by at +<tr><td class="label"><a name="id8">[1]</a></td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id9">2</a>, <a class="fn-backref" href="#id21">3</a>)</em> <p>A footnote contains body elements, consistently indented by at least 3 spaces.</p> <p class="last">This is the footnote's second paragraph.</p> </td></tr> @@ -446,107 +446,107 @@ least 3 spaces.</p> <table class="docutils footnote" frame="void" id="label" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a name="label">[2]</a></td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id8">2</a>)</em> Footnotes may be numbered, either manually (as in <a class="footnote-reference" href="#id6" id="id7" name="id7">[1]</a>) or +<tr><td class="label"><a name="label">[2]</a></td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id10">2</a>)</em> Footnotes may be numbered, either manually (as in <a class="footnote-reference" href="#id8" id="id9" name="id9">[1]</a>) or automatically using a "#"-prefixed label. This footnote has a label so it can be referred to from multiple places, both as a -footnote reference (<a class="footnote-reference" href="#label" id="id8" name="id8">[2]</a>) and as a hyperlink reference +footnote reference (<a class="footnote-reference" href="#label" id="id10" name="id10">[2]</a>) and as a hyperlink reference (<a class="reference" href="#label">label</a>).</td></tr> </tbody> </table> -<table class="docutils footnote" frame="void" id="id9" rules="none"> +<table class="docutils footnote" frame="void" id="id11" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id2" name="id9">[3]</a></td><td><p class="first">This footnote is numbered automatically and anonymously using a +<tr><td class="label"><a class="fn-backref" href="#id2" name="id11">[3]</a></td><td><p class="first">This footnote is numbered automatically and anonymously using a label of "#" only.</p> <p>This is the second paragraph.</p> <p class="last">And this is the third paragraph.</p> </td></tr> </tbody> </table> -<table class="docutils footnote" frame="void" id="id10" rules="none"> +<table class="docutils footnote" frame="void" id="id12" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id4" name="id10">[*]</a></td><td>Footnotes may also use symbols, specified with a "*" label. -Here's a reference to the next footnote: <a class="footnote-reference" href="#id12" id="id11" name="id11">[†]</a>.</td></tr> +<tr><td class="label"><a class="fn-backref" href="#id4" name="id12">[*]</a></td><td>Footnotes may also use symbols, specified with a "*" label. +Here's a reference to the next footnote: <a class="footnote-reference" href="#id14" id="id13" name="id13">[†]</a>.</td></tr> </tbody> </table> -<table class="docutils footnote" frame="void" id="id12" rules="none"> +<table class="docutils footnote" frame="void" id="id14" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id11" name="id12">[†]</a></td><td>This footnote shows the next symbol in the sequence.</td></tr> +<tr><td class="label"><a class="fn-backref" href="#id13" name="id14">[†]</a></td><td>This footnote shows the next symbol in the sequence.</td></tr> </tbody> </table> -<table class="docutils footnote" frame="void" id="id13" rules="none"> +<table class="docutils footnote" frame="void" id="id15" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a name="id13">[4]</a></td><td>Here's an unreferenced footnote, with a reference to a -nonexistent footnote: <a href="#id73" name="id74"><span class="problematic" id="id74"><span id="id14"></span>[5]_</span></a>.</td></tr> +<tr><td class="label"><a name="id15">[4]</a></td><td>Here's an unreferenced footnote, with a reference to a +nonexistent footnote: <a href="#id78" name="id79"><span class="problematic" id="id79"><span id="id16"></span>[5]_</span></a>.</td></tr> </tbody> </table> </div> <div class="section"> -<h2><a class="toc-backref" href="#id44" id="citations" name="citations">2.12   Citations</a></h2> +<h2><a class="toc-backref" href="#id49" id="citations" name="citations">2.12   Citations</a></h2> <table class="docutils citation" frame="void" id="cit2002" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a name="cit2002">[CIT2002]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id15">2</a>)</em> Citations are text-labeled footnotes. They may be +<tr><td class="label"><a name="cit2002">[CIT2002]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id17">2</a>)</em> Citations are text-labeled footnotes. They may be rendered separately and differently from footnotes.</td></tr> </tbody> </table> -<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id75" name="id76"><span class="problematic" id="id76"><span id="id16"></span>[nonexistent]_</span></a> +<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id17" name="id17">[CIT2002]</a>, and a <a href="#id80" name="id81"><span class="problematic" id="id81"><span id="id18"></span>[nonexistent]_</span></a> citation.</p> </div> <div class="section"> -<h2><a class="toc-backref" href="#id45" id="targets" name="targets"><span id="another-target"></span>2.13   Targets</a></h2> +<h2><a class="toc-backref" href="#id50" id="targets" name="targets"><span id="another-target"></span>2.13   Targets</a></h2> <p id="example">This paragraph is pointed to by the explicit "example" target. A reference can be found under <a class="reference" href="#inline-markup">Inline Markup</a>, above. <a class="reference" href="#inline-hyperlink-targets">Inline hyperlink targets</a> are also possible.</p> <p>Section headers are implicit targets, referred to by name. See -<a class="reference" href="#id20">Targets</a>, which is a subsection of <a class="reference" href="#body-elements">Body Elements</a>.</p> +<a class="reference" href="#id22">Targets</a>, which is a subsection of <a class="reference" href="#body-elements">Body Elements</a>.</p> <p>Explicit external targets are interpolated into references such as -"<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id23" id="id25" name="id25">[5]</a>".</p> -<p>Targets may be indirect and anonymous. Thus <a class="reference" href="#id20">this phrase</a> may also -refer to the <a class="reference" href="#id20">Targets</a> section.</p> -<p>Here's a <a href="#id77" name="id78"><span class="problematic" id="id78">`hyperlink reference without a target`_</span></a>, which generates an +"<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id25" id="id27" name="id27">[5]</a>".</p> +<p>Targets may be indirect and anonymous. Thus <a class="reference" href="#id22">this phrase</a> may also +refer to the <a class="reference" href="#id22">Targets</a> section.</p> +<p>Here's a <a href="#id82" name="id83"><span class="problematic" id="id83">`hyperlink reference without a target`_</span></a>, which generates an error.</p> <div class="section"> -<h3><a class="toc-backref" href="#id46" id="duplicate-target-names" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> +<h3><a class="toc-backref" href="#id51" id="duplicate-target-names" name="duplicate-target-names">2.13.1   Duplicate Target Names</a></h3> <p>Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages.</p> </div> <div class="section"> -<h3><a class="toc-backref" href="#id47" id="id18" name="id18">2.13.2   Duplicate Target Names</a></h3> +<h3><a class="toc-backref" href="#id52" id="id20" name="id20">2.13.2   Duplicate Target Names</a></h3> <p>Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: <a href="#id79" name="id80"><span class="problematic" id="id80">`Duplicate Target Names`_</span></a>), an error is generated.</p> +this: <a href="#id84" name="id85"><span class="problematic" id="id85">`Duplicate Target Names`_</span></a>), an error is generated.</p> </div> </div> <div class="section"> -<h2><a class="toc-backref" href="#id48" id="directives" name="directives">2.14   Directives</a></h2> +<h2><a class="toc-backref" href="#id53" id="directives" name="directives">2.14   Directives</a></h2> <div class="contents local topic"> <ul class="auto-toc simple"> -<li><a class="reference" href="#document-parts" id="id65" name="id65">2.14.1   Document Parts</a></li> -<li><a class="reference" href="#images" id="id66" name="id66">2.14.2   Images</a></li> -<li><a class="reference" href="#admonitions" id="id67" name="id67">2.14.3   Admonitions</a></li> -<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id68" name="id68">2.14.4   Topics, Sidebars, and Rubrics</a></li> -<li><a class="reference" href="#target-footnotes" id="id69" name="id69">2.14.5   Target Footnotes</a></li> -<li><a class="reference" href="#replacement-text" id="id70" name="id70">2.14.6   Replacement Text</a></li> -<li><a class="reference" href="#compound-paragraph" id="id71" name="id71">2.14.7   Compound Paragraph</a></li> -<li><a class="reference" href="#parsed-literal-blocks" id="id72" name="id72">2.14.8   Parsed Literal Blocks</a></li> +<li><a class="reference" href="#document-parts" id="id70" name="id70">2.14.1   Document Parts</a></li> +<li><a class="reference" href="#images" id="id71" name="id71">2.14.2   Images</a></li> +<li><a class="reference" href="#admonitions" id="id72" name="id72">2.14.3   Admonitions</a></li> +<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id73" name="id73">2.14.4   Topics, Sidebars, and Rubrics</a></li> +<li><a class="reference" href="#target-footnotes" id="id74" name="id74">2.14.5   Target Footnotes</a></li> +<li><a class="reference" href="#replacement-text" id="id75" name="id75">2.14.6   Replacement Text</a></li> +<li><a class="reference" href="#compound-paragraph" id="id76" name="id76">2.14.7   Compound Paragraph</a></li> +<li><a class="reference" href="#parsed-literal-blocks" id="id77" name="id77">2.14.8   Parsed Literal Blocks</a></li> </ul> </div> <p>These are just a sample of the many reStructuredText Directives. For others, please see <a class="reference" href="http://docutils.sourceforge.net/docs/ref/rst/directives.html">http://docutils.sourceforge.net/docs/ref/rst/directives.html</a>.</p> <div class="section"> -<h3><a class="toc-backref" href="#id65" id="document-parts" name="document-parts">2.14.1   Document Parts</a></h3> +<h3><a class="toc-backref" href="#id70" id="document-parts" name="document-parts">2.14.1   Document Parts</a></h3> <p>An example of the "contents" directive can be seen above this section (a local, untitled table of <a class="reference" href="#contents">contents</a>) and at the beginning of the document (a document-wide <a class="reference" href="#table-of-contents">table of contents</a>).</p> </div> <div class="section"> -<h3><a class="toc-backref" href="#id66" id="images" name="images">2.14.2   Images</a></h3> +<h3><a class="toc-backref" href="#id71" id="images" name="images">2.14.2   Images</a></h3> <p>An image directive (also clickable -- a hyperlink reference):</p> <a class="reference image-reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a> <p>Image with multiple IDs:</p> @@ -614,7 +614,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <img alt="../../../docs/user/rst/images/biohazard.png" src="../../../docs/user/rst/images/biohazard.png" style="height: 3cm;" /> </div> <div class="section"> -<h3><a class="toc-backref" href="#id67" id="admonitions" name="admonitions">2.14.3   Admonitions</a></h3> +<h3><a class="toc-backref" href="#id72" id="admonitions" name="admonitions">2.14.3   Admonitions</a></h3> <div class="attention"> <p class="first admonition-title">Attention!</p> <p class="last">Directives at large.</p> @@ -663,7 +663,7 @@ Reader discretion is strongly advised.</p> </div> </div> <div class="section"> -<h3><a class="toc-backref" href="#id68" id="topics-sidebars-and-rubrics" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> +<h3><a class="toc-backref" href="#id73" id="topics-sidebars-and-rubrics" name="topics-sidebars-and-rubrics">2.14.4   Topics, Sidebars, and Rubrics</a></h3> <div class="sidebar"> <p class="first sidebar-title">Sidebar Title</p> <p class="sidebar-subtitle">Optional Subtitle</p> @@ -680,20 +680,26 @@ background color.</p> <p class="rubric">This is a rubric</p> </div> <div class="section"> -<h3><a class="toc-backref" href="#id69" id="target-footnotes" name="target-footnotes">2.14.5   Target Footnotes</a></h3> -<table class="docutils footnote" frame="void" id="id23" rules="none"> +<h3><a class="toc-backref" href="#id74" id="target-footnotes" name="target-footnotes">2.14.5   Target Footnotes</a></h3> +<table class="docutils footnote" frame="void" id="id25" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a name="id25">[5]</a></td><td><em>(<a class="fn-backref" href="#id26">1</a>, <a class="fn-backref" href="#id27">2</a>, <a class="fn-backref" href="#id28">3</a>, <a class="fn-backref" href="#id29">4</a>)</em> <a class="reference" href="http://www.python.org/">http://www.python.org/</a></td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="id30" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a name="id23">[5]</a></td><td><em>(<a class="fn-backref" href="#id24">1</a>, <a class="fn-backref" href="#id25">2</a>, <a class="fn-backref" href="#id26">3</a>)</em> <a class="reference" href="http://www.python.org/">http://www.python.org/</a></td></tr> +<tr><td class="label"><a class="fn-backref" href="#id31" name="id30">[6]</a></td><td><a class="reference" href="http://docutils.sourceforge.net/">http://docutils.sourceforge.net/</a></td></tr> </tbody> </table> </div> <div class="section"> -<h3><a class="toc-backref" href="#id70" id="replacement-text" name="replacement-text">2.14.6   Replacement Text</a></h3> -<p>I recommend you try <a class="reference" href="http://www.python.org/">Python, <em>the</em> best language around</a> <a class="footnote-reference" href="#id23" id="id26" name="id26">[5]</a>.</p> +<h3><a class="toc-backref" href="#id75" id="replacement-text" name="replacement-text">2.14.6   Replacement Text</a></h3> +<p>I recommend you try <a class="reference" href="http://www.python.org/">Python, <em>the</em> best language around</a> <a class="footnote-reference" href="#id25" id="id28" name="id28">[5]</a>.</p> </div> <div class="section"> -<h3><a class="toc-backref" href="#id71" id="compound-paragraph" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> +<h3><a class="toc-backref" href="#id76" id="compound-paragraph" name="compound-paragraph">2.14.7   Compound Paragraph</a></h3> <div class="some-class compound"> <p class="compound-first">Compound 1, paragraph 1.</p> <p class="compound-middle">Compound 1, paragraph 2.</p> @@ -761,23 +767,23 @@ paragraph.</td> </div> </div> <div class="section"> -<h3><a class="toc-backref" href="#id72" id="parsed-literal-blocks" name="parsed-literal-blocks">2.14.8   Parsed Literal Blocks</a></h3> +<h3><a class="toc-backref" href="#id77" id="parsed-literal-blocks" name="parsed-literal-blocks">2.14.8   Parsed Literal Blocks</a></h3> <pre class="literal-block"> This is a parsed literal block. This line is indented. The next line is blank. Inline markup is supported, e.g. <em>emphasis</em>, <strong>strong</strong>, <tt class="docutils literal"><span class="pre">literal</span> -<span class="pre">text</span></tt>, footnotes <a class="footnote-reference" href="#id6" id="id19" name="id19">[1]</a>, <span class="target" id="id20">targets</span>, and <a class="reference" href="http://www.python.org/">references</a>. +<span class="pre">text</span></tt>, footnotes <a class="footnote-reference" href="#id8" id="id21" name="id21">[1]</a>, <span class="target" id="id22">targets</span>, and <a class="reference" href="http://www.python.org/">references</a>. </pre> </div> </div> <div class="section"> -<h2><a class="toc-backref" href="#id57" id="substitution-definitions" name="substitution-definitions">2.15   Substitution Definitions</a></h2> +<h2><a class="toc-backref" href="#id62" id="substitution-definitions" name="substitution-definitions">2.15   Substitution Definitions</a></h2> <p>An inline image (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" />) example:</p> <p>(Substitution definitions are not visible in the HTML source.)</p> </div> <div class="section"> -<h2><a class="toc-backref" href="#id58" id="comments" name="comments">2.16   Comments</a></h2> +<h2><a class="toc-backref" href="#id63" id="comments" name="comments">2.16   Comments</a></h2> <p>Here's one:</p> <!-- Comments begin with two dots and a space. Anything may follow, except for the syntax of footnotes, hyperlink @@ -787,13 +793,13 @@ Double-dashes - - "- -" - - must be escaped somehow in HTML output. --> <p>(View the HTML source to see the comment.)</p> </div> <div class="section"> -<h2><a class="toc-backref" href="#id59" id="raw-text" name="raw-text">2.17   Raw text</a></h2> +<h2><a class="toc-backref" href="#id64" id="raw-text" name="raw-text">2.17   Raw text</a></h2> <p>This does not necessarily look nice, because there may be missing white space.</p> <p>It's just there to freeze the behavior.</p> A test.Second test.<div class="myclass">Another test with myclass set.</div><p>This is the <span class="myrawroleclass">fourth test</span> with myrawroleclass set.</p> Fifth test in HTML.<br />Line two.</div> <div class="section"> -<h2><a class="toc-backref" href="#id60" id="colspanning-tables" name="colspanning-tables">2.18   Colspanning tables</a></h2> +<h2><a class="toc-backref" href="#id65" id="colspanning-tables" name="colspanning-tables">2.18   Colspanning tables</a></h2> <p>This table has a cell spanning two columns:</p> <table border="1" class="docutils"> <colgroup> @@ -831,7 +837,7 @@ Fifth test in HTML.<br />Line two.</div> </table> </div> <div class="section"> -<h2><a class="toc-backref" href="#id61" id="rowspanning-tables" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> +<h2><a class="toc-backref" href="#id66" id="rowspanning-tables" name="rowspanning-tables">2.19   Rowspanning tables</a></h2> <p>Here's a table with cells spanning several rows:</p> <table border="1" class="docutils"> <colgroup> @@ -864,7 +870,7 @@ cell.</td> </table> </div> <div class="section"> -<h2><a class="toc-backref" href="#id62" id="complex-tables" name="complex-tables">2.20   Complex tables</a></h2> +<h2><a class="toc-backref" href="#id67" id="complex-tables" name="complex-tables">2.20   Complex tables</a></h2> <p>Here's a complex table, which should test all features.</p> <table border="1" class="docutils"> <colgroup> @@ -913,7 +919,7 @@ empty: <tt class="docutils literal"><span class="pre">--></span></tt></td> </table> </div> <div class="section"> -<h2><a class="toc-backref" href="#id63" id="list-tables" name="list-tables">2.21   List Tables</a></h2> +<h2><a class="toc-backref" href="#id68" id="list-tables" name="list-tables">2.21   List Tables</a></h2> <p>Here's a list table exercising all features:</p> <table border="1" class="test docutils"> <caption>list table with integral header</caption> @@ -947,7 +953,7 @@ crunchy, now would it?</td> </div> </div> <div class="section"> -<h1><a class="toc-backref" href="#id64" id="error-handling" name="error-handling">3   Error Handling</a></h1> +<h1><a class="toc-backref" href="#id69" id="error-handling" name="error-handling">3   Error Handling</a></h1> <p>Any errors caught during processing will generate system messages.</p> <p>There should be five messages in the following, auto-generated section, "Docutils System Messages":</p> @@ -955,20 +961,20 @@ section, "Docutils System Messages":</p> </div> <div class="system-messages section"> <h1><a>Docutils System Messages</a></h1> -<div class="system-message" id="id21"> -<p class="system-message-title">System Message: <a name="id21">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 100); <em><a href="#id22">backlink</a></em></p> +<div class="system-message" id="id23"> +<p class="system-message-title">System Message: <a name="id23">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 100); <em><a href="#id24">backlink</a></em></p> Undefined substitution referenced: "problematic".</div> -<div class="system-message" id="id73"> -<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 354); <em><a href="#id74">backlink</a></em></p> +<div class="system-message" id="id78"> +<p class="system-message-title">System Message: <a name="id78">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 358); <em><a href="#id79">backlink</a></em></p> Unknown target name: "5".</div> -<div class="system-message" id="id75"> -<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 363); <em><a href="#id76">backlink</a></em></p> +<div class="system-message" id="id80"> +<p class="system-message-title">System Message: <a name="id80">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 367); <em><a href="#id81">backlink</a></em></p> Unknown target name: "nonexistent".</div> -<div class="system-message" id="id77"> -<p class="system-message-title">System Message: <a name="id77">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 390); <em><a href="#id78">backlink</a></em></p> +<div class="system-message" id="id82"> +<p class="system-message-title">System Message: <a name="id82">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 394); <em><a href="#id83">backlink</a></em></p> Unknown target name: "hyperlink reference without a target".</div> -<div class="system-message" id="id79"> -<p class="system-message-title">System Message: <a name="id79">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 403); <em><a href="#id80">backlink</a></em></p> +<div class="system-message" id="id84"> +<p class="system-message-title">System Message: <a name="id84">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 407); <em><a href="#id85">backlink</a></em></p> Duplicate target name, cannot be used as a unique reference: "duplicate target names".</div> </div> </div> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 0a5aec391..4f318f90a 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -178,7 +178,7 @@ reStructuredText construct. \begin{list}{}{} \item {} \href{\#duplicate-target-names}{2.13.1~~~Duplicate Target Names} -\item {} \href{\#id18}{2.13.2~~~Duplicate Target Names} +\item {} \href{\#id20}{2.13.2~~~Duplicate Target Names} \end{list} @@ -298,17 +298,16 @@ A paragraph. Paragraphs contain text and may contain inline markup: \emph{emphasis}, \textbf{strong emphasis}, \texttt{inline literals}, standalone hyperlinks -(\href{http://www.python.org}{http://www.python.org}), external hyperlinks (\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}), internal +(\href{http://www.python.org}{http://www.python.org}), external hyperlinks (\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id25}{5}}), internal cross-references (\href{\#example}{example}), external hyperlinks with embedded URIs -(\href{http://www.python.org}{Python web site}), footnote references -(manually numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id6}{1}}, anonymous auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id9}{3}}, labeled -auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{label}{2}}, or symbolic\raisebox{.5em}[0em]{\scriptsize\hyperlink{id10}{*}}), citation references -([\hyperlink{cit2002}{CIT2002}]), substitution references (\includegraphics{../../../docs/user/rst/images/biohazard.png}), and \hypertarget{inline-hyperlink-targets}{inline -hyperlink targets} (see \href{\#id20}{Targets} below for a reference back to here). -Character-level inline markup is also possible (although exceedingly -ugly!) in \emph{re}\texttt{Structured}\emph{Text}. Problems are indicated by -{\color{red}\bfseries{}{\textbar}problematic{\textbar}} text (generated by processing errors; this one is -intentional). Here is a reference to the \href{\#doctitle}{doctitle} and the \href{\#subtitle}{subtitle}. +(\href{http://www.python.org}{Python web site}), \href{http://www.python.org/}{anonymous hyperlink +references}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id25}{5}} (\href{http://docutils.sourceforge.net/}{a second reference}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id30}{6}}), footnote references (manually +numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id8}{1}}, anonymous auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{id11}{3}}, labeled auto-numbered\raisebox{.5em}[0em]{\scriptsize\hyperlink{label}{2}}, or symbolic\raisebox{.5em}[0em]{\scriptsize\hyperlink{id12}{*}}), citation references ([\hyperlink{cit2002}{CIT2002}]), +substitution references (\includegraphics{../../../docs/user/rst/images/biohazard.png}), and \hypertarget{inline-hyperlink-targets}{inline hyperlink targets} +(see \href{\#id22}{Targets} below for a reference back to here). Character-level +inline markup is also possible (although exceedingly ugly!) in \emph{re}\texttt{Structured}\emph{Text}. Problems are indicated by {\color{red}\bfseries{}{\textbar}problematic{\textbar}} text +(generated by processing errors; this one is intentional). Here is a +reference to the \href{\#doctitle}{doctitle} and the \href{\#subtitle}{subtitle}. The default role for interpreted text is \titlereference{Title Reference}. Here are some explicit interpreted text roles: a PEP reference (\href{http://www.python.org/peps/pep-0287.html}{PEP 287}); an @@ -725,20 +724,20 @@ Python-specific usage examples; begun with ">>>" \hypertarget{footnotes}{} \pdfbookmark[1]{2.11~~~Footnotes}{footnotes} \subsection*{2.11~~~Footnotes} -\begin{figure}[b]\hypertarget{id6}$^{1}$ +\begin{figure}[b]\hypertarget{id8}$^{1}$ A footnote contains body elements, consistently indented by at least 3 spaces. This is the footnote's second paragraph. \end{figure} \begin{figure}[b]\hypertarget{label}$^{2}$ -Footnotes may be numbered, either manually (as in\raisebox{.5em}[0em]{\scriptsize\hyperlink{id6}{1}}) or +Footnotes may be numbered, either manually (as in\raisebox{.5em}[0em]{\scriptsize\hyperlink{id8}{1}}) or automatically using a ``{\#}''-prefixed label. This footnote has a label so it can be referred to from multiple places, both as a footnote reference (\raisebox{.5em}[0em]{\scriptsize\hyperlink{label}{2}}) and as a hyperlink reference (\href{\#label}{label}). \end{figure} -\begin{figure}[b]\hypertarget{id9}$^{3}$ +\begin{figure}[b]\hypertarget{id11}$^{3}$ This footnote is numbered automatically and anonymously using a label of ``{\#}'' only. @@ -746,14 +745,14 @@ This is the second paragraph. And this is the third paragraph. \end{figure} -\begin{figure}[b]\hypertarget{id10}$^{*}$ +\begin{figure}[b]\hypertarget{id12}$^{*}$ Footnotes may also use symbols, specified with a ``*'' label. -Here's a reference to the next footnote:\raisebox{.5em}[0em]{\scriptsize\hyperlink{id12}{{\dag}}}. +Here's a reference to the next footnote:\raisebox{.5em}[0em]{\scriptsize\hyperlink{id14}{{\dag}}}. \end{figure} -\begin{figure}[b]\hypertarget{id12}$^{{\dag}}$ +\begin{figure}[b]\hypertarget{id14}$^{{\dag}}$ This footnote shows the next symbol in the sequence. \end{figure} -\begin{figure}[b]\hypertarget{id13}$^{4}$ +\begin{figure}[b]\hypertarget{id15}$^{4}$ Here's an unreferenced footnote, with a reference to a nonexistent footnote:{\color{red}\bfseries{}{[}5{]}{\_}}. \end{figure} @@ -786,13 +785,13 @@ reference can be found under \href{\#inline-markup}{Inline Markup}, above. \href hyperlink targets} are also possible. Section headers are implicit targets, referred to by name. See -\href{\#id20}{Targets}, which is a subsection of \href{\#body-elements}{Body Elements}. +\href{\#id22}{Targets}, which is a subsection of \href{\#body-elements}{Body Elements}. Explicit external targets are interpolated into references such as -``\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}''. +``\href{http://www.python.org/}{Python}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id25}{5}}''. -Targets may be indirect and anonymous. Thus \href{\#id20}{this phrase} may also -refer to the \href{\#id20}{Targets} section. +Targets may be indirect and anonymous. Thus \href{\#id22}{this phrase} may also +refer to the \href{\#id22}{Targets} section. Here's a {\color{red}\bfseries{}`hyperlink reference without a target`{\_}}, which generates an error. @@ -811,8 +810,8 @@ explicit targets will generate ``warning'' (level-2) system messages. %___________________________________________________________________________ -\hypertarget{id18}{} -\pdfbookmark[2]{2.13.2~~~Duplicate Target Names}{id18} +\hypertarget{id20}{} +\pdfbookmark[2]{2.13.2~~~Duplicate Target Names}{id20} \subsubsection*{2.13.2~~~Duplicate Target Names} Since there are two ``Duplicate Target Names'' section headers, we @@ -1109,9 +1108,12 @@ This is a topic. \hypertarget{target-footnotes}{} \pdfbookmark[2]{2.14.5~~~Target Footnotes}{target-footnotes} \subsubsection*{2.14.5~~~Target Footnotes} -\begin{figure}[b]\hypertarget{id23}$^{5}$ +\begin{figure}[b]\hypertarget{id25}$^{5}$ \href{http://www.python.org/}{http://www.python.org/} \end{figure} +\begin{figure}[b]\hypertarget{id30}$^{6}$ +\href{http://docutils.sourceforge.net/}{http://docutils.sourceforge.net/} +\end{figure} %___________________________________________________________________________ @@ -1120,7 +1122,7 @@ This is a topic. \pdfbookmark[2]{2.14.6~~~Replacement Text}{replacement-text} \subsubsection*{2.14.6~~~Replacement Text} -I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id23}{5}}. +I recommend you try \href{http://www.python.org/}{Python, \emph{the} best language around}\raisebox{.5em}[0em]{\scriptsize\hyperlink{id25}{5}}. %___________________________________________________________________________ @@ -1207,7 +1209,7 @@ This~is~a~parsed~literal~block.~\\ ~~~~This~line~is~indented.~~The~next~line~is~blank.~\\ ~\\ Inline~markup~is~supported,~e.g.~\emph{emphasis},~\textbf{strong},~\texttt{literal~\\ -text},~footnotes\raisebox{.5em}[0em]{\scriptsize\hyperlink{id6}{1}},~\hypertarget{id20}{targets},~and~\href{http://www.python.org/}{references}. +text},~footnotes\raisebox{.5em}[0em]{\scriptsize\hyperlink{id8}{1}},~\hypertarget{id22}{targets},~and~\href{http://www.python.org/}{references}. }\end{quote} diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index ac3fc98a7..6af1c9ded 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -91,244 +91,244 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id27" refid="structural-elements"> + <reference ids="id32" refid="structural-elements"> <generated classes="sectnum"> 1    Structural Elements <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id28" refid="section-title"> + <reference ids="id33" refid="section-title"> <generated classes="sectnum"> 1.1    Section Title <list_item> <paragraph> - <reference ids="id29" refid="empty-section"> + <reference ids="id34" refid="empty-section"> <generated classes="sectnum"> 1.2    Empty Section <list_item> <paragraph> - <reference ids="id30" refid="transitions"> + <reference ids="id35" refid="transitions"> <generated classes="sectnum"> 1.3    Transitions <list_item> <paragraph> - <reference ids="id31" refid="body-elements"> + <reference ids="id36" refid="body-elements"> <generated classes="sectnum"> 2    Body Elements <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id32" refid="paragraphs"> + <reference ids="id37" refid="paragraphs"> <generated classes="sectnum"> 2.1    Paragraphs <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id33" refid="inline-markup"> + <reference ids="id38" refid="inline-markup"> <generated classes="sectnum"> 2.1.1    Inline Markup <list_item> <paragraph> - <reference ids="id34" refid="bullet-lists"> + <reference ids="id39" refid="bullet-lists"> <generated classes="sectnum"> 2.2    Bullet Lists <list_item> <paragraph> - <reference ids="id35" refid="enumerated-lists"> + <reference ids="id40" refid="enumerated-lists"> <generated classes="sectnum"> 2.3    Enumerated Lists <list_item> <paragraph> - <reference ids="id36" refid="definition-lists"> + <reference ids="id41" refid="definition-lists"> <generated classes="sectnum"> 2.4    Definition Lists <list_item> <paragraph> - <reference ids="id37" refid="field-lists"> + <reference ids="id42" refid="field-lists"> <generated classes="sectnum"> 2.5    Field Lists <list_item> <paragraph> - <reference ids="id38" refid="option-lists"> + <reference ids="id43" refid="option-lists"> <generated classes="sectnum"> 2.6    Option Lists <list_item> <paragraph> - <reference ids="id39" refid="literal-blocks"> + <reference ids="id44" refid="literal-blocks"> <generated classes="sectnum"> 2.7    Literal Blocks <list_item> <paragraph> - <reference ids="id40" refid="line-blocks"> + <reference ids="id45" refid="line-blocks"> <generated classes="sectnum"> 2.8    Line Blocks <list_item> <paragraph> - <reference ids="id41" refid="block-quotes"> + <reference ids="id46" refid="block-quotes"> <generated classes="sectnum"> 2.9    Block Quotes <list_item> <paragraph> - <reference ids="id42" refid="doctest-blocks"> + <reference ids="id47" refid="doctest-blocks"> <generated classes="sectnum"> 2.10    Doctest Blocks <list_item> <paragraph> - <reference ids="id43" refid="footnotes"> + <reference ids="id48" refid="footnotes"> <generated classes="sectnum"> 2.11    Footnotes <list_item> <paragraph> - <reference ids="id44" refid="citations"> + <reference ids="id49" refid="citations"> <generated classes="sectnum"> 2.12    Citations <list_item> <paragraph> - <reference ids="id45" refid="targets"> + <reference ids="id50" refid="targets"> <generated classes="sectnum"> 2.13    Targets <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id46" refid="duplicate-target-names"> + <reference ids="id51" refid="duplicate-target-names"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names <list_item> <paragraph> - <reference ids="id47" refid="id18"> + <reference ids="id52" refid="id20"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names <list_item> <paragraph> - <reference ids="id48" refid="directives"> + <reference ids="id53" refid="directives"> <generated classes="sectnum"> 2.14    Directives <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id49" refid="document-parts"> + <reference ids="id54" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id50" refid="images"> + <reference ids="id55" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id51" refid="admonitions"> + <reference ids="id56" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id52" refid="topics-sidebars-and-rubrics"> + <reference ids="id57" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id53" refid="target-footnotes"> + <reference ids="id58" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id54" refid="replacement-text"> + <reference ids="id59" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id55" refid="compound-paragraph"> + <reference ids="id60" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph <list_item> <paragraph> - <reference ids="id56" refid="parsed-literal-blocks"> + <reference ids="id61" refid="parsed-literal-blocks"> <generated classes="sectnum"> 2.14.8    Parsed Literal Blocks <list_item> <paragraph> - <reference ids="id57" refid="substitution-definitions"> + <reference ids="id62" refid="substitution-definitions"> <generated classes="sectnum"> 2.15    Substitution Definitions <list_item> <paragraph> - <reference ids="id58" refid="comments"> + <reference ids="id63" refid="comments"> <generated classes="sectnum"> 2.16    Comments <list_item> <paragraph> - <reference ids="id59" refid="raw-text"> + <reference ids="id64" refid="raw-text"> <generated classes="sectnum"> 2.17    Raw text <list_item> <paragraph> - <reference ids="id60" refid="colspanning-tables"> + <reference ids="id65" refid="colspanning-tables"> <generated classes="sectnum"> 2.18    Colspanning tables <list_item> <paragraph> - <reference ids="id61" refid="rowspanning-tables"> + <reference ids="id66" refid="rowspanning-tables"> <generated classes="sectnum"> 2.19    Rowspanning tables <list_item> <paragraph> - <reference ids="id62" refid="complex-tables"> + <reference ids="id67" refid="complex-tables"> <generated classes="sectnum"> 2.20    Complex tables <list_item> <paragraph> - <reference ids="id63" refid="list-tables"> + <reference ids="id68" refid="list-tables"> <generated classes="sectnum"> 2.21    List Tables <list_item> <paragraph> - <reference ids="id64" refid="error-handling"> + <reference ids="id69" refid="error-handling"> <generated classes="sectnum"> 3    Error Handling <section ids="structural-elements" names="structural\ elements"> - <title auto="1" refid="id27"> + <title auto="1" refid="id32"> <generated classes="sectnum"> 1    Structural Elements <section ids="section-title" names="section\ title"> - <title auto="1" refid="id28"> + <title auto="1" refid="id33"> <generated classes="sectnum"> 1.1    Section Title @@ -337,12 +337,12 @@ <paragraph> That's it, the text just above this line. <section ids="empty-section" names="empty\ section"> - <title auto="1" refid="id29"> + <title auto="1" refid="id34"> <generated classes="sectnum"> 1.2    Empty Section <section ids="transitions" names="transitions"> - <title auto="1" refid="id30"> + <title auto="1" refid="id35"> <generated classes="sectnum"> 1.3    Transitions @@ -353,19 +353,19 @@ It divides the section. Transitions may also occur between sections: <transition> <section ids="body-elements" names="body\ elements"> - <title auto="1" refid="id31"> + <title auto="1" refid="id36"> <generated classes="sectnum"> 2    Body Elements <section ids="paragraphs" names="paragraphs"> - <title auto="1" refid="id32"> + <title auto="1" refid="id37"> <generated classes="sectnum"> 2.1    Paragraphs <paragraph> A paragraph. <section ids="inline-markup" names="inline\ markup"> - <title auto="1" refid="id33"> + <title auto="1" refid="id38"> <generated classes="sectnum"> 2.1.1    Inline Markup @@ -387,7 +387,7 @@ <reference name="Python" refuri="http://www.python.org/"> Python - <footnote_reference auto="1" ids="id24" refid="id23"> + <footnote_reference auto="1" ids="id26" refid="id25"> 5 ), internal cross-references ( @@ -397,53 +397,67 @@ ( <reference name="Python web site" refuri="http://www.python.org"> Python web site - ), footnote references - (manually numbered - <footnote_reference ids="id1" refid="id6"> + ), + <reference anonymous="1" name="anonymous hyperlink references" refuri="http://www.python.org/"> + anonymous hyperlink + references + + <footnote_reference auto="1" ids="id29" refid="id25"> + 5 + ( + <reference anonymous="1" name="a second reference" refuri="http://docutils.sourceforge.net/"> + a second reference + + <footnote_reference auto="1" ids="id31" refid="id30"> + 6 + ), footnote references (manually + numbered + <footnote_reference ids="id1" refid="id8"> 1 , anonymous auto-numbered - <footnote_reference auto="1" ids="id2" refid="id9"> + <footnote_reference auto="1" ids="id2" refid="id11"> 3 - , labeled - auto-numbered + , labeled auto-numbered <footnote_reference auto="1" ids="id3" refid="label"> 2 , or symbolic - <footnote_reference auto="*" ids="id4" refid="id10"> + <footnote_reference auto="*" ids="id4" refid="id12"> * - ), citation references - ( + ), citation references ( <citation_reference ids="id5" refid="cit2002"> CIT2002 - ), substitution references ( + ), + substitution references ( <image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"> ), and <target ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets"> - inline - hyperlink targets - (see - <reference name="Targets" refid="id20"> + inline hyperlink targets + + (see + <reference name="Targets" refid="id22"> Targets - below for a reference back to here). - Character-level inline markup is also possible (although exceedingly - ugly!) in + below for a reference back to here). Character-level + inline markup is also possible (although exceedingly ugly!) in <emphasis> re <literal> Structured <emphasis> Text - . Problems are indicated by - <problematic ids="id22" refid="id21"> + . Problems are indicated by + <problematic ids="id24" refid="id23"> |problematic| - text (generated by processing errors; this one is - intentional). Here is a reference to the + text + (generated by processing errors; this one is intentional). Here is a + reference to the <reference name="doctitle" refid="doctitle"> doctitle and the <reference name="subtitle" refid="subtitle"> subtitle . + <target anonymous="1" ids="id6" refuri="http://www.python.org/"> + <target anonymous="1" ids="id7" refuri="http://docutils.sourceforge.net/"> <paragraph> The default role for interpreted text is <title_reference> @@ -490,7 +504,7 @@ option was supplied, there should be a live link to PEP 258 here. <section ids="bullet-lists" names="bullet\ lists"> - <title auto="1" refid="id34"> + <title auto="1" refid="id39"> <generated classes="sectnum"> 2.2    Bullet Lists @@ -534,7 +548,7 @@ <comment xml:space="preserve"> Even if this item contains a target and a comment. <section ids="enumerated-lists" names="enumerated\ lists"> - <title auto="1" refid="id35"> + <title auto="1" refid="id40"> <generated classes="sectnum"> 2.3    Enumerated Lists @@ -583,7 +597,7 @@ <paragraph> iv <section ids="definition-lists" names="definition\ lists"> - <title auto="1" refid="id36"> + <title auto="1" refid="id41"> <generated classes="sectnum"> 2.4    Definition Lists @@ -621,7 +635,7 @@ <paragraph> Definition <section ids="field-lists" names="field\ lists"> - <title auto="1" refid="id37"> + <title auto="1" refid="id42"> <generated classes="sectnum"> 2.5    Field Lists @@ -655,7 +669,7 @@ about credits but just for ensuring that the class attribute doesn't get stripped away.) <section ids="option-lists" names="option\ lists"> - <title auto="1" refid="id38"> + <title auto="1" refid="id43"> <generated classes="sectnum"> 2.6    Option Lists @@ -768,7 +782,7 @@ There must be at least two spaces between the option and the description. <section ids="literal-blocks" names="literal\ blocks"> - <title auto="1" refid="id39"> + <title auto="1" refid="id44"> <generated classes="sectnum"> 2.7    Literal Blocks @@ -790,7 +804,7 @@ > > Why didn't I think of that? <section ids="line-blocks" names="line\ blocks"> - <title auto="1" refid="id40"> + <title auto="1" refid="id45"> <generated classes="sectnum"> 2.8    Line Blocks @@ -868,7 +882,7 @@ <line> Singing... <section ids="block-quotes" names="block\ quotes"> - <title auto="1" refid="id41"> + <title auto="1" refid="id46"> <generated classes="sectnum"> 2.9    Block Quotes @@ -884,7 +898,7 @@ <attribution> Anne Elk (Miss) <section ids="doctest-blocks" names="doctest\ blocks"> - <title auto="1" refid="id42"> + <title auto="1" refid="id47"> <generated classes="sectnum"> 2.10    Doctest Blocks @@ -894,11 +908,11 @@ >>> print '(cut and pasted from interactive Python sessions)' (cut and pasted from interactive Python sessions) <section ids="footnotes" names="footnotes"> - <title auto="1" refid="id43"> + <title auto="1" refid="id48"> <generated classes="sectnum"> 2.11    Footnotes - <footnote backrefs="id1 id7 id19" ids="id6" names="1"> + <footnote backrefs="id1 id9 id21" ids="id8" names="1"> <label> 1 <paragraph> @@ -906,25 +920,25 @@ least 3 spaces. <paragraph> This is the footnote's second paragraph. - <footnote auto="1" backrefs="id3 id8" ids="label" names="label"> + <footnote auto="1" backrefs="id3 id10" ids="label" names="label"> <label> 2 <paragraph> Footnotes may be numbered, either manually (as in - <footnote_reference ids="id7" refid="id6"> + <footnote_reference ids="id9" refid="id8"> 1 ) or automatically using a "#"-prefixed label. This footnote has a label so it can be referred to from multiple places, both as a footnote reference ( - <footnote_reference auto="1" ids="id8" refid="label"> + <footnote_reference auto="1" ids="id10" refid="label"> 2 ) and as a hyperlink reference ( <reference name="label" refid="label"> label ). - <footnote auto="1" backrefs="id2" ids="id9" names="3"> + <footnote auto="1" backrefs="id2" ids="id11" names="3"> <label> 3 <paragraph> @@ -934,35 +948,35 @@ This is the second paragraph. <paragraph> And this is the third paragraph. - <footnote auto="*" backrefs="id4" ids="id10"> + <footnote auto="*" backrefs="id4" ids="id12"> <label> * <paragraph> Footnotes may also use symbols, specified with a "*" label. Here's a reference to the next footnote: - <footnote_reference auto="*" ids="id11" refid="id12"> + <footnote_reference auto="*" ids="id13" refid="id14"> † . - <footnote auto="*" backrefs="id11" ids="id12"> + <footnote auto="*" backrefs="id13" ids="id14"> <label> † <paragraph> This footnote shows the next symbol in the sequence. - <footnote ids="id13" names="4"> + <footnote ids="id15" names="4"> <label> 4 <paragraph> Here's an unreferenced footnote, with a reference to a nonexistent footnote: - <problematic ids="id74 id14" refid="id73"> + <problematic ids="id79 id16" refid="id78"> [5]_ . <section ids="citations" names="citations"> - <title auto="1" refid="id44"> + <title auto="1" refid="id49"> <generated classes="sectnum"> 2.12    Citations - <citation backrefs="id5 id15" ids="cit2002" names="cit2002"> + <citation backrefs="id5 id17" ids="cit2002" names="cit2002"> <label> CIT2002 <paragraph> @@ -970,16 +984,16 @@ rendered separately and differently from footnotes. <paragraph> Here's a reference to the above, - <citation_reference ids="id15" refid="cit2002"> + <citation_reference ids="id17" refid="cit2002"> CIT2002 , and a - <problematic ids="id76 id16" refid="id75"> + <problematic ids="id81 id18" refid="id80"> [nonexistent]_ citation. <target refid="another-target"> <section dupnames="targets" ids="targets another-target" names="another\ target"> - <title auto="1" refid="id45"> + <title auto="1" refid="id50"> <generated classes="sectnum"> 2.13    Targets @@ -996,7 +1010,7 @@ are also possible. <paragraph> Section headers are implicit targets, referred to by name. See - <reference name="Targets" refid="id20"> + <reference name="Targets" refid="id22"> Targets , which is a subsection of <reference name="Body Elements" refid="body-elements"> @@ -1008,28 +1022,28 @@ <reference name="Python" refuri="http://www.python.org/"> Python - <footnote_reference auto="1" ids="id25" refid="id23"> + <footnote_reference auto="1" ids="id27" refid="id25"> 5 ". <target ids="python" names="python" refuri="http://www.python.org/"> <paragraph> Targets may be indirect and anonymous. Thus - <reference anonymous="1" name="this phrase" refid="id20"> + <reference anonymous="1" name="this phrase" refid="id22"> this phrase may also refer to the - <reference name="Targets" refid="id20"> + <reference name="Targets" refid="id22"> Targets section. - <target anonymous="1" ids="id17" refid="id20"> + <target anonymous="1" ids="id19" refid="id22"> <paragraph> Here's a - <problematic ids="id78" refid="id77"> + <problematic ids="id83" refid="id82"> `hyperlink reference without a target`_ , which generates an error. <section dupnames="duplicate\ target\ names" ids="duplicate-target-names"> - <title auto="1" refid="id46"> + <title auto="1" refid="id51"> <generated classes="sectnum"> 2.13.1    Duplicate Target Names @@ -1037,8 +1051,8 @@ Duplicate names in section headers or other implicit targets will generate "info" (level-1) system messages. Duplicate names in explicit targets will generate "warning" (level-2) system messages. - <section dupnames="duplicate\ target\ names" ids="id18"> - <title auto="1" refid="id47"> + <section dupnames="duplicate\ target\ names" ids="id20"> + <title auto="1" refid="id52"> <generated classes="sectnum"> 2.13.2    Duplicate Target Names @@ -1046,11 +1060,11 @@ Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: - <problematic ids="id80" refid="id79"> + <problematic ids="id85" refid="id84"> `Duplicate Target Names`_ ), an error is generated. <section ids="directives" names="directives"> - <title auto="1" refid="id48"> + <title auto="1" refid="id53"> <generated classes="sectnum"> 2.14    Directives @@ -1058,49 +1072,49 @@ <bullet_list classes="auto-toc"> <list_item> <paragraph> - <reference ids="id65" refid="document-parts"> + <reference ids="id70" refid="document-parts"> <generated classes="sectnum"> 2.14.1    Document Parts <list_item> <paragraph> - <reference ids="id66" refid="images"> + <reference ids="id71" refid="images"> <generated classes="sectnum"> 2.14.2    Images <list_item> <paragraph> - <reference ids="id67" refid="admonitions"> + <reference ids="id72" refid="admonitions"> <generated classes="sectnum"> 2.14.3    Admonitions <list_item> <paragraph> - <reference ids="id68" refid="topics-sidebars-and-rubrics"> + <reference ids="id73" refid="topics-sidebars-and-rubrics"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics <list_item> <paragraph> - <reference ids="id69" refid="target-footnotes"> + <reference ids="id74" refid="target-footnotes"> <generated classes="sectnum"> 2.14.5    Target Footnotes <list_item> <paragraph> - <reference ids="id70" refid="replacement-text"> + <reference ids="id75" refid="replacement-text"> <generated classes="sectnum"> 2.14.6    Replacement Text <list_item> <paragraph> - <reference ids="id71" refid="compound-paragraph"> + <reference ids="id76" refid="compound-paragraph"> <generated classes="sectnum"> 2.14.7    Compound Paragraph <list_item> <paragraph> - <reference ids="id72" refid="parsed-literal-blocks"> + <reference ids="id77" refid="parsed-literal-blocks"> <generated classes="sectnum"> 2.14.8    Parsed Literal Blocks @@ -1111,7 +1125,7 @@ http://docutils.sourceforge.net/docs/ref/rst/directives.html . <section ids="document-parts" names="document\ parts"> - <title auto="1" refid="id65"> + <title auto="1" refid="id70"> <generated classes="sectnum"> 2.14.1    Document Parts @@ -1126,7 +1140,7 @@ table of contents ). <section ids="images" names="images"> - <title auto="1" refid="id66"> + <title auto="1" refid="id71"> <generated classes="sectnum"> 2.14.2    Images @@ -1227,7 +1241,7 @@ An image 3 cm high: <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> - <title auto="1" refid="id67"> + <title auto="1" refid="id72"> <generated classes="sectnum"> 2.14.3    Admonitions @@ -1277,7 +1291,7 @@ You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> <section ids="topics-sidebars-and-rubrics" names="topics,\ sidebars,\ and\ rubrics"> - <title auto="1" refid="id68"> + <title auto="1" refid="id73"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics @@ -1302,18 +1316,24 @@ <rubric> This is a rubric <section ids="target-footnotes" names="target\ footnotes"> - <title auto="1" refid="id69"> + <title auto="1" refid="id74"> <generated classes="sectnum"> 2.14.5    Target Footnotes - <footnote auto="1" backrefs="id24 id25 id26" ids="id23" names="TARGET_NOTE:\ id23"> + <footnote auto="1" backrefs="id26 id27 id28 id29" ids="id25" names="TARGET_NOTE:\ id25"> <label> 5 <paragraph> <reference refuri="http://www.python.org/"> http://www.python.org/ + <footnote auto="1" backrefs="id31" ids="id30" names="TARGET_NOTE:\ id30"> + <label> + 6 + <paragraph> + <reference refuri="http://docutils.sourceforge.net/"> + http://docutils.sourceforge.net/ <section ids="replacement-text" names="replacement\ text"> - <title auto="1" refid="id70"> + <title auto="1" refid="id75"> <generated classes="sectnum"> 2.14.6    Replacement Text @@ -1325,7 +1345,7 @@ the best language around - <footnote_reference auto="1" ids="id26" refid="id23"> + <footnote_reference auto="1" ids="id28" refid="id25"> 5 . <substitution_definition names="Python"> @@ -1334,7 +1354,7 @@ the best language around <section ids="compound-paragraph" names="compound\ paragraph"> - <title auto="1" refid="id71"> + <title auto="1" refid="id76"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1420,7 +1440,7 @@ <paragraph> Compound 7, another paragraph. <section ids="parsed-literal-blocks" names="parsed\ literal\ blocks"> - <title auto="1" refid="id72"> + <title auto="1" refid="id77"> <generated classes="sectnum"> 2.14.8    Parsed Literal Blocks @@ -1439,10 +1459,10 @@ literal text , footnotes - <footnote_reference ids="id19" refid="id6"> + <footnote_reference ids="id21" refid="id8"> 1 , - <target ids="id20" names="targets"> + <target ids="id22" names="targets"> targets , and <reference name="references" refuri="http://www.python.org/"> @@ -1450,7 +1470,7 @@ <target ids="references" names="references" refuri="http://www.python.org/"> . <section ids="substitution-definitions" names="substitution\ definitions"> - <title auto="1" refid="id57"> + <title auto="1" refid="id62"> <generated classes="sectnum"> 2.15    Substitution Definitions @@ -1463,7 +1483,7 @@ <paragraph> (Substitution definitions are not visible in the HTML source.) <section ids="comments" names="comments"> - <title auto="1" refid="id58"> + <title auto="1" refid="id63"> <generated classes="sectnum"> 2.16    Comments @@ -1478,7 +1498,7 @@ <paragraph> (View the HTML source to see the comment.) <section ids="raw-text" names="raw\ text"> - <title auto="1" refid="id59"> + <title auto="1" refid="id64"> <generated classes="sectnum"> 2.17    Raw text @@ -1502,7 +1522,7 @@ <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. <section ids="colspanning-tables" names="colspanning\ tables"> - <title auto="1" refid="id60"> + <title auto="1" refid="id65"> <generated classes="sectnum"> 2.18    Colspanning tables @@ -1573,7 +1593,7 @@ <paragraph> True <section ids="rowspanning-tables" names="rowspanning\ tables"> - <title auto="1" refid="id61"> + <title auto="1" refid="id66"> <generated classes="sectnum"> 2.19    Rowspanning tables @@ -1625,7 +1645,7 @@ <paragraph> body row 3 <section ids="complex-tables" names="complex\ tables"> - <title auto="1" refid="id62"> + <title auto="1" refid="id67"> <generated classes="sectnum"> 2.20    Complex tables @@ -1710,7 +1730,7 @@ --> <entry> <section ids="list-tables" names="list\ tables"> - <title auto="1" refid="id63"> + <title auto="1" refid="id68"> <generated classes="sectnum"> 2.21    List Tables @@ -1767,7 +1787,7 @@ <paragraph> On a stick! <section ids="error-handling" names="error\ handling"> - <title auto="1" refid="id64"> + <title auto="1" refid="id69"> <generated classes="sectnum"> 3    Error Handling @@ -1781,18 +1801,18 @@ <section classes="system-messages"> <title> Docutils System Messages - <system_message backrefs="id22" ids="id21" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id24" ids="id23" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id74" ids="id73" level="3" line="354" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id79" ids="id78" level="3" line="358" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id76" ids="id75" level="3" line="363" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id81" ids="id80" level="3" line="367" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id78" ids="id77" level="3" line="390" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id83" ids="id82" level="3" line="394" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id80" ids="id79" level="3" line="403" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id85" ids="id84" level="3" line="407" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index ccb5ddbeb..ea904eaec 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -99,15 +99,19 @@ Paragraphs contain text and may contain inline markup: *emphasis*, **strong emphasis**, ``inline literals``, standalone hyperlinks (http://www.python.org), external hyperlinks (Python_), internal cross-references (example_), external hyperlinks with embedded URIs -(`Python web site <http://www.python.org>`__), footnote references -(manually numbered [1]_, anonymous auto-numbered [#]_, labeled -auto-numbered [#label]_, or symbolic [*]_), citation references -([CIT2002]_), substitution references (|example|), and _`inline -hyperlink targets` (see Targets_ below for a reference back to here). -Character-level inline markup is also possible (although exceedingly -ugly!) in *re*\ ``Structured``\ *Text*. Problems are indicated by -|problematic| text (generated by processing errors; this one is -intentional). Here is a reference to the doctitle_ and the subtitle_. +(`Python web site <http://www.python.org>`__), `anonymous hyperlink +references`__ (`a second reference`__), footnote references (manually +numbered [1]_, anonymous auto-numbered [#]_, labeled auto-numbered +[#label]_, or symbolic [*]_), citation references ([CIT2002]_), +substitution references (|example|), and _`inline hyperlink targets` +(see Targets_ below for a reference back to here). Character-level +inline markup is also possible (although exceedingly ugly!) in *re*\ +``Structured``\ *Text*. Problems are indicated by |problematic| text +(generated by processing errors; this one is intentional). Here is a +reference to the doctitle_ and the subtitle_. + +__ http://www.python.org/ +__ http://docutils.sourceforge.net/ The default role for interpreted text is `Title Reference`. Here are some explicit interpreted text roles: a PEP reference (:PEP:`287`); an -- cgit v1.2.1 From c6e1fdb5efb32575f69e1c0c68cb6715ac896a85 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 21:36:06 +0000 Subject: removed more internal state (`document.anonymous_refs` and `document.anonymous_targets`) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3939 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 2 ++ docutils/nodes.py | 10 -------- docutils/parsers/rst/states.py | 4 --- docutils/transforms/references.py | 44 +++++++++++++++++++-------------- test/test_transforms/test_hyperlinks.py | 30 ++++++++++++++++++++++ 5 files changed, 57 insertions(+), 33 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 57d7a2319..2a06087ea 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -41,6 +41,8 @@ Changes Since 0.3.9 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``. * docutils/parsers/null.py: Added to project; a do-nothing parser. diff --git a/docutils/nodes.py b/docutils/nodes.py index 17ef75e99..195293a9e 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -834,12 +834,6 @@ class document(Root, Structural, Element): self.citation_refs = {} """Mapping of citation labels to lists of citation_reference nodes.""" - self.anonymous_targets = [] - """List of anonymous target nodes.""" - - self.anonymous_refs = [] - """List of anonymous reference nodes.""" - self.autofootnotes = [] """List of auto-numbered footnote nodes.""" @@ -1017,10 +1011,6 @@ class document(Root, Structural, Element): def note_anonymous_target(self, target): self.set_id(target) - self.anonymous_targets.append(target) - - def note_anonymous_ref(self, ref): - self.anonymous_refs.append(ref) def note_autofootnote(self, footnote): self.set_id(footnote) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index db19c34b6..be064db8a 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -783,7 +783,6 @@ class Inliner: reference['refuri'] = uri else: reference['anonymous'] = 1 - self.document.note_anonymous_ref(reference) else: if target: reference['refuri'] = uri @@ -846,8 +845,6 @@ class Inliner: '|%s%s' % (subref_text, endstring), '') if endstring[-2:] == '__': reference_node['anonymous'] = 1 - self.document.note_anonymous_ref( - reference_node) else: reference_node['refname'] = normalize_name(subref_text) self.document.note_refname(reference_node) @@ -898,7 +895,6 @@ class Inliner: name=whitespace_normalize_name(referencename)) if anonymous: referencenode['anonymous'] = 1 - self.document.note_anonymous_ref(referencenode) else: referencenode['refname'] = refname self.document.note_refname(referencenode) diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index d7ad9376f..bcf33dfe5 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -114,23 +114,29 @@ class AnonymousHyperlinks(Transform): default_priority = 440 def apply(self): - if len(self.document.anonymous_refs) \ - != len(self.document.anonymous_targets): + 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(self.document.anonymous_refs), - len(self.document.anonymous_targets))) + % (len(anonymous_refs), len(anonymous_targets))) msgid = self.document.set_id(msg) - for ref in self.document.anonymous_refs: + 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(self.document.anonymous_refs, - self.document.anonymous_targets): + for ref, target in zip(anonymous_refs, anonymous_targets): target.referenced = 1 while 1: if target.hasattr('refuri'): @@ -720,23 +726,23 @@ class TargetNotes(Transform): refs.extend(self.document.refnames.get(name, [])) if not refs: continue - footnote = self.make_target_footnote(target, refs, notes) + footnote = self.make_target_footnote(target['refuri'], refs, + notes) if not notes.has_key(target['refuri']): notes[target['refuri']] = footnote nodelist.append(footnote) - if len(self.document.anonymous_targets) \ - == len(self.document.anonymous_refs): - for target, ref in zip(self.document.anonymous_targets, - self.document.anonymous_refs): - if target.hasattr('refuri'): - footnote = self.make_target_footnote(target, [ref], notes) - if not notes.has_key(target['refuri']): - 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 not notes.has_key(ref['refuri']): + notes[ref['refuri']] = footnote + nodelist.append(footnote) self.startnode.replace_self(nodelist) - def make_target_footnote(self, target, refs, notes): - refuri = target['refuri'] + def make_target_footnote(self, refuri, refs, notes): if notes.has_key(refuri): # duplicate? footnote = notes[refuri] assert len(footnote['names']) == 1 diff --git a/test/test_transforms/test_hyperlinks.py b/test/test_transforms/test_hyperlinks.py index 1b84a18c4..cef12a4f1 100755 --- a/test/test_transforms/test_hyperlinks.py +++ b/test/test_transforms/test_hyperlinks.py @@ -281,6 +281,36 @@ __ ztarget_ Indirect hyperlink target (id="id2") refers to target "ztarget", which is a duplicate, and cannot be used as a unique reference. """], ["""\ +The next anonymous hyperlink reference is parsed (and discarded) at +some point, but nonetheless anonymous hyperlink references and targets +match in this snippet. + +.. |invalid| replace:: anonymous__ + +hyperlink__ + +__ URL +""", +"""\ +<document source="test data"> + <paragraph> + The next anonymous hyperlink reference is parsed (and discarded) at + some point, but nonetheless anonymous hyperlink references and targets + match in this snippet. + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Substitution definition contains illegal element: + <literal_block xml:space="preserve"> + <reference anonymous="1" name="anonymous"> + anonymous + <literal_block xml:space="preserve"> + .. |invalid| replace:: anonymous__ + <paragraph> + <reference anonymous="1" name="hyperlink" refuri="URL"> + hyperlink + <target anonymous="1" ids="id1" refuri="URL"> +"""], +["""\ An `embedded uri <http://direct>`_. Another reference to the same `embedded URI`_. -- cgit v1.2.1 From 5da7532801abf44378d5422760ab68a84bc39fbc Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Tue, 11 Oct 2005 23:00:39 +0000 Subject: removed references to default.css; to-do: update PEP writer (-> pep.css) and then docs/user/tools.txt git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3940 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 1 - docs/dev/distributing.txt | 43 ++++++++++--------------------------------- docs/dev/hacking.txt | 4 ++-- docs/dev/testing.txt | 2 +- docutils/writers/html4css1.py | 4 ++-- test/DocutilsTestSupport.py | 4 ---- 6 files changed, 15 insertions(+), 43 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 37b955a3e..8e5925036 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -764,7 +764,6 @@ Here's the question in full: <head> ... <title>Heading 1 -
    diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index c1cfc3603..e4495512c 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -87,7 +87,9 @@ The documentation should be generated using ``buildhtml.py``. To generate HTML for all documentation files, go to the ``tools/`` directory and run:: - ./buildhtml.py .. + # Place html4css1.css in base directory. + cp ../docutils/writers/support/html4css1.css .. + ./buildhtml.py --stylesheet-path=../html4css1.css .. Then install the following files to ``/usr/share/doc/docutils/`` (or wherever you install documentation): @@ -102,15 +104,7 @@ wherever you install documentation): * The ``licenses/`` directory. -* ``tools/stylesheets/default.css``, creating the ``tools/`` and - ``tools/stylesheets/`` directory beforehand. This file is needed - for correct viewing of the HTML files. The remaining contents of - the ``tools/`` and ``tools/stylesheets/`` directories are not - needed. - - Be sure not to install ``default.css`` into the root of the - documentation directory, or the relative references to the - stylesheet will not work. +* ``html4css1.css`` in the base directory. Removing the ``.txt`` Files @@ -126,40 +120,23 @@ the tree except for: be readable in source form. Before you remove the ``.txt`` files you should rerun ``buildhtml.py`` -as ``./buildhtml.py .. --no-source-link`` to avoid broken references -to the source files. +with the ``--no-source-link`` switch to avoid broken references to the +source files. Other Files =========== -Install ``tools/stylesheets/`` to ``/usr/lib/docutils/stylesheets/`` -and ``tools/pep-html-template`` to -``/usr/lib/docutils/pep-html-template``. - -You may also want to install the Emacs-Lisp files +You may want to install the Emacs-Lisp files ``tools/editors/emacs/*.el`` into the appropriate directory. Configuration File ================== -The system-wide configuration file is located in -``/etc/docutils.conf``. You should *not* install -``tools/docutils.conf`` into ``/etc/``. Instead, we recommend that -you create a new ``/etc/docutils.conf`` file containing references to -the appropriate files on your system:: - - [html4css1 writer] - # These entries affect HTML output: - stylesheet-path: /usr/lib/docutils/stylesheets/default.css - - [pep_html writer] - # These entries affect reStructuredText-style PEPs: - template: /usr/lib/docutils/pep-html-template - stylesheet-path: /usr/lib/docutils/stylesheets/pep.css - -(Adjust the paths as necessary.) +It is possible to have a system-wide configuration file at +``/etc/docutils.conf``. However, this is usually not necessary. You +should *not* install ``tools/docutils.conf`` into ``/etc/``. Tests diff --git a/docs/dev/hacking.txt b/docs/dev/hacking.txt index ab0c85259..dcbc80943 100644 --- a/docs/dev/hacking.txt +++ b/docs/dev/hacking.txt @@ -158,7 +158,7 @@ HTML writer in this case (``docutils/writers/html4css1.py``). The writer receives the node tree and returns the output document. For HTML output, we can test this using the ``rst2html.py`` tool:: - $ rst2html.py test.txt + $ rst2html.py --link-stylesheet test.txt @@ -166,7 +166,7 @@ For HTML output, we can test this using the ``rst2html.py`` tool:: - +
    diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index 681cb7ae9..fc6feae2b 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -134,7 +134,7 @@ For example, ``functional/tests/some_test.py`` could read like this:: writer_name = "html" settings_overrides['output-encoding'] = 'utf-8' # Relative to main ``test/`` directory. - settings_overrides['stylesheet_path'] = '../tools/stylesheets/default.css' + settings_overrides['stylesheet_path'] = '../docutils/writers/support/html4css1.css' The two variables ``test_source`` and ``test_destination`` contain the input file name (relative to ``functional/input/``) and the output diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 14d0424da..d11e88c48 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -9,8 +9,8 @@ Simple HyperText Markup Language document tree Writer. The output conforms to the XHTML version 1.0 Transitional DTD (*almost* strict). The output contains a minimum of formatting -information. A cascading style sheet ("default.css" by default) is -required for proper viewing with a modern graphical browser. +information. The cascading style sheet "html4css1.css" is required +for proper viewing with a modern graphical browser. """ __docformat__ = 'reStructuredText' diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index ea1672d1b..6947c4478 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -767,8 +767,6 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): standard_content_type_template + standard_generator_template % docutils.__version__) standard_meta_value = standard_html_meta_value % 'utf-8' - standard_stylesheet_value = ('\n') standard_html_prolog = """\ @@ -782,8 +780,6 @@ class HtmlWriterPublishPartsTestCase(WriterPublishTestCase): del parts['body'] # remove standard portions: parts['meta'] = parts['meta'].replace(self.standard_meta_value, '') - if parts['stylesheet'] == self.standard_stylesheet_value: - del parts['stylesheet'] parts['html_head'] = parts['html_head'].replace( self.standard_html_meta_value, '...') parts['html_prolog'] = parts['html_prolog'].replace( -- cgit v1.2.1 From 67d3d970573174d53ca2f814f1205864470ecd91 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 14 Oct 2005 16:42:15 +0000 Subject: updated tools.txt to match recent reorganisation; fixed some relicts; esp. the "pep2html.py" section has been deleted; the script is no longer included in the Docutils distribution (maybe you want to use the text somewhere else, David?) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3942 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 60 ++++++++++------------------------------------------- 1 file changed, 11 insertions(+), 49 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 20e22e356..887959613 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -106,13 +106,13 @@ installed and used by default (see Stylesheets_ below). For example, to process a reStructuredText file "``test.txt``" into HTML:: - rst2html.py --stylesheet=mystyles.css test.txt test.html + rst2html.py test.txt test.html Now open the "``test.html``" file in your favorite browser to see the results. To get a footer with a link to the source file, date & time of processing, and links to the Docutils project, add some options:: - rst2html.py --stylesheet=mystyles.css -stg test.txt test.html + rst2html.py -stg test.txt test.html Stylesheets @@ -126,9 +126,9 @@ installation directory) is provided for basic use. To use a different stylesheet, you must specify the stylesheet's location with a "``--stylesheet``" (for a URL) or "``--stylesheet-path``" (for a local file) command-line option, or with `configuration file`_ settings -(e.g. ``./docutils.conf`` or ``~/.docutils.conf``). To experiment -with styles, please see the `guide to writing HTML (CSS) stylesheets -for Docutils`__. +(e.g. ``./docutils.conf`` or ``~/.docutils``). To experiment with +styles, please see the `guide to writing HTML (CSS) stylesheets for +Docutils`__. __ ../howto/html-stylesheets.html @@ -143,52 +143,14 @@ rstpep2html.py ``rstpep2html.py`` reads a new-style PEP (marked up with reStructuredText) and produces HTML. It requires a template file and a stylesheet. By default, it makes use of a "``pep-html-template``" -file and a "``default.css``" stylesheet in the current directory, but -these can be overridden by command-line options or configuration -files. The "``tools/stylesheets/pep.css``" stylesheet is intended -specifically for PEP use. - -The "``docutils.conf``" `configuration file`_ in the "``tools``" -directory of Docutils contains a default setup for use in processing -the PEP files (``docs/peps/pep-*.txt``) into HTML. It specifies a -default template (``tools/pep-html-template``) and a default -stylesheet (``tools/stylesheets/pep.css``). See Stylesheets_ above -for more information. - -``rstpep2html.py`` can be run from the ``tools`` directory or from the -``docs/peps/`` directory, by adjusting the settings. These two sets -of commands are equivalent:: - - cd /tools - # This will pick up the "docutils.conf" file automatically: - rstpep2html.py ../docs/peps/pep-0287.txt ../docs/peps/pep-0287.html - - cd /docs/peps - # Must tell the tool where to find the config file: - ../../tools/rstpep2html.py --config ../../tools/docutils.conf \ - pep-0287.txt pep-0287.html +file and the "``pep.css``" stylesheet (both in the +``docutils/writers/support/`` directory), but these can be overridden +by command-line options or configuration files. +For example, to process a PEP into HTML:: -pep2html.py ------------ - -:Reader: PEP -:Parser: reStructuredText -:Writer: PEP/HTML - -``pep2html.py`` is a modified version of the original script by -Fredrik Lundh, with support for Docutils added. It reads the -beginning of a PEP text file to determine the format (old-style -indented or new-style reStructuredText) and processes accordingly. -Since it does not use the Docutils front end mechanism (the common -command-line options are not supported), it can only be configured -using `configuration files`_. The template and stylesheet -requirements of ``pep2html.py`` are the same as those of -`rstpep2html.py`_ above. - -Arguments to ``pep2html.py`` may be a list of PEP numbers or .txt -files. If no arguments are given, all files of the form -"``pep-*.txt``" are processed. + cd /docs/peps + rstpep2html.py pep-0287.txt pep-0287.html rst2latex.py -- cgit v1.2.1 From cf20217231f6f941b8e149e55f60c628141d70b2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 16 Oct 2005 12:04:22 +0000 Subject: fixed internal link to "rstpep2html.py" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3943 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/tools.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 887959613..48105e1ba 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -27,10 +27,11 @@ pattern:: toolname [options] [ [ Date: Fri, 21 Oct 2005 20:43:14 +0000 Subject: added link target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3944 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUGS.txt b/BUGS.txt index 89b5998df..e19654e6b 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -235,7 +235,7 @@ Also see the `SourceForge Bug Tracker`_. the HTML output at ``test/functional/expected/standalone_rst_html4css1.html``. -* Blank first columns in simple tables with explicit row separators +* _`Blank first columns` in simple tables with explicit row separators silently swallow their input. They should at least produce system error messages. But, with explicit row separators, the meaning is unambiguous and ought to be supported:: -- cgit v1.2.1 From 89e2386d371a4db1da5b181cf8c90e5d8be77c64 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 21 Oct 2005 21:31:29 +0000 Subject: added link to latex-math role and directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3945 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FAQ.txt b/FAQ.txt index 8e5925036..37fb57374 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -1,3 +1,5 @@ +.. -*- coding: utf-8 -*- + =========================================== Docutils FAQ (Frequently Asked Questions) =========================================== @@ -496,6 +498,11 @@ They all presently use LaTeX syntax or dialects of it. directives.html#raw-data-pass-through .. _raw role: http://docutils.sourceforge.net/docs/ref/rst/roles.html#raw +* Jens Jørgen Mortensen has implemented a "latex-math" role and + directive, available from `his sandbox`__. + + __ http://docutils.sourceforge.net/sandbox/jensj/latex_math/ + * For HTML the "Right" w3c-standard way to include math is MathML_. Unfortunately its rendering is still quite broken (or absent) on many browsers but it's getting better. Another bad problem is that typing -- cgit v1.2.1 From 86b4342590996eca287f427aa5b88b370d81d227 Mon Sep 17 00:00:00 2001 From: blais Date: Sat, 22 Oct 2005 17:57:34 +0000 Subject: - Added new funtion and binding to display the Table of Contents and jump to any section title from it (press return); - Renamed a rest-display-secitons-hierarchy to rest-display-decorations-hierarchy which is more accurate. - Replaced C-x C-= binding by the new more useful TOC display feature. The display hierarchy feature is still available by calling this with a prefix-argument. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3946 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 185 +++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 16 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index b03e7cbf8..b656af2ca 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -20,12 +20,15 @@ ;; C-= : updates or rotates the section title around point or ;; promotes/demotes the decorations within the region (see full details ;; below). -;; +;; ;; Note that C-= is a good binding, since it allows you to specify a ;; negative arg easily with C-- C-= (easy to type), as well as ordinary ;; prefix arg with C-u C-=. ;; -;; C-x C-= : displays the hierarchy of title decorations from this file. +;; C-x C-= : displays the hierarchical table-of-contents of the document and +;; allows you to jump to any section from it. +;; +;; C-u C-x C-= : displays the title decorations from this file. ;; ;; C-M-{, C-M-} : navigate between section titles. ;; @@ -38,7 +41,7 @@ ;; - rest-default-indent ;; - rest-preferred-decorations ;; -;; TODO: +;; TODO: ;; - Add an option to forego using the file structure in order to make ;; suggestion, and to always use the preferred decorations to do that. ;; @@ -75,7 +78,7 @@ is for which (pred elem) is true)" (goto-char opoint) (forward-line 0) (1+ (count-lines start (point)))))) ) - + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The following functions implement a smart automatic title sectioning feature. @@ -151,10 +154,17 @@ is for which (pred elem) is true)" ;; adjustment (unless we cycle, in which case we use the indent that has been ;; found previously). +(defun rest-toc-or-hierarchy () + "Binding for either TOC or decorations hierarchy." + (interactive) + (if (not current-prefix-arg) + (rest-toc) + (rest-display-decorations-hierarchy))) + (defun rest-text-mode-hook () "Default text mode hook for rest." (local-set-key [(control ?=)] 'rest-adjust) - (local-set-key [(control x)(control ?=)] 'rest-display-sections-hierarchy) + (local-set-key [(control x)(control ?=)] 'rest-toc-or-hierarchy) (local-set-key [(control meta ?{)] 'rest-backward-section) (local-set-key [(control meta ?})] 'rest-forward-section) ) @@ -563,7 +573,7 @@ A list of the previous and next decorations is returned." )) -(defun rest-get-next-decoration +(defun rest-get-next-decoration (curdeco hier &optional suggestion reverse-direction) "Get the next decoration for CURDECO, in given hierarchy HIER, and suggesting for new decoration SUGGESTION." @@ -590,7 +600,7 @@ and suggesting for new decoration SUGGESTION." (eq style (cadar cur))))) (setq cur (cdr cur))) cur)) - + ;; If not found, take the first of all decorations. suggestion ))) @@ -904,7 +914,7 @@ of the right hand fingers and the binding is unused in text-mode." hier (car (rest-get-decorations-around alldecos)))) - (nextdeco (rest-get-next-decoration + (nextdeco (rest-get-next-decoration curdeco hier suggestion reverse-direction)) ) @@ -948,7 +958,7 @@ the hierarchy is similar to that used by rest-adjust-decoration." (let* ((demote (or current-prefix-arg demote)) (alldecos (rest-find-all-decorations)) (cur alldecos) - + (hier (rest-get-hierarchy alldecos)) (suggestion (rest-suggest-new-decoration hier)) @@ -961,7 +971,7 @@ the hierarchy is similar to that used by rest-adjust-decoration." ;; Skip the markers that come before the region beginning (while (and cur (< (caar cur) region-begin-line)) (setq cur (cdr cur))) - + ;; Create a list of markers for all the decorations which are found within ;; the region. (save-excursion @@ -977,23 +987,23 @@ the hierarchy is similar to that used by rest-adjust-decoration." (dolist (p marker-list) ;; Go to the decoration to promote. (goto-char (car p)) - + ;; Rotate the next decoration. - (setq nextdeco (rest-get-next-decoration + (setq nextdeco (rest-get-next-decoration (cadr p) hier suggestion demote)) - + ;; Update the decoration. (apply 'rest-update-section nextdeco) - + ;; Clear marker to avoid slowing down the editing after we're done. (set-marker (car p) nil) )) - (setq deactivate-mark nil) + (setq deactivate-mark nil) ))) -(defun rest-display-sections-hierarchy (&optional decorations) +(defun rest-display-decorations-hierarchy (&optional decorations) "Display the current file's section title decorations hierarchy. This function expects a list of (char, style, indent) triples." (interactive) @@ -1013,6 +1023,149 @@ the hierarchy is similar to that used by rest-adjust-decoration." ))) +(defun rest-get-stripped-line () + "Returns the line at cursor, stripped from whitespace." + (re-search-forward "\\S-.*\\S-" (line-end-position)) + (buffer-substring-no-properties (match-beginning 0) + (match-end 0)) ) + + +(defvar rest-toc-indent 4 + "Indentation for table-of-contents display.") + +(defun rest-toc () + "Finds all the section titles and their decorations in the + file, and displays a hierarchically-organized list of the + titles, which is essentially a table-of-contents of the + document. + + The emacs buffer can be navigated, and selecting a section + brings the cursor in that section." + (interactive) + (let* ((curpoint (point)) + foundline + (alldecos (rest-find-all-decorations)) + (hier (rest-get-hierarchy alldecos)) + (levels (make-hash-table :test 'equal :size 10)) + (buf (get-buffer-create rest-toc-buffer-name)) + lines) + (let ((lev 0)) + (dolist (deco hier) + (puthash deco lev levels) + (incf lev))) + + (let ((curline 1)) + (save-excursion + (setq lines + (mapcar (lambda (deco) + (goto-line (car deco)) + (if (and (not foundline) (> (point) curpoint)) + (setq foundline curline)) + (incf curline) + (list (rest-get-stripped-line) + (gethash (cdr deco) levels) + (let ((m (make-marker))) + (beginning-of-line 1) + (set-marker m (point))) + )) + alldecos)))) + + (with-current-buffer buf + (let ((inhibit-read-only t)) + (rest-toc-mode) + (delete-region (point-min) (point-max)) + (insert (format "Table of Contents: %s\n" (caar lines))) + (put-text-property (point-min) (point) + 'face (list '(background-color . "lightgray"))) + (dolist (x lines) + (let* ( + ;; Compute line text to be inserted. + (ins (concat (make-string (* rest-toc-indent (cadr x)) ? ) + (car x))) + + ;; Compute boundaries of this text. + (beg (point)) + (end (+ beg (length ins))) + ) + ;; Insert line. + (insert ins "\n") + + ;; Highlight lines. + (put-text-property beg end 'mouse-face 'highlight) + + ;; Add link on lines. + (put-text-property beg end 'rest-toc-target (caddr x)) + )) + )) + (display-buffer buf) + (pop-to-buffer buf) + (goto-line foundline) + )) + + +(defun rest-toc-mode-find-section () + (let ((pos (get-text-property (point) 'rest-toc-target))) + (unless pos + (error "No section on this line")) + (unless (buffer-live-p (marker-buffer pos)) + (error "Buffer for this section was killed")) + pos)) + +(defvar rest-toc-buffer-name "*Table of Contents*" + "Name of the Table of Contents buffer.") + +(defun rest-toc-mode-goto-section () + "Go to the section the current line describes." + (interactive) + (let ((pos (rest-toc-mode-find-section))) + (kill-buffer (get-buffer rest-toc-buffer-name)) + (pop-to-buffer (marker-buffer pos)) + (goto-char pos) + (recenter 5))) + +(defun rest-toc-mode-mouse-goto (event) + "In Rest-Toc mode, go to the occurrence whose line you click on." + (interactive "e") + (let (pos) + (save-excursion + (set-buffer (window-buffer (posn-window (event-end event)))) + (save-excursion + (goto-char (posn-point (event-end event))) + (setq pos (rest-toc-mode-find-section)))) + (pop-to-buffer (marker-buffer pos)) + (goto-char pos))) + +(defun rest-toc-mode-mouse-goto-kill (event) + (interactive "e") + (call-interactively 'rest-toc-mode-mouse-goto event) + (kill-buffer (get-buffer rest-toc-buffer-name))) + +(defvar rest-toc-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'rest-toc-mode-mouse-goto-kill) + (define-key map [mouse-2] 'rest-toc-mode-mouse-goto) + (define-key map "\C-m" 'rest-toc-mode-goto-section) + (define-key map "f" 'rest-toc-mode-goto-section) + (define-key map "q" 'quit-window) + (define-key map "z" 'kill-this-buffer) + map) + "Keymap for `rest-toc-mode'.") + +(put 'rest-toc-mode 'mode-class 'special) +(defun rest-toc-mode () + "Major mode for output from \\[rest-toc]." + (interactive) + (kill-all-local-variables) + (use-local-map rest-toc-mode-map) + (setq major-mode 'rest-toc-mode) + (setq mode-name "Rest-TOC") + (setq buffer-read-only t) + ) + +;; Note: use occur-mode (replace.el) as a good example to complete missing +;; features. + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Section movement commands. -- cgit v1.2.1 From 88e05f8b6d298dc43fddbac594c413847edfa0d4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 23 Oct 2005 20:34:38 +0000 Subject: added to-do list entry about false positives with list recognition git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3947 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 1a9fd1d98..397fa2299 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -660,6 +660,19 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* The current list-recognition logic has too many false positives, as + in :: + + * Aorta + * V. cava superior + * V. cava inferior + + Here ``V.`` is recognized as an enumerator, which leads to + confusion. We need to find a solution that resolves such problems + without complicating the spec to much. + + See . + * Add indirect links via citation references & footnote references. Example:: -- cgit v1.2.1 From d8d6331e6b37db000ab572e9b71a00aa6bd001fa Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 25 Oct 2005 23:32:20 +0000 Subject: Fixed minor bug with TOC feature when the cursor is in the last section of the file. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3948 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 5 ++- tools/editors/emacs/tests/tests-adjust-section.el | 47 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index b656af2ca..a8ecdf15f 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -1068,7 +1068,10 @@ the hierarchy is similar to that used by rest-adjust-decoration." (beginning-of-line 1) (set-marker m (point))) )) - alldecos)))) + alldecos))) + (if (not foundline) + (setq foundline curline)) + ) (with-current-buffer buf (let ((inhibit-read-only t)) diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index be27dc8e3..850f9e76f 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -760,6 +760,53 @@ Document Title2 " ) +;;------------------------------------------------------------------------------ +(cycle-previous-only +" +================== + Document Title +================== + +Document Title2 +=============== + +======= + Bli@ +======= + +Document Title2 +=============== + +Document Title3 +--------------- + +Document Title4 +~~~~~~~~~~~~~~~ + +" +" +================== + Document Title +================== + +Document Title2 +=============== + +Bli@ +--- + +Document Title2 +=============== + +Document Title3 +--------------- + +Document Title4 +~~~~~~~~~~~~~~~ + +" +) + )) -- cgit v1.2.1 From fbe523c302d2ad6bbc669bd7edcbb95665567cac Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 25 Oct 2005 23:33:40 +0000 Subject: Rollback new test that does not pass yet. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3949 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/tests/tests-adjust-section.el | 93 ++++++++++++----------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index 850f9e76f..84a8d4ea3 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -760,52 +760,53 @@ Document Title2 " ) -;;------------------------------------------------------------------------------ -(cycle-previous-only -" -================== - Document Title -================== - -Document Title2 -=============== - -======= - Bli@ -======= - -Document Title2 -=============== - -Document Title3 ---------------- - -Document Title4 -~~~~~~~~~~~~~~~ - -" -" -================== - Document Title -================== - -Document Title2 -=============== - -Bli@ ---- - -Document Title2 -=============== - -Document Title3 ---------------- - -Document Title4 -~~~~~~~~~~~~~~~ - -" -) +;; FIXME: todo +;; ;;------------------------------------------------------------------------------ +;; (cycle-previous-only +;; " +;; ================== +;; Document Title +;; ================== +;; +;; Document Title2 +;; =============== +;; +;; ======= +;; Bli@ +;; ======= +;; +;; Document Title2 +;; =============== +;; +;; Document Title3 +;; --------------- +;; +;; Document Title4 +;; ~~~~~~~~~~~~~~~ +;; +;; " +;; " +;; ================== +;; Document Title +;; ================== +;; +;; Document Title2 +;; =============== +;; +;; Bli@ +;; --- +;; +;; Document Title2 +;; =============== +;; +;; Document Title3 +;; --------------- +;; +;; Document Title4 +;; ~~~~~~~~~~~~~~~ +;; +;; " +;; ) )) -- cgit v1.2.1 From d30297348e43d04a8006c12b35f407141b499dae Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 26 Oct 2005 11:48:21 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3950 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 397fa2299..706f19b61 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -38,7 +38,7 @@ Please see also the Bugs_ document for a list of bugs in Docutils. Release 0.4 =========== -We should get Docutils 0.4 out soon. But we shouldn't just cut a +We should get Docutils 0.4 out soon, but we shouldn't just cut a "frozen snapshot" release. Here's a list of features (achievable in the short term) to include: @@ -54,6 +54,18 @@ the short term) to include: Anything else? +Once released, + +* Tag it and create a maintenance branch (perhaps "maint-0-4"). + +* Declare that: + + - Docutils 0.4.x is the last version that will support Python 2.1 + (and perhaps higher?) + + - Docutils 0.4.x is the last version that will support (make + compromises for) Netscape Navigator 4 + Minimum Requirements for Python Standard Library Candidacy ========================================================== @@ -92,6 +104,9 @@ for inclusion in the Python standard library. General ======= +* Change the docutils-update script (in sandbox/infrastructure), to + support arbitrary branch snapshots. + * Add a --strip-comments command-line option (& strip_comments runtime setting), declared in docutils/frontend.py, and implemented as a transform. This feature isn't specific to rst2html.py, or to the @@ -817,8 +832,12 @@ __ rst/alternatives.html#or-not-to-do Tony Ibbs spoke out against this idea (2002-06-14 Doc-SIG thread "docutils feedback"). -* Should the "doctest" element go away, and the construct simply be a - front-end to generic literal blocks? +* The "doctest" element should go away. The construct could simply be + a front-end to generic literal blocks. We could immediately (in + 0.4, or 0.5) remove the doctest node from the doctree, but leave the + syntax in reST. The reST parser could represent doctest blocks as + literal blocks with a class attribute. The syntax could be left in + reST for a set period of time. * Add support for pragma (syntax-altering) directives. @@ -1137,6 +1156,11 @@ when used in a document. - _`misc.settings`: Set any(?) Docutils runtime setting from within a document? Needs much thought and discussion. + - _`misc.gather`: Gather (move, or copy) all instances of a specific + element. A generalization of the "endnotes" & "citations" ideas. + + - Add a "directive" directive, equivalent to "role"? + - .. _conditional directives: Docutils already has the ability to say "use this content for -- cgit v1.2.1 From 56626f76d702387823fa3f455c136e9c7069b6c9 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 26 Oct 2005 11:57:06 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3952 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/website.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dev/website.txt b/docs/dev/website.txt index e54acb802..193e9c0f2 100644 --- a/docs/dev/website.txt +++ b/docs/dev/website.txt @@ -31,10 +31,10 @@ After adding directories to SVN, allow the script to run once to create the directories in the filesystem before preparing for HTML processing as described above. -The docutils-update__ script is located as -``sandbox/davidg/infrastructure/docutils-update``. +The docutils-update__ script is located at +``sandbox/infrastructure/docutils-update``. -__ http://docutils.sf.net/sandbox/davidg/infrastructure/docutils-update +__ http://docutils.sf.net/sandbox/infrastructure/docutils-update .. -- cgit v1.2.1 From 525ed2d525c1f256fdfce118d86817cc0007072d Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 26 Oct 2005 13:32:03 +0000 Subject: promoted sublist item git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3953 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 37fb57374..9126a5d2a 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -526,18 +526,18 @@ They all presently use LaTeX syntax or dialects of it. .. _itex2mml: http://pear.math.pitt.edu/mathzilla/itex2mml.html .. _HOWTO: http://www.american.edu/econ/itex2mml/mathhack.rst - * The other way to add math to HTML is to use images of the equations, - typically generated by TeX. This is inferior to MathML in the long - term but is perhaps more accessible nowdays. - - Of course, doing it by hand is too much work. Beni Cherniavsky has - written some `preprocessing scripts`__ for converting the - ``texmath`` role/directive into images for HTML output and raw - directives/subsitution for LaTeX output. This way you can *generate - LaTeX and HTML+images from the same source*. `Instructions here`__. - - __ http://docutils.sourceforge.net/sandbox/cben/rolehack/ - __ http://docutils.sourceforge.net/sandbox/cben/rolehack/README.html +* The other way to add math to HTML is to use images of the equations, + typically generated by TeX. This is inferior to MathML in the long + term but is perhaps more accessible nowdays. + + Of course, doing it by hand is too much work. Beni Cherniavsky has + written some `preprocessing scripts`__ for converting the + ``texmath`` role/directive into images for HTML output and raw + directives/subsitution for LaTeX output. This way you can *generate + LaTeX and HTML+images from the same source*. `Instructions here`__. + + __ http://docutils.sourceforge.net/sandbox/cben/rolehack/ + __ http://docutils.sourceforge.net/sandbox/cben/rolehack/README.html Is nested inline markup possible? -- cgit v1.2.1 From 09990717cff73a01c118f208643551e47871f032 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 27 Oct 2005 01:28:36 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3954 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 706f19b61..11c8046ab 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1012,6 +1012,9 @@ __ rst/alternatives.html#or-not-to-do .. _list-table: ../ref/rst/directives.html#list-table +* Generalize docinfo contents (bibliographic fields): remove specific + fields, and have only a single generic "field"? + Directives ---------- -- cgit v1.2.1 From 3152d1a9398847f2cc3b842cb89a15bb17270dd1 Mon Sep 17 00:00:00 2001 From: blais Date: Thu, 27 Oct 2005 15:47:03 +0000 Subject: - Added new function to insert the TOC inside the document; (bound to C-x + by default). See the many options. - Fixed quit command in TOC mode, to always go back to the original buffer. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3955 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 297 ++++++++++++++++++++++++++------ 1 file changed, 244 insertions(+), 53 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index a8ecdf15f..15f4d9df4 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -20,7 +20,7 @@ ;; C-= : updates or rotates the section title around point or ;; promotes/demotes the decorations within the region (see full details ;; below). -;; +;; ;; Note that C-= is a good binding, since it allows you to specify a ;; negative arg easily with C-- C-= (easy to type), as well as ordinary ;; prefix arg with C-u C-=. @@ -30,6 +30,9 @@ ;; ;; C-u C-x C-= : displays the title decorations from this file. ;; +;; C-x + : insert the table of contents in the text. See the many options +;; for customizing how it will look. +;; ;; C-M-{, C-M-} : navigate between section titles. ;; ;; Other specialized and more generic functions are also available (see source @@ -165,6 +168,7 @@ is for which (pred elem) is true)" "Default text mode hook for rest." (local-set-key [(control ?=)] 'rest-adjust) (local-set-key [(control x)(control ?=)] 'rest-toc-or-hierarchy) + (local-set-key [(control x)(?+)] 'rest-toc-insert) (local-set-key [(control meta ?{)] 'rest-backward-section) (local-set-key [(control meta ?})] 'rest-forward-section) ) @@ -1022,6 +1026,15 @@ the hierarchy is similar to that used by rest-adjust-decoration." )) ))) +(if (not (fboundp 'strip-whitespace)) + (defun strip-whitespace (str) + "Strips the whitespace around a string." + (let ((tmp)) + (string-match "\\`[ \t\n]*" str) + (setq tmp (substring str (match-end 0))) + (string-match "[ \t\n]*\\'" tmp) + (substring tmp 0 (match-beginning 0)) + ))) (defun rest-get-stripped-line () "Returns the line at cursor, stripped from whitespace." @@ -1033,6 +1046,194 @@ the hierarchy is similar to that used by rest-adjust-decoration." (defvar rest-toc-indent 4 "Indentation for table-of-contents display.") + +(defun rest-section-tree (alldecos) + "Returns a pair of a hierarchical tree of the sections titles +in the document, and a reference to the node where the cursor +lives. This can be used to generate a table of contents for the +document. + +Each section title consists in a cons of the stripped title +string and a marker to the section in the original text document. + +If there are missing section levels, the section titles are +inserted automatically, and are set to nil." + + (let* (thelist + (hier (rest-get-hierarchy alldecos)) + (levels (make-hash-table :test 'equal :size 10)) + lines) + + (let ((lev 0)) + (dolist (deco hier) + (puthash deco lev levels) + (incf lev))) + + ;; Create a list of lines that contains (text, level, marker) for each + ;; decoration. + (save-excursion + (setq lines + (mapcar (lambda (deco) + (goto-line (car deco)) + (list (gethash (cdr deco) levels) + (rest-get-stripped-line) + (let ((m (make-marker))) + (beginning-of-line 1) + (set-marker m (point))) + )) + alldecos))) + + (let ((lcontnr (cons nil lines))) + (rest-section-tree-rec lcontnr -1)))) + + +(defun rest-section-tree-rec (decos lev) + "Recursive function for the implementation of the section tree + building. DECOS is a cons cell whose cdr is the remaining list + of decorations, and we change it as we consume them. LEV is + the current level of that node. This function returns a pair + of the subtree that was built. This treats the decos list + destructively." + + (let ((ndeco (cadr decos)) + node + children) + ;; If the next decoration matches our level + (if (= (car ndeco) lev) + (progn + ;; Pop the next decoration and create the current node with it + (setcdr decos (cddr decos)) + (setq node (cdr ndeco)) )) + ;; Else we let the node title/marker be unset. + + ;; Build the child nodes + (while (and (cdr decos) (> (caadr decos) lev)) + (setq children + (cons (rest-section-tree-rec decos (1+ lev)) + children))) + + ;; Return this node with its children. + (cons node (reverse children)) + )) + +(defun rest-toc-insert (&optional pfxarg) + "Insert a simple text rendering of the table of contents. +By default the top level is ignored if there is only one, because +we assume that the document will have a single title. + +If a numeric prefix argument is given, +- if it is zero or generic, include the top level titles; +- otherwise insert the TOC up to the specified level." + (interactive "P") + + (let* (;; Check maximum level override + (rest-toc-insert-max-level + (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) + (prefix-numeric-value pfxarg) rest-toc-insert-max-level)) + + ;; Get the section tree. + (sectree (rest-section-tree (rest-find-all-decorations))) + + ;; If there is only one top-level title, remove it by starting to print + ;; one index lower (revert this behaviour with the prefix arg), + ;; otherwise print all. + (gen-pfx-arg (or (and pfxarg (listp pfxarg)) + (and (integerp pfxarg) + (= (prefix-numeric-value pfxarg) 0)))) + (start-lev (if (and (not rest-toc-insert-always-include-top) + (= (length (cdr sectree)) 1) + (not gen-pfx-arg)) -1 0))) + + (rest-toc-insert-node sectree start-lev ""))) + +(defvar rest-toc-insert-always-include-top nil + "Set this to 't if you want to always include top-level titles, + even when there is only one.") + +(defvar rest-toc-insert-numbering t + "Set this to 't if you want to always include top-level titles, + even when there is only one.") + +(defvar rest-toc-insert-initial-indent " " + "Initial string that is inserted to the left of the inserted TOC. +You will want to make this match the block indent where you mean to insert it.") + +(defvar rest-toc-insert-max-level nil + "If non-nil, maximum depth of the inserted TOC.") + +(defun rest-toc-insert-node (node level pfx) + "Recursive function that does the print of the inserted +toc. PFX is the prefix numbering, that includes the alignment +necessary for all the children of this level to align." + (let ((do-print (> level 0)) + (count 1) + b) + (if do-print + (progn + (if (car node) + (progn + (insert rest-toc-insert-initial-indent) + (insert (make-string (* rest-toc-indent (1- level)) ? )) + (let ((b (point))) + (if rest-toc-insert-numbering + (insert pfx " ")) + (insert (caar node)) + ;; Add properties to the text, even though in normal text mode + ;; it won't be doing anything for now. Not sure that I want + ;; to change mode stuff. At least the highlighting gives the + ;; idea that this is generated automatically. + (put-text-property b (point) 'mouse-face 'highlight) + (put-text-property b (point) 'rest-toc-target (cadar node)) + ) + (insert "\n"))) + )) + + (if (or (eq rest-toc-insert-max-level nil) (< level rest-toc-insert-max-level)) + (let ((do-child-numbering (>= level 0)) + fmt) + (if do-child-numbering + (progn + ;; Add a separating dot if there is already a prefix + (if (> (length pfx) 0) + (setq pfx (concat (strip-whitespace pfx) "."))) + + ;; Calculate the amount of space that the prefix will require for + ;; the numbers. + (if (cdr node) + (setq fmt (format "%%-%dd" (1+ (floor (log10 (length (cdr node)))))))) + )) + + (dolist (child (cdr node)) + (rest-toc-insert-node child + (1+ level) + (if do-child-numbering + (concat pfx (format fmt count)) pfx)) + (incf count))) + + ))) + + +(defun rest-toc-node (node level) + "Recursive function that does the print of the TOC in rest-toc-mode." + + (if (> level 0) + (let ((b (point))) + ;; Insert line text. + (insert (make-string (* rest-toc-indent (1- level)) ? )) + (insert (if (car node) (caar node) "(missing node)")) + + ;; Highlight lines. + (put-text-property b (point) 'mouse-face 'highlight) + + ;; Add link on lines. + (put-text-property b (point) 'rest-toc-target (cadar node)) + + (insert "\n"))) + + (dolist (child (cdr node)) + (rest-toc-node child (1+ level)))) + + (defun rest-toc () "Finds all the section titles and their decorations in the file, and displays a hierarchically-organized list of the @@ -1042,67 +1243,47 @@ the hierarchy is similar to that used by rest-adjust-decoration." The emacs buffer can be navigated, and selecting a section brings the cursor in that section." (interactive) - (let* ((curpoint (point)) - foundline - (alldecos (rest-find-all-decorations)) - (hier (rest-get-hierarchy alldecos)) - (levels (make-hash-table :test 'equal :size 10)) + (let* ((curbuf (current-buffer)) + outline + + ;; Get the section tree + (alldecos (rest-find-all-decorations)) + (sectree (rest-section-tree alldecos)) + + ;; Create a temporary buffer. (buf (get-buffer-create rest-toc-buffer-name)) - lines) - (let ((lev 0)) - (dolist (deco hier) - (puthash deco lev levels) - (incf lev))) + ) + + ;; Find the index of the section where the cursor currently is. + (setq outline (let ((idx 1) + (curline (line-number-at-pos (point))) + (decos alldecos)) + (while (and decos (<= (caar decos) curline)) + (setq decos (cdr decos)) + (incf idx)) + idx)) + ;; FIXME: if there is a missing node inserted, the calculation of the + ;; current line will be off. You need to fix this by moving the finding of + ;; the current line somewhere else. - (let ((curline 1)) - (save-excursion - (setq lines - (mapcar (lambda (deco) - (goto-line (car deco)) - (if (and (not foundline) (> (point) curpoint)) - (setq foundline curline)) - (incf curline) - (list (rest-get-stripped-line) - (gethash (cdr deco) levels) - (let ((m (make-marker))) - (beginning-of-line 1) - (set-marker m (point))) - )) - alldecos))) - (if (not foundline) - (setq foundline curline)) - ) (with-current-buffer buf (let ((inhibit-read-only t)) (rest-toc-mode) (delete-region (point-min) (point-max)) - (insert (format "Table of Contents: %s\n" (caar lines))) - (put-text-property (point-min) (point) + (insert (format "Table of Contents: %s\n" (or (caar sectree) ""))) + (put-text-property (point-min) (point) 'face (list '(background-color . "lightgray"))) - (dolist (x lines) - (let* ( - ;; Compute line text to be inserted. - (ins (concat (make-string (* rest-toc-indent (cadr x)) ? ) - (car x))) - - ;; Compute boundaries of this text. - (beg (point)) - (end (+ beg (length ins))) - ) - ;; Insert line. - (insert ins "\n") - - ;; Highlight lines. - (put-text-property beg end 'mouse-face 'highlight) - - ;; Add link on lines. - (put-text-property beg end 'rest-toc-target (caddr x)) - )) + (rest-toc-node sectree 0) )) (display-buffer buf) (pop-to-buffer buf) - (goto-line foundline) + + ;; Save the buffer to return to. + (set (make-local-variable 'rest-toc-return-buffer) curbuf) + + ;; Move the cursor near the right section in the TOC. + (goto-line outline) )) @@ -1142,19 +1323,29 @@ the hierarchy is similar to that used by rest-adjust-decoration." (interactive "e") (call-interactively 'rest-toc-mode-mouse-goto event) (kill-buffer (get-buffer rest-toc-buffer-name))) - + +(defvar rest-toc-return-buffer nil + "Buffer local variable that is used to return to the original + buffer from the TOC.") + +(defun rest-toc-quit-window () + (interactive) + (quit-window) + (pop-to-buffer rest-toc-return-buffer)) + (defvar rest-toc-mode-map (let ((map (make-sparse-keymap))) (define-key map [mouse-1] 'rest-toc-mode-mouse-goto-kill) (define-key map [mouse-2] 'rest-toc-mode-mouse-goto) (define-key map "\C-m" 'rest-toc-mode-goto-section) (define-key map "f" 'rest-toc-mode-goto-section) - (define-key map "q" 'quit-window) + (define-key map "q" 'rest-toc-quit-window) (define-key map "z" 'kill-this-buffer) map) "Keymap for `rest-toc-mode'.") (put 'rest-toc-mode 'mode-class 'special) + (defun rest-toc-mode () "Major mode for output from \\[rest-toc]." (interactive) -- cgit v1.2.1 From 25dc2754796b3acf2f3f0aaa49a1cbd39f0de3d0 Mon Sep 17 00:00:00 2001 From: blais Date: Thu, 27 Oct 2005 16:31:46 +0000 Subject: Small changes in numbered toc insertion style following dave comments. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3956 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 96 ++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 15f4d9df4..642b2e364 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -1026,15 +1026,13 @@ the hierarchy is similar to that used by rest-adjust-decoration." )) ))) -(if (not (fboundp 'strip-whitespace)) - (defun strip-whitespace (str) - "Strips the whitespace around a string." - (let ((tmp)) - (string-match "\\`[ \t\n]*" str) - (setq tmp (substring str (match-end 0))) - (string-match "[ \t\n]*\\'" tmp) - (substring tmp 0 (match-beginning 0)) - ))) + +(defun rest-rstrip (str) + "Strips the whitespace at the end of a string." + (let ((tmp)) + (string-match "[ \t\n]*\\'" str) + (substring str 0 (match-beginning 0)) + )) (defun rest-get-stripped-line () "Returns the line at cursor, stripped from whitespace." @@ -1044,7 +1042,8 @@ the hierarchy is similar to that used by rest-adjust-decoration." (defvar rest-toc-indent 4 - "Indentation for table-of-contents display.") + "Indentation for table-of-contents display (also used for + formatting insertion, when numbering is disabled).") (defun rest-section-tree (alldecos) @@ -1123,7 +1122,10 @@ we assume that the document will have a single title. If a numeric prefix argument is given, - if it is zero or generic, include the top level titles; -- otherwise insert the TOC up to the specified level." +- otherwise insert the TOC up to the specified level. + +The TOC is inserted indented at the current column." + (interactive "P") (let* (;; Check maximum level override @@ -1142,9 +1144,17 @@ If a numeric prefix argument is given, (= (prefix-numeric-value pfxarg) 0)))) (start-lev (if (and (not rest-toc-insert-always-include-top) (= (length (cdr sectree)) 1) - (not gen-pfx-arg)) -1 0))) + (not gen-pfx-arg)) -1 0)) + + ;; Figure out initial indent. + (initial-indent (make-string (current-column) ? )) + (init-point (point))) + + (rest-toc-insert-node sectree start-lev initial-indent "") - (rest-toc-insert-node sectree start-lev ""))) + ;; Fixup for the first line. + (delete-region init-point (+ init-point (length initial-indent))) + )) (defvar rest-toc-insert-always-include-top nil "Set this to 't if you want to always include top-level titles, @@ -1154,38 +1164,49 @@ If a numeric prefix argument is given, "Set this to 't if you want to always include top-level titles, even when there is only one.") -(defvar rest-toc-insert-initial-indent " " - "Initial string that is inserted to the left of the inserted TOC. -You will want to make this match the block indent where you mean to insert it.") - (defvar rest-toc-insert-max-level nil "If non-nil, maximum depth of the inserted TOC.") -(defun rest-toc-insert-node (node level pfx) +(defun rest-toc-insert-node (node level indent pfx) "Recursive function that does the print of the inserted toc. PFX is the prefix numbering, that includes the alignment necessary for all the children of this level to align." (let ((do-print (> level 0)) (count 1) + (numbered-indent-style 'aligned) b) (if do-print (progn - (if (car node) - (progn - (insert rest-toc-insert-initial-indent) - (insert (make-string (* rest-toc-indent (1- level)) ? )) - (let ((b (point))) - (if rest-toc-insert-numbering - (insert pfx " ")) - (insert (caar node)) - ;; Add properties to the text, even though in normal text mode - ;; it won't be doing anything for now. Not sure that I want - ;; to change mode stuff. At least the highlighting gives the - ;; idea that this is generated automatically. - (put-text-property b (point) 'mouse-face 'highlight) - (put-text-property b (point) 'rest-toc-target (cadar node)) - ) - (insert "\n"))) + (insert indent) + (let ((b (point))) + (if rest-toc-insert-numbering + (insert pfx " ")) + (insert (or (caar node) "[missing node]")) + ;; Add properties to the text, even though in normal text mode it + ;; won't be doing anything for now. Not sure that I want to change + ;; mode stuff. At least the highlighting gives the idea that this + ;; is generated automatically. + (put-text-property b (point) 'mouse-face 'highlight) + (put-text-property b (point) 'rest-toc-target (cadar node)) + ) + (insert "\n") + + ;; Prepare indent for children. + (setq indent + (if (not rest-toc-insert-numbering) + (concat indent rest-toc-indent) + (cond + ((eq numbered-indent-style 'fixed) + (concat indent (make-string rest-toc-indent ? ))) + + ((eq numbered-indent-style 'aligned) + (concat indent (make-string (+ (length pfx) 2) ? ))) + + ((eq numbered-indent-style 'listed) + (concat (substring indent 0 -3) + (concat (make-string (+ (length pfx) 2) ? ) " - "))) + ))) + )) (if (or (eq rest-toc-insert-max-level nil) (< level rest-toc-insert-max-level)) @@ -1195,7 +1216,7 @@ necessary for all the children of this level to align." (progn ;; Add a separating dot if there is already a prefix (if (> (length pfx) 0) - (setq pfx (concat (strip-whitespace pfx) "."))) + (setq pfx (concat (rest-rstrip pfx) "."))) ;; Calculate the amount of space that the prefix will require for ;; the numbers. @@ -1205,7 +1226,8 @@ necessary for all the children of this level to align." (dolist (child (cdr node)) (rest-toc-insert-node child - (1+ level) + (1+ level) + indent (if do-child-numbering (concat pfx (format fmt count)) pfx)) (incf count))) @@ -1220,7 +1242,7 @@ necessary for all the children of this level to align." (let ((b (point))) ;; Insert line text. (insert (make-string (* rest-toc-indent (1- level)) ? )) - (insert (if (car node) (caar node) "(missing node)")) + (insert (if (car node) (caar node) "[missing node]")) ;; Highlight lines. (put-text-property b (point) 'mouse-face 'highlight) -- cgit v1.2.1 From 1512a0a05f8f988c305e9a0f5f8dab08f20e8ae4 Mon Sep 17 00:00:00 2001 From: blais Date: Fri, 28 Oct 2005 13:14:43 +0000 Subject: Added auto-updating TOC at the top of the file and refined TOC features. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3957 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/restructuredtext.el | 223 ++++++++++++++++++++++++-------- 1 file changed, 168 insertions(+), 55 deletions(-) diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el index 642b2e364..738ac18b4 100644 --- a/tools/editors/emacs/restructuredtext.el +++ b/tools/editors/emacs/restructuredtext.el @@ -39,12 +39,31 @@ ;; code). The most important function provided by this file for section title ;; adjustments is rest-adjust. ;; -;; You should consider customizing the following variables: +;; There are many variables that can be customized, look for defcustom and +;; defvar in this file. ;; -;; - rest-default-indent -;; - rest-preferred-decorations +;; If you use the table-of-contents feature, you may want to add a hook to +;; update the TOC automatically everytime you adjust a section title:: ;; -;; TODO: +;; (add-hook 'rest-adjust-hook 'rest-toc-insert-update) +;; +;; +;; TODO +;; ==== +;; +;; rest-toc-insert features +;; ------------------------ +;; - Support local table of contents, like in doctree.txt. +;; - On load, detect any existing TOCs and set the properties for links. +;; - TOC insertion should have an option to add empty lines. +;; - TOC insertion should deal with multiple lines +;; +;; - There is a bug on redo after undo of adjust when rest-adjust-hook uses the +;; automatic toc update. The cursor ends up in the TOC and this is +;; annoying. Gotta fix that. +;; +;; Other +;; ----- ;; - Add an option to forego using the file structure in order to make ;; suggestion, and to always use the preferred decorations to do that. ;; @@ -52,6 +71,34 @@ (require 'cl) +(defun rest-toc-or-hierarchy () + "Binding for either TOC or decorations hierarchy." + (interactive) + (if (not current-prefix-arg) + (rest-toc) + (rest-display-decorations-hierarchy))) + +(defun rest-text-mode-hook () + "Default text mode hook for rest." + (local-set-key [(control ?=)] 'rest-adjust) + (local-set-key [(control x)(control ?=)] 'rest-toc-or-hierarchy) + (local-set-key [(control x)(?+)] 'rest-toc-insert) + (local-set-key [(control meta ?{)] 'rest-backward-section) + (local-set-key [(control meta ?})] 'rest-forward-section) + ) + +;; Note: we cannot do this because it messes with undo. If we disable undo, +;; since it adds and removes characters, the positions in the undo list are not +;; making sense anymore. Dunno what to do with this, it would be nice to update +;; when saving. +;; +;; (add-hook 'write-contents-hooks 'rest-toc-insert-update-fun) +;; (defun rest-toc-insert-update-fun () +;; ;; Disable undo for the write file hook. +;; (let ((buffer-undo-list t)) (rest-toc-insert-update) )) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Generic Filter function. @@ -157,22 +204,6 @@ is for which (pred elem) is true)" ;; adjustment (unless we cycle, in which case we use the indent that has been ;; found previously). -(defun rest-toc-or-hierarchy () - "Binding for either TOC or decorations hierarchy." - (interactive) - (if (not current-prefix-arg) - (rest-toc) - (rest-display-decorations-hierarchy))) - -(defun rest-text-mode-hook () - "Default text mode hook for rest." - (local-set-key [(control ?=)] 'rest-adjust) - (local-set-key [(control x)(control ?=)] 'rest-toc-or-hierarchy) - (local-set-key [(control x)(?+)] 'rest-toc-insert) - (local-set-key [(control meta ?{)] 'rest-backward-section) - (local-set-key [(control meta ?})] 'rest-forward-section) - ) - (defcustom rest-preferred-decorations '( (?= over-and-under 1) (?= simple 0) (?- simple 0) @@ -655,8 +686,14 @@ b. a negative numerical argument, which generally inverts the (rest-promote-region current-prefix-arg) ;; Adjust decoration around point. (rest-adjust-decoration toggle-style reverse-direction)) + + ;; Run the hooks to run after adjusting. + (run-hooks 'rest-adjust-hook) + )) +(defvar rest-adjust-hook nil + "Hooks to be run after running rest-adjust.") (defun rest-adjust-decoration (&optional toggle-style reverse-direction) "Adjust/rotate the section decoration for the section title around point. @@ -1041,7 +1078,7 @@ the hierarchy is similar to that used by rest-adjust-decoration." (match-end 0)) ) -(defvar rest-toc-indent 4 +(defcustom rest-toc-indent 2 "Indentation for table-of-contents display (also used for formatting insertion, when numbering is disabled).") @@ -1093,7 +1130,7 @@ inserted automatically, and are set to nil." the current level of that node. This function returns a pair of the subtree that was built. This treats the decos list destructively." - + (let ((ndeco (cadr decos)) node children) @@ -1107,7 +1144,7 @@ inserted automatically, and are set to nil." ;; Build the child nodes (while (and (cdr decos) (> (caadr decos) lev)) - (setq children + (setq children (cons (rest-section-tree-rec decos (1+ lev)) children))) @@ -1115,12 +1152,13 @@ inserted automatically, and are set to nil." (cons node (reverse children)) )) + (defun rest-toc-insert (&optional pfxarg) "Insert a simple text rendering of the table of contents. By default the top level is ignored if there is only one, because -we assume that the document will have a single title. +we assume that the document will have a single title. -If a numeric prefix argument is given, +If a numeric prefix argument is given, - if it is zero or generic, include the top level titles; - otherwise insert the TOC up to the specified level. @@ -1132,15 +1170,15 @@ The TOC is inserted indented at the current column." (rest-toc-insert-max-level (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) (prefix-numeric-value pfxarg) rest-toc-insert-max-level)) - + ;; Get the section tree. (sectree (rest-section-tree (rest-find-all-decorations))) - + ;; If there is only one top-level title, remove it by starting to print ;; one index lower (revert this behaviour with the prefix arg), ;; otherwise print all. (gen-pfx-arg (or (and pfxarg (listp pfxarg)) - (and (integerp pfxarg) + (and (integerp pfxarg) (= (prefix-numeric-value pfxarg) 0)))) (start-lev (if (and (not rest-toc-insert-always-include-top) (= (length (cdr sectree)) 1) @@ -1154,17 +1192,36 @@ The TOC is inserted indented at the current column." ;; Fixup for the first line. (delete-region init-point (+ init-point (length initial-indent))) + + ;; Delete the last newline added. + (delete-backward-char 1) )) -(defvar rest-toc-insert-always-include-top nil - "Set this to 't if you want to always include top-level titles, - even when there is only one.") -(defvar rest-toc-insert-numbering t +(defcustom rest-toc-insert-always-include-top nil "Set this to 't if you want to always include top-level titles, even when there is only one.") -(defvar rest-toc-insert-max-level nil +(defcustom rest-toc-insert-style 'fixed + "Set this to one of the following values to determine numbering and +indentation style: +- plain: no numbering (fixed indentation) +- fixed: numbering, but fixed indentation +- aligned: numbering, titles aligned under each other +- listed: numbering, with dashes like list items (EXPERIMENTAL) +") + +(defcustom rest-toc-insert-number-separator " " + "Separator that goes between the TOC number and the title.") + +;; This is used to avoid having to change the user's mode. +(defvar rest-toc-insert-click-keymap + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'rest-toc-mode-mouse-goto) + map) + "(Internal) What happens when you click on propertized text in the TOC.") + +(defcustom rest-toc-insert-max-level nil "If non-nil, maximum depth of the inserted TOC.") (defun rest-toc-insert-node (node level indent pfx) @@ -1173,14 +1230,13 @@ toc. PFX is the prefix numbering, that includes the alignment necessary for all the children of this level to align." (let ((do-print (> level 0)) (count 1) - (numbered-indent-style 'aligned) b) (if do-print (progn (insert indent) (let ((b (point))) - (if rest-toc-insert-numbering - (insert pfx " ")) + (if (not (equal rest-toc-insert-style 'plain)) + (insert pfx rest-toc-insert-number-separator)) (insert (or (caar node) "[missing node]")) ;; Add properties to the text, even though in normal text mode it ;; won't be doing anything for now. Not sure that I want to change @@ -1188,28 +1244,32 @@ necessary for all the children of this level to align." ;; is generated automatically. (put-text-property b (point) 'mouse-face 'highlight) (put-text-property b (point) 'rest-toc-target (cadar node)) + (put-text-property b (point) 'keymap rest-toc-insert-click-keymap) + ) (insert "\n") ;; Prepare indent for children. - (setq indent - (if (not rest-toc-insert-numbering) - (concat indent rest-toc-indent) - (cond - ((eq numbered-indent-style 'fixed) - (concat indent (make-string rest-toc-indent ? ))) - - ((eq numbered-indent-style 'aligned) - (concat indent (make-string (+ (length pfx) 2) ? ))) - - ((eq numbered-indent-style 'listed) - (concat (substring indent 0 -3) - (concat (make-string (+ (length pfx) 2) ? ) " - "))) - ))) + (setq indent + (cond + ((eq rest-toc-insert-style 'plain) + (concat indent rest-toc-indent)) + + ((eq rest-toc-insert-style 'fixed) + (concat indent (make-string rest-toc-indent ? ))) + + ((eq rest-toc-insert-style 'aligned) + (concat indent (make-string (+ (length pfx) 2) ? ))) + + ((eq rest-toc-insert-style 'listed) + (concat (substring indent 0 -3) + (concat (make-string (+ (length pfx) 2) ? ) " - "))) + )) )) - (if (or (eq rest-toc-insert-max-level nil) (< level rest-toc-insert-max-level)) + (if (or (eq rest-toc-insert-max-level nil) + (< level rest-toc-insert-max-level)) (let ((do-child-numbering (>= level 0)) fmt) (if do-child-numbering @@ -1221,20 +1281,73 @@ necessary for all the children of this level to align." ;; Calculate the amount of space that the prefix will require for ;; the numbers. (if (cdr node) - (setq fmt (format "%%-%dd" (1+ (floor (log10 (length (cdr node)))))))) + (setq fmt (format "%%-%dd" + (1+ (floor (log10 (length (cdr node)))))))) )) (dolist (child (cdr node)) - (rest-toc-insert-node child + (rest-toc-insert-node child (1+ level) indent - (if do-child-numbering + (if do-child-numbering (concat pfx (format fmt count)) pfx)) (incf count))) ))) +(defun rest-toc-insert-find-delete-contents () + "Finds and deletes an existing comment after the first contents directive and +delete that region. Return t if found and the cursor is left after the comment." + (goto-char (point-min)) + ;; We look for the following and the following only (in other words, if your + ;; syntax differs, this won't work. If you would like a more flexible thing, + ;; contact the author, I just can't imagine that this requirement is + ;; unreasonable for now). + ;; + ;; .. contents:: [...anything here...] + ;; .. + ;; XXXXXXXX + ;; XXXXXXXX + ;; [more lines] + ;; + (let ((beg + (re-search-forward "^\\.\\. contents[ \t]*::\\(.*\\)\n\\.\\." + nil t)) + last-real) + (when beg + ;; Look for the first line that starts at the first column. + (forward-line 1) + (beginning-of-line) + (while (or (and (looking-at "[ \t]+[^ \t]") + (setq last-real (point)) t) + (looking-at "\\s-*$")) + (forward-line 1) + ) + (if last-real + (progn + (goto-char last-real) + (end-of-line) + (delete-region beg (point))) + (goto-char beg)) + t + ))) + +(defun rest-toc-insert-update () + "Automatically find the .. contents:: section of a document and update the +inserted TOC if present. You can use this in your file-write hook to always +make it up-to-date automatically." + (interactive) + (save-excursion + (if (rest-toc-insert-find-delete-contents) + (progn (insert "\n ") + (rest-toc-insert))) ) + ;; Note: always return nil, because this may be used as a hook. + ) + + +;;------------------------------------------------------------------------------ + (defun rest-toc-node (node level) "Recursive function that does the print of the TOC in rest-toc-mode." @@ -1246,7 +1359,7 @@ necessary for all the children of this level to align." ;; Highlight lines. (put-text-property b (point) 'mouse-face 'highlight) - + ;; Add link on lines. (put-text-property b (point) 'rest-toc-target (cadar node)) -- cgit v1.2.1 From b4e10620d3e91babd7b976a694ddc68ba3824777 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 28 Oct 2005 15:10:06 +0000 Subject: test for non-breaking space git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3959 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_parsers/test_rst/test_enumerated_lists.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index 6824efdbb..b8ab093e5 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -650,13 +650,19 @@ Nested enumerated lists: Item 3. """], -["""\ +[u"""\ A. Einstein was a great influence on B. Physicist, who was a colleague of C. Chemist. They all worked in Princeton, NJ. + +Using a non-breaking space as a workaround: + +A.\u00a0Einstein was a great influence on +B. Physicist, who was a colleague of +C. Chemist. They all worked in +Princeton, NJ. """, -# @@@ I think this is the correct result, but I'm not certain: """\ @@ -672,6 +678,13 @@ Princeton, NJ. C. Chemist. They all worked in Princeton, NJ. + + Using a non-breaking space as a workaround: + + A.\xa0Einstein was a great influence on + B. Physicist, who was a colleague of + C. Chemist. They all worked in + Princeton, NJ. """], ["""\ 1. Item one: line 1, -- cgit v1.2.1 From 2b57cc35ca4e7793926e93ad1f7642acac61f5df Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 28 Oct 2005 16:11:45 +0000 Subject: clarified role of indentation git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3960 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/restructuredtext.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 921ac31a4..3359d19a7 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -241,15 +241,14 @@ line of a document is treated as if it is followed by a blank line. Indentation ----------- -Indentation is used to indicate, and is only significant in -indicating: - -- multi-line contents of list items, -- multiple body elements within a list item (including nested lists), -- the definition part of a definition list item, -- block quotes, -- the extent of literal blocks, and -- the extent of explicit markup blocks. +Indentation is used to indicate -- and is only significant in +indicating -- block quotes, definitions (in definition list items), +and local nested content: + +- list item content (multi-line contents of list items, and multiple + body elements within a list item, including nested lists), +- the content of literal blocks, and +- the content of explicit markup blocks. Any text whose indentation is less than that of the current level (i.e., unindented text or "dedents") ends the current level of -- cgit v1.2.1 From 346f8dfa0961a46400be6764ea74337b5e13c7b6 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 28 Oct 2005 16:12:07 +0000 Subject: updated the project policies for trunk/branch development & version numbering git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3961 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 388 +++++++++++++++++++++++++++++------------------- docs/dev/repository.txt | 23 +-- docs/dev/testing.txt | 54 ++++++- 3 files changed, 302 insertions(+), 163 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 3feae2f30..e09f5ea67 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -10,17 +10,17 @@ .. contents:: -Docutils is a meritocracy based on code contribution and lots of -discussion [#bcs]_. A few quotes sum up the policies of the Docutils -project. The IETF's classic credo (by MIT professor Dave Clark) is an -ideal we can aspire to: +The Docutils project group is a meritocracy based on code contribution +and lots of discussion [#bcs]_. A few quotes sum up the policies of +the Docutils project. The IETF's classic credo (by MIT professor Dave +Clark) is an ideal we can aspire to: We reject: kings, presidents, and voting. We believe in: rough consensus and running code. -As architect, chief cook and bottle-washer, I currently function as -BDFN (Benevolent Dictator For Now), but I would happily abdicate the -throne given a suitable candidate. Any takers? +As architect, chief cook and bottle-washer, David Goodger currently +functions as BDFN (Benevolent Dictator For Now). (But he would +happily abdicate the throne given a suitable candidate. Any takers?) Eric S. Raymond, anthropologist of the hacker subculture, writes in his essay `The Magic Cauldron`_: @@ -32,10 +32,10 @@ his essay `The Magic Cauldron`_: .. _The Magic Cauldron: http://www.tuxedo.org/~esr/writings/magic-cauldron/ -Therefore, we will endeavour to keep the barrier to entry as low as -possible. The policies below should not be thought of as barriers, -but merely as a codification of experience to date. These are "best -practices", not absolutes; exceptions are expected, tolerated, and +We will endeavour to keep the barrier to entry as low as possible. +The policies below should not be thought of as barriers, but merely as +a codification of experience to date. These are "best practices"; +guidelines, not absolutes. Exceptions are expected, tolerated, and used as a source of improvement. Feedback and criticism is welcome. As for control issues, Emmett Plant (CEO of the Xiph.org Foundation, @@ -51,25 +51,24 @@ originators of Ogg Vorbis) put it well when he said: Python Coding Conventions ========================= -These are the conventions I use in my own code. Contributed code will -not be refused merely because it does not strictly adhere to these -conditions; as long as it's internally consistent, clean, and correct, -it probably will be accepted. But don't be surprised if the -"offending" code gets fiddled over time to conform to these -conventions. +Contributed code will not be refused merely because it does not +strictly adhere to these conditions; as long as it's internally +consistent, clean, and correct, it probably will be accepted. But +don't be surprised if the "offending" code gets fiddled over time to +conform to these conventions. The Docutils project shall follow the generic coding conventions as specified in the `Style Guide for Python Code`_ and `Docstring Conventions`_ PEPs, with the following clarifications and extensions: -* 4 spaces per indentation level. No tabs. +* 4 spaces per indentation level. No hard tabs. -* Use only ASCII, no 8-bit strings. See `Docutils +* Use only 7-bit ASCII, no 8-bit strings. See `Docutils Internationalization`_. * No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method - definitions (i.e., ``class X: pass`` is O.K.). + definitions (i.e., ``class X: pass`` is OK.). * Lines should be no more than 78 characters long. @@ -109,7 +108,8 @@ Documentation Conventions * Docutils documentation is written using reStructuredText, of course. -* Use 7-bit ASCII if at all possible. +* Use 7-bit ASCII if at all possible, and Unicode substitutions when + necessary. * Use the following section title adornment styles:: @@ -121,16 +121,20 @@ Documentation Conventions Document Subtitle (optional) ------------------------------ + (The doc. subtitle adornment style can also be used for major + top-level sections.) + Section ======= Subsection ---------- - If you need subsubsections and further, these characters are - recommended for title underlines:: + Sub-Subsection + `````````````` - ` . + Sub-Sub-Subsection + .................. * Use two blank lines before each section/subsection/etc. title. One blank line is sufficient between immediately adjacent titles. @@ -138,7 +142,7 @@ Documentation Conventions * Add a bibliographic field list immediately after the document title/subtitle. See the beginning of this document for an example. -* Add an Emacs local variables block in a comment at the end of the +* Add an Emacs "local variables" block in a comment at the end of the document. See the end of this document for an example. @@ -169,120 +173,121 @@ Software Foundation (PSF), and will be released under Python's license. If the copyright/license option is chosen for new files, the license should be compatible with Python's current license, and the author(s) of the files should be willing to assign copyright to the -PSF. +PSF. The PSF accepts the `Academic Free License v. 2.1 +`_ and the `Apache +License, Version 2.0 `_. -Subversion Check-ins -==================== +Subversion Repository +===================== Please see the `repository documentation`_ for details on how to access Docutils' Subversion repository. Anyone can access the repository anonymously. Only project developers can make changes. -Also see `Setting Up For Docutils Development`_ below for more info. +(If you would like to become a project developer, just ask!) Also see +`Setting Up For Docutils Development`_ below for some useful info. -.. _repository documentation: repository.html +.. Caution:: -Unless you really *really* know what you're doing, please limit your -Subversion commands to ``svn checkout``, ``svn commit``, and ``svn -add``. Do **NOT** use ``svn import`` unless you're absolutely sure -you know what you're doing. Even then, grab a copy of the `nightly -repository tarball`_, set it up on your own machine, and experiment -*there* first (but remove hooks/post-commit first). + Unless you really *really* know what you're doing, please do + **NOT** use ``svn import``. Only use ``svn import`` if you're + **absolutely sure you know what you're doing**. Even then, first + grab a copy of the `nightly repository tarball`_, set it up on your + own machine, remove ``hooks/post-commit``, and experiment *there*. + It's quite easy to mess up the repository with an import. -The `main source tree`_ ("trunk/docutils" directory) should always be -kept in a stable state (usable and as problem-free as possible). The -Docutils project shall follow the `Python Check-in Policies`_ (as -applicable), with particular emphasis as follows: +.. _repository documentation: repository.html -* Before checking in any changes, run the entire Docutils test suite - to be sure that you haven't broken anything. From a shell:: - cd docutils/test - ./alltests.py +Branches +-------- - Docutils currently supports Python 2.1 [#py21]_ or later, with some - things only working (and being tested) on Python 2.3+. Therefore, - you should actually have Pythons 2.1 [#py21]_, 2.2 and 2.3 installed - and always run the tests on all of them. (A good way to do that is - to always run the test suite through a short script that runs - ``alltests.py`` under each version of Python.) If you can't afford - intalling 3 Python versions, the edge cases (2.1 and 2.3) should - cover most of it. +The "docutils" directory of the **trunk** (a.k.a. the **Docutils +core**) is used for active -- but stable, fully tested, and reviewed +-- development. - .. [#py21] Python 2.1 may be used providing the compiler package is - installed. The compiler package can be found in the Tools/ - directory of Python 2.1's source distribution. +There will be at least one active **maintenance branch** at a time, +based on at least the latest feature release. For example, when +Docutils 0.5 is released, its maintenance branch will take over, and +the 0.4.x maintenance branch may be retired. Maintenance branches +will receive bug fixes only; no new features will be allowed here. - Good resources covering the differences between Python versions: +Obvious and uncontroversial bug fixes *with tests* can be checked in +directly to the core and to the maintenance branches. Don't forget to +add test cases! Many (but not all) bug fixes will be applicable both +to the core and to the maintenance branches; these should be applied +to both. No patches or dedicated branches are required for bug fixes, +but they may be used. It is up to the discretion of project +developers to decide which mechanism to use for each case. - * `What's New in Python 2.2`__ - * `What's New in Python 2.3`__ - * `What's New in Python 2.4`__ - * `PEP 290 - Code Migration and Modernization`__ +Feature additions and API changes will be done in **feature +branches**. Feature branches will not be managed in any way. +Frequent small checkins are encouraged here. Feature branches must be +discussed on the docutils-develop mailing list and reviewed before +being merged into the core. - __ http://www.python.org/doc/2.2.3/whatsnew/whatsnew22.html - __ http://www.python.org/doc/2.3.5/whatsnew/whatsnew23.html - __ http://www.python.org/doc/2.4.1/whatsnew/whatsnew24.html - __ http://www.python.org/peps/pep-0290.html -* When adding new functionality (or fixing bugs), be sure to add test - cases to the test suite. Practise test-first programming; it's fun, - it's addictive, and it works! +Review Criteria +``````````````` -* The `sandbox directory`_ is the place to put new, incomplete or - experimental code. See `Additions to Docutils`_ and `The Sandbox`_ - below. +Before a new feature, an API change, or a complex, disruptive, or +controversial bug fix can be checked in to the core or into a +maintenance branch, it must undergo review. These are the criteria: -* For bugs or omissions that have an obvious fix and can't possibly - mess up anything else, go right ahead and check it in directly. +* The branch must be complete, and include full documentation and + tests. -* For larger changes, use your best judgement. If you're unsure of - the impact, or feel that you require advice or approval, branches, - patches, or `the sandbox`_ are the way to go. +* There should ideally be one branch merge commit per feature or + change. In other words, each branch merge should represent a + coherent change set. -* You must be prepared to fix any code you have committed. +* The code must be stable and uncontroversial. Moving targets and + features under debate are not ready to be merged. -Docutils will pursue an open and trusting policy for as long as -possible, and deal with any aberrations if (and hopefully not when) -they happen. I'd rather see a torrent of loose contributions than -just a trickle of perfect-as-they-stand changes. The occasional -mistake is easy to fix. That's what Subversion is for. +* The code must work. The test suite must complete with no failures. + See `Docutils Testing`_. -.. _main source tree: - http://svn.berlios.de/viewcvs/docutils/trunk/docutils/ -.. _Python Check-in Policies: http://www.python.org/dev/tools.html -.. _sandbox directory: - http://svn.berlios.de/viewcvs/docutils/trunk/sandbox/ -.. _nightly repository tarball: - http://svn.berlios.de/svndumps/docutils-repos.gz +The review process will ensure that at least one other set of eyeballs +& brains sees the code before it enters the core. In addition to the +above, the general `Check-ins`_ policy (below) also applies. +.. _Docutils Testing: testing.html -Additions to Docutils ---------------------- -Additions to the project, such as new components, should be developed -in the `sandbox directory`_ until they're in `good shape`_, usable_, -documented_, and `reasonably complete`_. Adding to the `main source -tree`_ or to a `parallel project`_ implies a commitment to the -Docutils user community. +Check-ins +--------- -* Why the sandbox? +In general, the Docutils project follows the `Python Check-in +Policies`_ as applicable. There are some differences (e.g., we use +Subversion now, not CVS), and we place particular emphasis as follows. - Developers should be able to try out new components while they're - being developed for addition to main source tree. See `The - Sandbox`_ below. +Changes or additions to the Docutils core and maintenance branches +carry a commitment to the Docutils user community. Developers must be +prepared to fix and maintain any code they have committed. -* _`Good shape` means that the component code is clean, readable, and - free of junk code (unused legacy code; by analogy with "junk DNA"). +The Docutils core (``trunk/docutils`` directory) and maintenance +branches should always be kept in a stable state (usable and as +problem-free as possible). All changes to the Docutils core or +maintenance branches must be in `good shape`_, usable_, documented_, +tested_, and `reasonably complete`_. + +* _`Good shape` means that the code is clean, readable, and free of + junk code (unused legacy code; by analogy to "junk DNA"). * _`Usable` means that the code does what it claims to do. An "XYZ - Writer" should produce reasonable XYZ. + Writer" should produce reasonable XYZ output. + +* _`Documented`: The more complete the documentation the better. + Modules & files must be at least minimally documented internally. + `Docutils Front-End Tools`_ should have a new section for any + front-end tool that is added. `Docutils Configuration Files`_ + should be modified with any settings/options defined. -* _`Documented`: The more the better. The modules/files must be at - least minimally documented internally. `Docutils Front-End Tools`_ - should have a new section for any front-end tool that is added. - `Docutils Configuration Files`_ should be modified with any - settings/options defined. +* _`Tested` means that unit and/or functional tests, that catch all + bugs fixed and/or cover all new functionality, have been added to + the test suite. These tests must be checked by running the test + suite under all supported Python versions, and the entire test suite + must pass. See `Docutils Testing`_. * _`Reasonably complete` means that the code must handle all input. Here "handle" means that no input can cause the code to fail (cause @@ -293,67 +298,143 @@ Docutils user community. must *at the very least* warn that "Output for element X is not yet implemented in writer Y". -If you really want to check code into the main source tree, you can, -but you'll have to be prepared to work on it intensively and complete -it quickly. People will start to use it and they will expect it to -work! If there are any issues with your code, or if you only have -time for gradual development, you should put it in the sandbox first. -It's easy to move code over to the main source tree once it's closer -to completion. +If you really want to check code directly into the Docutils core, +you can, but you must ensure that it fulfills the above criteria +first. People will start to use it and they will expect it to work! +If there are any issues with your code, or if you only have time for +gradual development, you should put it on a branch or in the sandbox +first. It's easy to move code over to the Docutils core once it's +complete. + +It is the responsibility and obligation of all developers to keep the +Docutils core and maintenance branches stable. If a commit is made to +the core or maintenance branch which breaks any test, the solution is +simply to revert the change. This is not vindictive; it's practical. +We revert first, and discuss later. + +Docutils will pursue an open and trusting policy for as long as +possible, and deal with any aberrations if (and hopefully not when) +they happen. We'd rather see a torrent of loose contributions than +just a trickle of perfect-as-they-stand changes. The occasional +mistake is easy to fix. That's what Subversion is for! .. _Docutils Front-End Tools: ../user/tools.html -.. _Docutils Configuration Files: ../user/config.html +.. _Docutils Configuration Files: ../user/config.htm +.. _Python Check-in Policies: + http://www.python.org/dev/tools.html#check-in-policies +.. _nightly repository tarball: + http://svn.berlios.de/svndumps/docutils-repos.gz + + +Version Numbering +================= + +Docutils version numbering uses a ``major.minor.micro`` scheme (x.y.z; +for example, 0.4.1). + +**Major releases** (x.0, e.g. 1.0) will be rare, and will represent +major changes in API, functionality, or commitment. For example, as +long as the major version of Docutils is 0, it is to be considered +*experimental code*. When Docutils reaches version 1.0, the major +APIs will be considered frozen and backward compatibility will become +of paramount importance. + +Releases that change the minor number (x.y, e.g. 0.5) will be +**feature releases**; new features from the `Docutils core`_ will be +included. + +Releases that change the micro number (x.y.z, e.g. 0.4.1) will be +**bug-fix releases**. No new features will be introduced in these +releases; only bug fixes off of `maintenance branches`_ will be +included. + +This policy was adopted in October 2005, and will take effect with +Docutils version 0.4. Prior to version 0.4, Docutils didn't have an +official version numbering policy, and micro releases contained both +bug fixes and new features. + +.. _Docutils core: + http://svn.berlios.de/viewcvs/docutils/trunk/docutils/ +.. _maintenance branches: + http://svn.berlios.de/viewcvs/docutils/branches/ + + +Snapshots +========= + +Snapshot tarballs will be generated regularly from + +* the Docutils core, representing the current cutting-edge state of + development; + +* each active maintenance branch, for bug fixes; + +* each development branch, representing the unstable + seat-of-your-pants bleeding edge. + +The ``sandbox/infrastructure/docutils-update`` shell script, run as an +hourly cron job on the BerliOS server, is responsible for +automatically generating the snapshots and updating the web site. See +the `web site docs `__. Setting Up For Docutils Development ------------------------------------ +=================================== + +When making changes to the code, testing is a must. The code should +be run to verify that it produces the expected results, and the entire +test suite should be run too. The modified Docutils code has to be +accessible to Python for the tests to have any meaning. There are two +ways to keep the Docutils code accessible during development: + +1. Update your ``PYTHONPATH`` environment variable so that Python + picks up your local working copy of the code. This is the + recommended method. -When making changes to the code, good developers always test their -changes. That means running the code to check that it produces the -expected results, and running the test suite too. The modified -Docutils code has to be accessible to Python for the tests to have any -meaning. There are two ways to keep the Docutils code accessible: + We'll assume that the Docutils trunk is checked out under your + ~/projects/ directory as follows:: -* Update your ``PYTHONPATH`` environment variable so that Python picks - up your local working copy of the code. This is the recommended - method. + svn co svn+ssh://@svn.berlios.de/svnroot/repos/docutils/trunk \ + docutils - For the bash shell and Docutils checked out from Subversion in - ``~/projects/docutils/``, add this to your ``~/.profile``:: + For the bash shell, add this to your ``~/.profile``:: - PYTHONPATH=$HOME/projects/docutils/docutils - PYTHONPATH=$PYTHONPATH:$HOME/projects/docutils/docutils/extras - export PYTHONPATH + PYTHONPATH=$HOME/projects/docutils/docutils + PYTHONPATH=$PYTHONPATH:$HOME/projects/docutils/docutils/extras + export PYTHONPATH - The first line points to the directory containing the ``docutils`` - package. The second line adds the directory containing the - third-party modules Docutils depends on. The third line exports - this environment variable. You may also wish to add the ``tools`` - directory to your ``PATH``:: + The first line points to the directory containing the ``docutils`` + package. The second line adds the directory containing the + third-party modules Docutils depends on. The third line exports + this environment variable. You may also wish to add the ``tools`` + directory to your ``PATH``:: - PATH=$PATH:$HOME/projects/docutils/docutils/tools + PATH=$PATH:$HOME/projects/docutils/docutils/tools + export PATH -* Before you run anything, every time you make a change, reinstall - Docutils:: +2. Before you run anything, every time you make a change, reinstall + Docutils:: - python setup.py install + python setup.py install - .. CAUTION:: + .. CAUTION:: - This method is **not** recommended for day-to-day development; - it's too easy to forget. Confusion inevitably ensues. + This method is **not** recommended for day-to-day development; + it's too easy to forget. Confusion inevitably ensues. - If you install Docutils this way, Python will always pick up the - last-installed copy of the code. If you ever forget to reinstall - the "docutils" package, Python won't see your latest changes. + If you install Docutils this way, Python will always pick up the + last-installed copy of the code. If you ever forget to + reinstall the "docutils" package, Python won't see your latest + changes. Mailing Lists ============= -Developers are recommended to subscribe to all `mailing lists`_. +Developers are recommended to subscribe to all `Docutils mailing +lists`_. -.. _mailing lists: ../user/mailing-lists.html +.. _Docutils mailing lists: ../user/mailing-lists.html The Wiki @@ -371,11 +452,12 @@ The `sandbox directory`_ is a place to play around, to try out and share ideas. It's a part of the Subversion repository but it isn't distributed as part of Docutils releases. Feel free to check in code to the sandbox; that way people can try it out but you won't have to -worry about it working 100% error-free, as is the goal of the `main -source tree`_. Each developer who wants to play in the sandbox should -create either a project-specific subdirectory or personal subdirectory +worry about it working 100% error-free, as is the goal of the Docutils +core. Each developer who wants to play in the sandbox should create +either a project-specific subdirectory or personal subdirectory (suggested name: SourceForge ID, nickname, or given name + family -initial). It's OK to make a mess! But please, play nice. +initial). It's OK to make a mess in your personal space! But please, +play nice. Please update the `sandbox README`_ file with links and a brief description of your work. @@ -385,11 +467,11 @@ out new, experimental components, the following sandbox directory structure is recommended:: sandbox/ - project_name/ # For a project where you invite contributions. + project_name/ # For a collaborative project. # Structure as in userid/component_name below. userid/ # For personal space. component_name/ # A verbose name is best. - README.txt # Please explain requirements, + README.txt # Please explain the requirements, # purpose/goals, and usage. docs/ ... @@ -413,6 +495,8 @@ completed. Others, such as add-ons to Docutils or applications of Docutils, graduate to become `parallel projects`_. .. _sandbox README: http://docutils.sf.net/sandbox/README.html +.. _sandbox directory: + http://svn.berlios.de/viewcvs/docutils/trunk/sandbox/ .. _parallel project: diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 730e54e42..6c9e0f94a 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -12,7 +12,6 @@ .. contents:: - Docutils uses a Subversion_ repository located at ``svn.berlios.de``. Subversion is exhaustively documented in the `Subversion Book`_ (svnbook). @@ -26,6 +25,11 @@ Subversion is exhaustively documented in the `Subversion Book`_ (web site, snapshots, releases, mailing lists, trackers) is hosted at SourceForge. +For the project policy on repository use (check-in requirements, +branching, etc.), please see the `Docutils Project Policies`__. + +__ policies.html#subversion-repository + Accessing the Repository ======================== @@ -74,20 +78,21 @@ their BerliOS user name to `Felix Wiemann `_.) __ https://developer.berlios.de/account/register.php If you are a developer, you get read-write access via -``svn+ssh://username@svn.berlios.de/svnroot/repos/docutils/``, where -``username`` is your BerliOS user name. So to retrieve a working -copy, type :: +``svn+ssh://@svn.berlios.de/svnroot/repos/docutils/``, where +```` is your BerliOS user account name. So to retrieve a +working copy, type :: - svn checkout svn+ssh://username@svn.berlios.de/svnroot/repos/docutils/trunk docutils + svn checkout svn+ssh://@svn.berlios.de/svnroot/repos/docutils/trunk \ + docutils If you previously had an anonymous working copy and gained developer access, you can switch the URL associated with your working copy by typing :: svn switch --relocate svn://svn.berlios.de/docutils/trunk/docutils \ - svn+ssh://username@svn.berlios.de/svnroot/repos/docutils + svn+ssh://@svn.berlios.de/svnroot/repos/docutils -(``username`` is again your BerliOS user name.) +(Again, ```` is your BerliOS user account name.) Setting Up Your Subversion Client For Development @@ -142,7 +147,7 @@ your shell account. 1. Log in to the BerliOS shell server:: - ssh username@shell.berlios.de + ssh @shell.berlios.de You'll be asked for your password, which you set when you created your account. @@ -157,7 +162,7 @@ your shell account. 3. Copy your public key to the .ssh directory on BerliOS:: - scp .ssh/id_dsa.pub username@shell.berlios.de:.ssh/authorized_keys + scp .ssh/id_dsa.pub @shell.berlios.de:.ssh/authorized_keys Now you should be able to start an SSH session without needing your password. diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index fc6feae2b..6963f6541 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -3,6 +3,7 @@ =================== :Author: Felix Wiemann +:Author: David Goodger :Revision: $Revision$ :Date: $Date$ :Copyright: This document has been placed in the public domain. @@ -11,8 +12,57 @@ .. contents:: -This document describes how the tests are organized and how to add new -tests or modify existing tests. +When adding new functionality (or fixing bugs), be sure to add test +cases to the test suite. Practise test-first programming; it's fun, +it's addictive, and it works! + +This document describes how to run the Docutils test suite, how the +tests are organized and how to add new tests or modify existing tests. + + +Running the Test Suite +====================== + +Before checking in any changes, run the entire Docutils test suite to +be sure that you haven't broken anything. From a shell:: + + cd docutils/test + ./alltests.py + + +Python Versions +=============== + +The Docutils 0.4 release supports Python 2.1 [#py21]_ or later, with +some features only working (and being tested) with Python 2.3+. +Therefore, you should actually have Pythons 2.1 [#py21]_, 2.2, 2.3, as +well as the latest Python installed and always run the tests on all of +them. (A good way to do that is to always run the test suite through +a short script that runs ``alltests.py`` under each version of +Python.) If you can't afford intalling 3 or more Python versions, the +edge cases (2.1 and 2.3) should cover most of it. + +.. [#py21] Python 2.1 may be used providing the compiler package is + installed. The compiler package can be found in the Tools/ + directory of Python 2.1's source distribution. + +Good resources covering the differences between Python versions: + +* `What's New in Python 2.2`__ +* `What's New in Python 2.3`__ +* `What's New in Python 2.4`__ +* `PEP 290 - Code Migration and Modernization`__ + +__ http://www.python.org/doc/2.2.3/whatsnew/whatsnew22.html +__ http://www.python.org/doc/2.3.5/whatsnew/whatsnew23.html +__ http://www.python.org/doc/2.4.1/whatsnew/whatsnew24.html +__ http://www.python.org/peps/pep-0290.html + +.. _Python Check-in Policies: http://www.python.org/dev/tools.html +.. _sandbox directory: + http://svn.berlios.de/viewcvs/docutils/trunk/sandbox/ +.. _nightly repository tarball: + http://svn.berlios.de/svndumps/docutils-repos.gz Unit Tests -- cgit v1.2.1 From 1c603453f1653f485cf9246a50f5cb817cc7408c Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 28 Oct 2005 16:12:21 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3962 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index 2a06087ea..86250b48b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -14,6 +14,11 @@ Changes Since 0.3.9 =================== +* General: + + - Updated the project policies for trunk/branch development & + version numbering. + * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. @@ -43,6 +48,7 @@ Changes Since 0.3.9 - Added ``Node.deepcopy()`` method. - Removed the internal lists ``document.substitution_refs``, ``document.anonymous_refs``, and ``document.anonymous_targets``. + - Added a "container" element. * docutils/parsers/null.py: Added to project; a do-nothing parser. @@ -59,6 +65,10 @@ Changes Since 0.3.9 and auto-numbered footnote references inside of substitution definitions are now disallowed. +* docutils/parsers/rst/directives/body.py: + + - Added the "container" directive. + * docutils/parsers/rst/directives/misc.py: - Added the "default-role" and "title" directives. @@ -166,6 +176,7 @@ Changes Since 0.3.9 - Updated for plural attributes "classes", "ids", "names", "dupnames". + - Added the "container" element. * docs/ref/docutils.dtd: -- cgit v1.2.1 From 5eaa35732246484d010b80d2848eba8cd77158d8 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 28 Oct 2005 16:12:56 +0000 Subject: added the "container" element & directive, a generic container git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3963 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/doctree.txt | 22 ++++++++----- docs/ref/docutils.dtd | 5 ++- docs/ref/rst/directives.txt | 38 +++++++++++++++++++--- docs/user/rst/cheatsheet.txt | 1 + docutils/nodes.py | 3 +- docutils/parsers/rst/directives/__init__.py | 1 + docutils/parsers/rst/directives/body.py | 27 +++++++++++++++ docutils/parsers/rst/languages/af.py | 1 + docutils/parsers/rst/languages/ca.py | 1 + docutils/parsers/rst/languages/cs.py | 1 + docutils/parsers/rst/languages/de.py | 1 + docutils/parsers/rst/languages/en.py | 1 + docutils/parsers/rst/languages/eo.py | 1 + docutils/parsers/rst/languages/es.py | 1 + docutils/parsers/rst/languages/fi.py | 1 + docutils/parsers/rst/languages/fr.py | 3 +- docutils/parsers/rst/languages/it.py | 1 + docutils/parsers/rst/languages/nl.py | 1 + docutils/parsers/rst/languages/pt_br.py | 1 + docutils/parsers/rst/languages/ru.py | 1 + docutils/parsers/rst/languages/sk.py | 1 + docutils/parsers/rst/languages/sv.py | 1 + docutils/parsers/rst/languages/zh_tw.py | 1 + docutils/writers/html4css1.py | 6 ++++ .../expected/standalone_rst_html4css1.html | 4 +++ .../expected/standalone_rst_pseudoxml.txt | 5 +++ test/functional/input/standalone_rst_html4css1.txt | 6 ++++ 27 files changed, 120 insertions(+), 16 deletions(-) diff --git a/docs/ref/doctree.txt b/docs/ref/doctree.txt index caffc3a89..25e5f9594 100644 --- a/docs/ref/doctree.txt +++ b/docs/ref/doctree.txt @@ -146,12 +146,12 @@ body elements. There are two subcategories of body elements: simple and compound. Category members: admonition_, attention_, block_quote_, bullet_list_, -caution_, citation_, comment_, compound_, danger_, definition_list_, -doctest_block_, enumerated_list_, error_, field_list_, figure_, -footnote_, hint_, image_, important_, line_block_, literal_block_, -note_, option_list_, paragraph_, pending_, raw_, rubric_, -substitution_definition_, system_message_, table_, target_, tip_, -warning_ +caution_, citation_, comment_, compound_, container_, danger_, +definition_list_, doctest_block_, enumerated_list_, error_, +field_list_, figure_, footnote_, hint_, image_, important_, +line_block_, literal_block_, note_, option_list_, paragraph_, +pending_, raw_, rubric_, substitution_definition_, system_message_, +table_, target_, tip_, warning_ Simple Body Elements @@ -172,7 +172,7 @@ Compound body elements contain local substructure (body subelements) and further body elements. They do not directly contain text data. Category members: admonition_, attention_, block_quote_, bullet_list_, -caution_, citation_, compound_, danger_, definition_list_, +caution_, citation_, compound_, container_, danger_, definition_list_, enumerated_list_, error_, field_list_, figure_, footnote_, hint_, important_, line_block, note_, option_list_, system_message_, table_, tip_, warning_ @@ -1036,6 +1036,12 @@ See docinfo_ for a more complete example, including processing context. +``container`` +============= + +`To be completed`_. + + ``copyright`` ============= @@ -4714,7 +4720,7 @@ Entity definition: .. parsed-literal:: - paragraph_ | compound_ | literal_block_ | doctest_block_ + paragraph_ | compound_ | container_ | literal_block_ | doctest_block_ | line_block_ | block_quote_ | table_ | figure_ | image_ | footnote_ | citation_ | rubric_ | bullet_list_ | enumerated_list_ | definition_list_ | field_list_ diff --git a/docs/ref/docutils.dtd b/docs/ref/docutils.dtd index c2024391f..154566033 100644 --- a/docs/ref/docutils.dtd +++ b/docs/ref/docutils.dtd @@ -124,7 +124,7 @@ resolve to either an internal or external reference. + + + `` element. Do not use it only to group a sequence of elements, or you may get unexpected results. - If you happen to need a generic block-level container, please - describe your use-case in an email to the Docutils-users_ mailing - list. - - .. _Docutils-users: ../../user/mailing-lists.html#docutils-users + If you need a generic block-level container, please use the + container_ directive, described below. Compound paragraphs are typically rendered as multiple distinct text blocks, with the possibility of variations to emphasize their logical @@ -645,6 +642,37 @@ The following option is recognized: class_ directive below. +Container +========= + +:Directive Type: "container" +:Doctree Element: container +:Directive Arguments: One or more, optional (class names). +:Directive Options: None. +:Directive Content: Interpreted as body elements. + +(New in Docutils 0.3.10) + +The "container" directive surrounds its contents (arbitrary body +elements) with a generic block-level "container" element. Combined +with the optional "class_" attribute argument(s), this is an extension +mechanism for users & applications. For example:: + + .. container:: custom + + This paragraph might be rendered in a custom way. + +Parsing the above results in the following pseudo-XML:: + + + + This paragraph might be rendered in a custom way. + +The "container" directive is the equivalent of HTML's ``
    `` +element. It may be used to group a sequence of elements for user- or +application-specific purposes. + + -------- Tables -------- diff --git a/docs/user/rst/cheatsheet.txt b/docs/user/rst/cheatsheet.txt index 2142d9ce0..3a2a488d1 100644 --- a/docs/user/rst/cheatsheet.txt +++ b/docs/user/rst/cheatsheet.txt @@ -86,6 +86,7 @@ epigraph Block quote with class="epigraph" highlights Block quote with class="highlights" pull-quote Block quote with class="pull-quote" compound Compound paragraphs [0.3.6] +container Generic block-level container element [0.3.10] table Create a titled table [0.3.1] list-table Create a table from a uniform two-level bullet list [0.3.8] csv-table Create a table from CSV data (requires Python 2.3+) [0.3.4] diff --git a/docutils/nodes.py b/docutils/nodes.py index 195293a9e..b45cd1bcf 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1188,6 +1188,7 @@ class transition(Structural, Element): pass class paragraph(General, TextElement): pass class compound(General, Element): pass +class container(General, Element): pass class bullet_list(Sequential, Element): pass class enumerated_list(Sequential, Element): pass class list_item(Part, Element): pass @@ -1410,7 +1411,7 @@ node_class_names = """ authors block_quote bullet_list caption caution citation citation_reference classifier colspec comment - compound contact copyright + compound contact container copyright danger date decoration definition definition_list definition_list_item description docinfo doctest_block document emphasis entry enumerated_list error diff --git a/docutils/parsers/rst/directives/__init__.py b/docutils/parsers/rst/directives/__init__.py index 0bfb6abd6..1a7e680e0 100644 --- a/docutils/parsers/rst/directives/__init__.py +++ b/docutils/parsers/rst/directives/__init__.py @@ -110,6 +110,7 @@ _directive_registry = { 'highlights': ('body', 'highlights'), 'pull-quote': ('body', 'pull_quote'), 'compound': ('body', 'compound'), + 'container': ('body', 'container'), #'questions': ('body', 'question_list'), 'table': ('tables', 'table'), 'csv-table': ('tables', 'csv_table'), diff --git a/docutils/parsers/rst/directives/body.py b/docutils/parsers/rst/directives/body.py index 28682328a..2ff89e617 100644 --- a/docutils/parsers/rst/directives/body.py +++ b/docutils/parsers/rst/directives/body.py @@ -167,3 +167,30 @@ def compound(name, arguments, options, content, lineno, compound.options = {'class': directives.class_option} compound.content = 1 + +def container(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + text = '\n'.join(content) + if not text: + error = state_machine.reporter.error( + 'The "%s" directive is empty; content required.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + try: + if arguments: + classes = directives.class_option(arguments[0]) + else: + classes = [] + except ValueError: + error = state_machine.reporter.error( + 'Invalid class attribute value for "%s" directive: "%s".' + % (name, arguments[0]), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + node = nodes.container(text) + node['classes'].extend(classes) + state.nested_parse(content, content_offset, node) + return [node] + +container.arguments = (0, 1, 1) +container.content = 1 diff --git a/docutils/parsers/rst/languages/af.py b/docutils/parsers/rst/languages/af.py index e8fa9cbb8..c9c636044 100644 --- a/docutils/parsers/rst/languages/af.py +++ b/docutils/parsers/rst/languages/af.py @@ -37,6 +37,7 @@ directives = { 'hoogtepunte': 'highlights', 'pull-quote (translation required)': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #'vrae': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/ca.py b/docutils/parsers/rst/languages/ca.py index d534ecfbc..dbee8c267 100644 --- a/docutils/parsers/rst/languages/ca.py +++ b/docutils/parsers/rst/languages/ca.py @@ -40,6 +40,7 @@ directives = { u'sumari': 'highlights', u'cita-destacada': 'pull-quote', u'compost': 'compound', + u'container (translation required)': 'container', #'questions': 'questions', u'taula': 'table', u'taula-csv': 'csv-table', diff --git a/docutils/parsers/rst/languages/cs.py b/docutils/parsers/rst/languages/cs.py index cf3fbf132..80614fe99 100644 --- a/docutils/parsers/rst/languages/cs.py +++ b/docutils/parsers/rst/languages/cs.py @@ -38,6 +38,7 @@ directives = { u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/de.py b/docutils/parsers/rst/languages/de.py index 7bf72c149..ab32eedac 100644 --- a/docutils/parsers/rst/languages/de.py +++ b/docutils/parsers/rst/languages/de.py @@ -39,6 +39,7 @@ directives = { 'pull-quote (translation required)': 'pull-quote', # kasten too ? 'zusammengesetzt': 'compound', 'verbund': 'compound', + u'container (translation required)': 'container', #'fragen': 'questions', 'tabelle': 'table', 'csv-tabelle': 'csv-table', diff --git a/docutils/parsers/rst/languages/en.py b/docutils/parsers/rst/languages/en.py index 2c9e78737..a38f08342 100644 --- a/docutils/parsers/rst/languages/en.py +++ b/docutils/parsers/rst/languages/en.py @@ -38,6 +38,7 @@ directives = { 'highlights': 'highlights', 'pull-quote': 'pull-quote', 'compound': 'compound', + 'container': 'container', #'questions': 'questions', 'table': 'table', 'csv-table': 'csv-table', diff --git a/docutils/parsers/rst/languages/eo.py b/docutils/parsers/rst/languages/eo.py index 316b98e03..c25b8da25 100644 --- a/docutils/parsers/rst/languages/eo.py +++ b/docutils/parsers/rst/languages/eo.py @@ -42,6 +42,7 @@ directives = { u'ekstera-cita\u0135o': 'pull-quote', u'kombinajxo': 'compound', u'kombina\u0135o': 'compound', + u'container (translation required)': 'container', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index d2f650b14..ad7b6c8af 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -44,6 +44,7 @@ directives = { u'cita-destacada': 'pull-quote', u'combinacion': 'compound', u'combinaci\u00f3n': 'compound', + u'container (translation required)': 'container', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/fi.py b/docutils/parsers/rst/languages/fi.py index bf175081e..c36b37615 100644 --- a/docutils/parsers/rst/languages/fi.py +++ b/docutils/parsers/rst/languages/fi.py @@ -41,6 +41,7 @@ directives = { u'csv-taulukko': u'csv-table', u'list-table (translation required)': 'list-table', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #u'kysymykset': u'questions', u'meta': u'meta', #u'kuvakartta': u'imagemap', diff --git a/docutils/parsers/rst/languages/fr.py b/docutils/parsers/rst/languages/fr.py index b75cad50b..8324da3fe 100644 --- a/docutils/parsers/rst/languages/fr.py +++ b/docutils/parsers/rst/languages/fr.py @@ -39,6 +39,7 @@ directives = { u'chapeau': 'highlights', u'accroche': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #u'questions': 'questions', #u'qr': 'questions', #u'faq': 'questions', @@ -57,7 +58,7 @@ directives = { u'classe': 'class', u'role (translation required)': 'role', u'default-role (translation required)': 'default-role', - u'title (translation required)': 'title', + u'titre (translation required)': 'title', u'sommaire': 'contents', u'table-des-mati\u00E8res': 'contents', u'sectnum': 'sectnum', diff --git a/docutils/parsers/rst/languages/it.py b/docutils/parsers/rst/languages/it.py index de5e32d8b..e5cc9a3ac 100644 --- a/docutils/parsers/rst/languages/it.py +++ b/docutils/parsers/rst/languages/it.py @@ -37,6 +37,7 @@ directives = { 'punti-salienti': 'highlights', 'estratto-evidenziato': 'pull-quote', 'composito': 'compound', + u'container (translation required)': 'container', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/nl.py b/docutils/parsers/rst/languages/nl.py index 7ade5d721..a5d256464 100644 --- a/docutils/parsers/rst/languages/nl.py +++ b/docutils/parsers/rst/languages/nl.py @@ -39,6 +39,7 @@ directives = { 'pull-quote': 'pull-quote', # Dutch printers use the english term 'samenstelling': 'compound', 'verbinding': 'compound', + u'container (translation required)': 'container', #'vragen': 'questions', 'tabel': 'table', 'csv-tabel': 'csv-table', diff --git a/docutils/parsers/rst/languages/pt_br.py b/docutils/parsers/rst/languages/pt_br.py index ba02538fd..9eeb23820 100644 --- a/docutils/parsers/rst/languages/pt_br.py +++ b/docutils/parsers/rst/languages/pt_br.py @@ -38,6 +38,7 @@ directives = { 'destaques': 'highlights', u'cita\u00E7\u00E3o-destacada': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #'perguntas': 'questions', #'qa': 'questions', #'faq': 'questions', diff --git a/docutils/parsers/rst/languages/ru.py b/docutils/parsers/rst/languages/ru.py index 61a8f2297..db1eb8617 100644 --- a/docutils/parsers/rst/languages/ru.py +++ b/docutils/parsers/rst/languages/ru.py @@ -24,6 +24,7 @@ directives = { u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f-\u0446\u0438\u0442\u0430\u0442\u0430': u'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', u'table (translation required)': 'table', u'csv-table (translation required)': 'csv-table', u'list-table (translation required)': 'list-table', diff --git a/docutils/parsers/rst/languages/sk.py b/docutils/parsers/rst/languages/sk.py index b47e6228d..f92ffedf1 100644 --- a/docutils/parsers/rst/languages/sk.py +++ b/docutils/parsers/rst/languages/sk.py @@ -37,6 +37,7 @@ directives = { u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', #u'questions': 'questions', #u'qa': 'questions', #u'faq': 'questions', diff --git a/docutils/parsers/rst/languages/sv.py b/docutils/parsers/rst/languages/sv.py index 11697ec55..bbf749e30 100644 --- a/docutils/parsers/rst/languages/sv.py +++ b/docutils/parsers/rst/languages/sv.py @@ -36,6 +36,7 @@ directives = { u'highlights (translation required)': 'highlights', u'pull-quote (translation required)': 'pull-quote', u'compound (translation required)': 'compound', + u'container (translation required)': 'container', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # u'fr\u00e5gor-och-svar': 'questions', diff --git a/docutils/parsers/rst/languages/zh_tw.py b/docutils/parsers/rst/languages/zh_tw.py index 664aaf6ea..b1b83f5a1 100644 --- a/docutils/parsers/rst/languages/zh_tw.py +++ b/docutils/parsers/rst/languages/zh_tw.py @@ -38,6 +38,7 @@ directives = { 'highlights (translation required)': 'highlights', 'pull-quote (translation required)': 'pull-quote', 'compound (translation required)': 'compound', + u'container (translation required)': 'container', #'questions (translation required)': 'questions', 'table (translation required)': 'table', 'csv-table (translation required)': 'csv-table', diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index d11e88c48..ff32f936d 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -587,6 +587,12 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_compound(self, node): self.body.append('
    \n') + def visit_container(self, node): + self.body.append(self.starttag(node, 'div', CLASS='container')) + + def depart_container(self, node): + self.body.append('
    \n') + def visit_contact(self, node): self.visit_docinfo_item(node, 'contact', meta=None) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index e14d5a72d..a781aa784 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -958,6 +958,10 @@ crunchy, now would it?

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    +
    +

    paragraph 1

    +

    paragraph 2

    +

    Docutils System Messages

    diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 6af1c9ded..22c8f4bde 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1798,6 +1798,11 @@ section, "Docutils System Messages": section should be added by Docutils automatically + + + paragraph 1 + + paragraph 2
    Docutils System Messages diff --git a/test/functional/input/standalone_rst_html4css1.txt b/test/functional/input/standalone_rst_html4css1.txt index 05f0287d0..4b1e2fdda 100644 --- a/test/functional/input/standalone_rst_html4css1.txt +++ b/test/functional/input/standalone_rst_html4css1.txt @@ -5,3 +5,9 @@ .. include:: data/table_complex.txt .. include:: data/list_table.txt .. include:: data/errors.txt + +.. container:: custom + + paragraph 1 + + paragraph 2 -- cgit v1.2.1 From 4250498dab37bd03b15cce64e310a3b9eba7233a Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Oct 2005 11:53:25 +0000 Subject: added missing target; typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3966 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 ++ docs/ref/rst/restructuredtext.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index ec6dceb41..a2b016f57 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1273,6 +1273,8 @@ Raw Data Pass-Through describe your situation in an email to the Docutils-users_ mailing list. +.. _Docutils-users: ../../user/mailing-lists.html#docutils-users + The "raw" directive indicates non-reStructuredText data that is to be passed untouched to the Writer. The names of the output formats are given in the directive arguments. The interpretation of the raw data diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index 3359d19a7..d503d9054 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -2239,7 +2239,7 @@ constructs is recognized, leave the ".." on a line by itself:: .. |even| this:: ! -A explicit markup start followed by a blank line and nothing else +An explicit markup start followed by a blank line and nothing else (apart from whitespace) is an "empty comment". It serves to terminate a preceding construct, and does **not** consume any indented text following. To have a block quote follow a list or any indented -- cgit v1.2.1 From e033ee28f912b3a7c0708c318daff3fd43d7859b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Oct 2005 12:21:09 +0000 Subject: another minor text fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3967 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/directives.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index a2b016f57..0b2148267 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1270,7 +1270,7 @@ Raw Data Pass-Through If you often need to use the "raw" directive or a "raw"-derived interpreted text role, that is a sign either of overuse/abuse or that functionality may be missing from reStructuredText. Please - describe your situation in an email to the Docutils-users_ mailing + describe your situation in a message to the Docutils-users_ mailing list. .. _Docutils-users: ../../user/mailing-lists.html#docutils-users -- cgit v1.2.1 From d92350b57c08a3f642a8a2e6147eb999769180f7 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Oct 2005 12:28:44 +0000 Subject: converted latin1 files to utf8; removed unnecessary -*- coding -*- tags; made some source files ASCII only git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3968 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/distributing.txt | 2 -- docutils/languages/es.py | 4 ++-- docutils/languages/zh_tw.py | 2 +- docutils/parsers/rst/languages/es.py | 4 ++-- test/test_writers/test_docutils_xml.py | 3 +-- test/test_writers/test_html4css1.py | 1 - test/test_writers/test_html4css1_misc.py | 7 ++++--- tools/editors/emacs/README.txt | 4 ++-- 8 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/dev/distributing.txt b/docs/dev/distributing.txt index e4495512c..498a9fa34 100644 --- a/docs/dev/distributing.txt +++ b/docs/dev/distributing.txt @@ -1,5 +1,3 @@ -.. -*- coding: utf-8 -*- - =============================== Docutils_ Distributor's Guide =============================== diff --git a/docutils/languages/es.py b/docutils/languages/es.py index a1149b97e..7e3eb9b75 100644 --- a/docutils/languages/es.py +++ b/docutils/languages/es.py @@ -1,5 +1,5 @@ -# -*- coding: iso-8859-1 -*- -# Author: Marcelo Huerta San Martn +# -*- coding: utf-8 -*- +# Author: Marcelo Huerta San Martín # Contact: mghsm@uol.com.ar # Revision: $Revision$ # Date: $Date$ diff --git a/docutils/languages/zh_tw.py b/docutils/languages/zh_tw.py index 00cffb586..12570cfba 100644 --- a/docutils/languages/zh_tw.py +++ b/docutils/languages/zh_tw.py @@ -1,4 +1,4 @@ -# -*- coding: UTF-8 -*- +# -*- coding: utf-8 -*- # Author: Joe YS Jaw # Contact: joeysj@users.sourceforge.net # Revision: $Revision$ diff --git a/docutils/parsers/rst/languages/es.py b/docutils/parsers/rst/languages/es.py index ad7b6c8af..bdbc8c188 100644 --- a/docutils/parsers/rst/languages/es.py +++ b/docutils/parsers/rst/languages/es.py @@ -1,5 +1,5 @@ -# -*- coding: iso-8859-1 -*- -# Author: Marcelo Huerta San Martn +# -*- coding: utf-8 -*- +# Author: Marcelo Huerta San Martín # Contact: richieadler@users.sourceforge.net # Revision: $Revision$ # Date: $Date$ diff --git a/test/test_writers/test_docutils_xml.py b/test/test_writers/test_docutils_xml.py index eeb5bc94a..c51d71379 100755 --- a/test/test_writers/test_docutils_xml.py +++ b/test/test_writers/test_docutils_xml.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # Author: Felix Wiemann # Contact: Felix_Wiemann@ososo.de @@ -24,7 +23,7 @@ Test ---------- -Test. äöü€""" +Test. \xc3\xa4\xc3\xb6\xc3\xbc\xe2\x82\xac""" xmldecl = '<?xml version="1.0" encoding="iso-8859-1"?>\n' doctypedecl = '<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n' generatedby = '<!-- Generated by Docutils %s -->\n' % docutils.__version__ diff --git a/test/test_writers/test_html4css1.py b/test/test_writers/test_html4css1.py index 1df84de15..7d87ee324 100755 --- a/test/test_writers/test_html4css1.py +++ b/test/test_writers/test_html4css1.py @@ -1,5 +1,4 @@ #! /usr/bin/env python -# -*- coding: utf-8 -*- # Author: reggie dugard # Contact: reggie@users.sourceforge.net diff --git a/test/test_writers/test_html4css1_misc.py b/test/test_writers/test_html4css1_misc.py index ab728be13..8b63d6f1c 100755 --- a/test/test_writers/test_html4css1_misc.py +++ b/test/test_writers/test_html4css1_misc.py @@ -1,5 +1,4 @@ #! /usr/bin/env python -# -*- coding: utf-8 -*- # Author: Felix Wiemann # Contact: Felix_Wiemann@ososo.de @@ -25,9 +24,11 @@ class EncodingTestCase(DocutilsTestSupport.StandardTestCase): 'stylesheet': '', '_disable_config': 1,} result = core.publish_string( - 'äöü€', writer_name='html4css1', + 'EUR = \xe2\x82\xac', writer_name='html4css1', settings_overrides=settings_overrides) - self.assert_(result.find('\xe4\xf6\xfc€') != -1) + # Encoding a euro sign with latin1 doesn't work, so the + # xmlcharrefreplcae handler is used. + self.assert_(result.find('EUR = €') != -1) if __name__ == '__main__': diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index 366a826da..115927604 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -1,4 +1,4 @@ -.. -*- coding: iso-8859-1 -*- +.. -*- coding: utf-8 -*- ===================================== Emacs Support for reStructuredText_ @@ -49,7 +49,7 @@ here are some useful resources for Emacs users in the Unicode world: to your .emacs file. - To get direct keyboard input of non-ASCII characters (like - "option-e e" resulting in "" [eacute]), first enable the option + "option-e e" resulting in "é" [eacute]), first enable the option key by setting the command key as your meta key:: (setq mac-command-key-is-meta t) ;; nil for option key -- cgit v1.2.1 From f50fd0893b3d46828d2acc46d8aa5c2bfcd9079f Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 29 Oct 2005 12:39:13 +0000 Subject: changed the HTML rendering of the "Authors" bibliographic field git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3971 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/html4css1.py | 18 ++++++++++++++---- test/functional/expected/standalone_rst_html4css1.html | 14 +++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index ff32f936d..380d648af 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -272,6 +272,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.html_body = [] self.in_document_title = 0 self.in_mailto = 0 + self.author_in_authors = None def astext(self): return ''.join(self.head_prefix + self.head @@ -467,16 +468,25 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.context.pop() + '</p>\n') def visit_author(self, node): - self.visit_docinfo_item(node, 'author') + if isinstance(node.parent, nodes.authors): + if self.author_in_authors: + self.body.append('\n<br />') + else: + self.visit_docinfo_item(node, 'author') def depart_author(self, node): - self.depart_docinfo_item() + if isinstance(node.parent, nodes.authors): + self.author_in_authors += 1 + else: + self.depart_docinfo_item() def visit_authors(self, node): - pass + self.visit_docinfo_item(node, 'authors') + self.author_in_authors = 0 def depart_authors(self, node): - pass + self.depart_docinfo_item() + self.author_in_authors = None def visit_block_quote(self, node): self.body.append(self.starttag(node, 'blockquote')) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index a781aa784..a898da047 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -6,9 +6,7 @@ <meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" /> <title>reStructuredText Test Document - - - + @@ -39,12 +37,10 @@ A1B 2C3
    - - - - - - + + -- cgit v1.2.1 From e18f16fa2f916f7abddab81446308e285a5570ef Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 29 Oct 2005 14:28:55 +0000 Subject: added bug "footnote references with hyperlink targets" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3973 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index e19654e6b..f0ee7f202 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -255,6 +255,19 @@ Also see the `SourceForge Bug Tracker`_. Added a commented-out test case to test/test_parsers/test_rst/test_SimpleTableParser.py. +* _`Footnote references with hyperlink targets` cause a possibly + invalid node tree and make the HTML writer crash:: + + $ rst2pseudoxml.py + [1]_ + + .. _1: URI + + + + 1 + + .. Local Variables: -- cgit v1.2.1 From db725ada9c838f95536ce02e0d311ac0387180d3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 29 Oct 2005 14:39:45 +0000 Subject: fixed links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3974 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 4 ++-- docs/dev/rst/alternatives.txt | 2 +- docs/dev/rst/problems.txt | 7 ++++--- docs/peps/pep-0287.txt | 2 +- docs/ref/rst/directives.txt | 4 ++-- docs/ref/rst/introduction.txt | 4 ++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index e09f5ea67..2bc0158e8 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -30,7 +30,7 @@ his essay `The Magic Cauldron`_: through to contribute. .. _The Magic Cauldron: - http://www.tuxedo.org/~esr/writings/magic-cauldron/ + http://www.catb.org/~esr/writings/magic-cauldron/ We will endeavour to keep the barrier to entry as low as possible. The policies below should not be thought of as barriers, but merely as @@ -319,7 +319,7 @@ just a trickle of perfect-as-they-stand changes. The occasional mistake is easy to fix. That's what Subversion is for! .. _Docutils Front-End Tools: ../user/tools.html -.. _Docutils Configuration Files: ../user/config.htm +.. _Docutils Configuration Files: ../user/config.html .. _Python Check-in Policies: http://www.python.org/dev/tools.html#check-in-policies .. _nightly repository tarball: diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index e8730b650..d6e0957e7 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -32,7 +32,7 @@ The ideas are divided into sections: .. _Setext: http://docutils.sourceforge.net/mirror/setext.html .. _StructuredText: - http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/FrontPage .. _Problems with StructuredText: problems.html .. _reStructuredText Markup Specification: ../../ref/rst/restructuredtext.html diff --git a/docs/dev/rst/problems.txt b/docs/dev/rst/problems.txt index 01853c8bd..bc0101cbf 100644 --- a/docs/dev/rst/problems.txt +++ b/docs/dev/rst/problems.txt @@ -114,7 +114,8 @@ markup-significant characters as the characters themselves. Currently there is no such mechanism (although ZWiki uses '!'). What are the candidates? -1. ``!`` (http://dev.zope.org/Members/jim/StructuredTextWiki/NGEscaping) +1. ``!`` + (http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/NGEscaping) 2. ``\`` 3. ``~`` 4. doubling of characters @@ -847,14 +848,14 @@ text is separated from the link URI and the footnote, resulting in cleanly readable text. .. _StructuredText: - http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/FrontPage .. _Setext: http://docutils.sourceforge.net/mirror/setext.html .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _detailed description: http://homepage.ntlworld.com/tibsnjoan/docutils/STNG-format.html .. _STMinus: http://www.cis.upenn.edu/~edloper/pydoc/stminus.html .. _StructuredTextNG: - http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNG + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/StructuredTextNG .. _README: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/ python/python/dist/src/README .. _Emacs table mode: http://table.sourceforge.net/ diff --git a/docs/peps/pep-0287.txt b/docs/peps/pep-0287.txt index 18b3abfa7..689d6b919 100644 --- a/docs/peps/pep-0287.txt +++ b/docs/peps/pep-0287.txt @@ -764,7 +764,7 @@ __ http://www.python.org/doc/Humor.html#zen .. _Setext: http://docutils.sourceforge.net/mirror/setext.html .. _StructuredText: - http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/FrontPage .. _A ReStructuredText Primer: http://docutils.sourceforge.net/docs/user/rst/quickstart.html diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 0b2148267..58fa324cf 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -844,7 +844,7 @@ List Table (New in Docutils 0.3.8. This is an initial implementation; `further ideas`__ may be implemented in the future.) -__ http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables +__ ../../dev/rst/alternatives.html#list-driven-tables The "list-table" directive is used to create a table from data in a uniform two-level bullet list. "Uniform" means that each sublist @@ -1512,7 +1512,7 @@ The text above is parsed and transformed into this doctree fragment:: character must be a letter; no "unicode", "latin1", or "escape" characters), this results in the ``[a-z](-?[a-z0-9]+)*`` pattern. - .. _HTML 4.01 spec: http://www.w3.org/TR/html401 + .. _HTML 4.01 spec: http://www.w3.org/TR/html401/ .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1 diff --git a/docs/ref/rst/introduction.txt b/docs/ref/rst/introduction.txt index 2b64399a5..b7829816e 100644 --- a/docs/ref/rst/introduction.txt +++ b/docs/ref/rst/introduction.txt @@ -31,7 +31,7 @@ http://docutils.sourceforge.net/rst.html. .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _StructuredText: - http://dev.zope.org/Members/jim/StructuredTextWiki/FrontPage + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/FrontPage .. _Setext: http://docutils.sourceforge.net/mirror/setext.html .. _Docutils: http://docutils.sourceforge.net/ .. _A ReStructuredText Primer: ../../user/rst/quickstart.html @@ -295,7 +295,7 @@ followed. http://structuredtext.sourceforge.net/ .. _pythondoc: http://starship.python.net/crew/danilo/pythondoc/ .. _StructuredTextNG: - http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNG + http://www.zope.org/DevHome/Members/jim/StructuredTextWiki/StructuredTextNG .. _project history file: ../../../HISTORY.html .. _PEP 287: ../../peps/pep-0287.html .. _Docstring Processing System framework: ../../peps/pep-0256.html -- cgit v1.2.1 From 2d9be866bdfd38044a368345f77d93ef9907df9c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 29 Oct 2005 15:05:25 +0000 Subject: fixed links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3975 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/enthought-rfp.txt | 5 ++--- docs/dev/todo.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/dev/enthought-rfp.txt b/docs/dev/enthought-rfp.txt index 86c932c70..5001a5600 100644 --- a/docs/dev/enthought-rfp.txt +++ b/docs/dev/enthought-rfp.txt @@ -49,9 +49,8 @@ Source Format 2. The tool must support the use of Traits. Special comment syntax for Traits may be necessary. Information about the Traits package - is available at http://old.scipy.org/site_content/traits. In the - following example, each trait definition is prefaced by a plain - comment:: + is available at http://www.enthought.com/traits/. In the following + example, each trait definition is prefaced by a plain comment:: __traits__ = { diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 11c8046ab..9513837b3 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -461,7 +461,7 @@ General (Had I known about traits when I was implementing docutils.frontend, I may have used them instead of rolling my own.) - .. _traits: http://old.scipy.org/site_content/traits + .. _traits: http://www.enthought.com/traits/ .. _SciPy: http://www.scipy.org/ * tools/buildhtml.py: Extend the --prune option ("prune" config -- cgit v1.2.1 From ba18f6d97838e852cd174a21c0ba013cf3ee2d5a Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 29 Oct 2005 15:56:28 +0000 Subject: removed coding guideline items which are contained in PEP 8; shortened warning about "svn import" -- it's not as dangerous as it used to be in CVS; removed reference to Python Check-in Policies because it's not of much use for us -- many items are not applicable and some even contradict what we're currently doing (e.g. bug/patch tracking) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3976 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 2bc0158e8..bc5ce93ac 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -29,8 +29,8 @@ his essay `The Magic Cauldron`_: correlated with the number of hoops each project makes a user go through to contribute. - .. _The Magic Cauldron: - http://www.catb.org/~esr/writings/magic-cauldron/ +.. _The Magic Cauldron: + http://www.catb.org/~esr/writings/magic-cauldron/ We will endeavour to keep the barrier to entry as low as possible. The policies below should not be thought of as barriers, but merely as @@ -63,9 +63,6 @@ Conventions`_ PEPs, with the following clarifications and extensions: * 4 spaces per indentation level. No hard tabs. -* Use only 7-bit ASCII, no 8-bit strings. See `Docutils - Internationalization`_. - * No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is OK.). @@ -75,14 +72,6 @@ Conventions`_ PEPs, with the following clarifications and extensions: * Use "StudlyCaps" for class names (except for element classes in docutils.nodes). -* Use "lowercase" or "lowercase_with_underscores" for function, - method, and variable names. For short names, maximum two words, - joined lowercase may be used (e.g. "tagname"). For long names with - three or more words, or where it's hard to parse the split between - two words, use lowercase_with_underscores (e.g., - "note_explicit_target", "explicit_target"). If in doubt, use - underscores. - * Avoid lambda expressions, which are inherently difficult to understand. Named functions are preferable and superior: they're faster (no run-time compilation), and well-chosen names serve to @@ -121,9 +110,6 @@ Documentation Conventions Document Subtitle (optional) ------------------------------ - (The doc. subtitle adornment style can also be used for major - top-level sections.) - Section ======= @@ -187,14 +173,9 @@ repository anonymously. Only project developers can make changes. (If you would like to become a project developer, just ask!) Also see `Setting Up For Docutils Development`_ below for some useful info. -.. Caution:: - - Unless you really *really* know what you're doing, please do - **NOT** use ``svn import``. Only use ``svn import`` if you're - **absolutely sure you know what you're doing**. Even then, first - grab a copy of the `nightly repository tarball`_, set it up on your - own machine, remove ``hooks/post-commit``, and experiment *there*. - It's quite easy to mess up the repository with an import. +Unless you really *really* know what you're doing, please do *not* use +``svn import``. It's quite easy to mess up the repository with an +import. .. _repository documentation: repository.html @@ -257,10 +238,6 @@ above, the general `Check-ins`_ policy (below) also applies. Check-ins --------- -In general, the Docutils project follows the `Python Check-in -Policies`_ as applicable. There are some differences (e.g., we use -Subversion now, not CVS), and we place particular emphasis as follows. - Changes or additions to the Docutils core and maintenance branches carry a commitment to the Docutils user community. Developers must be prepared to fix and maintain any code they have committed. @@ -320,8 +297,6 @@ mistake is easy to fix. That's what Subversion is for! .. _Docutils Front-End Tools: ../user/tools.html .. _Docutils Configuration Files: ../user/config.html -.. _Python Check-in Policies: - http://www.python.org/dev/tools.html#check-in-policies .. _nightly repository tarball: http://svn.berlios.de/svndumps/docutils-repos.gz -- cgit v1.2.1 From 049c0dd4035c4f6aae3b0491f159535539e1c032 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 29 Oct 2005 21:17:26 +0000 Subject: fixed more occurences of "an email" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3978 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 2 +- docs/ref/rst/roles.txt | 2 +- docs/user/mailing-lists.txt | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 6c9e0f94a..95e54800a 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -72,7 +72,7 @@ Developer Access ---------------- (Developers who had write-access for Docutils' CVS repository on -SourceForge.net should `register at BerliOS`__ and send an email with +SourceForge.net should `register at BerliOS`__ and send a message with their BerliOS user name to `Felix Wiemann `_.) __ https://developer.berlios.de/account/register.php diff --git a/docs/ref/rst/roles.txt b/docs/ref/rst/roles.txt index b396af2eb..3b8b114bc 100644 --- a/docs/ref/rst/roles.txt +++ b/docs/ref/rst/roles.txt @@ -279,7 +279,7 @@ must be used to obtain a ``title_reference`` element. If you often need to use "raw"-derived interpreted text roles or the "raw" directive, that is a sign either of overuse/abuse or that functionality may be missing from reStructuredText. Please - describe your situation in an email to the Docutils-users_ mailing + describe your situation in a message to the Docutils-users_ mailing list. .. _Docutils-users: ../../user/mailing-lists.html#docutils-user diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt index de4aff3de..828b19510 100644 --- a/docs/user/mailing-lists.txt +++ b/docs/user/mailing-lists.txt @@ -41,16 +41,16 @@ mailing lists; use the one you feel most comfortable with. __ nntp://news.gmane.org/gmane.text.docutils.user. **If you do not wish to subscribe,** you can also just send an email -to Docutils-users@lists.sourceforge.net. Please note in your email -that you are not subscribed (to make sure that you receive copies -[CCs] of any replies). +message to Docutils-users@lists.sourceforge.net. Please note in your +message that you are not subscribed (to make sure that you receive +copies [CCs] of any replies). The first time you post a message without being subscribed (also when -posting via Gmane), you will receive an email with the subject "Your -message to Docutils-users awaits moderator approval"; this is done to -prevent spam to the mailing lists. Your message will usually be -approved within a few hours. To avoid duplicates, please do not -resend your message using a different email address. +posting via Gmane), you will receive an automatic response with the +subject "Your message to Docutils-users awaits moderator approval"; +this is done to prevent spam to the mailing lists. Your message will +usually be approved within a few hours. To avoid duplicates, please +do not resend your message using a different email address. Doc-SIG -- cgit v1.2.1 From 4daab9f9ccb5c522de264c7352bbd40ee82c34ee Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 Oct 2005 14:23:25 +0000 Subject: again updated the link to traits git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3979 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/enthought-rfp.txt | 5 +++-- docs/dev/todo.txt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/dev/enthought-rfp.txt b/docs/dev/enthought-rfp.txt index 5001a5600..986f5604f 100644 --- a/docs/dev/enthought-rfp.txt +++ b/docs/dev/enthought-rfp.txt @@ -49,8 +49,9 @@ Source Format 2. The tool must support the use of Traits. Special comment syntax for Traits may be necessary. Information about the Traits package - is available at http://www.enthought.com/traits/. In the following - example, each trait definition is prefaced by a plain comment:: + is available at http://code.enthought.com/traits/. In the + following example, each trait definition is prefaced by a plain + comment:: __traits__ = { diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 9513837b3..ccda16513 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -461,7 +461,7 @@ General (Had I known about traits when I was implementing docutils.frontend, I may have used them instead of rolling my own.) - .. _traits: http://www.enthought.com/traits/ + .. _traits: http://code.enthought.com/traits/ .. _SciPy: http://www.scipy.org/ * tools/buildhtml.py: Extend the --prune option ("prune" config -- cgit v1.2.1 From d54a138b591aaf47c7fa64c51473926fe0c449b9 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 Oct 2005 14:32:45 +0000 Subject: added note about whitelisting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3980 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/mailing-lists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/user/mailing-lists.txt b/docs/user/mailing-lists.txt index 828b19510..8137e29e7 100644 --- a/docs/user/mailing-lists.txt +++ b/docs/user/mailing-lists.txt @@ -50,7 +50,10 @@ posting via Gmane), you will receive an automatic response with the subject "Your message to Docutils-users awaits moderator approval"; this is done to prevent spam to the mailing lists. Your message will usually be approved within a few hours. To avoid duplicates, please -do not resend your message using a different email address. +do not resend your message using a different email address. After +your first message has been approved, your email address will be added +to the whitelist and future messages will be posted to the mailing +list without moderation. Doc-SIG -- cgit v1.2.1 From 323d842b2d1803c0e27fa029745dc9f1eeb6e214 Mon Sep 17 00:00:00 2001 From: blais Date: Sun, 30 Oct 2005 15:13:46 +0000 Subject: I have cleaned up all the emacs support code for restructured text. If you are using it, this will most certainly affect you, here are the list of changes: 1. I moved the contents of restructuredtext.el, rst-mode.el and rst-html.el into a single file, named rst.el, and removed the old files. You can remove the old files from your load-path and replace them with rst.el, the old files are to be considered OBSOLETE from now (2005-10-30). All new contents will go to rst.el. 2. All the rest-* function names from restructuredtext.el have been RENAMED to rst-* (to be consistent with the code that was in rst-mode.el). Almost all the contents of rst.el now start with rst-. 3. rst-text-mode-hook has been renamed to rst-text-mode-bindings. Because it is not a hook, but rather a function to be bound to a hook. This was confusing and is now following the general emacs conventions. This will affect you if you were enabling the adjusting and toc functions. 4. I removed the rst-html-stylesheet and the simpler rst-html-compile function. It was replaced by the implementation of rst-html-html-comple-with-conf, which is more generic, and which now also uses the rst-html-options. In addition, I wrote a document that describes how to use all the features included in rst.el, because many emacs users I meet are not aware of them. You will be able to find it under docs/user/emacs.txt. I linked to it from the index page. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3981 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/index.txt | 4 + docs/user/emacs.txt | 475 ++++ tools/editors/emacs/README.txt | 89 +- tools/editors/emacs/restructuredtext.el | 1649 -------------- tools/editors/emacs/rst-html.el | 125 -- tools/editors/emacs/rst-mode.el | 700 ------ tools/editors/emacs/rst.el | 2479 +++++++++++++++++++++ tools/editors/emacs/tests/tests-adjust-section.el | 10 +- tools/editors/emacs/tests/tests-basic.el | 42 +- 9 files changed, 2995 insertions(+), 2578 deletions(-) create mode 100644 docs/user/emacs.txt delete mode 100644 tools/editors/emacs/restructuredtext.el delete mode 100644 tools/editors/emacs/rst-html.el delete mode 100644 tools/editors/emacs/rst-mode.el create mode 100644 tools/editors/emacs/rst.el diff --git a/docs/index.txt b/docs/index.txt index ab77b94a2..69cceb717 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -95,6 +95,10 @@ Docutils-general: demonstration of most reStructuredText features; you can also have a look at the `text source `__) +Editor support: + +* `Emacs support for reStructuredText `_ + .. _ref: diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt new file mode 100644 index 000000000..347ee6b19 --- /dev/null +++ b/docs/user/emacs.txt @@ -0,0 +1,475 @@ +======================================== + Emacs Support for reStructuredText +======================================== + +:Author: Martin Blais +:Date: 2005-10-29 +:Abstract: + + High-level description of the existing emacs support for editing + reStructuredText text documents. Suggested setup code and usage + instructions are provided. + +.. contents:: +.. + 1 Introduction + 2 Basic Setup + 3 Section Decoration Adjustment + 3.1 Promoting and Demoting Many Sections + 3.2 Customizations + 4 Viewing the Hierarchy of Section Decorations + 5 Table of Contents + 5.1 Inserting a Table of Contents + 5.2 Maintaining the Table of Contents Up-to-date + 6 Navigating Between the Section Titles + 7 Shifting Bulleted List Levels + 8 Major Mode for Editing reStructuredText Documents + 9 Converting Documents from Emacs + 10 Other / External Useful Emacs Settings + 10.1 Settings for Filling Bulleted Lists + 10.2 ``text-mode`` Settings + 10.3 Editing Tables: Emacs table mode + 10.4 Character Processing + 11 Credits + 12 Obsolete Files + 13 Future Work + + +Introduction +============ + +reStructuredText_ is a series of conventions that allows a toolset--docutils--to +extract generic document structure from simple text files. For people who use +Emacs_, there is a package that adds some support for the conventions that +reStructuredText_ specifies: ``rst.el``. + +This document describes the most important features that it provides, how to +setup your emacs to use them and how to invoke them. + + +Basic Setup +=========== + +The emacs support is completely provided by the ``rst.el`` emacs package. In +order to use these features, you need to put the file in your emacs load-path, +and to load it with:: + + (require 'rst) ;; or (load "rst") + +Additional configuration variables can be customized and can be found by +browsing the source code for ``rst.el``. + +Then you will want to bind keys to the most common commands it provides. A +standard text-mode hook function is maintained and provided by the package for +this use, set it up like this:: + + (add-hook 'text-mode-hook 'rst-text-mode-hook) + + +Section Decoration Adjustment +============================= + +The rst package does not completely parse all the reStructuredText_ constructs, +but it contains the ability to recognize the section decorations and to build +the hierarchy of the document. What we call section decorations or adornments +are the underlines or under- and overlines used to mark a section title. + +There is a function that helps a great deal to maintain these decorations: +``rst-adjust`` (bound on ``C-=`` by default). This function is a swiss knife +that can be invoked repeatedly and whose behaviour depends on context: + +#. If there is an incomplete underline, e.g.:: + + My Section Title + ^^ + + Invocation will complete the section title. You can simply enter a few + characters of the title and invoke the function to complete it. It can also + be used to adjust the length of the existing decoration when you need to edit + the title. + +#. If there is no section decoration, a decoration one level under the last + encountered section level is added; + +#. If there is already a section decoration, it is promoted to the next level. + You can invoke it like this repeatedly to cycle the title through the + hierarchy of existing decorations. + +Invoking the function with a negative prefix argument, e.g. ``C-- C-=``, will +effectively reverse the direction of decoration cycling. To alternate between +underline-only and over-and-under styles, you can use a regular prefix argument, +e.g. ``C-u C-=``. See the documentation of ``rst-adjust`` for more description +of the prefix arguments to alter the behaviour of the function. + + +Promoting and Demoting Many Sections +------------------------------------ + +When you are re-organizing the structure of a document, it can be useful to +change the level of a number of section titles. The same key binding can be +used to do that: if the region is active when the binding is invoked, all the +section titles that are within the region are promoted accordingly (or demoted, +with negative prefix arg). + + +Customizations +-------------- + +You can set the variable ``rst-preferred-decorations`` to a list of the +decorations that you like to use for documents. Everyone has their preference. +``rst-default-indent`` can be set to the number of characters preferred for the +over-and-under decoration style. + + +Viewing the Hierarchy of Section Decorations +============================================ + +You can visualize the hierarchy of the section decorations in the current buffer +by invoking ``rst-display-decorations-hierarchy``, bound on ``C-u C-x C-=``. A +temporary buffer will appear with fake section titles rendered in the style of +the current document. This can be useful when editing other people's documents +to find out which section decorations correspond to which levels. + + +Table of Contents +================= + +When you are editing long documents, it can be a bit difficult to orient +yourself in the structure of your text. To that effect, a function is provided +that quickly parses the document and presents a hierarchically indented table of +contents of the document in a temporary buffer, in which you can navigate and +press ``Ret`` to go to a specific section. + +Invoke this function (``rst-toc``) with ``C-x C-=``. It should present a +temporary buffer that looks somewhat like this:: + + Table of Contents: + Debugging Meta-Techniques + Introduction + Debugging Solution Patterns + Recognize That a Bug Exists + Subdivide and Isolate + Identify and Verify Assumptions + Use a Tool for Introspection + Change one thing at a time + Learn about the System + Understanding a bug + The Basic Steps in Debugging + Attitude + Bad Feelings + Good Feelings + References + + +When you select a section title, the temporary buffer disappears and you are +left with the cursor positioned at the chosen section. + + +Inserting a Table of Contents +----------------------------- + +Oftentimes in long text documents that are meant to be read directly, a Table of +Contents is inserted at the beginning of the text. This is the case for most +internet FAQs, for example. In reStructuredText_ documents, since the table of +contents is automatically generated by the parser with the ``.. contents::`` +directive, people generally have not been adding a text table of contents to +their source documents, and partly because it is too much trouble to edit and +maintain. + +The emacs support for reStructuredText_ provides a function to insert such a +table of contents in your document. Since it gets computed automatically by +docutils, you should place such a table of contents within a contents, so that +it gets ignored by docutils, e.g. this is the favoured usage:: + + .. contents:: + .. + 1 Introduction + 2 Debugging Solution Patterns + 2.1 Recognize That a Bug Exists + 2.2 Subdivide and Isolate + 2.3 Identify and Verify Assumptions + 2.4 Use a Tool for Introspection + 2.5 Change one thing at a time + 2.6 Learn about the System + 3 Understanding a bug + 4 The Basic Steps in Debugging + 5 Attitude + 5.1 Bad Feelings + 5.2 Good Feelings + 6 References + +Just place the cursor at the top-left corner where you want to insert the TOC +and invoke the function with ``C-x +``. If there is a single top-level section +level (i.e. the document title), by default it is ignored. If you have deep +nesting of sections, you can use a numeric prefix argument to limit the depth of +rendenring of the TOC. + +You can also customize the look of the TOC by setting the values of the +following variables:: ``rst-toc-indent``, +``rst-toc-insert-always-include-top``, ``rst-toc-insert-style``, +``rst-toc-insert-max-level``. + + +Maintaining the Table of Contents Up-to-date +-------------------------------------------- + +One issue is that you will probably want to maintain the inserted table of +contents up-to-date. There is a function that will automatically look for the +inserted TOC (``rst-toc-insert-update``) and it can be added to a hook on the +section decoration adjustment function, so that everytime you adjust a section +title, the TOC is updated. Add this functionality with the following emacs +configuration:: + + (add-hook 'rst-adjust-hook 'rst-toc-insert-update) + + +Navigating Between the Section Titles +===================================== + +You can move the cursor between the different sections by using the +``rst-backward-section`` and ``rst-forward-section`` functions, by default bound +to the ``C-M-{`` and ``C-M-}`` keys. + + +Shifting Bulleted List Levels +============================= + +Due to the nature of reStructuredText_, bulleted lists are always indented by +two characters (unless they are part of a blockquote), e.g. :: + + - Fruits + + - Bananas + - Apples + - Oranges + + - Veggies + + - Zucchini + - Chick Peas + +To this effect, when re-organizing bulleted lists, it can be useful to shift +regions of text by indents of two characters. You can use the ``C-c C-r`` and +``C-c C-l`` to shift the current region. These bindings are similar to the ones +provided by python-mode for editing python code and behave similarly. + + +Major Mode for Editing reStructuredText Documents +================================================= + +There is a major mode available for editing and syntax highlighting +reStructuredText_ constructs. This mode was written by Stefan Merten [#]. It +mostly provides lazy syntax coloring for many of the constructs that +reStructuredText_ prescribes. + +To enable this mode, type ``M-x rst-mode`` or you can setup an +``auto-mode-alist`` to automatically turn it on whenever you visit +reStructuredText_ documents:: + + (add-to-list 'auto-mode-alist '("\\.rst$" . rst-mode) ) + +If have local variables enabled (see ``enable-local-variables`` in the Emacs +manual), you can also add the following at the top of your documents to trigger +rst-mode:: + + .. -*- mode: rst -*- + +By default, the font-lock colouring is performed lazily. If you don't like +this, you can turn this off by setting the value of ``rst-mode-lazy``. You can +also change the various colours (see the source file for the whole list of +customizable faces). + +.. [#] This mode used to be provided by the file ``rst-mode.el`` and has now + been integrated with the rest of the emacs code. + + +Converting Documents from Emacs +=============================== + +At the moment there is minimal support for calling ``rst2html.py`` from within +Emacs. You can add a key binding like this to invoke it:: + + (local-set-key [(control c)(?9)] 'rst-html-compile) + +This function basically creates a compilation command with the correct HTML +output name for the current buffer and then invokes Emacs' compile function. It +also looks for the presence of a ``docutils.conf`` configuration file in the +parent directories and adds it to the cmdline options. You can customize which +tool is used to perform the conversion and some standard options to always be +added as well. + +.. note:: + + In general it is preferred to use a Makefile to automate the conversion of + many documents or a hierarchy of documents. The functionality presented + above is meant to be convenient for use on single files. + + +Other / External Useful Emacs Settings +====================================== + +This section covers general emacs text-mode settings that are useful in the +context of reStructuredText_ conventions. These are not provided by ``rst.el`` +but you may find them useful specifically for reStructuredText_ documents. + + +Settings for Filling Bulleted Lists +----------------------------------- + +One problem with the default text-mode settings is that *filling* long lines in +bulleted lists that do not have an empty line between them merges them together, +e.g.:: + + - Bananas; + - One Apple a day keeps the doctor away, and eating more keeps the pirates at bay; + - Oranges; + +Becomes:: + + - Bananas; One Apple a day keeps the doctor away, and + - eating more keeps the pirates at bay; Oranges; + +This is usually not what you want. What you want is this:: + + - Bananas; + - One Apple a day keeps the doctor away, and eating more + keeps the pirates at bay; + - Oranges; + +The problem is that emacs does not recognize the various consecutive items as +forming paragraph boundaries. You can fix this easily by changing the global +value of the parapraph boundary detection to recognize such lists, like this:: + + (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-*] ")) + + +``text-mode`` Settings +---------------------- + +Consult the Emacs manual for more text-mode customizations. In particular, you +may be interested in setting the following variables, functions and modes that +pertain somewhat to text-mode: + +- indent-tabs-mode +- colon-double-space +- auto-fill-mode +- auto-mode-alist +- fill-region + + +Editing Tables: Emacs table mode +-------------------------------- + +You may want to check out `Emacs table mode`_ to create an edit tables, it +allows creating ascii tables compatible with reStructuredText_. + +.. _Emacs table mode: http://table.sourceforge.net/ + + + +Character Processing +-------------------- + +Since reStructuredText punts on the issue of character processing, +here are some useful resources for Emacs users in the Unicode world: + +* `xmlunicode.el and unichars.el from Norman Walsh + `__ + +* `An essay by Tim Bray, with example code + `__ + +* For Emacs users on Mac OS X, here are some useful useful additions + to your .emacs file. + + - To get direct keyboard input of non-ASCII characters (like + "option-e e" resulting in "" [eacute]), first enable the option + key by setting the command key as your meta key:: + + (setq mac-command-key-is-meta t) ;; nil for option key + + Next, use one of these lines:: + + (set-keyboard-coding-system 'mac-roman) + (setq mac-keyboard-text-encoding kTextEncodingISOLatin1) + + I prefer the first line, because it enables non-Latin-1 characters + as well (em-dash, curly quotes, etc.). + + - To enable the display of all characters in the Mac-Roman charset, + first create a fontset listing the fonts to use for each range of + characters using charsets that Emacs understands:: + + (create-fontset-from-fontset-spec + "-apple-monaco-medium-r-normal--10-*-*-*-*-*-fontset-monaco, + ascii:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman, + latin-iso8859-1:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman, + mule-unicode-0100-24ff:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman") + + Latin-1 doesn't cover characters like em-dash and curly quotes, so + "mule-unicode-0100-24ff" is needed. + + Next, use that fontset:: + + (set-frame-font "fontset-monaco") + + - To enable cooperation between the system clipboard and the Emacs + kill ring, add this line:: + + (set-clipboard-coding-system 'mac-roman) + + Other useful resources are in `Andrew Choi's Emacs 21 for Mac OS X + FAQ `__. + +No matter what platform (or editor) you're using, I recommend the +ProFont__ programmer's font. It's monospaced, small but readable, +similar characters are visually distinctive (like "I1l|", "0O", "ao", +and ".,:;"), and free. + +__ http://www.tobias-jung.de/seekingprofont/ + + + + +Credits +======= + +- The automatic section adjustment and table of contents features were written + by Martin Blais; +- ``rst-mode`` and its syntax highlighting was implemented by Stefan Merten; +- Various other functions were implemented by David Goodger. + + +Obsolete Files +============== + +On 2005-10-30, ``restructuredtext.el``, ``rst-html.el`` and ``rst-mode.el`` were +merged to form the new ``rst.el``. You can consider the old files obsolete and +remove them. + + +Future Work +=========== + +Here are some features and ideas that will be worked on in the future, in those +frenzy morning of excitement over the virtues of the one-true-way kitchen sink +of editors: + +- It would be nice to differentiate between text files using reStructuredText_ + and other general text files. If we had a function to automatically guess + whether a .txt file is following the reStructuredText_ conventions, we could + trigger rst-mode without having to hardcode this on every text file, nor + forcing the user to add a local mode variable at the top of the file. + + We could perform this guessing by searching for a valid decoration at the top + of the document or searching for reStructuredText_ directives further on. + +- We would like to support local table of contents insertion. + +- The suggested decorations when adjusting should not have to cycle below one + below the last section decoration level preceding the cursor. We need to fix + that. + + +.. _Emacs: http://www.gnu.org/emacs FIXME check +.. _reStructuredText: http://docutils.sf.net/rst.html diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index 115927604..27be19f16 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -12,85 +12,18 @@ Directory Contents This directory contains the following Emacs lisp package files: -* restructuredtext.el by Martin Blais and David Goodger +* rst.el : Emacs support for ReStructuredText. This file contains - Support code for editing reStructuredText with Emacs indented-text - mode. + * Section decoration/adornment creation and updating (M. Blais); + * Table-of-contents mode and insertion (M. Blais); + * Font-lock syntax highlighting (S. Merten); + * Some handy editing functions (D. Goodger). + * Some functions for converting documents from emacs (M. Blais). -* rst-mode.el by Stefan Merten +* tests subdirectory: automated tests for some of the features in rst.el. + Please make sure the tests pass if you change the LISP code. Just type "make" + to run the tests. - Provides support for documents marked up using the reStructuredText - format, including font locking as well as some convenience functions - for editing. +To install the package, put a copy of the package file in a directory on your +``load-path`` (use ``C-h v load-path`` to check). -* rst-html.el by Martin Blais - - Provides a few functions and variables that can help in automating - the conversion of reST documents to HTML from within Emacs. - -Each file includes specific usage instructions. To install a package, -put a copy of the package file in a directory on your ``load-path`` -(use ``C-h v load-path`` to check). - - -Character Processing Notes -========================== - -Since reStructuredText punts on the issue of character processing, -here are some useful resources for Emacs users in the Unicode world: - -* `xmlunicode.el and unichars.el from Norman Walsh - `__ - -* `An essay by Tim Bray, with example code - `__ - -* For Emacs users on Mac OS X, here are some useful useful additions - to your .emacs file. - - - To get direct keyboard input of non-ASCII characters (like - "option-e e" resulting in "é" [eacute]), first enable the option - key by setting the command key as your meta key:: - - (setq mac-command-key-is-meta t) ;; nil for option key - - Next, use one of these lines:: - - (set-keyboard-coding-system 'mac-roman) - (setq mac-keyboard-text-encoding kTextEncodingISOLatin1) - - I prefer the first line, because it enables non-Latin-1 characters - as well (em-dash, curly quotes, etc.). - - - To enable the display of all characters in the Mac-Roman charset, - first create a fontset listing the fonts to use for each range of - characters using charsets that Emacs understands:: - - (create-fontset-from-fontset-spec - "-apple-monaco-medium-r-normal--10-*-*-*-*-*-fontset-monaco, - ascii:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman, - latin-iso8859-1:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman, - mule-unicode-0100-24ff:-apple-monaco-medium-r-normal--10-100-75-75-m-100-mac-roman") - - Latin-1 doesn't cover characters like em-dash and curly quotes, so - "mule-unicode-0100-24ff" is needed. - - Next, use that fontset:: - - (set-frame-font "fontset-monaco") - - - To enable cooperation between the system clipboard and the Emacs - kill ring, add this line:: - - (set-clipboard-coding-system 'mac-roman) - - Other useful resources are in `Andrew Choi's Emacs 21 for Mac OS X - FAQ `__. - -No matter what platform (or editor) you're using, I recommend the -ProFont__ programmer's font. It's monospaced, small but readable, -similar characters are visually distinctive (like "I1l|", "0O", "ao", -and ".,:;"), and free. - -__ http://www.tobias-jung.de/seekingprofont/ -.. _reStructuredText: http://docutils.sf.net/rst.html diff --git a/tools/editors/emacs/restructuredtext.el b/tools/editors/emacs/restructuredtext.el deleted file mode 100644 index 738ac18b4..000000000 --- a/tools/editors/emacs/restructuredtext.el +++ /dev/null @@ -1,1649 +0,0 @@ -;; Authors: Martin Blais , -;; David Goodger -;; Date: $Date$ -;; Copyright: This module has been placed in the public domain. -;; -;; Support code for editing reStructuredText with Emacs indented-text mode. -;; The goal is to create an integrated reStructuredText editing mode. -;; -;; Installation instructions -;; ------------------------- -;; -;; Add this line to your .emacs file and bind the versatile sectioning commands -;; in text mode, like this:: -;; -;; (require 'restructuredtext) -;; (add-hook 'text-mode-hook 'rest-text-mode-hook) -;; -;; The keys it defines are: -;; -;; C-= : updates or rotates the section title around point or -;; promotes/demotes the decorations within the region (see full details -;; below). -;; -;; Note that C-= is a good binding, since it allows you to specify a -;; negative arg easily with C-- C-= (easy to type), as well as ordinary -;; prefix arg with C-u C-=. -;; -;; C-x C-= : displays the hierarchical table-of-contents of the document and -;; allows you to jump to any section from it. -;; -;; C-u C-x C-= : displays the title decorations from this file. -;; -;; C-x + : insert the table of contents in the text. See the many options -;; for customizing how it will look. -;; -;; C-M-{, C-M-} : navigate between section titles. -;; -;; Other specialized and more generic functions are also available (see source -;; code). The most important function provided by this file for section title -;; adjustments is rest-adjust. -;; -;; There are many variables that can be customized, look for defcustom and -;; defvar in this file. -;; -;; If you use the table-of-contents feature, you may want to add a hook to -;; update the TOC automatically everytime you adjust a section title:: -;; -;; (add-hook 'rest-adjust-hook 'rest-toc-insert-update) -;; -;; -;; TODO -;; ==== -;; -;; rest-toc-insert features -;; ------------------------ -;; - Support local table of contents, like in doctree.txt. -;; - On load, detect any existing TOCs and set the properties for links. -;; - TOC insertion should have an option to add empty lines. -;; - TOC insertion should deal with multiple lines -;; -;; - There is a bug on redo after undo of adjust when rest-adjust-hook uses the -;; automatic toc update. The cursor ends up in the TOC and this is -;; annoying. Gotta fix that. -;; -;; Other -;; ----- -;; - Add an option to forego using the file structure in order to make -;; suggestion, and to always use the preferred decorations to do that. -;; - - -(require 'cl) - -(defun rest-toc-or-hierarchy () - "Binding for either TOC or decorations hierarchy." - (interactive) - (if (not current-prefix-arg) - (rest-toc) - (rest-display-decorations-hierarchy))) - -(defun rest-text-mode-hook () - "Default text mode hook for rest." - (local-set-key [(control ?=)] 'rest-adjust) - (local-set-key [(control x)(control ?=)] 'rest-toc-or-hierarchy) - (local-set-key [(control x)(?+)] 'rest-toc-insert) - (local-set-key [(control meta ?{)] 'rest-backward-section) - (local-set-key [(control meta ?})] 'rest-forward-section) - ) - -;; Note: we cannot do this because it messes with undo. If we disable undo, -;; since it adds and removes characters, the positions in the undo list are not -;; making sense anymore. Dunno what to do with this, it would be nice to update -;; when saving. -;; -;; (add-hook 'write-contents-hooks 'rest-toc-insert-update-fun) -;; (defun rest-toc-insert-update-fun () -;; ;; Disable undo for the write file hook. -;; (let ((buffer-undo-list t)) (rest-toc-insert-update) )) - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Generic Filter function. - -(if (not (fboundp 'filter)) - (defun filter (pred list) - "Returns a list of all the elements fulfilling the pred requirement (that -is for which (pred elem) is true)" - (if list - (let ((head (car list)) - (tail (filter pred (cdr list)))) - (if (funcall pred head) - (cons head tail) - tail))))) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; From emacs-22 - -(if (not (fboundp 'line-number-at-pos)) - (defun line-number-at-pos (&optional pos) - "Return (narrowed) buffer line number at position POS. - If POS is nil, use current buffer location." - (let ((opoint (or pos (point))) start) - (save-excursion - (goto-char (point-min)) - (setq start (point)) - (goto-char opoint) - (forward-line 0) - (1+ (count-lines start (point)))))) ) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; The following functions implement a smart automatic title sectioning feature. -;; The idea is that with the cursor sitting on a section title, we try to get as -;; much information from context and try to do the best thing automatically. -;; This function can be invoked many times and/or with prefix argument to rotate -;; between the various sectioning decorations. -;; -;; Definitions: the two forms of sectioning define semantically separate section -;; levels. A sectioning DECORATION consists in: -;; -;; - a CHARACTER -;; -;; - a STYLE which can be either of 'simple' or 'over-and-under'. -;; -;; - an INDENT (meaningful for the over-and-under style only) which determines -;; how many characters and over-and-under style is hanging outside of the -;; title at the beginning and ending. -;; -;; Important note: an existing decoration must be formed by at least two -;; characters to be recognized. -;; -;; Here are two examples of decorations (| represents the window border, column -;; 0): -;; -;; | -;; 1. char: '-' e |Some Title -;; style: simple |---------- -;; | -;; 2. char: '=' |============== -;; style: over-and-under | Some Title -;; indent: 2 |============== -;; | -;; -;; Some notes: -;; -;; - The underlining character that is used depends on context. The file is -;; scanned to find other sections and an appropriate character is selected. -;; If the function is invoked on a section that is complete, the character is -;; rotated among the existing section decorations. -;; -;; Note that when rotating the characters, if we come to the end of the -;; hierarchy of decorations, the variable rest-preferred-decorations is -;; consulted to propose a new underline decoration, and if continued, we cycle -;; the decorations all over again. Set this variable to nil if you want to -;; limit the underlining character propositions to the existing decorations in -;; the file. -;; -;; - A prefix argument can be used to alternate the style. -;; -;; - An underline/overline that is not extended to the column at which it should -;; be hanging is dubbed INCOMPLETE. For example:: -;; -;; |Some Title -;; |------- -;; -;; Examples of default invocation: -;; -;; |Some Title ---> |Some Title -;; | |---------- -;; -;; |Some Title ---> |Some Title -;; |----- |---------- -;; -;; | |------------ -;; | Some Title ---> | Some Title -;; | |------------ -;; -;; In over-and-under style, when alternating the style, a variable is available -;; to select how much default indent to use (it can be zero). Note that if the -;; current section decoration already has an indent, we don't adjust it to the -;; default, we rather use the current indent that is already there for -;; adjustment (unless we cycle, in which case we use the indent that has been -;; found previously). - -(defcustom rest-preferred-decorations '( (?= over-and-under 1) - (?= simple 0) - (?- simple 0) - (?~ simple 0) - (?+ simple 0) - (?` simple 0) - (?# simple 0) - (?@ simple 0) ) - "Preferred ordering of section title decorations. This - sequence is consulted to offer a new decoration suggestion when - we rotate the underlines at the end of the existing hierarchy - of characters, or when there is no existing section title in - the file.") - - -(defcustom rest-default-indent 1 - "Number of characters to indent the section title when toggling - decoration styles. This is used when switching from a simple - decoration style to a over-and-under decoration style.") - - -(defvar rest-section-text-regexp "^[ \t]*\\S-*[a-zA-Z0-9]\\S-*" - "Regular expression for valid section title text.") - - -(defun rest-line-homogeneous-p (&optional accept-special) - "Predicate return the unique char if the current line is - composed only of a single repeated non-whitespace - character. This returns the char even if there is whitespace at - the beginning of the line. - - If ACCEPT-SPECIAL is specified we do not ignore special sequences - which normally we would ignore when doing a search on many lines. - For example, normally we have cases to ignore commonly occuring - patterns, such as :: or ...; with the flag do not ignore them." - (save-excursion - (back-to-indentation) - (if (not (looking-at "\n")) - (let ((c (thing-at-point 'char))) - (if (and (looking-at (format "[%s]+[ \t]*$" c)) - (or accept-special - (and - ;; Common patterns. - (not (looking-at "::[ \t]*$")) - (not (looking-at "\\.\\.\\.[ \t]*$")) - ;; Discard one char line - (not (looking-at ".[ \t]*$")) - ))) - (string-to-char c)) - )) - )) - -(defun rest-line-homogeneous-nodent-p (&optional accept-special) - (save-excursion - (beginning-of-line) - (if (looking-at "^[ \t]+") - nil - (rest-line-homogeneous-p accept-special) - ))) - - -(defun rest-compare-decorations (deco1 deco2) - "Compare decorations. Returns true if both are equal, -according to restructured text semantics (only the character and -the style are compared, the indentation does not matter." - (and (eq (car deco1) (car deco2)) - (eq (cadr deco1) (cadr deco2)))) - - -(defun rest-get-decoration-match (hier deco) - "Returns the index (level) of the decoration in the given hierarchy. -This basically just searches for the item using the appropriate -comparison and returns the index. We return nil if the item is -not found." - (let ((cur hier)) - (while (and cur (not (rest-compare-decorations (car cur) deco))) - (setq cur (cdr cur))) - cur)) - - -(defun rest-suggest-new-decoration (alldecos &optional prev) - "Suggest a new, different decoration, different from all that -have been seen. - - ALLDECOS is the set of all decorations, including the line - numbers. PREV is the optional previous decoration, in order to - suggest a better match." - - ;; For all the preferred decorations... - (let* ( - ;; If 'prev' is given, reorder the list to start searching after the - ;; match. - (fplist - (cdr (rest-get-decoration-match rest-preferred-decorations prev))) - - ;; List of candidates to search. - (curpotential (append fplist rest-preferred-decorations))) - (while - ;; For all the decorations... - (let ((cur alldecos) - found) - (while (and cur (not found)) - (if (rest-compare-decorations (car cur) (car curpotential)) - ;; Found it! - (setq found (car curpotential)) - (setq cur (cdr cur)))) - found) - - (setq curpotential (cdr curpotential))) - - (copy-list (car curpotential)) )) - -(defun rest-delete-line () - "A version of kill-line that does not use the kill-ring." - (delete-region (line-beginning-position) (+ 1 (line-end-position)))) - -(defun rest-update-section (char style &optional indent) - "Unconditionally updates the style of a section decoration - using the given character CHAR, with STYLE 'simple or - 'over-and-under, and with indent INDENT. If the STYLE is - 'simple, whitespace before the title is removed (indent is - always assume to be 0). - - If there are existing overline and/or underline from the - existing decoration, they are removed before adding the - requested decoration." - - (interactive) - (let (marker - len - ec - (c ?-)) - - (end-of-line) - (setq marker (point-marker)) - - ;; Fixup whitespace at the beginning and end of the line - (if (or (null indent) (eq style 'simple)) - (setq indent 0)) - (beginning-of-line) - (delete-horizontal-space) - (insert (make-string indent ? )) - - (end-of-line) - (delete-horizontal-space) - - ;; Set the current column, we're at the end of the title line - (setq len (+ (current-column) indent)) - - ;; Remove previous line if it consists only of a single repeated character - (save-excursion - (forward-line -1) - (and (rest-line-homogeneous-p 1) - ;; Avoid removing the underline of a title right above us. - (save-excursion (forward-line -1) - (not (looking-at rest-section-text-regexp))) - (rest-delete-line))) - - ;; Remove following line if it consists only of a single repeated - ;; character - (save-excursion - (forward-line +1) - (and (rest-line-homogeneous-p 1) - (rest-delete-line)) - ;; Add a newline if we're at the end of the buffer, for the subsequence - ;; inserting of the underline - (if (= (point) (buffer-end 1)) - (newline 1))) - - ;; Insert overline - (if (eq style 'over-and-under) - (save-excursion - (beginning-of-line) - (open-line 1) - (insert (make-string len char)))) - - ;; Insert underline - (forward-line +1) - (open-line 1) - (insert (make-string len char)) - - (forward-line +1) - (goto-char marker) - )) - - -(defun rest-normalize-cursor-position () - "If the cursor is on a decoration line or an empty line , place - it on the section title line (at the end). Returns the line - offset by which the cursor was moved. This works both over or - under a line." - (if (save-excursion (beginning-of-line) - (or (rest-line-homogeneous-p 1) - (looking-at "^[ \t]*$"))) - (progn - (beginning-of-line) - (cond - ((save-excursion (forward-line -1) - (beginning-of-line) - (and (looking-at rest-section-text-regexp) - (not (rest-line-homogeneous-p 1)))) - (progn (forward-line -1) -1)) - ((save-excursion (forward-line +1) - (beginning-of-line) - (and (looking-at rest-section-text-regexp) - (not (rest-line-homogeneous-p 1)))) - (progn (forward-line +1) +1)) - (t 0))) - 0 )) - - -(defun rest-find-all-decorations () - "Finds all the decorations in the file, and returns a list of - (line, decoration) pairs. Each decoration consists in a (char, - style, indent) triple. - - This function does not detect the hierarchy of decorations, it - just finds all of them in a file. You can then invoke another - function to remove redundancies and inconsistencies." - - (let (positions - (curline 1)) - ;; Iterate over all the section titles/decorations in the file. - (save-excursion - (beginning-of-buffer) - (while (< (point) (buffer-end 1)) - (if (rest-line-homogeneous-nodent-p) - (progn - (setq curline (+ curline (rest-normalize-cursor-position))) - - ;; Here we have found a potential site for a decoration, - ;; characterize it. - (let ((deco (rest-get-decoration))) - (if (cadr deco) ;; Style is existing. - ;; Found a real decoration site. - (progn - (push (cons curline deco) positions) - ;; Push beyond the underline. - (forward-line 1) - (setq curline (+ curline 1)) - ))) - )) - (forward-line 1) - (setq curline (+ curline 1)) - )) - (reverse positions))) - - -(defun rest-infer-hierarchy (decorations) - "Build a hierarchy of decorations using the list of given decorations. - - This function expects a list of (char, style, indent) - decoration specifications, in order that they appear in a file, - and will infer a hierarchy of section levels by removing - decorations that have already been seen in a forward traversal of the - decorations, comparing just the character and style. - - Similarly returns a list of (char, style, indent), where each - list element should be unique." - - (let ((hierarchy-alist (list))) - (dolist (x decorations) - (let ((char (car x)) - (style (cadr x)) - (indent (caddr x))) - (if (not (assoc (cons char style) hierarchy-alist)) - (progn - (setq hierarchy-alist - (append hierarchy-alist - (list (cons (cons char style) x)))) - )) - )) - (mapcar 'cdr hierarchy-alist) - )) - - -(defun rest-get-hierarchy (&optional alldecos ignore) - "Returns a list of decorations that represents the hierarchy of - section titles in the file. - - If the line number in IGNORE is specified, the decoration found - on that line (if there is one) is not taken into account when - building the hierarchy." - (let ((all (or alldecos (rest-find-all-decorations)))) - (setq all (assq-delete-all ignore all)) - (rest-infer-hierarchy (mapcar 'cdr all)))) - - -(defun rest-get-decoration (&optional point) - "Looks around point and finds the characteristics of the - decoration that is found there. We assume that the cursor is - already placed on the title line (and not on the overline or - underline). - - This function returns a (char, style, indent) triple. If the - characters of overline and underline are different, we return - the underline character. The indent is always calculated. A - decoration can be said to exist if the style is not nil. - - A point can be specified to go to the given location before - extracting the decoration." - - (let (char style indent) - (save-excursion - (if point (goto-char point)) - (beginning-of-line) - (if (looking-at rest-section-text-regexp) - (let* ((over (save-excursion - (forward-line -1) - (rest-line-homogeneous-nodent-p))) - - (under (save-excursion - (forward-line +1) - (rest-line-homogeneous-nodent-p))) - ) - - ;; Check that the line above the overline is not part of a title - ;; above it. - (if (and over - (save-excursion - (and (equal (forward-line -2) 0) - (looking-at rest-section-text-regexp)))) - (setq over nil)) - - (cond - ;; No decoration found, leave all return values nil. - ((and (eq over nil) (eq under nil))) - - ;; Overline only, leave all return values nil. - ;; - ;; Note: we don't return the overline character, but it could perhaps - ;; in some cases be used to do something. - ((and over (eq under nil))) - - ;; Underline only. - ((and under (eq over nil)) - (setq char under - style 'simple)) - - ;; Both overline and underline. - (t - (setq char under - style 'over-and-under)) - ) - ) - ) - ;; Find indentation. - (setq indent (save-excursion (back-to-indentation) (current-column))) - ) - ;; Return values. - (list char style indent))) - - -(defun rest-get-decorations-around (&optional alldecos) - "Given the list of all decorations (with positions), -find the decorations before and after the given point. -A list of the previous and next decorations is returned." - (let* ((all (or alldecos (rest-find-all-decorations))) - (curline (line-number-at-pos)) - prev next - (cur all)) - - ;; Search for the decorations around the current line. - (while (and cur (< (caar cur) curline)) - (setq prev cur - cur (cdr cur))) - ;; 'cur' is the following decoration. - - (if (and cur (caar cur)) - (setq next (if (= curline (caar cur)) (cdr cur) cur))) - - (mapcar 'cdar (list prev next)) - )) - - -(defun rest-decoration-complete-p (deco &optional point) - "Return true if the decoration DECO around POINT is complete." - ;; Note: we assume that the detection of the overline as being the underline - ;; of a preceding title has already been detected, and has been eliminated - ;; from the decoration that is given to us. - - ;; There is some sectioning already present, so check if the current - ;; sectioning is complete and correct. - (let* ((char (car deco)) - (style (cadr deco)) - (indent (caddr deco)) - (endcol (save-excursion (end-of-line) (current-column))) - ) - (if char - (let ((exps (concat "^" - (regexp-quote (make-string (+ endcol indent) char)) - "$"))) - (and - (save-excursion (forward-line +1) - (beginning-of-line) - (looking-at exps)) - (or (not (eq style 'over-and-under)) - (save-excursion (forward-line -1) - (beginning-of-line) - (looking-at exps)))) - )) - )) - - -(defun rest-get-next-decoration - (curdeco hier &optional suggestion reverse-direction) - "Get the next decoration for CURDECO, in given hierarchy HIER, -and suggesting for new decoration SUGGESTION." - - (let* ( - (char (car curdeco)) - (style (cadr curdeco)) - - ;; Build a new list of decorations for the rotation. - (rotdecos - (append hier - ;; Suggest a new decoration. - (list suggestion - ;; If nothing to suggest, use first decoration. - (car hier)))) ) - (or - ;; Search for next decoration. - (cadr - (let ((cur (if reverse-direction rotdecos - (reverse rotdecos))) - found) - (while (and cur - (not (and (eq char (caar cur)) - (eq style (cadar cur))))) - (setq cur (cdr cur))) - cur)) - - ;; If not found, take the first of all decorations. - suggestion - ))) - - -(defun rest-adjust () - "Adjust/rotate the section decoration for the section title -around point or promote/demote the decorations inside the region, -depending on if the region is active. This function is meant to -be invoked possibly multiple times, and can vary its behaviour -with a positive prefix argument (toggle style), or with a -negative prefix argument (alternate behaviour). - -This function is the main focus of this module and is a bit of a -swiss knife. It is meant as the single most essential function -to be bound to invoke to adjust the decorations of a section -title in restructuredtext. It tries to deal with all the -possible cases gracefully and to do `the right thing' in all -cases. - -See the documentations of rest-adjust-decoration and -rest-promote-region for full details. - -Prefix Arguments -================ - -The method can take either (but not both) of - -a. a (non-negative) prefix argument, which means to toggle the - decoration style. Invoke with C-u prefix for example; - -b. a negative numerical argument, which generally inverts the - direction of search in the file or hierarchy. Invoke with C-- - prefix for example. - -" - (interactive) - - (let* ( ;; Parse the positive and negative prefix arguments. - (reverse-direction - (and current-prefix-arg - (< (prefix-numeric-value current-prefix-arg) 0))) - (toggle-style - (and current-prefix-arg (not reverse-direction)))) - - (if (and transient-mark-mode mark-active) - ;; Adjust decorations within region. - (rest-promote-region current-prefix-arg) - ;; Adjust decoration around point. - (rest-adjust-decoration toggle-style reverse-direction)) - - ;; Run the hooks to run after adjusting. - (run-hooks 'rest-adjust-hook) - - )) - -(defvar rest-adjust-hook nil - "Hooks to be run after running rest-adjust.") - -(defun rest-adjust-decoration (&optional toggle-style reverse-direction) -"Adjust/rotate the section decoration for the section title around point. - -This function is meant to be invoked possibly multiple times, and -can vary its behaviour with a true TOGGLE-STYLE argument, or with -a REVERSE-DIRECTION argument. - -General Behaviour -================= - -The next action it takes depends on context around the point, and -it is meant to be invoked possibly more than once to rotate among -the various possibilities. Basically, this function deals with: - -- adding a decoration if the title does not have one; - -- adjusting the length of the underline characters to fit a - modified title; - -- rotating the decoration in the set of already existing - sectioning decorations used in the file; - -- switching between simple and over-and-under styles. - -You should normally not have to read all the following, just -invoke the method and it will do the most obvious thing that you -would expect. - - -Decoration Definitions -====================== - -The decorations consist in - -1. a CHARACTER - -2. a STYLE which can be either of 'simple' or 'over-and-under'. - -3. an INDENT (meaningful for the over-and-under style only) - which determines how many characters and over-and-under - style is hanging outside of the title at the beginning and - ending. - -See source code for mode details. - - -Detailed Behaviour Description -============================== - -Here are the gory details of the algorithm (it seems quite -complicated, but really, it does the most obvious thing in all -the particular cases): - -Before applying the decoration change, the cursor is placed on -the closest line that could contain a section title. - -Case 1: No Decoration ---------------------- - -If the current line has no decoration around it, - -- search backwards for the last previous decoration, and apply - the decoration one level lower to the current line. If there - is no defined level below this previous decoration, we suggest - the most appropriate of the rest-preferred-decorations. - - If REVERSE-DIRECTION is true, we simply use the previous - decoration found directly. - -- if there is no decoration found in the given direction, we use - the first of rest-preferred-decorations. - -The prefix argument forces a toggle of the prescribed decoration -style. - -Case 2: Incomplete Decoration ------------------------------ - -If the current line does have an existing decoration, but the -decoration is incomplete, that is, the underline/overline does -not extend to exactly the end of the title line (it is either too -short or too long), we simply extend the length of the -underlines/overlines to fit exactly the section title. - -If the prefix argument is given, we toggle the style of the -decoration as well. - -REVERSE-DIRECTION has no effect in this case. - -Case 3: Complete Existing Decoration ------------------------------------- - -If the decoration is complete (i.e. the underline (overline) -length is already adjusted to the end of the title line), we -search/parse the file to establish the hierarchy of all the -decorations (making sure not to include the decoration around -point), and we rotate the current title's decoration from within -that list (by default, going *down* the hierarchy that is present -in the file, i.e. to a lower section level). This is meant to be -used potentially multiple times, until the desired decoration is -found around the title. - -If we hit the boundary of the hierarchy, exactly one choice from -the list of preferred decorations is suggested/chosen, the first -of those decoration that has not been seen in the file yet (and -not including the decoration around point), and the next -invocation rolls over to the other end of the hierarchy (i.e. it -cycles). This allows you to avoid having to set which character -to use by always using the - -If REVERSE-DIRECTION is true, the effect is to change the -direction of rotation in the hierarchy of decorations, thus -instead going *up* the hierarchy. - -However, if there is a non-negative prefix argument, we do not -rotate the decoration, but instead simply toggle the style of the -current decoration (this should be the most common way to toggle -the style of an existing complete decoration). - - -Point Location -============== - -The invocation of this function can be carried out anywhere -within the section title line, on an existing underline or -overline, as well as on an empty line following a section title. -This is meant to be as convenient as possible. - - -Indented Sections -================= - -Indented section titles such as :: - - My Title - -------- - -are illegal in restructuredtext and thus not recognized by the -parser. This code will thus not work in a way that would support -indented sections (it would be ambiguous anyway). - - -Joint Sections -============== - -Section titles that are right next to each other may not be -treated well. More work might be needed to support those, and -special conditions on the completeness of existing decorations -might be required to make it non-ambiguous. - -For now we assume that the decorations are disjoint, that is, -there is at least a single line between the titles/decoration -lines. - - -Suggested Binding -================= - -We suggest that you bind this function on C-=. It is close to -C-- so a negative argument can be easily specified with a flick -of the right hand fingers and the binding is unused in text-mode." - (interactive) - - ;; If we were invoked directly, parse the prefix arguments into the - ;; arguments of the function. - (if current-prefix-arg - (setq reverse-direction - (and current-prefix-arg - (< (prefix-numeric-value current-prefix-arg) 0)) - - toggle-style - (and current-prefix-arg (not reverse-direction)))) - - (let* (;; Check if we're on an underline around a section title, and move the - ;; cursor to the title if this is the case. - (moved (rest-normalize-cursor-position)) - - ;; Find the decoration and completeness around point. - (curdeco (rest-get-decoration)) - (char (car curdeco)) - (style (cadr curdeco)) - (indent (caddr curdeco)) - - ;; New values to be computed. - char-new style-new indent-new - ) - - ;; We've moved the cursor... if we're not looking at some text, we have - ;; nothing to do. - (if (save-excursion (beginning-of-line) - (looking-at rest-section-text-regexp)) - (progn - (cond - ;;--------------------------------------------------------------------- - ;; Case 1: No Decoration - ((and (eq char nil) (eq style nil)) - - (let* ((alldecos (rest-find-all-decorations)) - - (around (rest-get-decorations-around alldecos)) - (prev (car around)) - cur - - (hier (rest-get-hierarchy alldecos)) - ) - - ;; Advance one level down. - (setq cur - (if prev - (if (not reverse-direction) - (or (cadr (rest-get-decoration-match hier prev)) - (rest-suggest-new-decoration hier prev)) - prev) - (copy-list (car rest-preferred-decorations)) - )) - - ;; Invert the style if requested. - (if toggle-style - (setcar (cdr cur) (if (eq (cadr cur) 'simple) - 'over-and-under 'simple)) ) - - (setq char-new (car cur) - style-new (cadr cur) - indent-new (caddr cur)) - )) - - ;;--------------------------------------------------------------------- - ;; Case 2: Incomplete Decoration - ((not (rest-decoration-complete-p curdeco)) - - ;; Invert the style if requested. - (if toggle-style - (setq style (if (eq style 'simple) 'over-and-under 'simple))) - - (setq char-new char - style-new style - indent-new indent)) - - ;;--------------------------------------------------------------------- - ;; Case 3: Complete Existing Decoration - (t - (if toggle-style - - ;; Simply switch the style of the current decoration. - (setq char-new char - style-new (if (eq style 'simple) 'over-and-under 'simple) - indent-new rest-default-indent) - - ;; Else, we rotate, ignoring the decoration around the current - ;; line... - (let* ((alldecos (rest-find-all-decorations)) - - (hier (rest-get-hierarchy alldecos (line-number-at-pos))) - - ;; Suggestion, in case we need to come up with something - ;; new - (suggestion (rest-suggest-new-decoration - hier - (car (rest-get-decorations-around alldecos)))) - - (nextdeco (rest-get-next-decoration - curdeco hier suggestion reverse-direction)) - - ) - - ;; Indent, if present, always overrides the prescribed indent. - (setq char-new (car nextdeco) - style-new (cadr nextdeco) - indent-new (caddr nextdeco)) - - ))) - ) - - ;; Override indent with present indent! - (setq indent-new (if (> indent 0) indent indent-new)) - - (if (and char-new style-new) - (rest-update-section char-new style-new indent-new)) - )) - - - ;; Correct the position of the cursor to more accurately reflect where it - ;; was located when the function was invoked. - (if (not (= moved 0)) - (progn (forward-line (- moved)) - (end-of-line))) - - )) - -;; Maintain an alias for compatibility. -(defalias 'rest-adjust-section-title 'rest-adjust) - - -(defun rest-promote-region (&optional demote) - "Promote the section titles within the region. - -With argument DEMOTE or a prefix argument, demote the -section titles instead. The algorithm used at the boundaries of -the hierarchy is similar to that used by rest-adjust-decoration." - (interactive) - - (let* ((demote (or current-prefix-arg demote)) - (alldecos (rest-find-all-decorations)) - (cur alldecos) - - (hier (rest-get-hierarchy alldecos)) - (suggestion (rest-suggest-new-decoration hier)) - - (region-begin-line (line-number-at-pos (region-beginning))) - (region-end-line (line-number-at-pos (region-end))) - - marker-list - ) - - ;; Skip the markers that come before the region beginning - (while (and cur (< (caar cur) region-begin-line)) - (setq cur (cdr cur))) - - ;; Create a list of markers for all the decorations which are found within - ;; the region. - (save-excursion - (let (m line) - (while (and cur (< (setq line (caar cur)) region-end-line)) - (setq m (make-marker)) - (goto-line line) - (push (list (set-marker m (point)) (cdar cur)) marker-list) - (setq cur (cdr cur)) )) - - ;; Apply modifications. - (let (nextdeco) - (dolist (p marker-list) - ;; Go to the decoration to promote. - (goto-char (car p)) - - ;; Rotate the next decoration. - (setq nextdeco (rest-get-next-decoration - (cadr p) hier suggestion demote)) - - ;; Update the decoration. - (apply 'rest-update-section nextdeco) - - ;; Clear marker to avoid slowing down the editing after we're done. - (set-marker (car p) nil) - )) - (setq deactivate-mark nil) - ))) - - - -(defun rest-display-decorations-hierarchy (&optional decorations) - "Display the current file's section title decorations hierarchy. - This function expects a list of (char, style, indent) triples." - (interactive) - - (if (not decorations) - (setq decorations (rest-get-hierarchy))) - (with-output-to-temp-buffer "*rest section hierarchy*" - (let ((level 1)) - (with-current-buffer standard-output - (dolist (x decorations) - (insert (format "\nSection Level %d" level)) - (apply 'rest-update-section x) - (end-of-buffer) - (insert "\n") - (incf level) - )) - ))) - - -(defun rest-rstrip (str) - "Strips the whitespace at the end of a string." - (let ((tmp)) - (string-match "[ \t\n]*\\'" str) - (substring str 0 (match-beginning 0)) - )) - -(defun rest-get-stripped-line () - "Returns the line at cursor, stripped from whitespace." - (re-search-forward "\\S-.*\\S-" (line-end-position)) - (buffer-substring-no-properties (match-beginning 0) - (match-end 0)) ) - - -(defcustom rest-toc-indent 2 - "Indentation for table-of-contents display (also used for - formatting insertion, when numbering is disabled).") - - -(defun rest-section-tree (alldecos) - "Returns a pair of a hierarchical tree of the sections titles -in the document, and a reference to the node where the cursor -lives. This can be used to generate a table of contents for the -document. - -Each section title consists in a cons of the stripped title -string and a marker to the section in the original text document. - -If there are missing section levels, the section titles are -inserted automatically, and are set to nil." - - (let* (thelist - (hier (rest-get-hierarchy alldecos)) - (levels (make-hash-table :test 'equal :size 10)) - lines) - - (let ((lev 0)) - (dolist (deco hier) - (puthash deco lev levels) - (incf lev))) - - ;; Create a list of lines that contains (text, level, marker) for each - ;; decoration. - (save-excursion - (setq lines - (mapcar (lambda (deco) - (goto-line (car deco)) - (list (gethash (cdr deco) levels) - (rest-get-stripped-line) - (let ((m (make-marker))) - (beginning-of-line 1) - (set-marker m (point))) - )) - alldecos))) - - (let ((lcontnr (cons nil lines))) - (rest-section-tree-rec lcontnr -1)))) - - -(defun rest-section-tree-rec (decos lev) - "Recursive function for the implementation of the section tree - building. DECOS is a cons cell whose cdr is the remaining list - of decorations, and we change it as we consume them. LEV is - the current level of that node. This function returns a pair - of the subtree that was built. This treats the decos list - destructively." - - (let ((ndeco (cadr decos)) - node - children) - ;; If the next decoration matches our level - (if (= (car ndeco) lev) - (progn - ;; Pop the next decoration and create the current node with it - (setcdr decos (cddr decos)) - (setq node (cdr ndeco)) )) - ;; Else we let the node title/marker be unset. - - ;; Build the child nodes - (while (and (cdr decos) (> (caadr decos) lev)) - (setq children - (cons (rest-section-tree-rec decos (1+ lev)) - children))) - - ;; Return this node with its children. - (cons node (reverse children)) - )) - - -(defun rest-toc-insert (&optional pfxarg) - "Insert a simple text rendering of the table of contents. -By default the top level is ignored if there is only one, because -we assume that the document will have a single title. - -If a numeric prefix argument is given, -- if it is zero or generic, include the top level titles; -- otherwise insert the TOC up to the specified level. - -The TOC is inserted indented at the current column." - - (interactive "P") - - (let* (;; Check maximum level override - (rest-toc-insert-max-level - (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) - (prefix-numeric-value pfxarg) rest-toc-insert-max-level)) - - ;; Get the section tree. - (sectree (rest-section-tree (rest-find-all-decorations))) - - ;; If there is only one top-level title, remove it by starting to print - ;; one index lower (revert this behaviour with the prefix arg), - ;; otherwise print all. - (gen-pfx-arg (or (and pfxarg (listp pfxarg)) - (and (integerp pfxarg) - (= (prefix-numeric-value pfxarg) 0)))) - (start-lev (if (and (not rest-toc-insert-always-include-top) - (= (length (cdr sectree)) 1) - (not gen-pfx-arg)) -1 0)) - - ;; Figure out initial indent. - (initial-indent (make-string (current-column) ? )) - (init-point (point))) - - (rest-toc-insert-node sectree start-lev initial-indent "") - - ;; Fixup for the first line. - (delete-region init-point (+ init-point (length initial-indent))) - - ;; Delete the last newline added. - (delete-backward-char 1) - )) - - -(defcustom rest-toc-insert-always-include-top nil - "Set this to 't if you want to always include top-level titles, - even when there is only one.") - -(defcustom rest-toc-insert-style 'fixed - "Set this to one of the following values to determine numbering and -indentation style: -- plain: no numbering (fixed indentation) -- fixed: numbering, but fixed indentation -- aligned: numbering, titles aligned under each other -- listed: numbering, with dashes like list items (EXPERIMENTAL) -") - -(defcustom rest-toc-insert-number-separator " " - "Separator that goes between the TOC number and the title.") - -;; This is used to avoid having to change the user's mode. -(defvar rest-toc-insert-click-keymap - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'rest-toc-mode-mouse-goto) - map) - "(Internal) What happens when you click on propertized text in the TOC.") - -(defcustom rest-toc-insert-max-level nil - "If non-nil, maximum depth of the inserted TOC.") - -(defun rest-toc-insert-node (node level indent pfx) - "Recursive function that does the print of the inserted -toc. PFX is the prefix numbering, that includes the alignment -necessary for all the children of this level to align." - (let ((do-print (> level 0)) - (count 1) - b) - (if do-print - (progn - (insert indent) - (let ((b (point))) - (if (not (equal rest-toc-insert-style 'plain)) - (insert pfx rest-toc-insert-number-separator)) - (insert (or (caar node) "[missing node]")) - ;; Add properties to the text, even though in normal text mode it - ;; won't be doing anything for now. Not sure that I want to change - ;; mode stuff. At least the highlighting gives the idea that this - ;; is generated automatically. - (put-text-property b (point) 'mouse-face 'highlight) - (put-text-property b (point) 'rest-toc-target (cadar node)) - (put-text-property b (point) 'keymap rest-toc-insert-click-keymap) - - ) - (insert "\n") - - ;; Prepare indent for children. - (setq indent - (cond - ((eq rest-toc-insert-style 'plain) - (concat indent rest-toc-indent)) - - ((eq rest-toc-insert-style 'fixed) - (concat indent (make-string rest-toc-indent ? ))) - - ((eq rest-toc-insert-style 'aligned) - (concat indent (make-string (+ (length pfx) 2) ? ))) - - ((eq rest-toc-insert-style 'listed) - (concat (substring indent 0 -3) - (concat (make-string (+ (length pfx) 2) ? ) " - "))) - )) - - )) - - (if (or (eq rest-toc-insert-max-level nil) - (< level rest-toc-insert-max-level)) - (let ((do-child-numbering (>= level 0)) - fmt) - (if do-child-numbering - (progn - ;; Add a separating dot if there is already a prefix - (if (> (length pfx) 0) - (setq pfx (concat (rest-rstrip pfx) "."))) - - ;; Calculate the amount of space that the prefix will require for - ;; the numbers. - (if (cdr node) - (setq fmt (format "%%-%dd" - (1+ (floor (log10 (length (cdr node)))))))) - )) - - (dolist (child (cdr node)) - (rest-toc-insert-node child - (1+ level) - indent - (if do-child-numbering - (concat pfx (format fmt count)) pfx)) - (incf count))) - - ))) - - -(defun rest-toc-insert-find-delete-contents () - "Finds and deletes an existing comment after the first contents directive and -delete that region. Return t if found and the cursor is left after the comment." - (goto-char (point-min)) - ;; We look for the following and the following only (in other words, if your - ;; syntax differs, this won't work. If you would like a more flexible thing, - ;; contact the author, I just can't imagine that this requirement is - ;; unreasonable for now). - ;; - ;; .. contents:: [...anything here...] - ;; .. - ;; XXXXXXXX - ;; XXXXXXXX - ;; [more lines] - ;; - (let ((beg - (re-search-forward "^\\.\\. contents[ \t]*::\\(.*\\)\n\\.\\." - nil t)) - last-real) - (when beg - ;; Look for the first line that starts at the first column. - (forward-line 1) - (beginning-of-line) - (while (or (and (looking-at "[ \t]+[^ \t]") - (setq last-real (point)) t) - (looking-at "\\s-*$")) - (forward-line 1) - ) - (if last-real - (progn - (goto-char last-real) - (end-of-line) - (delete-region beg (point))) - (goto-char beg)) - t - ))) - -(defun rest-toc-insert-update () - "Automatically find the .. contents:: section of a document and update the -inserted TOC if present. You can use this in your file-write hook to always -make it up-to-date automatically." - (interactive) - (save-excursion - (if (rest-toc-insert-find-delete-contents) - (progn (insert "\n ") - (rest-toc-insert))) ) - ;; Note: always return nil, because this may be used as a hook. - ) - - -;;------------------------------------------------------------------------------ - -(defun rest-toc-node (node level) - "Recursive function that does the print of the TOC in rest-toc-mode." - - (if (> level 0) - (let ((b (point))) - ;; Insert line text. - (insert (make-string (* rest-toc-indent (1- level)) ? )) - (insert (if (car node) (caar node) "[missing node]")) - - ;; Highlight lines. - (put-text-property b (point) 'mouse-face 'highlight) - - ;; Add link on lines. - (put-text-property b (point) 'rest-toc-target (cadar node)) - - (insert "\n"))) - - (dolist (child (cdr node)) - (rest-toc-node child (1+ level)))) - - -(defun rest-toc () - "Finds all the section titles and their decorations in the - file, and displays a hierarchically-organized list of the - titles, which is essentially a table-of-contents of the - document. - - The emacs buffer can be navigated, and selecting a section - brings the cursor in that section." - (interactive) - (let* ((curbuf (current-buffer)) - outline - - ;; Get the section tree - (alldecos (rest-find-all-decorations)) - (sectree (rest-section-tree alldecos)) - - ;; Create a temporary buffer. - (buf (get-buffer-create rest-toc-buffer-name)) - ) - - ;; Find the index of the section where the cursor currently is. - (setq outline (let ((idx 1) - (curline (line-number-at-pos (point))) - (decos alldecos)) - (while (and decos (<= (caar decos) curline)) - (setq decos (cdr decos)) - (incf idx)) - idx)) - ;; FIXME: if there is a missing node inserted, the calculation of the - ;; current line will be off. You need to fix this by moving the finding of - ;; the current line somewhere else. - - - (with-current-buffer buf - (let ((inhibit-read-only t)) - (rest-toc-mode) - (delete-region (point-min) (point-max)) - (insert (format "Table of Contents: %s\n" (or (caar sectree) ""))) - (put-text-property (point-min) (point) - 'face (list '(background-color . "lightgray"))) - (rest-toc-node sectree 0) - )) - (display-buffer buf) - (pop-to-buffer buf) - - ;; Save the buffer to return to. - (set (make-local-variable 'rest-toc-return-buffer) curbuf) - - ;; Move the cursor near the right section in the TOC. - (goto-line outline) - )) - - -(defun rest-toc-mode-find-section () - (let ((pos (get-text-property (point) 'rest-toc-target))) - (unless pos - (error "No section on this line")) - (unless (buffer-live-p (marker-buffer pos)) - (error "Buffer for this section was killed")) - pos)) - -(defvar rest-toc-buffer-name "*Table of Contents*" - "Name of the Table of Contents buffer.") - -(defun rest-toc-mode-goto-section () - "Go to the section the current line describes." - (interactive) - (let ((pos (rest-toc-mode-find-section))) - (kill-buffer (get-buffer rest-toc-buffer-name)) - (pop-to-buffer (marker-buffer pos)) - (goto-char pos) - (recenter 5))) - -(defun rest-toc-mode-mouse-goto (event) - "In Rest-Toc mode, go to the occurrence whose line you click on." - (interactive "e") - (let (pos) - (save-excursion - (set-buffer (window-buffer (posn-window (event-end event)))) - (save-excursion - (goto-char (posn-point (event-end event))) - (setq pos (rest-toc-mode-find-section)))) - (pop-to-buffer (marker-buffer pos)) - (goto-char pos))) - -(defun rest-toc-mode-mouse-goto-kill (event) - (interactive "e") - (call-interactively 'rest-toc-mode-mouse-goto event) - (kill-buffer (get-buffer rest-toc-buffer-name))) - -(defvar rest-toc-return-buffer nil - "Buffer local variable that is used to return to the original - buffer from the TOC.") - -(defun rest-toc-quit-window () - (interactive) - (quit-window) - (pop-to-buffer rest-toc-return-buffer)) - -(defvar rest-toc-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'rest-toc-mode-mouse-goto-kill) - (define-key map [mouse-2] 'rest-toc-mode-mouse-goto) - (define-key map "\C-m" 'rest-toc-mode-goto-section) - (define-key map "f" 'rest-toc-mode-goto-section) - (define-key map "q" 'rest-toc-quit-window) - (define-key map "z" 'kill-this-buffer) - map) - "Keymap for `rest-toc-mode'.") - -(put 'rest-toc-mode 'mode-class 'special) - -(defun rest-toc-mode () - "Major mode for output from \\[rest-toc]." - (interactive) - (kill-all-local-variables) - (use-local-map rest-toc-mode-map) - (setq major-mode 'rest-toc-mode) - (setq mode-name "Rest-TOC") - (setq buffer-read-only t) - ) - -;; Note: use occur-mode (replace.el) as a good example to complete missing -;; features. - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Section movement commands. -;; - -(defun rest-forward-section (&optional offset) - "Skip to the next restructured text section title. - OFFSET specifies how many titles to skip. Use a negative OFFSET to move - backwards in the file (default is to use 1)." - (interactive) - (let* (;; Default value for offset. - (offset (or offset 1)) - - ;; Get all the decorations in the file, with their line numbers. - (alldecos (rest-find-all-decorations)) - - ;; Get the current line. - (curline (line-number-at-pos)) - - (cur alldecos) - (idx 0) - line - ) - - ;; Find the index of the "next" decoration w.r.t. to the current line. - (while (and cur (< (caar cur) curline)) - (setq cur (cdr cur)) - (incf idx)) - ;; 'cur' is the decoration on or following the current line. - - (if (and (> offset 0) cur (= (caar cur) curline)) - (incf idx)) - - ;; Find the final index. - (setq idx (+ idx (if (> offset 0) (- offset 1) offset))) - (setq cur (nth idx alldecos)) - - ;; If the index is positive, goto the line, otherwise go to the buffer - ;; boundaries. - (if (and cur (>= idx 0)) - (goto-line (car cur)) - (if (> offset 0) (end-of-buffer) (beginning-of-buffer))) - )) - -(defun rest-backward-section () - "Like rest-forward-section, except move back one title." - (interactive) - (rest-forward-section -1)) - - - - - - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Generic text functions that are more convenient than the defaults. -;; - -(defun replace-lines (fromchar tochar) - "Replace flush-left lines, consisting of multiple FROMCHAR characters, -with equal-length lines of TOCHAR." - (interactive "\ -cSearch for flush-left lines of char: -cand replace with char: ") - (save-excursion - (let* ((fromstr (string fromchar)) - (searchre (concat "^" (regexp-quote fromstr) "+ *$")) - (found 0)) - (condition-case err - (while t - (search-forward-regexp searchre) - (setq found (1+ found)) - (search-backward fromstr) ;; point will be *before* last char - (setq p (1+ (point))) - (beginning-of-line) - (setq l (- p (point))) - (rest-delete-line) - (insert-char tochar l)) - (search-failed - (message (format "%d lines replaced." found))))))) - -(defun join-paragraph () - "Join lines in current paragraph into one line, removing end-of-lines." - (interactive) - (let ((fill-column 65000)) ; some big number - (call-interactively 'fill-paragraph))) - -(defun force-fill-paragraph () - "Fill paragraph at point, first joining the paragraph's lines into one. -This is useful for filling list item paragraphs." - (interactive) - (join-paragraph) - (fill-paragraph nil)) - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Generic character repeater function. -;; -;; For sections, better to use the specialized function above, but this can -;; be useful for creating separators. - -(defun repeat-last-character (&optional tofill) - "Fills the current line up to the length of the preceding line (if not -empty), using the last character on the current line. If the preceding line is -empty, we use the fill-column. - -If a prefix argument is provided, use the next line rather than the preceding -line. - -If the current line is longer than the desired length, shave the characters off -the current line to fit the desired length. - -As an added convenience, if the command is repeated immediately, the alternative -column is used (fill-column vs. end of previous/next line)." - (interactive) - (let* ((curcol (current-column)) - (curline (+ (count-lines (point-min) (point)) - (if (eq curcol 0) 1 0))) - (lbp (line-beginning-position 0)) - (prevcol (if (and (= curline 1) (not current-prefix-arg)) - fill-column - (save-excursion - (forward-line (if current-prefix-arg 1 -1)) - (end-of-line) - (skip-chars-backward " \t" lbp) - (let ((cc (current-column))) - (if (= cc 0) fill-column cc))))) - (rightmost-column - (cond (tofill fill-column) - ((equal last-command 'repeat-last-character) - (if (= curcol fill-column) prevcol fill-column)) - (t (save-excursion - (if (= prevcol 0) fill-column prevcol))) - )) ) - (end-of-line) - (if (> (current-column) rightmost-column) - ;; shave characters off the end - (delete-region (- (point) - (- (current-column) rightmost-column)) - (point)) - ;; fill with last characters - (insert-char (preceding-char) - (- rightmost-column (current-column)))) - )) - - -(provide 'restructuredtext) diff --git a/tools/editors/emacs/rst-html.el b/tools/editors/emacs/rst-html.el deleted file mode 100644 index 57e4d0b55..000000000 --- a/tools/editors/emacs/rst-html.el +++ /dev/null @@ -1,125 +0,0 @@ -;;; rst-mode.el --- Goodies to automate converting reST documents to HTML. -;;; -;;; Author: Martin Blais -;;; Contact: blais@furius.ca -;;; Revision: $Revision$ -;;; Date: $Date$ -;;; Copyright: This module has been placed in the public domain. -;;; -;;; This package provides a few functions and variables that can help in -;;; automating converting reST documents to HTML from within Emacs. You could -;;; use a makefile to do this, of use the compile command that this package -;;; provides. -;;; -;;; You can also bind a command to automate converting to HTML:: -;;; -;;; (defun user-rst-mode-hook () -;;; (local-set-key [(control c)(?9)] 'rst-html-compile)) -;;; (add-hook 'rst-mode-hook 'user-rst-mode-hook) -;;; -;;; Commentary: -;;; -;;; History: -;;; - -;;; Code: - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Customization: - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defgroup rst-html nil - "Settings for conversion to HTML available by \\[rst-html-compile]. Use of -this functionality is discouraged. Get a proper `Makefile' instead." - :group 'rst - :version "21.1") - -(defcustom rst-html-command "docutils-html" - "Command to convert an reST file to HTML." - :group 'rst-html - :type '(string)) - -(defcustom rst-html-stylesheet "" - "Stylesheet for reST to HTML conversion. Empty for no special stylesheet." - :group 'rst-html - :type '(string)) - -(defcustom rst-html-options "" - "Local file options for reST to HTML conversion. -Stylesheets are set by an own option." - :group 'rst-html - :type '(string)) - -(defcustom rst-html-extension ".html" - "Extension for HTML output file." - :group 'rst-html - :type '(string)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Conversion to HTML - -(defun rst-html-compile () - "Compile command to convert reST document into HTML." - (interactive) - (let* ((bufname (file-name-nondirectory buffer-file-name)) - (outname (file-name-sans-extension bufname)) - (ssheet - (or (and (not (zerop (length rst-html-stylesheet))) - (concat "--stylesheet=\"" rst-html-stylesheet "\"")) - ""))) - (set (make-local-variable 'compile-command) - (mapconcat 'identity - (list rst-html-command - ssheet rst-html-options - bufname (concat outname rst-html-extension)) - " ")) - (if (or compilation-read-command current-prefix-arg) - (call-interactively 'compile) - (compile compile-command)) - )) - -(defun rst-html-compile-with-conf () - "Compile command to convert reST document into HTML. -Attempts to find configuration file, if it can, overrides the options." - (interactive) - (let ((conffile (rst-html-find-conf))) - (if conffile - (let* ((bufname (file-name-nondirectory buffer-file-name)) - (outname (file-name-sans-extension bufname))) - (set (make-local-variable 'compile-command) - (mapconcat 'identity - (list rst-html-command - (concat "--config=\"" conffile "\"") - bufname (concat outname rst-html-extension)) - " ")) - (if (or compilation-read-command current-prefix-arg) - (call-interactively 'compile) - (compile compile-command))) - (call-interactively 'rst-html-compile) - ))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Find the configuration file in the parents. - -(defun rst-html-find-conf () - "Look for the configuration file in the parents of the current path." - (interactive) - (let ((file-name "docutils.conf") - (buffer-file (buffer-file-name))) - ;; Move up in the dir hierarchy till we find a change log file. - (let ((dir (file-name-directory buffer-file))) - (while (and (or (not (string= "/" dir)) (setq dir nil) nil) - (not (file-exists-p (concat dir file-name)))) - ;; Move up to the parent dir and try again. - (setq dir (expand-file-name (file-name-directory - (directory-file-name - (file-name-directory dir))))) ) - (or (and dir (concat dir file-name)) nil) - ))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(provide 'rst-html) - -;;; rst-html.el ends here diff --git a/tools/editors/emacs/rst-mode.el b/tools/editors/emacs/rst-mode.el deleted file mode 100644 index 8fc14e4a5..000000000 --- a/tools/editors/emacs/rst-mode.el +++ /dev/null @@ -1,700 +0,0 @@ -;;; rst-mode.el --- Mode for viewing and editing reStructuredText-documents. - -;; Copyright 2003 Stefan Merten -;; -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2 of the License, or -;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -;;; Commentary: - -;; This package provides support for documents marked up using the -;; reStructuredText format -;; [http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html]. -;; Support includes font locking as well as some convenience functions -;; for editing. - -;; The package is based on `text-mode' and inherits some things from it. -;; Particularly `text-mode-hook' is run before `rst-mode-hook'. - -;; Add the following lines to your `.emacs' file: -;; -;; (autoload 'rst-mode "rst-mode" "mode for editing reStructuredText documents" t) -;; (setq auto-mode-alist -;; (append '(("\\.rst$" . rst-mode) -;; ("\\.rest$" . rst-mode)) auto-mode-alist)) -;; -;; If you are using `.txt' as a standard extension for reST files as -;; http://docutils.sourceforge.net/FAQ.html#what-s-the-standard-filename-extension-for-a-restructuredtext-file -;; suggests you may use one of the `Local Variables in Files' mechanism Emacs -;; provides to set the major mode automatically. For instance you may use -;; -;; .. -*- mode: rst -*- -;; -;; in the very first line of your file. However, because this is a major -;; security breach you or your administrator may have chosen to switch that -;; feature off. See `Local Variables in Files' in the Emacs documentation for a -;; more complete discussion. - -;;; Code: - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Customization: - -(defgroup rst nil "Support for reStructuredText documents" - :group 'wp - :version "21.1" - :link '(url-link "http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html")) - -(defcustom rst-mode-hook nil - "Hook run when Rst Mode is turned on. The hook for Text Mode is run before - this one." - :group 'rst - :type '(hook)) - -(defcustom rst-mode-lazy t - "*If non-nil Rst Mode font-locks comment, literal blocks, and section titles -correctly. Because this is really slow it switches on Lazy Lock Mode -automatically. You may increase Lazy Lock Defer Time for reasonable results. - -If nil comments and literal blocks are font-locked only on the line they start. - -The value of this variable is used when Rst Mode is turned on." - :group 'rst - :type '(boolean)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defgroup rst-faces nil "Faces used in Rst Mode" - :group 'rst - :group 'faces - :version "21.1") - -(defcustom rst-block-face 'font-lock-keyword-face - "All syntax marking up a special block" - :group 'rst-faces - :type '(face)) - -(defcustom rst-external-face 'font-lock-type-face - "Field names and interpreted text" - :group 'rst-faces - :type '(face)) - -(defcustom rst-definition-face 'font-lock-function-name-face - "All other defining constructs" - :group 'rst-faces - :type '(face)) - -(defcustom rst-directive-face - ;; XEmacs compatibility - (if (boundp 'font-lock-builtin-face) - 'font-lock-builtin-face - 'font-lock-preprocessor-face) - "Directives and roles" - :group 'rst-faces - :type '(face)) - -(defcustom rst-comment-face 'font-lock-comment-face - "Comments" - :group 'rst-faces - :type '(face)) - -(defcustom rst-emphasis1-face - ;; XEmacs compatibility - (if (facep 'italic) - ''italic - 'italic) - "Simple emphasis" - :group 'rst-faces - :type '(face)) - -(defcustom rst-emphasis2-face - ;; XEmacs compatibility - (if (facep 'bold) - ''bold - 'bold) - "Double emphasis" - :group 'rst-faces - :type '(face)) - -(defcustom rst-literal-face 'font-lock-string-face - "Literal text" - :group 'rst-faces - :type '(face)) - -(defcustom rst-reference-face 'font-lock-variable-name-face - "References to a definition" - :group 'rst-faces - :type '(face)) - -;; Faces for displaying items on several levels; these definitions define -;; different shades of grey where the lightest one is used for level 1 -(defconst rst-level-face-max 6 - "Maximum depth of level faces defined") -(defconst rst-level-face-base-color "grey" - "The base color to be used for creating level faces") -(defconst rst-level-face-base-light 85 - "The lightness factor for the base color") -(defconst rst-level-face-format-light "%2d" - "The format for the lightness factor for the base color") -(defconst rst-level-face-step-light -7 - "The step width to use for next color") - -;; Define the faces -(let ((i 1)) - (while (<= i rst-level-face-max) - (let ((sym (intern (format "rst-level-%d-face" i))) - (doc (format "Face for showing section title text at level %d" i)) - (col (format (concat "%s" rst-level-face-format-light) - rst-level-face-base-color - (+ (* (1- i) rst-level-face-step-light) - rst-level-face-base-light)))) - (make-empty-face sym) - (set-face-doc-string sym doc) - (set-face-background sym col) - (set sym sym) - (setq i (1+ i))))) - -(defcustom rst-adornment-faces-alist - '((1 . rst-level-1-face) - (2 . rst-level-2-face) - (3 . rst-level-3-face) - (4 . rst-level-4-face) - (5 . rst-level-5-face) - (6 . rst-level-6-face) - (t . font-lock-keyword-face) - (nil . font-lock-keyword-face)) - "Provides faces for the various adornment types. Key is a number (for the -section title text of that level), t (for transitions) or nil (for section -title adornment)." - :group 'rst-faces - :type '(alist :key-type (choice (integer :tag "Section level") - (boolean :tag "transitions (on) / section title adornment (off)")) - :value-type (face))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; FIXME: Code from `restructuredtext.el' should be integrated - -(defvar rst-mode-syntax-table nil - "Syntax table used while in rst mode.") - -(unless rst-mode-syntax-table - (setq rst-mode-syntax-table (make-syntax-table text-mode-syntax-table)) - (modify-syntax-entry ?$ "." rst-mode-syntax-table) - (modify-syntax-entry ?% "." rst-mode-syntax-table) - (modify-syntax-entry ?& "." rst-mode-syntax-table) - (modify-syntax-entry ?' "." rst-mode-syntax-table) - (modify-syntax-entry ?* "." rst-mode-syntax-table) - (modify-syntax-entry ?+ "." rst-mode-syntax-table) - (modify-syntax-entry ?. "_" rst-mode-syntax-table) - (modify-syntax-entry ?/ "." rst-mode-syntax-table) - (modify-syntax-entry ?< "." rst-mode-syntax-table) - (modify-syntax-entry ?= "." rst-mode-syntax-table) - (modify-syntax-entry ?> "." rst-mode-syntax-table) - (modify-syntax-entry ?\\ "\\" rst-mode-syntax-table) - (modify-syntax-entry ?| "." rst-mode-syntax-table) - (modify-syntax-entry ?_ "." rst-mode-syntax-table) - ) - -(defvar rst-mode-abbrev-table nil - "Abbrev table used while in rst mode.") -(define-abbrev-table 'rst-mode-abbrev-table ()) - -;; FIXME: Movement keys to skip forward / backward over or mark an indented -;; block could be defined; keys to markup section titles based on -;; `rst-adornment-level-alist' would be useful -(defvar rst-mode-map nil - "Keymap for rst mode. This inherits from Text mode.") - -(unless rst-mode-map - (setq rst-mode-map (copy-keymap text-mode-map))) - -(defun rst-mode () - "Major mode for editing reStructuredText documents. - -You may customize `rst-mode-lazy' to switch font-locking of blocks. - -\\{rst-mode-map} -Turning on `rst-mode' calls the normal hooks `text-mode-hook' and -`rst-mode-hook'." - (interactive) - (kill-all-local-variables) - - ;; Maps and tables - (use-local-map rst-mode-map) - (setq local-abbrev-table rst-mode-abbrev-table) - (set-syntax-table rst-mode-syntax-table) - - ;; For editing text - ;; - ;; FIXME: It would be better if this matches more exactly the start of a reST - ;; paragraph; however, this not always possible with a simple regex because - ;; paragraphs are determined by indentation of the following line - (set (make-local-variable 'paragraph-start) - (concat page-delimiter "\\|[ \t]*$")) - (if (eq ?^ (aref paragraph-start 0)) - (setq paragraph-start (substring paragraph-start 1))) - (set (make-local-variable 'paragraph-separate) paragraph-start) - (set (make-local-variable 'indent-line-function) 'indent-relative-maybe) - (set (make-local-variable 'adaptive-fill-mode) t) - (set (make-local-variable 'comment-start) ".. ") - - ;; Special variables - (make-local-variable 'rst-adornment-level-alist) - - ;; Font lock - (set (make-local-variable 'font-lock-defaults) - '(rst-font-lock-keywords-function - t nil nil nil - (font-lock-multiline . t) - (font-lock-mark-block-function . mark-paragraph))) - (when (boundp 'font-lock-support-mode) - ;; rst-mode has its own mind about font-lock-support-mode - (make-local-variable 'font-lock-support-mode) - (cond - ((and (not rst-mode-lazy) (not font-lock-support-mode))) - ;; No support mode set and none required - leave it alone - ((or (not font-lock-support-mode) ;; No support mode set (but required) - (symbolp font-lock-support-mode)) ;; or a fixed mode for all - (setq font-lock-support-mode - (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) - (cons t font-lock-support-mode)))) - ((and (listp font-lock-support-mode) - (not (assoc 'rst-mode font-lock-support-mode))) - ;; A list of modes missing rst-mode - (setq font-lock-support-mode - (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) - font-lock-support-mode))))) - - ;; Names and hooks - (setq mode-name "reST") - (setq major-mode 'rst-mode) - (run-hooks 'text-mode-hook) - (run-hooks 'rst-mode-hook)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Font lock - -(defun rst-font-lock-keywords-function () - "Returns keywords to highlight in rst mode according to current settings." - ;; The reST-links in the comments below all relate to sections in - ;; http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html - (let* ( ;; This gets big - so let's define some abbreviations - ;; horizontal white space - (re-hws "[\t ]") - ;; beginning of line with possible indentation - (re-bol (concat "^" re-hws "*")) - ;; Separates block lead-ins from their content - (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) - ;; explicit markup tag - (re-emt "\\.\\.") - ;; explicit markup start - (re-ems (concat re-emt re-hws "+")) - ;; inline markup prefix - (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) - ;; symbol character - (re-sym1 "\\(\\sw\\|\\s_\\)") - ;; inline markup content begin - (re-imbeg2 "\\(\\S \\|\\S \\([^") - - ;; There seems to be a bug leading to error "Stack overflow in regexp - ;; matcher" when "|" or "\\*" are the characters searched for - (re-imendbeg - (if (< emacs-major-version 21) - "]" - "\\]\\|\\\\.")) - ;; inline markup content end - (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) - ;; inline markup content without asterisk - (re-ima2 (concat re-imbeg2 "*" re-imend)) - ;; inline markup content without backquote - (re-imb2 (concat re-imbeg2 "`" re-imend)) - ;; inline markup content without vertical bar - (re-imv2 (concat re-imbeg2 "|" re-imend)) - ;; Supported URI schemes - (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") - ;; Line starting with adornment and optional whitespace; complete - ;; adornment is in (match-string 1); there must be at least 3 - ;; characters because otherwise explicit markup start would be - ;; recognized - (re-ado2 (concat "^\\(\\([" - (if (or - (< emacs-major-version 21) - (save-match-data - (string-match "XEmacs\\|Lucid" emacs-version))) - "^a-zA-Z0-9 \t\x00-\x1F" - "^[:word:][:space:][:cntrl:]") - "]\\)\\2\\2+\\)" re-hws "*$")) - ) - (list - ;; FIXME: Block markup is not recognized in blocks after explicit markup - ;; start - - ;; Simple `Body Elements`_ - ;; `Bullet Lists`_ - (list - (concat re-bol "\\([-*+]" re-blksep1 "\\)") - 1 rst-block-face) - ;; `Enumerated Lists`_ - (list - (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" re-blksep1 "\\)") - 1 rst-block-face) - ;; `Definition Lists`_ FIXME: missing - ;; `Field Lists`_ - (list - (concat re-bol "\\(:[^:]+:\\)" re-blksep1) - 1 rst-external-face) - ;; `Option Lists`_ - (list - (concat re-bol "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*\\([ =]\\S +\\)?\\)\\(,[\t ]\\)?\\)+\\)\\($\\|[\t ]\\{2\\}\\)") - 1 rst-block-face) - - ;; `Tables`_ FIXME: missing - - ;; All the `Explicit Markup Blocks`_ - ;; `Footnotes`_ / `Citations`_ - (list - (concat re-bol "\\(" re-ems "\\[[^[]+\\]\\)" re-blksep1) - 1 rst-definition-face) - ;; `Directives`_ / `Substitution Definitions`_ - (list - (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" re-sym1 "+::\\)" re-blksep1) - (list 1 rst-directive-face) - (list 2 rst-definition-face) - (list 4 rst-directive-face)) - ;; `Hyperlink Targets`_ - (list - (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" re-blksep1) - 1 rst-definition-face) - (list - (concat re-bol "\\(__\\)" re-blksep1) - 1 rst-definition-face) - - ;; All `Inline Markup`_ - ;; FIXME: Condition 5 preventing fontification of e.g. "*" not implemented - ;; `Strong Emphasis`_ - (list - (concat re-imp1 "\\(\\*\\*" re-ima2 "\\*\\*\\)" re-ims1) - 2 rst-emphasis2-face) - ;; `Emphasis`_ - (list - (concat re-imp1 "\\(\\*" re-ima2 "\\*\\)" re-ims1) - 2 rst-emphasis1-face) - ;; `Inline Literals`_ - (list - (concat re-imp1 "\\(``" re-imb2 "``\\)" re-ims1) - 2 rst-literal-face) - ;; `Inline Internal Targets`_ - (list - (concat re-imp1 "\\(_`" re-imb2 "`\\)" re-ims1) - 2 rst-definition-face) - ;; `Hyperlink References`_ - ;; FIXME: `Embedded URIs`_ not considered - (list - (concat re-imp1 "\\(\\(`" re-imb2 "`\\|\\sw+\\)__?\\)" re-ims1) - 2 rst-reference-face) - ;; `Interpreted Text`_ - (list - (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" re-sym1 "+:\\)?\\)" re-ims1) - (list 2 rst-directive-face) - (list 5 rst-external-face) - (list 8 rst-directive-face)) - ;; `Footnote References`_ / `Citation References`_ - (list - (concat re-imp1 "\\(\\[[^]]+\\]_\\)" re-ims1) - 2 rst-reference-face) - ;; `Substitution References`_ - (list - (concat re-imp1 "\\(|" re-imv2 "|\\)" re-ims1) - 2 rst-reference-face) - ;; `Standalone Hyperlinks`_ - (list - ;; FIXME: This takes it easy by using a whitespace as delimiter - (concat re-imp1 "\\(" re-uris1 ":\\S +\\)" re-ims1) - 2 rst-definition-face) - (list - (concat re-imp1 "\\(" re-sym1 "+@" re-sym1 "+\\)" re-ims1) - 2 rst-definition-face) - - ;; Do all block fontification as late as possible so 'append works - - ;; Sections_ / Transitions_ - (append - (list - re-ado2) - (if (not rst-mode-lazy) - (list 1 rst-block-face) - (list - (list 'rst-font-lock-handle-adornment - '(progn - (setq rst-font-lock-adornment-point (match-end 1)) - (point-max)) - nil - (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t) - (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) - 'append t) - (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t))))) - - ;; `Comments`_ - (append - (list - (concat re-bol "\\(" re-ems "\\)\[^[|_]\\([^:]\\|:\\([^:]\\|$\\)\\)*$") - (list 1 rst-comment-face)) - (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point (match-end 1)) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) - (append - (list - (concat re-bol "\\(" re-emt "\\)\\(\\s *\\)$") - (list 1 rst-comment-face) - (list 2 rst-comment-face)) - (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point 'next) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) - - ;; `Literal Blocks`_ - (append - (list - (concat re-bol "\\(\\([^.\n]\\|\\.[^.\n]\\).*\\)?\\(::\\)$") - (list 3 rst-block-face)) - (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point t) - (point-max)) - nil - (list 0 rst-literal-face 'append))))) - ))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Indented blocks - -(defun rst-forward-indented-block (&optional column limit) - "Move forward across one indented block. -Find the next non-empty line which is not indented at least to COLUMN (defaults -to the column of the point). Moves point to first character of this line or the -first empty line immediately before it and returns that position. If there is -no such line before LIMIT (defaults to the end of the buffer) returns nil and -point is not moved." - (interactive) - (let ((clm (or column (current-column))) - (start (point)) - fnd beg cand) - (if (not limit) - (setq limit (point-max))) - (save-match-data - (while (and (not fnd) (< (point) limit)) - (forward-line 1) - (when (< (point) limit) - (setq beg (point)) - (if (looking-at "\\s *$") - (setq cand (or cand beg)) ; An empty line is a candidate - (move-to-column clm) - ;; FIXME: No indentation [(zerop clm)] must be handled in some - ;; useful way - though it is not clear what this should mean at all - (if (string-match - "^\\s *$" (buffer-substring-no-properties beg (point))) - (setq cand nil) ; An indented line resets a candidate - (setq fnd (or cand beg))))))) - (goto-char (or fnd start)) - fnd)) - -;; Stores the point where the current indentation ends if a number. If `next' -;; indicates `rst-font-lock-find-unindented-line' shall take the indentation -;; from the next line if this is not empty. If non-nil indicates -;; `rst-font-lock-find-unindented-line' shall take the indentation from the -;; next non-empty line. Also used as a trigger for -;; `rst-font-lock-find-unindented-line'. -(defvar rst-font-lock-indentation-point nil) - -(defun rst-font-lock-find-unindented-line (limit) - (let* ((ind-pnt rst-font-lock-indentation-point) - (beg-pnt ind-pnt)) - ;; May run only once - enforce this - (setq rst-font-lock-indentation-point nil) - (when (and ind-pnt (not (numberp ind-pnt))) - ;; Find indentation point in next line if any - (setq ind-pnt - (save-excursion - (save-match-data - (if (eq ind-pnt 'next) - (when (and (zerop (forward-line 1)) (< (point) limit)) - (setq beg-pnt (point)) - (when (not (looking-at "\\s *$")) - (looking-at "\\s *") - (match-end 0))) - (while (and (zerop (forward-line 1)) (< (point) limit) - (looking-at "\\s *$"))) - (when (< (point) limit) - (setq beg-pnt (point)) - (looking-at "\\s *") - (match-end 0))))))) - (when ind-pnt - (goto-char ind-pnt) - ;; Always succeeds because the limit set by PRE-MATCH-FORM is the - ;; ultimate point to find - (goto-char (or (rst-forward-indented-block nil limit) limit)) - (set-match-data (list beg-pnt (point))) - t))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Adornments - -;; Stores the point where the current adornment ends. Also used as a trigger -;; for `rst-font-lock-handle-adornment'. -(defvar rst-font-lock-adornment-point nil) - -;; Here `rst-font-lock-handle-adornment' stores the section level of the -;; current adornment or t for a transition. -(defvar rst-font-lock-level nil) - -;; FIXME: It would be good if this could be used to markup section titles of -;; given level with a special key; it would be even better to be able to -;; customize this so it can be used for a generally available personal style -;; -;; FIXME: There should be some way to reset and reload this variable - probably -;; a special key -;; -;; FIXME: Some support for `outline-mode' would be nice which should be based -;; on this information -(defvar rst-adornment-level-alist nil - "Associates adornments with section levels. -The key is a two character string. The first character is the adornment -character. The second character distinguishes underline section titles (`u') -from overline/underline section titles (`o'). The value is the section level. - -This is made buffer local on start and adornments found during font lock are -entered.") - -;; Returns section level for adornment key KEY. Adds new section level if KEY -;; is not found and ADD. If KEY is not a string it is simply returned. -(defun rst-adornment-level (key &optional add) - (let ((fnd (assoc key rst-adornment-level-alist)) - (new 1)) - (cond - ((not (stringp key)) - key) - (fnd - (cdr fnd)) - (add - (while (rassoc new rst-adornment-level-alist) - (setq new (1+ new))) - (setq rst-adornment-level-alist - (append rst-adornment-level-alist (list (cons key new)))) - new)))) - -;; Classifies adornment for section titles and transitions. ADORNMENT is the -;; complete adornment string as found in the buffer. END is the point after the -;; last character of ADORNMENT. For overline section adornment LIMIT limits the -;; search for the matching underline. Returns a list. The first entry is t for -;; a transition, or a key string for `rst-adornment-level' for a section title. -;; The following eight values forming four match groups as can be used for -;; `set-match-data'. First match group contains the maximum points of the whole -;; construct. Second and last match group matched pure section title adornment -;; while third match group matched the section title text or the transition. -;; Each group but the first may or may not exist. -(defun rst-classify-adornment (adornment end limit) - (save-excursion - (save-match-data - (goto-char end) - (let ((ado-ch (aref adornment 0)) - (ado-re (regexp-quote adornment)) - (end-pnt (point)) - (beg-pnt (progn - (forward-line 0) - (point))) - (nxt-emp - (save-excursion - (or (not (zerop (forward-line 1))) - (looking-at "\\s *$")))) - (prv-emp - (save-excursion - (or (not (zerop (forward-line -1))) - (looking-at "\\s *$")))) - key beg-ovr end-ovr beg-txt end-txt beg-und end-und) - (cond - ((and nxt-emp prv-emp) - ;; A transition - (setq key t) - (setq beg-txt beg-pnt) - (setq end-txt end-pnt)) - (prv-emp - ;; An overline - (setq key (concat (list ado-ch) "o")) - (setq beg-ovr beg-pnt) - (setq end-ovr end-pnt) - (forward-line 1) - (setq beg-txt (point)) - (while (and (< (point) limit) (not end-txt)) - (if (looking-at "\\s *$") - ;; No underline found - (setq end-txt (1- (point))) - (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) - (setq end-und (match-end 1)) - (setq beg-und (point)) - (setq end-txt (1- beg-und)))) - (forward-line 1))) - (t - ;; An underline - (setq key (concat (list ado-ch) "u")) - (setq beg-und beg-pnt) - (setq end-und end-pnt) - (setq end-txt (1- beg-und)) - (setq beg-txt (progn - (if (re-search-backward "^\\s *$" 1 'move) - (forward-line 1)) - (point))))) - (list key - (or beg-ovr beg-txt beg-und) - (or end-und end-txt end-und) - beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) - -;; Handles adornments for font-locking section titles and transitions. Returns -;; three match groups. First and last match group matched pure overline / -;; underline adornment while second group matched section title text. Each -;; group may not exist. -(defun rst-font-lock-handle-adornment (limit) - (let ((ado-pnt rst-font-lock-adornment-point)) - ;; May run only once - enforce this - (setq rst-font-lock-adornment-point nil) - (if ado-pnt - (let* ((ado (rst-classify-adornment (match-string-no-properties 1) - ado-pnt limit)) - (key (car ado)) - (mtc (cdr ado))) - (setq rst-font-lock-level (rst-adornment-level key t)) - (goto-char (nth 1 mtc)) - (set-match-data mtc) - t)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(provide 'rst-mode) - -;;; rst-mode.el ends here diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el new file mode 100644 index 000000000..94da15901 --- /dev/null +++ b/tools/editors/emacs/rst.el @@ -0,0 +1,2479 @@ +;; Authors: Martin Blais , +;; Stefan Merten +;; David Goodger +;; Date: $Date$ +;; Copyright: This module has been placed in the public domain. +;; +;; Support code for editing reStructuredText with Emacs. Basically, this +;; package contains: +;; +;; - Functions to automatically adjust and cycle the section underline +;; decorations; +;; - A mode that displays the table of contents and allows you to jump anywhere +;; from it; +;; - Functions to insert and automatically update a TOC in your source document; +;; - A mode which supports font-lock highlighting of reStructuredText +;; structures; +;; - Some other convenience functions. +;; +;; See the accompanying document in the docutils documentation about +;; the contents of this package and how to use it. +;; +;; For more information about reStructuredText, see +;; http://docutils.sourceforge.net/rst.html +;; +;; **IMPORTANT NOTE TO PACKAGERS**: this package is the result of merging: +;; +;; - restructuredtext.el +;; - rst-mode.el +;; - rst-html.el +;; +;; Those files are now OBSOLETE and have been replaced by this single package +;; file (2005-10-30). +;; +;; Installation instructions +;; ------------------------- +;; +;; Add this line to your .emacs file and bind the versatile sectioning commands +;; in text mode, like this:: +;; +;; (require 'rst) +;; (add-hook 'text-mode-hook 'rst-text-mode-bindings) +;; +;; The keys it defines are: +;; +;; C-= : updates or rotates the section title around point or +;; promotes/demotes the decorations within the region (see full details +;; below). +;; +;; Note that C-= is a good binding, since it allows you to specify a +;; negative arg easily with C-- C-= (easy to type), as well as ordinary +;; prefix arg with C-u C-=. +;; +;; C-x C-= : displays the hierarchical table-of-contents of the document and +;; allows you to jump to any section from it. +;; +;; C-u C-x C-= : displays the title decorations from this file. +;; +;; C-x + : insert the table of contents in the text. See the many options +;; for customizing how it will look. +;; +;; C-M-{, C-M-} : navigate between section titles. +;; +;; Other specialized and more generic functions are also available (see source +;; code). The most important function provided by this file for section title +;; adjustments is rst-adjust. +;; +;; There are many variables that can be customized, look for defcustom and +;; defvar in this file. +;; +;; If you use the table-of-contents feature, you may want to add a hook to +;; update the TOC automatically everytime you adjust a section title:: +;; +;; (add-hook 'rst-adjust-hook 'rst-toc-insert-update) +;; +;; rst-mode +;; -------- +;; +;; There is a special mode that you can setup if you want to have syntax +;; highlighting. The mode is based on `text-mode' and inherits some things from +;; it. Particularly `text-mode-hook' is run before `rst-mode-hook'. +;; +;; Add the following lines to your `.emacs' file: +;; +;; (setq auto-mode-alist +;; (append '(("\\.rst$" . rst-mode) +;; ("\\.rest$" . rst-mode)) auto-mode-alist)) +;; +;; If you are using `.txt' as a standard extension for reST files as +;; http://docutils.sourceforge.net/FAQ.html#what-s-the-standard-filename-extension-for-a-restructuredtext-file +;; suggests you may use one of the `Local Variables in Files' mechanism Emacs +;; provides to set the major mode automatically. For instance you may use +;; +;; .. -*- mode: rst -*- +;; +;; in the very first line of your file. However, because this is a major +;; security breach you or your administrator may have chosen to switch that +;; feature off. See `Local Variables in Files' in the Emacs documentation for a +;; more complete discussion. +;; +;; +;; TODO list +;; ========= +;; +;; Bindings +;; -------- +;; - We need to automatically add the rst-text-mode-bindings to rst-mode +;; - We need to find better bindings because C-= does not generate an event on +;; the Macs. +;; +;; rst-toc-insert features +;; ------------------------ +;; - Support local table of contents, like in doctree.txt. +;; - On load, detect any existing TOCs and set the properties for links. +;; - TOC insertion should have an option to add empty lines. +;; - TOC insertion should deal with multiple lines +;; +;; - There is a bug on redo after undo of adjust when rst-adjust-hook uses the +;; automatic toc update. The cursor ends up in the TOC and this is +;; annoying. Gotta fix that. +;; +;; Other +;; ----- +;; - Add an option to forego using the file structure in order to make +;; suggestion, and to always use the preferred decorations to do that. +;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Bindings and hooks + +(defgroup rst nil "Support for reStructuredText documents" + :group 'wp + :version "21.1" + :link '(url-link "http://docutils.sourceforge.net/rst.html")) + +(defun rst-toc-or-hierarchy () + "Binding for either TOC or decorations hierarchy." + (interactive) + (if (not current-prefix-arg) + (rst-toc) + (rst-display-decorations-hierarchy))) + +(defun rst-text-mode-bindings () + "Default text mode hook for rest." + (local-set-key [(control ?=)] 'rst-adjust) + (local-set-key [(control x)(control ?=)] 'rst-toc-or-hierarchy) + (local-set-key [(control x)(?+)] 'rst-toc-insert) + (local-set-key [(control meta ?{)] 'rst-backward-section) + (local-set-key [(control meta ?})] 'rst-forward-section) + (local-set-key [(control c)(control r)] 'rst-shift-region-right) + (local-set-key [(control c)(control l)] 'rst-shift-region-left) + ) + +;; Note: we cannot bind the TOC update on file write because it messes with +;; undo. If we disable undo, since it adds and removes characters, the +;; positions in the undo list are not making sense anymore. Dunno what to do +;; with this, it would be nice to update when saving. +;; +;; (add-hook 'write-contents-hooks 'rst-toc-insert-update-fun) +;; (defun rst-toc-insert-update-fun () +;; ;; Disable undo for the write file hook. +;; (let ((buffer-undo-list t)) (rst-toc-insert-update) )) + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Support functions + +(require 'cl) + +;; Generic Filter function. +(if (not (fboundp 'filter)) + (defun filter (pred list) + "Returns a list of all the elements fulfilling the pred requirement (that +is for which (pred elem) is true)" + (if list + (let ((head (car list)) + (tail (filter pred (cdr list)))) + (if (funcall pred head) + (cons head tail) + tail))))) + + +;; From emacs-22 +(if (not (fboundp 'line-number-at-pos)) + (defun line-number-at-pos (&optional pos) + "Return (narrowed) buffer line number at position POS. + If POS is nil, use current buffer location." + (let ((opoint (or pos (point))) start) + (save-excursion + (goto-char (point-min)) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines start (point)))))) ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Section Decoration Adjusment +;; ============================ +;; +;; The following functions implement a smart automatic title sectioning feature. +;; The idea is that with the cursor sitting on a section title, we try to get as +;; much information from context and try to do the best thing automatically. +;; This function can be invoked many times and/or with prefix argument to rotate +;; between the various sectioning decorations. +;; +;; Definitions: the two forms of sectioning define semantically separate section +;; levels. A sectioning DECORATION consists in: +;; +;; - a CHARACTER +;; +;; - a STYLE which can be either of 'simple' or 'over-and-under'. +;; +;; - an INDENT (meaningful for the over-and-under style only) which determines +;; how many characters and over-and-under style is hanging outside of the +;; title at the beginning and ending. +;; +;; Important note: an existing decoration must be formed by at least two +;; characters to be recognized. +;; +;; Here are two examples of decorations (| represents the window border, column +;; 0): +;; +;; | +;; 1. char: '-' e |Some Title +;; style: simple |---------- +;; | +;; 2. char: '=' |============== +;; style: over-and-under | Some Title +;; indent: 2 |============== +;; | +;; +;; Some notes: +;; +;; - The underlining character that is used depends on context. The file is +;; scanned to find other sections and an appropriate character is selected. +;; If the function is invoked on a section that is complete, the character is +;; rotated among the existing section decorations. +;; +;; Note that when rotating the characters, if we come to the end of the +;; hierarchy of decorations, the variable rst-preferred-decorations is +;; consulted to propose a new underline decoration, and if continued, we cycle +;; the decorations all over again. Set this variable to nil if you want to +;; limit the underlining character propositions to the existing decorations in +;; the file. +;; +;; - A prefix argument can be used to alternate the style. +;; +;; - An underline/overline that is not extended to the column at which it should +;; be hanging is dubbed INCOMPLETE. For example:: +;; +;; |Some Title +;; |------- +;; +;; Examples of default invocation: +;; +;; |Some Title ---> |Some Title +;; | |---------- +;; +;; |Some Title ---> |Some Title +;; |----- |---------- +;; +;; | |------------ +;; | Some Title ---> | Some Title +;; | |------------ +;; +;; In over-and-under style, when alternating the style, a variable is +;; available to select how much default indent to use (it can be zero). Note +;; that if the current section decoration already has an indent, we don't +;; adjust it to the default, we rather use the current indent that is already +;; there for adjustment (unless we cycle, in which case we use the indent +;; that has been found previously). + +(defgroup rst-adjust nil + "Settings for adjustment and cycling of section title +decorations." + :group 'rst + :version "21.1") + +(defcustom rst-preferred-decorations '( (?= over-and-under 1) + (?= simple 0) + (?- simple 0) + (?~ simple 0) + (?+ simple 0) + (?` simple 0) + (?# simple 0) + (?@ simple 0) ) + "Preferred ordering of section title decorations. This + sequence is consulted to offer a new decoration suggestion when + we rotate the underlines at the end of the existing hierarchy + of characters, or when there is no existing section title in + the file." + :group 'rst-adjust) + + +(defcustom rst-default-indent 1 + "Number of characters to indent the section title when toggling + decoration styles. This is used when switching from a simple + decoration style to a over-and-under decoration style." + :group 'rst-adjust) + + +(defvar rst-section-text-regexp "^[ \t]*\\S-*[a-zA-Z0-9]\\S-*" + "Regular expression for valid section title text.") + + +(defun rst-line-homogeneous-p (&optional accept-special) + "Predicate return the unique char if the current line is + composed only of a single repeated non-whitespace + character. This returns the char even if there is whitespace at + the beginning of the line. + + If ACCEPT-SPECIAL is specified we do not ignore special sequences + which normally we would ignore when doing a search on many lines. + For example, normally we have cases to ignore commonly occuring + patterns, such as :: or ...; with the flag do not ignore them." + (save-excursion + (back-to-indentation) + (if (not (looking-at "\n")) + (let ((c (thing-at-point 'char))) + (if (and (looking-at (format "[%s]+[ \t]*$" c)) + (or accept-special + (and + ;; Common patterns. + (not (looking-at "::[ \t]*$")) + (not (looking-at "\\.\\.\\.[ \t]*$")) + ;; Discard one char line + (not (looking-at ".[ \t]*$")) + ))) + (string-to-char c)) + )) + )) + +(defun rst-line-homogeneous-nodent-p (&optional accept-special) + (save-excursion + (beginning-of-line) + (if (looking-at "^[ \t]+") + nil + (rst-line-homogeneous-p accept-special) + ))) + + +(defun rst-compare-decorations (deco1 deco2) + "Compare decorations. Returns true if both are equal, +according to restructured text semantics (only the character and +the style are compared, the indentation does not matter." + (and (eq (car deco1) (car deco2)) + (eq (cadr deco1) (cadr deco2)))) + + +(defun rst-get-decoration-match (hier deco) + "Returns the index (level) of the decoration in the given hierarchy. +This basically just searches for the item using the appropriate +comparison and returns the index. We return nil if the item is +not found." + (let ((cur hier)) + (while (and cur (not (rst-compare-decorations (car cur) deco))) + (setq cur (cdr cur))) + cur)) + + +(defun rst-suggest-new-decoration (alldecos &optional prev) + "Suggest a new, different decoration, different from all that +have been seen. + + ALLDECOS is the set of all decorations, including the line + numbers. PREV is the optional previous decoration, in order to + suggest a better match." + + ;; For all the preferred decorations... + (let* ( + ;; If 'prev' is given, reorder the list to start searching after the + ;; match. + (fplist + (cdr (rst-get-decoration-match rst-preferred-decorations prev))) + + ;; List of candidates to search. + (curpotential (append fplist rst-preferred-decorations))) + (while + ;; For all the decorations... + (let ((cur alldecos) + found) + (while (and cur (not found)) + (if (rst-compare-decorations (car cur) (car curpotential)) + ;; Found it! + (setq found (car curpotential)) + (setq cur (cdr cur)))) + found) + + (setq curpotential (cdr curpotential))) + + (copy-list (car curpotential)) )) + +(defun rst-delete-line () + "A version of kill-line that does not use the kill-ring." + (delete-region (line-beginning-position) (+ 1 (line-end-position)))) + +(defun rst-update-section (char style &optional indent) + "Unconditionally updates the style of a section decoration + using the given character CHAR, with STYLE 'simple or + 'over-and-under, and with indent INDENT. If the STYLE is + 'simple, whitespace before the title is removed (indent is + always assume to be 0). + + If there are existing overline and/or underline from the + existing decoration, they are removed before adding the + requested decoration." + + (interactive) + (let (marker + len + ec + (c ?-)) + + (end-of-line) + (setq marker (point-marker)) + + ;; Fixup whitespace at the beginning and end of the line + (if (or (null indent) (eq style 'simple)) + (setq indent 0)) + (beginning-of-line) + (delete-horizontal-space) + (insert (make-string indent ? )) + + (end-of-line) + (delete-horizontal-space) + + ;; Set the current column, we're at the end of the title line + (setq len (+ (current-column) indent)) + + ;; Remove previous line if it consists only of a single repeated character + (save-excursion + (forward-line -1) + (and (rst-line-homogeneous-p 1) + ;; Avoid removing the underline of a title right above us. + (save-excursion (forward-line -1) + (not (looking-at rst-section-text-regexp))) + (rst-delete-line))) + + ;; Remove following line if it consists only of a single repeated + ;; character + (save-excursion + (forward-line +1) + (and (rst-line-homogeneous-p 1) + (rst-delete-line)) + ;; Add a newline if we're at the end of the buffer, for the subsequence + ;; inserting of the underline + (if (= (point) (buffer-end 1)) + (newline 1))) + + ;; Insert overline + (if (eq style 'over-and-under) + (save-excursion + (beginning-of-line) + (open-line 1) + (insert (make-string len char)))) + + ;; Insert underline + (forward-line +1) + (open-line 1) + (insert (make-string len char)) + + (forward-line +1) + (goto-char marker) + )) + + +(defun rst-normalize-cursor-position () + "If the cursor is on a decoration line or an empty line , place + it on the section title line (at the end). Returns the line + offset by which the cursor was moved. This works both over or + under a line." + (if (save-excursion (beginning-of-line) + (or (rst-line-homogeneous-p 1) + (looking-at "^[ \t]*$"))) + (progn + (beginning-of-line) + (cond + ((save-excursion (forward-line -1) + (beginning-of-line) + (and (looking-at rst-section-text-regexp) + (not (rst-line-homogeneous-p 1)))) + (progn (forward-line -1) -1)) + ((save-excursion (forward-line +1) + (beginning-of-line) + (and (looking-at rst-section-text-regexp) + (not (rst-line-homogeneous-p 1)))) + (progn (forward-line +1) +1)) + (t 0))) + 0 )) + + +(defun rst-find-all-decorations () + "Finds all the decorations in the file, and returns a list of + (line, decoration) pairs. Each decoration consists in a (char, + style, indent) triple. + + This function does not detect the hierarchy of decorations, it + just finds all of them in a file. You can then invoke another + function to remove redundancies and inconsistencies." + + (let (positions + (curline 1)) + ;; Iterate over all the section titles/decorations in the file. + (save-excursion + (beginning-of-buffer) + (while (< (point) (buffer-end 1)) + (if (rst-line-homogeneous-nodent-p) + (progn + (setq curline (+ curline (rst-normalize-cursor-position))) + + ;; Here we have found a potential site for a decoration, + ;; characterize it. + (let ((deco (rst-get-decoration))) + (if (cadr deco) ;; Style is existing. + ;; Found a real decoration site. + (progn + (push (cons curline deco) positions) + ;; Push beyond the underline. + (forward-line 1) + (setq curline (+ curline 1)) + ))) + )) + (forward-line 1) + (setq curline (+ curline 1)) + )) + (reverse positions))) + + +(defun rst-infer-hierarchy (decorations) + "Build a hierarchy of decorations using the list of given decorations. + + This function expects a list of (char, style, indent) + decoration specifications, in order that they appear in a file, + and will infer a hierarchy of section levels by removing + decorations that have already been seen in a forward traversal of the + decorations, comparing just the character and style. + + Similarly returns a list of (char, style, indent), where each + list element should be unique." + + (let ((hierarchy-alist (list))) + (dolist (x decorations) + (let ((char (car x)) + (style (cadr x)) + (indent (caddr x))) + (if (not (assoc (cons char style) hierarchy-alist)) + (progn + (setq hierarchy-alist + (append hierarchy-alist + (list (cons (cons char style) x)))) + )) + )) + (mapcar 'cdr hierarchy-alist) + )) + + +(defun rst-get-hierarchy (&optional alldecos ignore) + "Returns a list of decorations that represents the hierarchy of + section titles in the file. + + If the line number in IGNORE is specified, the decoration found + on that line (if there is one) is not taken into account when + building the hierarchy." + (let ((all (or alldecos (rst-find-all-decorations)))) + (setq all (assq-delete-all ignore all)) + (rst-infer-hierarchy (mapcar 'cdr all)))) + + +(defun rst-get-decoration (&optional point) + "Looks around point and finds the characteristics of the + decoration that is found there. We assume that the cursor is + already placed on the title line (and not on the overline or + underline). + + This function returns a (char, style, indent) triple. If the + characters of overline and underline are different, we return + the underline character. The indent is always calculated. A + decoration can be said to exist if the style is not nil. + + A point can be specified to go to the given location before + extracting the decoration." + + (let (char style indent) + (save-excursion + (if point (goto-char point)) + (beginning-of-line) + (if (looking-at rst-section-text-regexp) + (let* ((over (save-excursion + (forward-line -1) + (rst-line-homogeneous-nodent-p))) + + (under (save-excursion + (forward-line +1) + (rst-line-homogeneous-nodent-p))) + ) + + ;; Check that the line above the overline is not part of a title + ;; above it. + (if (and over + (save-excursion + (and (equal (forward-line -2) 0) + (looking-at rst-section-text-regexp)))) + (setq over nil)) + + (cond + ;; No decoration found, leave all return values nil. + ((and (eq over nil) (eq under nil))) + + ;; Overline only, leave all return values nil. + ;; + ;; Note: we don't return the overline character, but it could perhaps + ;; in some cases be used to do something. + ((and over (eq under nil))) + + ;; Underline only. + ((and under (eq over nil)) + (setq char under + style 'simple)) + + ;; Both overline and underline. + (t + (setq char under + style 'over-and-under)) + ) + ) + ) + ;; Find indentation. + (setq indent (save-excursion (back-to-indentation) (current-column))) + ) + ;; Return values. + (list char style indent))) + + +(defun rst-get-decorations-around (&optional alldecos) + "Given the list of all decorations (with positions), +find the decorations before and after the given point. +A list of the previous and next decorations is returned." + (let* ((all (or alldecos (rst-find-all-decorations))) + (curline (line-number-at-pos)) + prev next + (cur all)) + + ;; Search for the decorations around the current line. + (while (and cur (< (caar cur) curline)) + (setq prev cur + cur (cdr cur))) + ;; 'cur' is the following decoration. + + (if (and cur (caar cur)) + (setq next (if (= curline (caar cur)) (cdr cur) cur))) + + (mapcar 'cdar (list prev next)) + )) + + +(defun rst-decoration-complete-p (deco &optional point) + "Return true if the decoration DECO around POINT is complete." + ;; Note: we assume that the detection of the overline as being the underline + ;; of a preceding title has already been detected, and has been eliminated + ;; from the decoration that is given to us. + + ;; There is some sectioning already present, so check if the current + ;; sectioning is complete and correct. + (let* ((char (car deco)) + (style (cadr deco)) + (indent (caddr deco)) + (endcol (save-excursion (end-of-line) (current-column))) + ) + (if char + (let ((exps (concat "^" + (regexp-quote (make-string (+ endcol indent) char)) + "$"))) + (and + (save-excursion (forward-line +1) + (beginning-of-line) + (looking-at exps)) + (or (not (eq style 'over-and-under)) + (save-excursion (forward-line -1) + (beginning-of-line) + (looking-at exps)))) + )) + )) + + +(defun rst-get-next-decoration + (curdeco hier &optional suggestion reverse-direction) + "Get the next decoration for CURDECO, in given hierarchy HIER, +and suggesting for new decoration SUGGESTION." + + (let* ( + (char (car curdeco)) + (style (cadr curdeco)) + + ;; Build a new list of decorations for the rotation. + (rotdecos + (append hier + ;; Suggest a new decoration. + (list suggestion + ;; If nothing to suggest, use first decoration. + (car hier)))) ) + (or + ;; Search for next decoration. + (cadr + (let ((cur (if reverse-direction rotdecos + (reverse rotdecos))) + found) + (while (and cur + (not (and (eq char (caar cur)) + (eq style (cadar cur))))) + (setq cur (cdr cur))) + cur)) + + ;; If not found, take the first of all decorations. + suggestion + ))) + + +(defun rst-adjust () + "Adjust/rotate the section decoration for the section title +around point or promote/demote the decorations inside the region, +depending on if the region is active. This function is meant to +be invoked possibly multiple times, and can vary its behaviour +with a positive prefix argument (toggle style), or with a +negative prefix argument (alternate behaviour). + +This function is the main focus of this module and is a bit of a +swiss knife. It is meant as the single most essential function +to be bound to invoke to adjust the decorations of a section +title in restructuredtext. It tries to deal with all the +possible cases gracefully and to do `the right thing' in all +cases. + +See the documentations of rst-adjust-decoration and +rst-promote-region for full details. + +Prefix Arguments +================ + +The method can take either (but not both) of + +a. a (non-negative) prefix argument, which means to toggle the + decoration style. Invoke with C-u prefix for example; + +b. a negative numerical argument, which generally inverts the + direction of search in the file or hierarchy. Invoke with C-- + prefix for example. + +" + (interactive) + + (let* ( ;; Parse the positive and negative prefix arguments. + (reverse-direction + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0))) + (toggle-style + (and current-prefix-arg (not reverse-direction)))) + + (if (and transient-mark-mode mark-active) + ;; Adjust decorations within region. + (rst-promote-region current-prefix-arg) + ;; Adjust decoration around point. + (rst-adjust-decoration toggle-style reverse-direction)) + + ;; Run the hooks to run after adjusting. + (run-hooks 'rst-adjust-hook) + + )) + +(defvar rst-adjust-hook nil + "Hooks to be run after running rst-adjust.") + +(defun rst-adjust-decoration (&optional toggle-style reverse-direction) +"Adjust/rotate the section decoration for the section title around point. + +This function is meant to be invoked possibly multiple times, and +can vary its behaviour with a true TOGGLE-STYLE argument, or with +a REVERSE-DIRECTION argument. + +General Behaviour +================= + +The next action it takes depends on context around the point, and +it is meant to be invoked possibly more than once to rotate among +the various possibilities. Basically, this function deals with: + +- adding a decoration if the title does not have one; + +- adjusting the length of the underline characters to fit a + modified title; + +- rotating the decoration in the set of already existing + sectioning decorations used in the file; + +- switching between simple and over-and-under styles. + +You should normally not have to read all the following, just +invoke the method and it will do the most obvious thing that you +would expect. + + +Decoration Definitions +====================== + +The decorations consist in + +1. a CHARACTER + +2. a STYLE which can be either of 'simple' or 'over-and-under'. + +3. an INDENT (meaningful for the over-and-under style only) + which determines how many characters and over-and-under + style is hanging outside of the title at the beginning and + ending. + +See source code for mode details. + + +Detailed Behaviour Description +============================== + +Here are the gory details of the algorithm (it seems quite +complicated, but really, it does the most obvious thing in all +the particular cases): + +Before applying the decoration change, the cursor is placed on +the closest line that could contain a section title. + +Case 1: No Decoration +--------------------- + +If the current line has no decoration around it, + +- search backwards for the last previous decoration, and apply + the decoration one level lower to the current line. If there + is no defined level below this previous decoration, we suggest + the most appropriate of the rst-preferred-decorations. + + If REVERSE-DIRECTION is true, we simply use the previous + decoration found directly. + +- if there is no decoration found in the given direction, we use + the first of rst-preferred-decorations. + +The prefix argument forces a toggle of the prescribed decoration +style. + +Case 2: Incomplete Decoration +----------------------------- + +If the current line does have an existing decoration, but the +decoration is incomplete, that is, the underline/overline does +not extend to exactly the end of the title line (it is either too +short or too long), we simply extend the length of the +underlines/overlines to fit exactly the section title. + +If the prefix argument is given, we toggle the style of the +decoration as well. + +REVERSE-DIRECTION has no effect in this case. + +Case 3: Complete Existing Decoration +------------------------------------ + +If the decoration is complete (i.e. the underline (overline) +length is already adjusted to the end of the title line), we +search/parse the file to establish the hierarchy of all the +decorations (making sure not to include the decoration around +point), and we rotate the current title's decoration from within +that list (by default, going *down* the hierarchy that is present +in the file, i.e. to a lower section level). This is meant to be +used potentially multiple times, until the desired decoration is +found around the title. + +If we hit the boundary of the hierarchy, exactly one choice from +the list of preferred decorations is suggested/chosen, the first +of those decoration that has not been seen in the file yet (and +not including the decoration around point), and the next +invocation rolls over to the other end of the hierarchy (i.e. it +cycles). This allows you to avoid having to set which character +to use by always using the + +If REVERSE-DIRECTION is true, the effect is to change the +direction of rotation in the hierarchy of decorations, thus +instead going *up* the hierarchy. + +However, if there is a non-negative prefix argument, we do not +rotate the decoration, but instead simply toggle the style of the +current decoration (this should be the most common way to toggle +the style of an existing complete decoration). + + +Point Location +============== + +The invocation of this function can be carried out anywhere +within the section title line, on an existing underline or +overline, as well as on an empty line following a section title. +This is meant to be as convenient as possible. + + +Indented Sections +================= + +Indented section titles such as :: + + My Title + -------- + +are illegal in restructuredtext and thus not recognized by the +parser. This code will thus not work in a way that would support +indented sections (it would be ambiguous anyway). + + +Joint Sections +============== + +Section titles that are right next to each other may not be +treated well. More work might be needed to support those, and +special conditions on the completeness of existing decorations +might be required to make it non-ambiguous. + +For now we assume that the decorations are disjoint, that is, +there is at least a single line between the titles/decoration +lines. + + +Suggested Binding +================= + +We suggest that you bind this function on C-=. It is close to +C-- so a negative argument can be easily specified with a flick +of the right hand fingers and the binding is unused in text-mode." + (interactive) + + ;; If we were invoked directly, parse the prefix arguments into the + ;; arguments of the function. + (if current-prefix-arg + (setq reverse-direction + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0)) + + toggle-style + (and current-prefix-arg (not reverse-direction)))) + + (let* (;; Check if we're on an underline around a section title, and move the + ;; cursor to the title if this is the case. + (moved (rst-normalize-cursor-position)) + + ;; Find the decoration and completeness around point. + (curdeco (rst-get-decoration)) + (char (car curdeco)) + (style (cadr curdeco)) + (indent (caddr curdeco)) + + ;; New values to be computed. + char-new style-new indent-new + ) + + ;; We've moved the cursor... if we're not looking at some text, we have + ;; nothing to do. + (if (save-excursion (beginning-of-line) + (looking-at rst-section-text-regexp)) + (progn + (cond + ;;--------------------------------------------------------------------- + ;; Case 1: No Decoration + ((and (eq char nil) (eq style nil)) + + (let* ((alldecos (rst-find-all-decorations)) + + (around (rst-get-decorations-around alldecos)) + (prev (car around)) + cur + + (hier (rst-get-hierarchy alldecos)) + ) + + ;; Advance one level down. + (setq cur + (if prev + (if (not reverse-direction) + (or (cadr (rst-get-decoration-match hier prev)) + (rst-suggest-new-decoration hier prev)) + prev) + (copy-list (car rst-preferred-decorations)) + )) + + ;; Invert the style if requested. + (if toggle-style + (setcar (cdr cur) (if (eq (cadr cur) 'simple) + 'over-and-under 'simple)) ) + + (setq char-new (car cur) + style-new (cadr cur) + indent-new (caddr cur)) + )) + + ;;--------------------------------------------------------------------- + ;; Case 2: Incomplete Decoration + ((not (rst-decoration-complete-p curdeco)) + + ;; Invert the style if requested. + (if toggle-style + (setq style (if (eq style 'simple) 'over-and-under 'simple))) + + (setq char-new char + style-new style + indent-new indent)) + + ;;--------------------------------------------------------------------- + ;; Case 3: Complete Existing Decoration + (t + (if toggle-style + + ;; Simply switch the style of the current decoration. + (setq char-new char + style-new (if (eq style 'simple) 'over-and-under 'simple) + indent-new rst-default-indent) + + ;; Else, we rotate, ignoring the decoration around the current + ;; line... + (let* ((alldecos (rst-find-all-decorations)) + + (hier (rst-get-hierarchy alldecos (line-number-at-pos))) + + ;; Suggestion, in case we need to come up with something + ;; new + (suggestion (rst-suggest-new-decoration + hier + (car (rst-get-decorations-around alldecos)))) + + (nextdeco (rst-get-next-decoration + curdeco hier suggestion reverse-direction)) + + ) + + ;; Indent, if present, always overrides the prescribed indent. + (setq char-new (car nextdeco) + style-new (cadr nextdeco) + indent-new (caddr nextdeco)) + + ))) + ) + + ;; Override indent with present indent! + (setq indent-new (if (> indent 0) indent indent-new)) + + (if (and char-new style-new) + (rst-update-section char-new style-new indent-new)) + )) + + + ;; Correct the position of the cursor to more accurately reflect where it + ;; was located when the function was invoked. + (if (not (= moved 0)) + (progn (forward-line (- moved)) + (end-of-line))) + + )) + +;; Maintain an alias for compatibility. +(defalias 'rst-adjust-section-title 'rst-adjust) + + +(defun rst-promote-region (&optional demote) + "Promote the section titles within the region. + +With argument DEMOTE or a prefix argument, demote the +section titles instead. The algorithm used at the boundaries of +the hierarchy is similar to that used by rst-adjust-decoration." + (interactive) + + (let* ((demote (or current-prefix-arg demote)) + (alldecos (rst-find-all-decorations)) + (cur alldecos) + + (hier (rst-get-hierarchy alldecos)) + (suggestion (rst-suggest-new-decoration hier)) + + (region-begin-line (line-number-at-pos (region-beginning))) + (region-end-line (line-number-at-pos (region-end))) + + marker-list + ) + + ;; Skip the markers that come before the region beginning + (while (and cur (< (caar cur) region-begin-line)) + (setq cur (cdr cur))) + + ;; Create a list of markers for all the decorations which are found within + ;; the region. + (save-excursion + (let (m line) + (while (and cur (< (setq line (caar cur)) region-end-line)) + (setq m (make-marker)) + (goto-line line) + (push (list (set-marker m (point)) (cdar cur)) marker-list) + (setq cur (cdr cur)) )) + + ;; Apply modifications. + (let (nextdeco) + (dolist (p marker-list) + ;; Go to the decoration to promote. + (goto-char (car p)) + + ;; Rotate the next decoration. + (setq nextdeco (rst-get-next-decoration + (cadr p) hier suggestion demote)) + + ;; Update the decoration. + (apply 'rst-update-section nextdeco) + + ;; Clear marker to avoid slowing down the editing after we're done. + (set-marker (car p) nil) + )) + (setq deactivate-mark nil) + ))) + + + +(defun rst-display-decorations-hierarchy (&optional decorations) + "Display the current file's section title decorations hierarchy. + This function expects a list of (char, style, indent) triples." + (interactive) + + (if (not decorations) + (setq decorations (rst-get-hierarchy))) + (with-output-to-temp-buffer "*rest section hierarchy*" + (let ((level 1)) + (with-current-buffer standard-output + (dolist (x decorations) + (insert (format "\nSection Level %d" level)) + (apply 'rst-update-section x) + (end-of-buffer) + (insert "\n") + (incf level) + )) + ))) + + +(defun rst-rstrip (str) + "Strips the whitespace at the end of a string." + (let ((tmp)) + (string-match "[ \t\n]*\\'" str) + (substring str 0 (match-beginning 0)) + )) + +(defun rst-get-stripped-line () + "Returns the line at cursor, stripped from whitespace." + (re-search-forward "\\S-.*\\S-" (line-end-position)) + (buffer-substring-no-properties (match-beginning 0) + (match-end 0)) ) + +(defun rst-section-tree (alldecos) + "Returns a pair of a hierarchical tree of the sections titles +in the document, and a reference to the node where the cursor +lives. This can be used to generate a table of contents for the +document. + +Each section title consists in a cons of the stripped title +string and a marker to the section in the original text document. + +If there are missing section levels, the section titles are +inserted automatically, and are set to nil." + + (let* (thelist + (hier (rst-get-hierarchy alldecos)) + (levels (make-hash-table :test 'equal :size 10)) + lines) + + (let ((lev 0)) + (dolist (deco hier) + (puthash deco lev levels) + (incf lev))) + + ;; Create a list of lines that contains (text, level, marker) for each + ;; decoration. + (save-excursion + (setq lines + (mapcar (lambda (deco) + (goto-line (car deco)) + (list (gethash (cdr deco) levels) + (rst-get-stripped-line) + (let ((m (make-marker))) + (beginning-of-line 1) + (set-marker m (point))) + )) + alldecos))) + + (let ((lcontnr (cons nil lines))) + (rst-section-tree-rec lcontnr -1)))) + + +(defun rst-section-tree-rec (decos lev) + "Recursive function for the implementation of the section tree + building. DECOS is a cons cell whose cdr is the remaining list + of decorations, and we change it as we consume them. LEV is + the current level of that node. This function returns a pair + of the subtree that was built. This treats the decos list + destructively." + + (let ((ndeco (cadr decos)) + node + children) + ;; If the next decoration matches our level + (if (= (car ndeco) lev) + (progn + ;; Pop the next decoration and create the current node with it + (setcdr decos (cddr decos)) + (setq node (cdr ndeco)) )) + ;; Else we let the node title/marker be unset. + + ;; Build the child nodes + (while (and (cdr decos) (> (caadr decos) lev)) + (setq children + (cons (rst-section-tree-rec decos (1+ lev)) + children))) + + ;; Return this node with its children. + (cons node (reverse children)) + )) + + +(defun rst-toc-insert (&optional pfxarg) + "Insert a simple text rendering of the table of contents. +By default the top level is ignored if there is only one, because +we assume that the document will have a single title. + +If a numeric prefix argument is given, +- if it is zero or generic, include the top level titles; +- otherwise insert the TOC up to the specified level. + +The TOC is inserted indented at the current column." + + (interactive "P") + + (let* (;; Check maximum level override + (rst-toc-insert-max-level + (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) + (prefix-numeric-value pfxarg) rst-toc-insert-max-level)) + + ;; Get the section tree. + (sectree (rst-section-tree (rst-find-all-decorations))) + + ;; If there is only one top-level title, remove it by starting to print + ;; one index lower (revert this behaviour with the prefix arg), + ;; otherwise print all. + (gen-pfx-arg (or (and pfxarg (listp pfxarg)) + (and (integerp pfxarg) + (= (prefix-numeric-value pfxarg) 0)))) + (start-lev (if (and (not rst-toc-insert-always-include-top) + (= (length (cdr sectree)) 1) + (not gen-pfx-arg)) -1 0)) + + ;; Figure out initial indent. + (initial-indent (make-string (current-column) ? )) + (init-point (point))) + + (rst-toc-insert-node sectree start-lev initial-indent "") + + ;; Fixup for the first line. + (delete-region init-point (+ init-point (length initial-indent))) + + ;; Delete the last newline added. + (delete-backward-char 1) + )) + + +(defgroup rst-toc nil + "Settings for reStructuredText table of contents." + :group 'rst + :version "21.1") + +(defcustom rst-toc-indent 2 + "Indentation for table-of-contents display (also used for + formatting insertion, when numbering is disabled)." + :group 'rst-toc) + +(defcustom rst-toc-insert-always-include-top nil + "Set this to 't if you want to always include top-level titles, + even when there is only one." + :group 'rst-toc) + +(defcustom rst-toc-insert-style 'fixed + "Set this to one of the following values to determine numbering and +indentation style: +- plain: no numbering (fixed indentation) +- fixed: numbering, but fixed indentation +- aligned: numbering, titles aligned under each other +- listed: numbering, with dashes like list items (EXPERIMENTAL) +" + :group 'rst-toc) + +(defcustom rst-toc-insert-number-separator " " + "Separator that goes between the TOC number and the title." + :group 'rst-toc) + +;; This is used to avoid having to change the user's mode. +(defvar rst-toc-insert-click-keymap + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'rst-toc-mode-mouse-goto) + map) + "(Internal) What happens when you click on propertized text in the TOC.") + +(defcustom rst-toc-insert-max-level nil + "If non-nil, maximum depth of the inserted TOC." + :group 'rst-toc) + +(defun rst-toc-insert-node (node level indent pfx) + "Recursive function that does the print of the inserted +toc. PFX is the prefix numbering, that includes the alignment +necessary for all the children of this level to align." + (let ((do-print (> level 0)) + (count 1) + b) + (if do-print + (progn + (insert indent) + (let ((b (point))) + (if (not (equal rst-toc-insert-style 'plain)) + (insert pfx rst-toc-insert-number-separator)) + (insert (or (caar node) "[missing node]")) + ;; Add properties to the text, even though in normal text mode it + ;; won't be doing anything for now. Not sure that I want to change + ;; mode stuff. At least the highlighting gives the idea that this + ;; is generated automatically. + (put-text-property b (point) 'mouse-face 'highlight) + (put-text-property b (point) 'rst-toc-target (cadar node)) + (put-text-property b (point) 'keymap rst-toc-insert-click-keymap) + + ) + (insert "\n") + + ;; Prepare indent for children. + (setq indent + (cond + ((eq rst-toc-insert-style 'plain) + (concat indent rst-toc-indent)) + + ((eq rst-toc-insert-style 'fixed) + (concat indent (make-string rst-toc-indent ? ))) + + ((eq rst-toc-insert-style 'aligned) + (concat indent (make-string (+ (length pfx) 2) ? ))) + + ((eq rst-toc-insert-style 'listed) + (concat (substring indent 0 -3) + (concat (make-string (+ (length pfx) 2) ? ) " - "))) + )) + + )) + + (if (or (eq rst-toc-insert-max-level nil) + (< level rst-toc-insert-max-level)) + (let ((do-child-numbering (>= level 0)) + fmt) + (if do-child-numbering + (progn + ;; Add a separating dot if there is already a prefix + (if (> (length pfx) 0) + (setq pfx (concat (rst-rstrip pfx) "."))) + + ;; Calculate the amount of space that the prefix will require for + ;; the numbers. + (if (cdr node) + (setq fmt (format "%%-%dd" + (1+ (floor (log10 (length (cdr node)))))))) + )) + + (dolist (child (cdr node)) + (rst-toc-insert-node child + (1+ level) + indent + (if do-child-numbering + (concat pfx (format fmt count)) pfx)) + (incf count))) + + ))) + + +(defun rst-toc-insert-find-delete-contents () + "Finds and deletes an existing comment after the first contents directive and +delete that region. Return t if found and the cursor is left after the comment." + (goto-char (point-min)) + ;; We look for the following and the following only (in other words, if your + ;; syntax differs, this won't work. If you would like a more flexible thing, + ;; contact the author, I just can't imagine that this requirement is + ;; unreasonable for now). + ;; + ;; .. contents:: [...anything here...] + ;; .. + ;; XXXXXXXX + ;; XXXXXXXX + ;; [more lines] + ;; + (let ((beg + (re-search-forward "^\\.\\. contents[ \t]*::\\(.*\\)\n\\.\\." + nil t)) + last-real) + (when beg + ;; Look for the first line that starts at the first column. + (forward-line 1) + (beginning-of-line) + (while (or (and (looking-at "[ \t]+[^ \t]") + (setq last-real (point)) t) + (looking-at "\\s-*$")) + (forward-line 1) + ) + (if last-real + (progn + (goto-char last-real) + (end-of-line) + (delete-region beg (point))) + (goto-char beg)) + t + ))) + +(defun rst-toc-insert-update () + "Automatically find the .. contents:: section of a document and update the +inserted TOC if present. You can use this in your file-write hook to always +make it up-to-date automatically." + (interactive) + (save-excursion + (if (rst-toc-insert-find-delete-contents) + (progn (insert "\n ") + (rst-toc-insert))) ) + ;; Note: always return nil, because this may be used as a hook. + ) + + +;;------------------------------------------------------------------------------ + +(defun rst-toc-node (node level) + "Recursive function that does the print of the TOC in rst-toc-mode." + + (if (> level 0) + (let ((b (point))) + ;; Insert line text. + (insert (make-string (* rst-toc-indent (1- level)) ? )) + (insert (if (car node) (caar node) "[missing node]")) + + ;; Highlight lines. + (put-text-property b (point) 'mouse-face 'highlight) + + ;; Add link on lines. + (put-text-property b (point) 'rst-toc-target (cadar node)) + + (insert "\n"))) + + (dolist (child (cdr node)) + (rst-toc-node child (1+ level)))) + + +(defun rst-toc () + "Finds all the section titles and their decorations in the + file, and displays a hierarchically-organized list of the + titles, which is essentially a table-of-contents of the + document. + + The emacs buffer can be navigated, and selecting a section + brings the cursor in that section." + (interactive) + (let* ((curbuf (current-buffer)) + outline + + ;; Get the section tree + (alldecos (rst-find-all-decorations)) + (sectree (rst-section-tree alldecos)) + + ;; Create a temporary buffer. + (buf (get-buffer-create rst-toc-buffer-name)) + ) + + ;; Find the index of the section where the cursor currently is. + (setq outline (let ((idx 1) + (curline (line-number-at-pos (point))) + (decos alldecos)) + (while (and decos (<= (caar decos) curline)) + (setq decos (cdr decos)) + (incf idx)) + idx)) + ;; FIXME: if there is a missing node inserted, the calculation of the + ;; current line will be off. You need to fix this by moving the finding of + ;; the current line somewhere else. + + + (with-current-buffer buf + (let ((inhibit-read-only t)) + (rst-toc-mode) + (delete-region (point-min) (point-max)) + (insert (format "Table of Contents: %s\n" (or (caar sectree) ""))) + (put-text-property (point-min) (point) + 'face (list '(background-color . "lightgray"))) + (rst-toc-node sectree 0) + )) + (display-buffer buf) + (pop-to-buffer buf) + + ;; Save the buffer to return to. + (set (make-local-variable 'rst-toc-return-buffer) curbuf) + + ;; Move the cursor near the right section in the TOC. + (goto-line outline) + )) + + +(defun rst-toc-mode-find-section () + (let ((pos (get-text-property (point) 'rst-toc-target))) + (unless pos + (error "No section on this line")) + (unless (buffer-live-p (marker-buffer pos)) + (error "Buffer for this section was killed")) + pos)) + +(defvar rst-toc-buffer-name "*Table of Contents*" + "Name of the Table of Contents buffer.") + +(defun rst-toc-mode-goto-section () + "Go to the section the current line describes." + (interactive) + (let ((pos (rst-toc-mode-find-section))) + (kill-buffer (get-buffer rst-toc-buffer-name)) + (pop-to-buffer (marker-buffer pos)) + (goto-char pos) + (recenter 5))) + +(defun rst-toc-mode-mouse-goto (event) + "In Rst-Toc mode, go to the occurrence whose line you click on." + (interactive "e") + (let (pos) + (save-excursion + (set-buffer (window-buffer (posn-window (event-end event)))) + (save-excursion + (goto-char (posn-point (event-end event))) + (setq pos (rst-toc-mode-find-section)))) + (pop-to-buffer (marker-buffer pos)) + (goto-char pos))) + +(defun rst-toc-mode-mouse-goto-kill (event) + (interactive "e") + (call-interactively 'rst-toc-mode-mouse-goto event) + (kill-buffer (get-buffer rst-toc-buffer-name))) + +(defvar rst-toc-return-buffer nil + "Buffer local variable that is used to return to the original + buffer from the TOC.") + +(defun rst-toc-quit-window () + (interactive) + (quit-window) + (pop-to-buffer rst-toc-return-buffer)) + +(defvar rst-toc-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'rst-toc-mode-mouse-goto-kill) + (define-key map [mouse-2] 'rst-toc-mode-mouse-goto) + (define-key map "\C-m" 'rst-toc-mode-goto-section) + (define-key map "f" 'rst-toc-mode-goto-section) + (define-key map "q" 'rst-toc-quit-window) + (define-key map "z" 'kill-this-buffer) + map) + "Keymap for `rst-toc-mode'.") + +(put 'rst-toc-mode 'mode-class 'special) + +(defun rst-toc-mode () + "Major mode for output from \\[rst-toc]." + (interactive) + (kill-all-local-variables) + (use-local-map rst-toc-mode-map) + (setq major-mode 'rst-toc-mode) + (setq mode-name "Rst-TOC") + (setq buffer-read-only t) + ) + +;; Note: use occur-mode (replace.el) as a good example to complete missing +;; features. + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Section movement commands. +;; + +(defun rst-forward-section (&optional offset) + "Skip to the next restructured text section title. + OFFSET specifies how many titles to skip. Use a negative OFFSET to move + backwards in the file (default is to use 1)." + (interactive) + (let* (;; Default value for offset. + (offset (or offset 1)) + + ;; Get all the decorations in the file, with their line numbers. + (alldecos (rst-find-all-decorations)) + + ;; Get the current line. + (curline (line-number-at-pos)) + + (cur alldecos) + (idx 0) + line + ) + + ;; Find the index of the "next" decoration w.r.t. to the current line. + (while (and cur (< (caar cur) curline)) + (setq cur (cdr cur)) + (incf idx)) + ;; 'cur' is the decoration on or following the current line. + + (if (and (> offset 0) cur (= (caar cur) curline)) + (incf idx)) + + ;; Find the final index. + (setq idx (+ idx (if (> offset 0) (- offset 1) offset))) + (setq cur (nth idx alldecos)) + + ;; If the index is positive, goto the line, otherwise go to the buffer + ;; boundaries. + (if (and cur (>= idx 0)) + (goto-line (car cur)) + (if (> offset 0) (end-of-buffer) (beginning-of-buffer))) + )) + +(defun rst-backward-section () + "Like rst-forward-section, except move back one title." + (interactive) + (rst-forward-section -1)) + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Functions to indent/dedent item lists, which are always two-characters apart +;; horizontally with rest. + +(defun rst-shift-region-right () + "Indent region ridigly, by two characters to the right." + (interactive) + (indent-rigidly (region-beginning) (region-end) 2)) + +(defun rst-find-leftmost-column (beg end) + "Finds the leftmost column in the region." + (let ((mincol 1000)) + (save-excursion + (goto-char beg) + (while (< (point) end) + (back-to-indentation) + (if (not (looking-at "[ \t]*$")) + (setq mincol (min mincol (current-column)))) + (forward-line 1) + )) + mincol)) + +(defun rst-shift-region-left (pfxarg) + "Indent region ridigly, by two characters to the left. +If invoked with a prefix arg, the entire indentation is removed, +up to the leftmost character in the region." + (interactive "P") + (let ((chars + (if pfxarg + (- (rst-find-leftmost-column (region-beginning) (region-end))) + -2))) + (indent-rigidly (region-beginning) (region-end) chars))) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; rst-mode +;; ======== +;; +;;; Customization: + +(defcustom rst-mode-hook nil + "Hook run when Rst Mode is turned on. The hook for Text Mode is run before + this one." + :group 'rst + :type '(hook)) + +(defcustom rst-mode-lazy t + "*If non-nil Rst Mode font-locks comment, literal blocks, and section titles +correctly. Because this is really slow it switches on Lazy Lock Mode +automatically. You may increase Lazy Lock Defer Time for reasonable results. + +If nil comments and literal blocks are font-locked only on the line they start. + +The value of this variable is used when Rst Mode is turned on." + :group 'rst + :type '(boolean)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgroup rst-faces nil "Faces used in Rst Mode" + :group 'rst + :group 'faces + :version "21.1") + +(defcustom rst-block-face 'font-lock-keyword-face + "All syntax marking up a special block" + :group 'rst-faces + :type '(face)) + +(defcustom rst-external-face 'font-lock-type-face + "Field names and interpreted text" + :group 'rst-faces + :type '(face)) + +(defcustom rst-definition-face 'font-lock-function-name-face + "All other defining constructs" + :group 'rst-faces + :type '(face)) + +(defcustom rst-directive-face + ;; XEmacs compatibility + (if (boundp 'font-lock-builtin-face) + 'font-lock-builtin-face + 'font-lock-preprocessor-face) + "Directives and roles" + :group 'rst-faces + :type '(face)) + +(defcustom rst-comment-face 'font-lock-comment-face + "Comments" + :group 'rst-faces + :type '(face)) + +(defcustom rst-emphasis1-face + ;; XEmacs compatibility + (if (facep 'italic) + ''italic + 'italic) + "Simple emphasis" + :group 'rst-faces + :type '(face)) + +(defcustom rst-emphasis2-face + ;; XEmacs compatibility + (if (facep 'bold) + ''bold + 'bold) + "Double emphasis" + :group 'rst-faces + :type '(face)) + +(defcustom rst-literal-face 'font-lock-string-face + "Literal text" + :group 'rst-faces + :type '(face)) + +(defcustom rst-reference-face 'font-lock-variable-name-face + "References to a definition" + :group 'rst-faces + :type '(face)) + +;; Faces for displaying items on several levels; these definitions define +;; different shades of grey where the lightest one is used for level 1 +(defconst rst-level-face-max 6 + "Maximum depth of level faces defined") +(defconst rst-level-face-base-color "grey" + "The base color to be used for creating level faces") +(defconst rst-level-face-base-light 85 + "The lightness factor for the base color") +(defconst rst-level-face-format-light "%2d" + "The format for the lightness factor for the base color") +(defconst rst-level-face-step-light -7 + "The step width to use for next color") + +;; Define the faces +(let ((i 1)) + (while (<= i rst-level-face-max) + (let ((sym (intern (format "rst-level-%d-face" i))) + (doc (format "Face for showing section title text at level %d" i)) + (col (format (concat "%s" rst-level-face-format-light) + rst-level-face-base-color + (+ (* (1- i) rst-level-face-step-light) + rst-level-face-base-light)))) + (make-empty-face sym) + (set-face-doc-string sym doc) + (set-face-background sym col) + (set sym sym) + (setq i (1+ i))))) + +(defcustom rst-adornment-faces-alist + '((1 . rst-level-1-face) + (2 . rst-level-2-face) + (3 . rst-level-3-face) + (4 . rst-level-4-face) + (5 . rst-level-5-face) + (6 . rst-level-6-face) + (t . font-lock-keyword-face) + (nil . font-lock-keyword-face)) + "Provides faces for the various adornment types. Key is a number (for the +section title text of that level), t (for transitions) or nil (for section +title adornment)." + :group 'rst-faces + :type '(alist :key-type (choice (integer :tag "Section level") + (boolean :tag "transitions (on) / section title adornment (off)")) + :value-type (face))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; FIXME: Code from `restructuredtext.el' should be integrated + +(defvar rst-mode-syntax-table nil + "Syntax table used while in rst mode.") + +(unless rst-mode-syntax-table + (setq rst-mode-syntax-table (make-syntax-table text-mode-syntax-table)) + (modify-syntax-entry ?$ "." rst-mode-syntax-table) + (modify-syntax-entry ?% "." rst-mode-syntax-table) + (modify-syntax-entry ?& "." rst-mode-syntax-table) + (modify-syntax-entry ?' "." rst-mode-syntax-table) + (modify-syntax-entry ?* "." rst-mode-syntax-table) + (modify-syntax-entry ?+ "." rst-mode-syntax-table) + (modify-syntax-entry ?. "_" rst-mode-syntax-table) + (modify-syntax-entry ?/ "." rst-mode-syntax-table) + (modify-syntax-entry ?< "." rst-mode-syntax-table) + (modify-syntax-entry ?= "." rst-mode-syntax-table) + (modify-syntax-entry ?> "." rst-mode-syntax-table) + (modify-syntax-entry ?\\ "\\" rst-mode-syntax-table) + (modify-syntax-entry ?| "." rst-mode-syntax-table) + (modify-syntax-entry ?_ "." rst-mode-syntax-table) + ) + +(defvar rst-mode-abbrev-table nil + "Abbrev table used while in rst mode.") +(define-abbrev-table 'rst-mode-abbrev-table ()) + +;; FIXME: Movement keys to skip forward / backward over or mark an indented +;; block could be defined; keys to markup section titles based on +;; `rst-adornment-level-alist' would be useful +(defvar rst-mode-map nil + "Keymap for rst mode. This inherits from Text mode.") + +(unless rst-mode-map + (setq rst-mode-map (copy-keymap text-mode-map))) + +(defun rst-mode () + "Major mode for editing reStructuredText documents. + +You may customize `rst-mode-lazy' to switch font-locking of blocks. + +\\{rst-mode-map} +Turning on `rst-mode' calls the normal hooks `text-mode-hook' and +`rst-mode-hook'." + (interactive) + (kill-all-local-variables) + + ;; Maps and tables + (use-local-map rst-mode-map) + (setq local-abbrev-table rst-mode-abbrev-table) + (set-syntax-table rst-mode-syntax-table) + + ;; For editing text + ;; + ;; FIXME: It would be better if this matches more exactly the start of a reST + ;; paragraph; however, this not always possible with a simple regex because + ;; paragraphs are determined by indentation of the following line + (set (make-local-variable 'paragraph-start) + (concat page-delimiter "\\|[ \t]*$")) + (if (eq ?^ (aref paragraph-start 0)) + (setq paragraph-start (substring paragraph-start 1))) + (set (make-local-variable 'paragraph-separate) paragraph-start) + (set (make-local-variable 'indent-line-function) 'indent-relative-maybe) + (set (make-local-variable 'adaptive-fill-mode) t) + (set (make-local-variable 'comment-start) ".. ") + + ;; Special variables + (make-local-variable 'rst-adornment-level-alist) + + ;; Font lock + (set (make-local-variable 'font-lock-defaults) + '(rst-font-lock-keywords-function + t nil nil nil + (font-lock-multiline . t) + (font-lock-mark-block-function . mark-paragraph))) + (when (boundp 'font-lock-support-mode) + ;; rst-mode has its own mind about font-lock-support-mode + (make-local-variable 'font-lock-support-mode) + (cond + ((and (not rst-mode-lazy) (not font-lock-support-mode))) + ;; No support mode set and none required - leave it alone + ((or (not font-lock-support-mode) ;; No support mode set (but required) + (symbolp font-lock-support-mode)) ;; or a fixed mode for all + (setq font-lock-support-mode + (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) + (cons t font-lock-support-mode)))) + ((and (listp font-lock-support-mode) + (not (assoc 'rst-mode font-lock-support-mode))) + ;; A list of modes missing rst-mode + (setq font-lock-support-mode + (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) + font-lock-support-mode))))) + + ;; Names and hooks + (setq mode-name "reST") + (setq major-mode 'rst-mode) + (run-hooks 'text-mode-hook) + (run-hooks 'rst-mode-hook)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Font lock + +(defun rst-font-lock-keywords-function () + "Returns keywords to highlight in rst mode according to current settings." + ;; The reST links in the comments below all relate to sections in + ;; http://docutils.sourceforge.net/rst.html + (let* ( ;; This gets big - so let's define some abbreviations + ;; horizontal white space + (re-hws "[\t ]") + ;; beginning of line with possible indentation + (re-bol (concat "^" re-hws "*")) + ;; Separates block lead-ins from their content + (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) + ;; explicit markup tag + (re-emt "\\.\\.") + ;; explicit markup start + (re-ems (concat re-emt re-hws "+")) + ;; inline markup prefix + (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) + ;; symbol character + (re-sym1 "\\(\\sw\\|\\s_\\)") + ;; inline markup content begin + (re-imbeg2 "\\(\\S \\|\\S \\([^") + + ;; There seems to be a bug leading to error "Stack overflow in regexp + ;; matcher" when "|" or "\\*" are the characters searched for + (re-imendbeg + (if (< emacs-major-version 21) + "]" + "\\]\\|\\\\.")) + ;; inline markup content end + (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) + ;; inline markup content without asterisk + (re-ima2 (concat re-imbeg2 "*" re-imend)) + ;; inline markup content without backquote + (re-imb2 (concat re-imbeg2 "`" re-imend)) + ;; inline markup content without vertical bar + (re-imv2 (concat re-imbeg2 "|" re-imend)) + ;; Supported URI schemes + (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") + ;; Line starting with adornment and optional whitespace; complete + ;; adornment is in (match-string 1); there must be at least 3 + ;; characters because otherwise explicit markup start would be + ;; recognized + (re-ado2 (concat "^\\(\\([" + (if (or + (< emacs-major-version 21) + (save-match-data + (string-match "XEmacs\\|Lucid" emacs-version))) + "^a-zA-Z0-9 \t\x00-\x1F" + "^[:word:][:space:][:cntrl:]") + "]\\)\\2\\2+\\)" re-hws "*$")) + ) + (list + ;; FIXME: Block markup is not recognized in blocks after explicit markup + ;; start + + ;; Simple `Body Elements`_ + ;; `Bullet Lists`_ + (list + (concat re-bol "\\([-*+]" re-blksep1 "\\)") + 1 rst-block-face) + ;; `Enumerated Lists`_ + (list + (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" re-blksep1 "\\)") + 1 rst-block-face) + ;; `Definition Lists`_ FIXME: missing + ;; `Field Lists`_ + (list + (concat re-bol "\\(:[^:]+:\\)" re-blksep1) + 1 rst-external-face) + ;; `Option Lists`_ + (list + (concat re-bol "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*\\([ =]\\S +\\)?\\)\\(,[\t ]\\)?\\)+\\)\\($\\|[\t ]\\{2\\}\\)") + 1 rst-block-face) + + ;; `Tables`_ FIXME: missing + + ;; All the `Explicit Markup Blocks`_ + ;; `Footnotes`_ / `Citations`_ + (list + (concat re-bol "\\(" re-ems "\\[[^[]+\\]\\)" re-blksep1) + 1 rst-definition-face) + ;; `Directives`_ / `Substitution Definitions`_ + (list + (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" re-sym1 "+::\\)" re-blksep1) + (list 1 rst-directive-face) + (list 2 rst-definition-face) + (list 4 rst-directive-face)) + ;; `Hyperlink Targets`_ + (list + (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" re-blksep1) + 1 rst-definition-face) + (list + (concat re-bol "\\(__\\)" re-blksep1) + 1 rst-definition-face) + + ;; All `Inline Markup`_ + ;; FIXME: Condition 5 preventing fontification of e.g. "*" not implemented + ;; `Strong Emphasis`_ + (list + (concat re-imp1 "\\(\\*\\*" re-ima2 "\\*\\*\\)" re-ims1) + 2 rst-emphasis2-face) + ;; `Emphasis`_ + (list + (concat re-imp1 "\\(\\*" re-ima2 "\\*\\)" re-ims1) + 2 rst-emphasis1-face) + ;; `Inline Literals`_ + (list + (concat re-imp1 "\\(``" re-imb2 "``\\)" re-ims1) + 2 rst-literal-face) + ;; `Inline Internal Targets`_ + (list + (concat re-imp1 "\\(_`" re-imb2 "`\\)" re-ims1) + 2 rst-definition-face) + ;; `Hyperlink References`_ + ;; FIXME: `Embedded URIs`_ not considered + (list + (concat re-imp1 "\\(\\(`" re-imb2 "`\\|\\sw+\\)__?\\)" re-ims1) + 2 rst-reference-face) + ;; `Interpreted Text`_ + (list + (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" re-sym1 "+:\\)?\\)" re-ims1) + (list 2 rst-directive-face) + (list 5 rst-external-face) + (list 8 rst-directive-face)) + ;; `Footnote References`_ / `Citation References`_ + (list + (concat re-imp1 "\\(\\[[^]]+\\]_\\)" re-ims1) + 2 rst-reference-face) + ;; `Substitution References`_ + (list + (concat re-imp1 "\\(|" re-imv2 "|\\)" re-ims1) + 2 rst-reference-face) + ;; `Standalone Hyperlinks`_ + (list + ;; FIXME: This takes it easy by using a whitespace as delimiter + (concat re-imp1 "\\(" re-uris1 ":\\S +\\)" re-ims1) + 2 rst-definition-face) + (list + (concat re-imp1 "\\(" re-sym1 "+@" re-sym1 "+\\)" re-ims1) + 2 rst-definition-face) + + ;; Do all block fontification as late as possible so 'append works + + ;; Sections_ / Transitions_ + (append + (list + re-ado2) + (if (not rst-mode-lazy) + (list 1 rst-block-face) + (list + (list 'rst-font-lock-handle-adornment + '(progn + (setq rst-font-lock-adornment-point (match-end 1)) + (point-max)) + nil + (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t) + (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) + 'append t) + (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t))))) + + ;; `Comments`_ + (append + (list + (concat re-bol "\\(" re-ems "\\)\[^[|_]\\([^:]\\|:\\([^:]\\|$\\)\\)*$") + (list 1 rst-comment-face)) + (if rst-mode-lazy + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point (match-end 1)) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) + (append + (list + (concat re-bol "\\(" re-emt "\\)\\(\\s *\\)$") + (list 1 rst-comment-face) + (list 2 rst-comment-face)) + (if rst-mode-lazy + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point 'next) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) + + ;; `Literal Blocks`_ + (append + (list + (concat re-bol "\\(\\([^.\n]\\|\\.[^.\n]\\).*\\)?\\(::\\)$") + (list 3 rst-block-face)) + (if rst-mode-lazy + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point t) + (point-max)) + nil + (list 0 rst-literal-face 'append))))) + ))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Indented blocks + +(defun rst-forward-indented-block (&optional column limit) + "Move forward across one indented block. +Find the next non-empty line which is not indented at least to COLUMN (defaults +to the column of the point). Moves point to first character of this line or the +first empty line immediately before it and returns that position. If there is +no such line before LIMIT (defaults to the end of the buffer) returns nil and +point is not moved." + (interactive) + (let ((clm (or column (current-column))) + (start (point)) + fnd beg cand) + (if (not limit) + (setq limit (point-max))) + (save-match-data + (while (and (not fnd) (< (point) limit)) + (forward-line 1) + (when (< (point) limit) + (setq beg (point)) + (if (looking-at "\\s *$") + (setq cand (or cand beg)) ; An empty line is a candidate + (move-to-column clm) + ;; FIXME: No indentation [(zerop clm)] must be handled in some + ;; useful way - though it is not clear what this should mean at all + (if (string-match + "^\\s *$" (buffer-substring-no-properties beg (point))) + (setq cand nil) ; An indented line resets a candidate + (setq fnd (or cand beg))))))) + (goto-char (or fnd start)) + fnd)) + +;; Stores the point where the current indentation ends if a number. If `next' +;; indicates `rst-font-lock-find-unindented-line' shall take the indentation +;; from the next line if this is not empty. If non-nil indicates +;; `rst-font-lock-find-unindented-line' shall take the indentation from the +;; next non-empty line. Also used as a trigger for +;; `rst-font-lock-find-unindented-line'. +(defvar rst-font-lock-indentation-point nil) + +(defun rst-font-lock-find-unindented-line (limit) + (let* ((ind-pnt rst-font-lock-indentation-point) + (beg-pnt ind-pnt)) + ;; May run only once - enforce this + (setq rst-font-lock-indentation-point nil) + (when (and ind-pnt (not (numberp ind-pnt))) + ;; Find indentation point in next line if any + (setq ind-pnt + (save-excursion + (save-match-data + (if (eq ind-pnt 'next) + (when (and (zerop (forward-line 1)) (< (point) limit)) + (setq beg-pnt (point)) + (when (not (looking-at "\\s *$")) + (looking-at "\\s *") + (match-end 0))) + (while (and (zerop (forward-line 1)) (< (point) limit) + (looking-at "\\s *$"))) + (when (< (point) limit) + (setq beg-pnt (point)) + (looking-at "\\s *") + (match-end 0))))))) + (when ind-pnt + (goto-char ind-pnt) + ;; Always succeeds because the limit set by PRE-MATCH-FORM is the + ;; ultimate point to find + (goto-char (or (rst-forward-indented-block nil limit) limit)) + (set-match-data (list beg-pnt (point))) + t))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Adornments + +;; Stores the point where the current adornment ends. Also used as a trigger +;; for `rst-font-lock-handle-adornment'. +(defvar rst-font-lock-adornment-point nil) + +;; Here `rst-font-lock-handle-adornment' stores the section level of the +;; current adornment or t for a transition. +(defvar rst-font-lock-level nil) + +;; FIXME: It would be good if this could be used to markup section titles of +;; given level with a special key; it would be even better to be able to +;; customize this so it can be used for a generally available personal style +;; +;; FIXME: There should be some way to reset and reload this variable - probably +;; a special key +;; +;; FIXME: Some support for `outline-mode' would be nice which should be based +;; on this information +(defvar rst-adornment-level-alist nil + "Associates adornments with section levels. +The key is a two character string. The first character is the adornment +character. The second character distinguishes underline section titles (`u') +from overline/underline section titles (`o'). The value is the section level. + +This is made buffer local on start and adornments found during font lock are +entered.") + +;; Returns section level for adornment key KEY. Adds new section level if KEY +;; is not found and ADD. If KEY is not a string it is simply returned. +(defun rst-adornment-level (key &optional add) + (let ((fnd (assoc key rst-adornment-level-alist)) + (new 1)) + (cond + ((not (stringp key)) + key) + (fnd + (cdr fnd)) + (add + (while (rassoc new rst-adornment-level-alist) + (setq new (1+ new))) + (setq rst-adornment-level-alist + (append rst-adornment-level-alist (list (cons key new)))) + new)))) + +;; Classifies adornment for section titles and transitions. ADORNMENT is the +;; complete adornment string as found in the buffer. END is the point after the +;; last character of ADORNMENT. For overline section adornment LIMIT limits the +;; search for the matching underline. Returns a list. The first entry is t for +;; a transition, or a key string for `rst-adornment-level' for a section title. +;; The following eight values forming four match groups as can be used for +;; `set-match-data'. First match group contains the maximum points of the whole +;; construct. Second and last match group matched pure section title adornment +;; while third match group matched the section title text or the transition. +;; Each group but the first may or may not exist. +(defun rst-classify-adornment (adornment end limit) + (save-excursion + (save-match-data + (goto-char end) + (let ((ado-ch (aref adornment 0)) + (ado-re (regexp-quote adornment)) + (end-pnt (point)) + (beg-pnt (progn + (forward-line 0) + (point))) + (nxt-emp + (save-excursion + (or (not (zerop (forward-line 1))) + (looking-at "\\s *$")))) + (prv-emp + (save-excursion + (or (not (zerop (forward-line -1))) + (looking-at "\\s *$")))) + key beg-ovr end-ovr beg-txt end-txt beg-und end-und) + (cond + ((and nxt-emp prv-emp) + ;; A transition + (setq key t) + (setq beg-txt beg-pnt) + (setq end-txt end-pnt)) + (prv-emp + ;; An overline + (setq key (concat (list ado-ch) "o")) + (setq beg-ovr beg-pnt) + (setq end-ovr end-pnt) + (forward-line 1) + (setq beg-txt (point)) + (while (and (< (point) limit) (not end-txt)) + (if (looking-at "\\s *$") + ;; No underline found + (setq end-txt (1- (point))) + (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) + (setq end-und (match-end 1)) + (setq beg-und (point)) + (setq end-txt (1- beg-und)))) + (forward-line 1))) + (t + ;; An underline + (setq key (concat (list ado-ch) "u")) + (setq beg-und beg-pnt) + (setq end-und end-pnt) + (setq end-txt (1- beg-und)) + (setq beg-txt (progn + (if (re-search-backward "^\\s *$" 1 'move) + (forward-line 1)) + (point))))) + (list key + (or beg-ovr beg-txt beg-und) + (or end-und end-txt end-und) + beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) + +;; Handles adornments for font-locking section titles and transitions. Returns +;; three match groups. First and last match group matched pure overline / +;; underline adornment while second group matched section title text. Each +;; group may not exist. +(defun rst-font-lock-handle-adornment (limit) + (let ((ado-pnt rst-font-lock-adornment-point)) + ;; May run only once - enforce this + (setq rst-font-lock-adornment-point nil) + (if ado-pnt + (let* ((ado (rst-classify-adornment (match-string-no-properties 1) + ado-pnt limit)) + (key (car ado)) + (mtc (cdr ado))) + (setq rst-font-lock-level (rst-adornment-level key t)) + (goto-char (nth 1 mtc)) + (set-match-data mtc) + t)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Support for conversion from within Emacs + +(defgroup rst-html nil + "Settings for conversion to HTML available by \\[rst-html-compile]." + :group 'rst + :version "21.1") + +(defcustom rst-html-command "rst2html.py" + "Command to convert an reST file to HTML." + :group 'rst-html + :type '(string)) + +(defcustom rst-html-options "" + "Local file options for reST to HTML conversion. +Stylesheets are set by an own option." + :group 'rst-html + :type '(string)) + +(defcustom rst-html-extension ".html" + "Extension for HTML output file." + :group 'rst-html + :type '(string)) + +(defun rst-html-find-conf () + "Look for the configuration file in the parents of the current path." + (interactive) + (let ((file-name "docutils.conf") + (buffer-file (buffer-file-name))) + ;; Move up in the dir hierarchy till we find a change log file. + (let ((dir (file-name-directory buffer-file))) + (while (and (or (not (string= "/" dir)) (setq dir nil) nil) + (not (file-exists-p (concat dir file-name)))) + ;; Move up to the parent dir and try again. + (setq dir (expand-file-name (file-name-directory + (directory-file-name + (file-name-directory dir))))) ) + (or (and dir (concat dir file-name)) nil) + ))) + +(defun rst-html-compile () + "Compile command to convert reST document into HTML. +Attempts to find configuration file, if it can, overrides the options." + (interactive) + ;; Note: maybe we want to check if there is a Makefile too and not do anything + ;; if that is the case. I dunno. + (let* ((conffile (rst-html-find-conf)) + (bufname (file-name-nondirectory buffer-file-name)) + (outname (file-name-sans-extension bufname))) + + ;; Set compile-command before invocation of compile. + (set (make-local-variable 'compile-command) + (mapconcat 'identity + (list rst-html-command + rst-html-options + (if conffile + (concat "--config=\"" conffile "\"") + "") + bufname + (concat outname rst-html-extension)) + " ")) + + ;; Invoke the compile command. + (if (or compilation-read-command current-prefix-arg) + (call-interactively 'compile) + (compile compile-command)) + )) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Generic text functions that are more convenient than the defaults. +;; + +(defun replace-lines (fromchar tochar) + "Replace flush-left lines, consisting of multiple FROMCHAR characters, +with equal-length lines of TOCHAR." + (interactive "\ +cSearch for flush-left lines of char: +cand replace with char: ") + (save-excursion + (let* ((fromstr (string fromchar)) + (searchre (concat "^" (regexp-quote fromstr) "+ *$")) + (found 0)) + (condition-case err + (while t + (search-forward-regexp searchre) + (setq found (1+ found)) + (search-backward fromstr) ;; point will be *before* last char + (setq p (1+ (point))) + (beginning-of-line) + (setq l (- p (point))) + (rst-delete-line) + (insert-char tochar l)) + (search-failed + (message (format "%d lines replaced." found))))))) + +(defun join-paragraph () + "Join lines in current paragraph into one line, removing end-of-lines." + (interactive) + (let ((fill-column 65000)) ; some big number + (call-interactively 'fill-paragraph))) + +;; FIXME: can we remove this? +(defun force-fill-paragraph () + "Fill paragraph at point, first joining the paragraph's lines into one. +This is useful for filling list item paragraphs." + (interactive) + (join-paragraph) + (fill-paragraph nil)) + + +;; Generic character repeater function. +;; For sections, better to use the specialized function above, but this can +;; be useful for creating separators. +(defun repeat-last-character (&optional tofill) + "Fills the current line up to the length of the preceding line (if not +empty), using the last character on the current line. If the preceding line is +empty, we use the fill-column. + +If a prefix argument is provided, use the next line rather than the preceding +line. + +If the current line is longer than the desired length, shave the characters off +the current line to fit the desired length. + +As an added convenience, if the command is repeated immediately, the alternative +column is used (fill-column vs. end of previous/next line)." + (interactive) + (let* ((curcol (current-column)) + (curline (+ (count-lines (point-min) (point)) + (if (eq curcol 0) 1 0))) + (lbp (line-beginning-position 0)) + (prevcol (if (and (= curline 1) (not current-prefix-arg)) + fill-column + (save-excursion + (forward-line (if current-prefix-arg 1 -1)) + (end-of-line) + (skip-chars-backward " \t" lbp) + (let ((cc (current-column))) + (if (= cc 0) fill-column cc))))) + (rightmost-column + (cond (tofill fill-column) + ((equal last-command 'repeat-last-character) + (if (= curcol fill-column) prevcol fill-column)) + (t (save-excursion + (if (= prevcol 0) fill-column prevcol))) + )) ) + (end-of-line) + (if (> (current-column) rightmost-column) + ;; shave characters off the end + (delete-region (- (point) + (- (current-column) rightmost-column)) + (point)) + ;; fill with last characters + (insert-char (preceding-char) + (- rightmost-column (current-column)))) + )) + + + +(provide 'rst) +;;; rst.el ends here + diff --git a/tools/editors/emacs/tests/tests-adjust-section.el b/tools/editors/emacs/tests/tests-adjust-section.el index 84a8d4ea3..a4d39f2bc 100644 --- a/tools/editors/emacs/tests/tests-adjust-section.el +++ b/tools/editors/emacs/tests/tests-adjust-section.el @@ -2,7 +2,7 @@ ;; Date: $Date: 2005/04/01 23:19:41 $ ;; Copyright: This module has been placed in the public domain. ;; -;; Regression tests for rest-adjust-section-title. +;; Regression tests for rst-adjust-section-title. ;; ;; Run this with:: ;; @@ -12,7 +12,7 @@ ;; Define tests. -(setq rest-adjust-decoration-tests +(setq rst-adjust-decoration-tests '( ;;------------------------------------------------------------------------------ (nodec-first-simple-1 @@ -818,13 +818,13 @@ Document Title2 (add-to-list 'load-path ".") (load "tests-runner.el") (add-to-list 'load-path "..") -(load "restructuredtext.el") +(load "rst.el") (progn (regression-test-compare-expect-buffer "Test interactive adjustment of sections." - rest-adjust-decoration-tests + rst-adjust-decoration-tests (lambda () - (call-interactively 'rest-adjust)) + (call-interactively 'rst-adjust)) nil)) diff --git a/tools/editors/emacs/tests/tests-basic.el b/tools/editors/emacs/tests/tests-basic.el index b5c5d7948..5f94304ce 100644 --- a/tools/editors/emacs/tests/tests-basic.el +++ b/tools/editors/emacs/tests/tests-basic.el @@ -2,7 +2,7 @@ ;; Date: $Date: 2005/04/01 23:19:41 $ ;; Copyright: This module has been placed in the public domain. ;; -;; Regression tests for rest-adjust-section-title. +;; Regression tests for rst-adjust-section-title. ;; ;; Run this with:: ;; @@ -15,12 +15,12 @@ (add-to-list 'load-path ".") (load "tests-runner.el") (add-to-list 'load-path "..") -(load "restructuredtext.el") +(load "rst.el") ;; (setq debug-on-error t) -(setq rest-line-homogeneous-p-tests +(setq rst-line-homogeneous-p-tests '( ;;------------------------------------------------------------------------------ (simple "Blablabla bla@" nil) @@ -38,9 +38,9 @@ (progn (regression-test-compare-expect-values "Tests for predicate for one char line." - rest-line-homogeneous-p-tests 'rest-line-homogeneous-p nil)) + rst-line-homogeneous-p-tests 'rst-line-homogeneous-p nil)) -(setq rest-line-homogeneous-nodent-p-tests +(setq rst-line-homogeneous-nodent-p-tests '( ;;------------------------------------------------------------------------------ (simple "Blablabla bla@" nil) @@ -58,12 +58,12 @@ (progn (regression-test-compare-expect-values "Tests for predicate for one char line." - rest-line-homogeneous-nodent-p-tests 'rest-line-homogeneous-nodent-p nil)) + rst-line-homogeneous-nodent-p-tests 'rst-line-homogeneous-nodent-p nil)) -(setq rest-normalize-cursor-position-tests +(setq rst-normalize-cursor-position-tests '( ;;------------------------------------------------------------------------------ (under @@ -215,7 +215,7 @@ Another Title (progn (regression-test-compare-expect-buffer "Test preparation of cursor position." - rest-normalize-cursor-position-tests 'rest-normalize-cursor-position nil)) + rst-normalize-cursor-position-tests 'rst-normalize-cursor-position nil)) @@ -223,7 +223,7 @@ Another Title -(setq rest-get-decoration-tests +(setq rst-get-decoration-tests '( ;;------------------------------------------------------------------------------ (nodec-1 @@ -436,7 +436,7 @@ Du bon vin tous les jours (progn (regression-test-compare-expect-values "Test getting the decoration." - rest-get-decoration-tests 'rest-get-decoration nil)) + rst-get-decoration-tests 'rst-get-decoration nil)) @@ -528,7 +528,7 @@ Current@ ;; ;; ========== -(setq rest-find-all-decorations-tests +(setq rst-find-all-decorations-tests `( ;;------------------------------------------------------------------------------ (basic-1 ,text-1 @@ -558,12 +558,12 @@ Current@ (progn (regression-test-compare-expect-values "Test finding all the decorations in a file." - rest-find-all-decorations-tests 'rest-find-all-decorations nil)) + rst-find-all-decorations-tests 'rst-find-all-decorations nil)) -(setq rest-get-hierarchy-tests +(setq rst-get-hierarchy-tests `( ;;------------------------------------------------------------------------------ (basic-1 ,text-1 @@ -577,12 +577,12 @@ Current@ (progn (regression-test-compare-expect-values "Test finding the hierarchy of sections in a file." - rest-get-hierarchy-tests 'rest-get-hierarchy nil)) + rst-get-hierarchy-tests 'rst-get-hierarchy nil)) -(setq rest-get-hierarchy-ignore-tests +(setq rst-get-hierarchy-ignore-tests `( ;;------------------------------------------------------------------------------ (basic-1 ,text-1 @@ -595,8 +595,8 @@ Current@ (progn (regression-test-compare-expect-values "Test finding the hierarchy of sections in a file, ignoring lines." - rest-get-hierarchy-ignore-tests - (lambda () (rest-get-hierarchy nil (line-number-at-pos))) nil)) + rst-get-hierarchy-ignore-tests + (lambda () (rst-get-hierarchy nil (line-number-at-pos))) nil)) @@ -604,7 +604,7 @@ Current@ -(setq rest-decoration-complete-p-tests +(setq rst-decoration-complete-p-tests '( ;;------------------------------------------------------------------------------ (nodec @@ -759,7 +759,7 @@ Current@ (progn (regression-test-compare-expect-values "Tests for completeness predicate." - rest-decoration-complete-p-tests 'rest-decoration-complete-p nil)) + rst-decoration-complete-p-tests 'rst-decoration-complete-p nil)) @@ -773,7 +773,7 @@ Current@ -(setq rest-get-decorations-around-tests +(setq rst-get-decorations-around-tests '( ;;------------------------------------------------------------------------------ (simple @@ -809,5 +809,5 @@ Next (progn (regression-test-compare-expect-values "Tests getting the decorations around a point." - rest-get-decorations-around-tests 'rest-get-decorations-around nil)) + rst-get-decorations-around-tests 'rst-get-decorations-around nil)) -- cgit v1.2.1 From e70238510f7a1d2a93fd9e98226153c3c7370b2b Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 Oct 2005 16:55:21 +0000 Subject: added missing target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3983 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/README.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index 27be19f16..6f0f72891 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -6,6 +6,8 @@ :Date: $Date$ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html + Directory Contents ================== @@ -26,4 +28,3 @@ This directory contains the following Emacs lisp package files: To install the package, put a copy of the package file in a directory on your ``load-path`` (use ``C-h v load-path`` to check). - -- cgit v1.2.1 From 8e600dc640cf4db4919a452816bd20e336621d6b Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 Oct 2005 21:49:33 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3984 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 347ee6b19..b0ff38ee0 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -63,7 +63,7 @@ Then you will want to bind keys to the most common commands it provides. A standard text-mode hook function is maintained and provided by the package for this use, set it up like this:: - (add-hook 'text-mode-hook 'rst-text-mode-hook) + (add-hook 'text-mode-hook 'rst-text-mode-bindings) Section Decoration Adjustment -- cgit v1.2.1 From eda4517f748495eeeb6eb5a49c4fd11e8a10ceda Mon Sep 17 00:00:00 2001 From: blais Date: Sun, 30 Oct 2005 21:58:54 +0000 Subject: Minor changes to comments in rst.el for auto-gen of my web page. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3985 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 68 ++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 94da15901..5fb0aa6d7 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -1,26 +1,46 @@ -;; Authors: Martin Blais , -;; Stefan Merten -;; David Goodger -;; Date: $Date$ -;; Copyright: This module has been placed in the public domain. -;; -;; Support code for editing reStructuredText with Emacs. Basically, this -;; package contains: -;; -;; - Functions to automatically adjust and cycle the section underline -;; decorations; -;; - A mode that displays the table of contents and allows you to jump anywhere -;; from it; -;; - Functions to insert and automatically update a TOC in your source document; -;; - A mode which supports font-lock highlighting of reStructuredText -;; structures; -;; - Some other convenience functions. -;; -;; See the accompanying document in the docutils documentation about -;; the contents of this package and how to use it. -;; -;; For more information about reStructuredText, see -;; http://docutils.sourceforge.net/rst.html +;;; ================================================ +;;; rst.el -- ReStructuredText Support for Emacs +;;; ================================================ +;;; +;;; :Authors: Martin Blais , +;;; Stefan Merten , +;;; David Goodger +;;; :Date: $Date$ +;;; :Copyright: This module has been placed in the public domain. +;;; :Abstract: +;;; +;;; Support code for editing reStructuredText with Emacs. The latest version +;;; of this file lies in the docutils source code repository. +;;; +;;; Description +;;; =========== +;;; +;;; Basically, this package contains: +;;; +;;; - Functions to automatically adjust and cycle the section underline +;;; decorations; +;;; - A mode that displays the table of contents and allows you to jump anywhere +;;; from it; +;;; - Functions to insert and automatically update a TOC in your source document; +;;; - A mode which supports font-lock highlighting of reStructuredText +;;; structures; +;;; - Some other convenience functions. +;;; +;;; See the accompanying document in the docutils documentation about +;;; the contents of this package and how to use it. +;;; +;;; For more information about reStructuredText, see +;;; http://docutils.sourceforge.net/rst.html +;;; +;;; For full details on how to use the contents of this file, see +;;; http://docutils.sourceforge.net/docs/user/emacs.html +;;; +;;; Download +;;; ======== +;;; +;;; Click `Here `_ for download. +;;; +;;; END ;; ;; **IMPORTANT NOTE TO PACKAGERS**: this package is the result of merging: ;; @@ -120,6 +140,8 @@ ;; ;; Other ;; ----- +;; - We should rename "adornment" to "decoration" or vice-versa in this +;; document. ;; - Add an option to forego using the file structure in order to make ;; suggestion, and to always use the preferred decorations to do that. ;; -- cgit v1.2.1 From f43d60fa3d795ad3e2f7c7986cb76e2e450905cc Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 30 Oct 2005 22:08:45 +0000 Subject: added some file types git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3987 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 95e54800a..568e3c6c9 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -115,8 +115,12 @@ correct properties set:: *.html = svn:eol-style=native;svn:keywords=Author Date Id Revision *.xml = svn:eol-style=native;svn:keywords=Author Date Id Revision *.tex = svn:eol-style=native;svn:keywords=Author Date Id Revision + *.css = svn:eol-style=native;svn:keywords=Author Date Id Revision + *.patch = svn:eol-style=native *.sh = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id Revision *.png = svn:mime-type=image/png + *.jpg = svn:mime-type=image/jpeg + *.gif = svn:mime-type=image/gif Setting Up SSH Access -- cgit v1.2.1 From c5d1c54efe5b99787489f44e9fc60c78cb465e50 Mon Sep 17 00:00:00 2001 From: blais Date: Sun, 30 Oct 2005 22:58:09 +0000 Subject: Changed rst-html-compile to be generic and support multiple toolsets. The group now starts with rst-compile and the function rst-compile replaces rst-html-compile. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3988 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 22 +- tools/editors/emacs/rst.el | 1171 ++++++++++++++++++++++---------------------- 2 files changed, 606 insertions(+), 587 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index b0ff38ee0..ba21da05f 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -286,17 +286,21 @@ customizable faces). Converting Documents from Emacs =============================== -At the moment there is minimal support for calling ``rst2html.py`` from within -Emacs. You can add a key binding like this to invoke it:: +At the moment there is minimal support for calling the conversion tools from +within Emacs. You can add a key binding like this to invoke it:: - (local-set-key [(control c)(?9)] 'rst-html-compile) + (local-set-key [(control c)(?9)] 'rst-compile) -This function basically creates a compilation command with the correct HTML -output name for the current buffer and then invokes Emacs' compile function. It -also looks for the presence of a ``docutils.conf`` configuration file in the -parent directories and adds it to the cmdline options. You can customize which -tool is used to perform the conversion and some standard options to always be -added as well. +This function basically creates a compilation command with the correct output +name for the current buffer and then invokes Emacs' compile function. It also +looks for the presence of a ``docutils.conf`` configuration file in the parent +directories and adds it to the cmdline options. You can customize which tool is +used to perform the conversion and some standard options to always be added as +well. + +Invocation uses the toolset indicated by ``rst-compile-primary-toolset`` +(default is ``'html``). Invocation with a prefix argument uses +``rst-compile-secondary-toolset``. .. note:: diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 5fb0aa6d7..68179e73c 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -11,12 +11,12 @@ ;;; ;;; Support code for editing reStructuredText with Emacs. The latest version ;;; of this file lies in the docutils source code repository. -;;; +;;; ;;; Description ;;; =========== ;;; ;;; Basically, this package contains: -;;; +;;; ;;; - Functions to automatically adjust and cycle the section underline ;;; decorations; ;;; - A mode that displays the table of contents and allows you to jump anywhere @@ -25,10 +25,10 @@ ;;; - A mode which supports font-lock highlighting of reStructuredText ;;; structures; ;;; - Some other convenience functions. -;;; +;;; ;;; See the accompanying document in the docutils documentation about ;;; the contents of this package and how to use it. -;;; +;;; ;;; For more information about reStructuredText, see ;;; http://docutils.sourceforge.net/rst.html ;;; @@ -98,7 +98,7 @@ ;; There is a special mode that you can setup if you want to have syntax ;; highlighting. The mode is based on `text-mode' and inherits some things from ;; it. Particularly `text-mode-hook' is run before `rst-mode-hook'. -;; +;; ;; Add the following lines to your `.emacs' file: ;; ;; (setq auto-mode-alist @@ -303,13 +303,13 @@ decorations." :version "21.1") (defcustom rst-preferred-decorations '( (?= over-and-under 1) - (?= simple 0) - (?- simple 0) - (?~ simple 0) - (?+ simple 0) - (?` simple 0) - (?# simple 0) - (?@ simple 0) ) + (?= simple 0) + (?- simple 0) + (?~ simple 0) + (?+ simple 0) + (?` simple 0) + (?# simple 0) + (?@ simple 0) ) "Preferred ordering of section title decorations. This sequence is consulted to offer a new decoration suggestion when we rotate the underlines at the end of the existing hierarchy @@ -360,7 +360,7 @@ decorations." (save-excursion (beginning-of-line) (if (looking-at "^[ \t]+") - nil + nil (rst-line-homogeneous-p accept-special) ))) @@ -394,23 +394,23 @@ have been seen. ;; For all the preferred decorations... (let* ( - ;; If 'prev' is given, reorder the list to start searching after the - ;; match. - (fplist - (cdr (rst-get-decoration-match rst-preferred-decorations prev))) + ;; If 'prev' is given, reorder the list to start searching after the + ;; match. + (fplist + (cdr (rst-get-decoration-match rst-preferred-decorations prev))) - ;; List of candidates to search. - (curpotential (append fplist rst-preferred-decorations))) + ;; List of candidates to search. + (curpotential (append fplist rst-preferred-decorations))) (while - ;; For all the decorations... - (let ((cur alldecos) - found) - (while (and cur (not found)) - (if (rst-compare-decorations (car cur) (car curpotential)) - ;; Found it! - (setq found (car curpotential)) - (setq cur (cdr cur)))) - found) + ;; For all the decorations... + (let ((cur alldecos) + found) + (while (and cur (not found)) + (if (rst-compare-decorations (car cur) (car curpotential)) + ;; Found it! + (setq found (car curpotential)) + (setq cur (cdr cur)))) + found) (setq curpotential (cdr curpotential))) @@ -456,10 +456,10 @@ have been seen. ;; Remove previous line if it consists only of a single repeated character (save-excursion (forward-line -1) - (and (rst-line-homogeneous-p 1) - ;; Avoid removing the underline of a title right above us. - (save-excursion (forward-line -1) - (not (looking-at rst-section-text-regexp))) + (and (rst-line-homogeneous-p 1) + ;; Avoid removing the underline of a title right above us. + (save-excursion (forward-line -1) + (not (looking-at rst-section-text-regexp))) (rst-delete-line))) ;; Remove following line if it consists only of a single repeated @@ -612,21 +612,21 @@ have been seen. (beginning-of-line) (if (looking-at rst-section-text-regexp) (let* ((over (save-excursion - (forward-line -1) - (rst-line-homogeneous-nodent-p))) - - (under (save-excursion - (forward-line +1) - (rst-line-homogeneous-nodent-p))) - ) - - ;; Check that the line above the overline is not part of a title - ;; above it. - (if (and over - (save-excursion - (and (equal (forward-line -2) 0) - (looking-at rst-section-text-regexp)))) - (setq over nil)) + (forward-line -1) + (rst-line-homogeneous-nodent-p))) + + (under (save-excursion + (forward-line +1) + (rst-line-homogeneous-nodent-p))) + ) + + ;; Check that the line above the overline is not part of a title + ;; above it. + (if (and over + (save-excursion + (and (equal (forward-line -2) 0) + (looking-at rst-section-text-regexp)))) + (setq over nil)) (cond ;; No decoration found, leave all return values nil. @@ -662,18 +662,18 @@ have been seen. find the decorations before and after the given point. A list of the previous and next decorations is returned." (let* ((all (or alldecos (rst-find-all-decorations))) - (curline (line-number-at-pos)) - prev next - (cur all)) + (curline (line-number-at-pos)) + prev next + (cur all)) ;; Search for the decorations around the current line. (while (and cur (< (caar cur) curline)) (setq prev cur - cur (cdr cur))) + cur (cdr cur))) ;; 'cur' is the following decoration. (if (and cur (caar cur)) - (setq next (if (= curline (caar cur)) (cdr cur) cur))) + (setq next (if (= curline (caar cur)) (cdr cur) cur))) (mapcar 'cdar (list prev next)) )) @@ -714,27 +714,27 @@ A list of the previous and next decorations is returned." and suggesting for new decoration SUGGESTION." (let* ( - (char (car curdeco)) - (style (cadr curdeco)) - - ;; Build a new list of decorations for the rotation. - (rotdecos - (append hier - ;; Suggest a new decoration. - (list suggestion - ;; If nothing to suggest, use first decoration. - (car hier)))) ) + (char (car curdeco)) + (style (cadr curdeco)) + + ;; Build a new list of decorations for the rotation. + (rotdecos + (append hier + ;; Suggest a new decoration. + (list suggestion + ;; If nothing to suggest, use first decoration. + (car hier)))) ) (or ;; Search for next decoration. (cadr (let ((cur (if reverse-direction rotdecos - (reverse rotdecos))) - found) - (while (and cur - (not (and (eq char (caar cur)) - (eq style (cadar cur))))) - (setq cur (cdr cur))) - cur)) + (reverse rotdecos))) + found) + (while (and cur + (not (and (eq char (caar cur)) + (eq style (cadar cur))))) + (setq cur (cdr cur))) + cur)) ;; If not found, take the first of all decorations. suggestion @@ -775,18 +775,18 @@ b. a negative numerical argument, which generally inverts the (interactive) (let* ( ;; Parse the positive and negative prefix arguments. - (reverse-direction - (and current-prefix-arg - (< (prefix-numeric-value current-prefix-arg) 0))) - (toggle-style - (and current-prefix-arg (not reverse-direction)))) + (reverse-direction + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0))) + (toggle-style + (and current-prefix-arg (not reverse-direction)))) (if (and transient-mark-mode mark-active) - ;; Adjust decorations within region. - (rst-promote-region current-prefix-arg) + ;; Adjust decorations within region. + (rst-promote-region current-prefix-arg) ;; Adjust decoration around point. (rst-adjust-decoration toggle-style reverse-direction)) - + ;; Run the hooks to run after adjusting. (run-hooks 'rst-adjust-hook) @@ -962,11 +962,11 @@ of the right hand fingers and the binding is unused in text-mode." ;; arguments of the function. (if current-prefix-arg (setq reverse-direction - (and current-prefix-arg - (< (prefix-numeric-value current-prefix-arg) 0)) + (and current-prefix-arg + (< (prefix-numeric-value current-prefix-arg) 0)) - toggle-style - (and current-prefix-arg (not reverse-direction)))) + toggle-style + (and current-prefix-arg (not reverse-direction)))) (let* (;; Check if we're on an underline around a section title, and move the ;; cursor to the title if this is the case. @@ -978,102 +978,102 @@ of the right hand fingers and the binding is unused in text-mode." (style (cadr curdeco)) (indent (caddr curdeco)) - ;; New values to be computed. - char-new style-new indent-new + ;; New values to be computed. + char-new style-new indent-new ) ;; We've moved the cursor... if we're not looking at some text, we have ;; nothing to do. (if (save-excursion (beginning-of-line) (looking-at rst-section-text-regexp)) - (progn - (cond - ;;--------------------------------------------------------------------- - ;; Case 1: No Decoration - ((and (eq char nil) (eq style nil)) - - (let* ((alldecos (rst-find-all-decorations)) - - (around (rst-get-decorations-around alldecos)) - (prev (car around)) - cur - - (hier (rst-get-hierarchy alldecos)) - ) - - ;; Advance one level down. - (setq cur - (if prev - (if (not reverse-direction) - (or (cadr (rst-get-decoration-match hier prev)) - (rst-suggest-new-decoration hier prev)) - prev) - (copy-list (car rst-preferred-decorations)) - )) - - ;; Invert the style if requested. - (if toggle-style - (setcar (cdr cur) (if (eq (cadr cur) 'simple) - 'over-and-under 'simple)) ) - - (setq char-new (car cur) - style-new (cadr cur) - indent-new (caddr cur)) - )) - - ;;--------------------------------------------------------------------- - ;; Case 2: Incomplete Decoration - ((not (rst-decoration-complete-p curdeco)) - - ;; Invert the style if requested. - (if toggle-style - (setq style (if (eq style 'simple) 'over-and-under 'simple))) + (progn + (cond + ;;--------------------------------------------------------------------- + ;; Case 1: No Decoration + ((and (eq char nil) (eq style nil)) + + (let* ((alldecos (rst-find-all-decorations)) + + (around (rst-get-decorations-around alldecos)) + (prev (car around)) + cur + + (hier (rst-get-hierarchy alldecos)) + ) + + ;; Advance one level down. + (setq cur + (if prev + (if (not reverse-direction) + (or (cadr (rst-get-decoration-match hier prev)) + (rst-suggest-new-decoration hier prev)) + prev) + (copy-list (car rst-preferred-decorations)) + )) + + ;; Invert the style if requested. + (if toggle-style + (setcar (cdr cur) (if (eq (cadr cur) 'simple) + 'over-and-under 'simple)) ) + + (setq char-new (car cur) + style-new (cadr cur) + indent-new (caddr cur)) + )) + + ;;--------------------------------------------------------------------- + ;; Case 2: Incomplete Decoration + ((not (rst-decoration-complete-p curdeco)) + + ;; Invert the style if requested. + (if toggle-style + (setq style (if (eq style 'simple) 'over-and-under 'simple))) (setq char-new char - style-new style - indent-new indent)) + style-new style + indent-new indent)) - ;;--------------------------------------------------------------------- - ;; Case 3: Complete Existing Decoration - (t - (if toggle-style + ;;--------------------------------------------------------------------- + ;; Case 3: Complete Existing Decoration + (t + (if toggle-style - ;; Simply switch the style of the current decoration. - (setq char-new char - style-new (if (eq style 'simple) 'over-and-under 'simple) - indent-new rst-default-indent) + ;; Simply switch the style of the current decoration. + (setq char-new char + style-new (if (eq style 'simple) 'over-and-under 'simple) + indent-new rst-default-indent) - ;; Else, we rotate, ignoring the decoration around the current - ;; line... - (let* ((alldecos (rst-find-all-decorations)) + ;; Else, we rotate, ignoring the decoration around the current + ;; line... + (let* ((alldecos (rst-find-all-decorations)) - (hier (rst-get-hierarchy alldecos (line-number-at-pos))) + (hier (rst-get-hierarchy alldecos (line-number-at-pos))) - ;; Suggestion, in case we need to come up with something - ;; new - (suggestion (rst-suggest-new-decoration - hier - (car (rst-get-decorations-around alldecos)))) + ;; Suggestion, in case we need to come up with something + ;; new + (suggestion (rst-suggest-new-decoration + hier + (car (rst-get-decorations-around alldecos)))) - (nextdeco (rst-get-next-decoration - curdeco hier suggestion reverse-direction)) + (nextdeco (rst-get-next-decoration + curdeco hier suggestion reverse-direction)) - ) + ) - ;; Indent, if present, always overrides the prescribed indent. - (setq char-new (car nextdeco) - style-new (cadr nextdeco) - indent-new (caddr nextdeco)) + ;; Indent, if present, always overrides the prescribed indent. + (setq char-new (car nextdeco) + style-new (cadr nextdeco) + indent-new (caddr nextdeco)) - ))) - ) + ))) + ) - ;; Override indent with present indent! - (setq indent-new (if (> indent 0) indent indent-new)) + ;; Override indent with present indent! + (setq indent-new (if (> indent 0) indent indent-new)) - (if (and char-new style-new) - (rst-update-section char-new style-new indent-new)) - )) + (if (and char-new style-new) + (rst-update-section char-new style-new indent-new)) + )) ;; Correct the position of the cursor to more accurately reflect where it @@ -1097,17 +1097,17 @@ the hierarchy is similar to that used by rst-adjust-decoration." (interactive) (let* ((demote (or current-prefix-arg demote)) - (alldecos (rst-find-all-decorations)) - (cur alldecos) + (alldecos (rst-find-all-decorations)) + (cur alldecos) - (hier (rst-get-hierarchy alldecos)) - (suggestion (rst-suggest-new-decoration hier)) + (hier (rst-get-hierarchy alldecos)) + (suggestion (rst-suggest-new-decoration hier)) - (region-begin-line (line-number-at-pos (region-beginning))) - (region-end-line (line-number-at-pos (region-end))) + (region-begin-line (line-number-at-pos (region-beginning))) + (region-end-line (line-number-at-pos (region-end))) - marker-list - ) + marker-list + ) ;; Skip the markers that come before the region beginning (while (and cur (< (caar cur) region-begin-line)) @@ -1117,28 +1117,28 @@ the hierarchy is similar to that used by rst-adjust-decoration." ;; the region. (save-excursion (let (m line) - (while (and cur (< (setq line (caar cur)) region-end-line)) - (setq m (make-marker)) - (goto-line line) - (push (list (set-marker m (point)) (cdar cur)) marker-list) - (setq cur (cdr cur)) )) + (while (and cur (< (setq line (caar cur)) region-end-line)) + (setq m (make-marker)) + (goto-line line) + (push (list (set-marker m (point)) (cdar cur)) marker-list) + (setq cur (cdr cur)) )) ;; Apply modifications. (let (nextdeco) - (dolist (p marker-list) - ;; Go to the decoration to promote. - (goto-char (car p)) + (dolist (p marker-list) + ;; Go to the decoration to promote. + (goto-char (car p)) - ;; Rotate the next decoration. - (setq nextdeco (rst-get-next-decoration - (cadr p) hier suggestion demote)) + ;; Rotate the next decoration. + (setq nextdeco (rst-get-next-decoration + (cadr p) hier suggestion demote)) - ;; Update the decoration. - (apply 'rst-update-section nextdeco) + ;; Update the decoration. + (apply 'rst-update-section nextdeco) - ;; Clear marker to avoid slowing down the editing after we're done. - (set-marker (car p) nil) - )) + ;; Clear marker to avoid slowing down the editing after we're done. + (set-marker (car p) nil) + )) (setq deactivate-mark nil) ))) @@ -1175,7 +1175,7 @@ the hierarchy is similar to that used by rst-adjust-decoration." "Returns the line at cursor, stripped from whitespace." (re-search-forward "\\S-.*\\S-" (line-end-position)) (buffer-substring-no-properties (match-beginning 0) - (match-end 0)) ) + (match-end 0)) ) (defun rst-section-tree (alldecos) "Returns a pair of a hierarchical tree of the sections titles @@ -1190,28 +1190,28 @@ If there are missing section levels, the section titles are inserted automatically, and are set to nil." (let* (thelist - (hier (rst-get-hierarchy alldecos)) - (levels (make-hash-table :test 'equal :size 10)) - lines) + (hier (rst-get-hierarchy alldecos)) + (levels (make-hash-table :test 'equal :size 10)) + lines) (let ((lev 0)) (dolist (deco hier) - (puthash deco lev levels) - (incf lev))) + (puthash deco lev levels) + (incf lev))) ;; Create a list of lines that contains (text, level, marker) for each ;; decoration. (save-excursion (setq lines - (mapcar (lambda (deco) - (goto-line (car deco)) - (list (gethash (cdr deco) levels) - (rst-get-stripped-line) - (let ((m (make-marker))) - (beginning-of-line 1) - (set-marker m (point))) - )) - alldecos))) + (mapcar (lambda (deco) + (goto-line (car deco)) + (list (gethash (cdr deco) levels) + (rst-get-stripped-line) + (let ((m (make-marker))) + (beginning-of-line 1) + (set-marker m (point))) + )) + alldecos))) (let ((lcontnr (cons nil lines))) (rst-section-tree-rec lcontnr -1)))) @@ -1226,21 +1226,21 @@ inserted automatically, and are set to nil." destructively." (let ((ndeco (cadr decos)) - node - children) + node + children) ;; If the next decoration matches our level (if (= (car ndeco) lev) - (progn - ;; Pop the next decoration and create the current node with it - (setcdr decos (cddr decos)) - (setq node (cdr ndeco)) )) + (progn + ;; Pop the next decoration and create the current node with it + (setcdr decos (cddr decos)) + (setq node (cdr ndeco)) )) ;; Else we let the node title/marker be unset. ;; Build the child nodes (while (and (cdr decos) (> (caadr decos) lev)) (setq children - (cons (rst-section-tree-rec decos (1+ lev)) - children))) + (cons (rst-section-tree-rec decos (1+ lev)) + children))) ;; Return this node with its children. (cons node (reverse children)) @@ -1261,32 +1261,32 @@ The TOC is inserted indented at the current column." (interactive "P") (let* (;; Check maximum level override - (rst-toc-insert-max-level - (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) - (prefix-numeric-value pfxarg) rst-toc-insert-max-level)) - - ;; Get the section tree. - (sectree (rst-section-tree (rst-find-all-decorations))) - - ;; If there is only one top-level title, remove it by starting to print - ;; one index lower (revert this behaviour with the prefix arg), - ;; otherwise print all. - (gen-pfx-arg (or (and pfxarg (listp pfxarg)) - (and (integerp pfxarg) - (= (prefix-numeric-value pfxarg) 0)))) - (start-lev (if (and (not rst-toc-insert-always-include-top) - (= (length (cdr sectree)) 1) - (not gen-pfx-arg)) -1 0)) - - ;; Figure out initial indent. - (initial-indent (make-string (current-column) ? )) - (init-point (point))) + (rst-toc-insert-max-level + (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) + (prefix-numeric-value pfxarg) rst-toc-insert-max-level)) + + ;; Get the section tree. + (sectree (rst-section-tree (rst-find-all-decorations))) + + ;; If there is only one top-level title, remove it by starting to print + ;; one index lower (revert this behaviour with the prefix arg), + ;; otherwise print all. + (gen-pfx-arg (or (and pfxarg (listp pfxarg)) + (and (integerp pfxarg) + (= (prefix-numeric-value pfxarg) 0)))) + (start-lev (if (and (not rst-toc-insert-always-include-top) + (= (length (cdr sectree)) 1) + (not gen-pfx-arg)) -1 0)) + + ;; Figure out initial indent. + (initial-indent (make-string (current-column) ? )) + (init-point (point))) (rst-toc-insert-node sectree start-lev initial-indent "") ;; Fixup for the first line. (delete-region init-point (+ init-point (length initial-indent))) - + ;; Delete the last newline added. (delete-backward-char 1) )) @@ -1337,69 +1337,69 @@ indentation style: toc. PFX is the prefix numbering, that includes the alignment necessary for all the children of this level to align." (let ((do-print (> level 0)) - (count 1) - b) + (count 1) + b) (if do-print - (progn - (insert indent) - (let ((b (point))) - (if (not (equal rst-toc-insert-style 'plain)) - (insert pfx rst-toc-insert-number-separator)) - (insert (or (caar node) "[missing node]")) - ;; Add properties to the text, even though in normal text mode it - ;; won't be doing anything for now. Not sure that I want to change - ;; mode stuff. At least the highlighting gives the idea that this - ;; is generated automatically. - (put-text-property b (point) 'mouse-face 'highlight) - (put-text-property b (point) 'rst-toc-target (cadar node)) - (put-text-property b (point) 'keymap rst-toc-insert-click-keymap) - - ) - (insert "\n") - - ;; Prepare indent for children. - (setq indent - (cond - ((eq rst-toc-insert-style 'plain) - (concat indent rst-toc-indent)) - - ((eq rst-toc-insert-style 'fixed) - (concat indent (make-string rst-toc-indent ? ))) - - ((eq rst-toc-insert-style 'aligned) - (concat indent (make-string (+ (length pfx) 2) ? ))) - - ((eq rst-toc-insert-style 'listed) - (concat (substring indent 0 -3) - (concat (make-string (+ (length pfx) 2) ? ) " - "))) - )) - - )) + (progn + (insert indent) + (let ((b (point))) + (if (not (equal rst-toc-insert-style 'plain)) + (insert pfx rst-toc-insert-number-separator)) + (insert (or (caar node) "[missing node]")) + ;; Add properties to the text, even though in normal text mode it + ;; won't be doing anything for now. Not sure that I want to change + ;; mode stuff. At least the highlighting gives the idea that this + ;; is generated automatically. + (put-text-property b (point) 'mouse-face 'highlight) + (put-text-property b (point) 'rst-toc-target (cadar node)) + (put-text-property b (point) 'keymap rst-toc-insert-click-keymap) + + ) + (insert "\n") + + ;; Prepare indent for children. + (setq indent + (cond + ((eq rst-toc-insert-style 'plain) + (concat indent rst-toc-indent)) + + ((eq rst-toc-insert-style 'fixed) + (concat indent (make-string rst-toc-indent ? ))) + + ((eq rst-toc-insert-style 'aligned) + (concat indent (make-string (+ (length pfx) 2) ? ))) + + ((eq rst-toc-insert-style 'listed) + (concat (substring indent 0 -3) + (concat (make-string (+ (length pfx) 2) ? ) " - "))) + )) + + )) (if (or (eq rst-toc-insert-max-level nil) - (< level rst-toc-insert-max-level)) - (let ((do-child-numbering (>= level 0)) - fmt) - (if do-child-numbering - (progn - ;; Add a separating dot if there is already a prefix - (if (> (length pfx) 0) - (setq pfx (concat (rst-rstrip pfx) "."))) - - ;; Calculate the amount of space that the prefix will require for - ;; the numbers. - (if (cdr node) - (setq fmt (format "%%-%dd" - (1+ (floor (log10 (length (cdr node)))))))) - )) - - (dolist (child (cdr node)) - (rst-toc-insert-node child - (1+ level) - indent - (if do-child-numbering - (concat pfx (format fmt count)) pfx)) - (incf count))) + (< level rst-toc-insert-max-level)) + (let ((do-child-numbering (>= level 0)) + fmt) + (if do-child-numbering + (progn + ;; Add a separating dot if there is already a prefix + (if (> (length pfx) 0) + (setq pfx (concat (rst-rstrip pfx) "."))) + + ;; Calculate the amount of space that the prefix will require for + ;; the numbers. + (if (cdr node) + (setq fmt (format "%%-%dd" + (1+ (floor (log10 (length (cdr node)))))))) + )) + + (dolist (child (cdr node)) + (rst-toc-insert-node child + (1+ level) + indent + (if do-child-numbering + (concat pfx (format fmt count)) pfx)) + (incf count))) ))) @@ -1420,27 +1420,27 @@ delete that region. Return t if found and the cursor is left after the comment." ;; [more lines] ;; (let ((beg - (re-search-forward "^\\.\\. contents[ \t]*::\\(.*\\)\n\\.\\." - nil t)) - last-real) + (re-search-forward "^\\.\\. contents[ \t]*::\\(.*\\)\n\\.\\." + nil t)) + last-real) (when beg ;; Look for the first line that starts at the first column. (forward-line 1) (beginning-of-line) (while (or (and (looking-at "[ \t]+[^ \t]") - (setq last-real (point)) t) - (looking-at "\\s-*$")) - (forward-line 1) - ) + (setq last-real (point)) t) + (looking-at "\\s-*$")) + (forward-line 1) + ) (if last-real - (progn - (goto-char last-real) - (end-of-line) - (delete-region beg (point))) - (goto-char beg)) + (progn + (goto-char last-real) + (end-of-line) + (delete-region beg (point))) + (goto-char beg)) t ))) - + (defun rst-toc-insert-update () "Automatically find the .. contents:: section of a document and update the inserted TOC if present. You can use this in your file-write hook to always @@ -1448,8 +1448,8 @@ make it up-to-date automatically." (interactive) (save-excursion (if (rst-toc-insert-find-delete-contents) - (progn (insert "\n ") - (rst-toc-insert))) ) + (progn (insert "\n ") + (rst-toc-insert))) ) ;; Note: always return nil, because this may be used as a hook. ) @@ -1461,17 +1461,17 @@ make it up-to-date automatically." (if (> level 0) (let ((b (point))) - ;; Insert line text. - (insert (make-string (* rst-toc-indent (1- level)) ? )) - (insert (if (car node) (caar node) "[missing node]")) + ;; Insert line text. + (insert (make-string (* rst-toc-indent (1- level)) ? )) + (insert (if (car node) (caar node) "[missing node]")) - ;; Highlight lines. - (put-text-property b (point) 'mouse-face 'highlight) + ;; Highlight lines. + (put-text-property b (point) 'mouse-face 'highlight) - ;; Add link on lines. - (put-text-property b (point) 'rst-toc-target (cadar node)) + ;; Add link on lines. + (put-text-property b (point) 'rst-toc-target (cadar node)) - (insert "\n"))) + (insert "\n"))) (dolist (child (cdr node)) (rst-toc-node child (1+ level)))) @@ -1487,24 +1487,24 @@ make it up-to-date automatically." brings the cursor in that section." (interactive) (let* ((curbuf (current-buffer)) - outline + outline - ;; Get the section tree - (alldecos (rst-find-all-decorations)) - (sectree (rst-section-tree alldecos)) + ;; Get the section tree + (alldecos (rst-find-all-decorations)) + (sectree (rst-section-tree alldecos)) - ;; Create a temporary buffer. - (buf (get-buffer-create rst-toc-buffer-name)) - ) + ;; Create a temporary buffer. + (buf (get-buffer-create rst-toc-buffer-name)) + ) ;; Find the index of the section where the cursor currently is. (setq outline (let ((idx 1) - (curline (line-number-at-pos (point))) - (decos alldecos)) - (while (and decos (<= (caar decos) curline)) - (setq decos (cdr decos)) - (incf idx)) - idx)) + (curline (line-number-at-pos (point))) + (decos alldecos)) + (while (and decos (<= (caar decos) curline)) + (setq decos (cdr decos)) + (incf idx)) + idx)) ;; FIXME: if there is a missing node inserted, the calculation of the ;; current line will be off. You need to fix this by moving the finding of ;; the current line somewhere else. @@ -1512,13 +1512,13 @@ make it up-to-date automatically." (with-current-buffer buf (let ((inhibit-read-only t)) - (rst-toc-mode) - (delete-region (point-min) (point-max)) - (insert (format "Table of Contents: %s\n" (or (caar sectree) ""))) - (put-text-property (point-min) (point) - 'face (list '(background-color . "lightgray"))) - (rst-toc-node sectree 0) - )) + (rst-toc-mode) + (delete-region (point-min) (point-max)) + (insert (format "Table of Contents: %s\n" (or (caar sectree) ""))) + (put-text-property (point-min) (point) + 'face (list '(background-color . "lightgray"))) + (rst-toc-node sectree 0) + )) (display-buffer buf) (pop-to-buffer buf) @@ -1557,8 +1557,8 @@ make it up-to-date automatically." (save-excursion (set-buffer (window-buffer (posn-window (event-end event)))) (save-excursion - (goto-char (posn-point (event-end event))) - (setq pos (rst-toc-mode-find-section)))) + (goto-char (posn-point (event-end event))) + (setq pos (rst-toc-mode-find-section)))) (pop-to-buffer (marker-buffer pos)) (goto-char pos))) @@ -1614,18 +1614,18 @@ make it up-to-date automatically." backwards in the file (default is to use 1)." (interactive) (let* (;; Default value for offset. - (offset (or offset 1)) + (offset (or offset 1)) - ;; Get all the decorations in the file, with their line numbers. - (alldecos (rst-find-all-decorations)) + ;; Get all the decorations in the file, with their line numbers. + (alldecos (rst-find-all-decorations)) - ;; Get the current line. - (curline (line-number-at-pos)) + ;; Get the current line. + (curline (line-number-at-pos)) - (cur alldecos) - (idx 0) - line - ) + (cur alldecos) + (idx 0) + line + ) ;; Find the index of the "next" decoration w.r.t. to the current line. (while (and cur (< (caar cur) curline)) @@ -1634,7 +1634,7 @@ make it up-to-date automatically." ;; 'cur' is the decoration on or following the current line. (if (and (> offset 0) cur (= (caar cur) curline)) - (incf idx)) + (incf idx)) ;; Find the final index. (setq idx (+ idx (if (> offset 0) (- offset 1) offset))) @@ -1643,7 +1643,7 @@ make it up-to-date automatically." ;; If the index is positive, goto the line, otherwise go to the buffer ;; boundaries. (if (and cur (>= idx 0)) - (goto-line (car cur)) + (goto-line (car cur)) (if (> offset 0) (end-of-buffer) (beginning-of-buffer))) )) @@ -1663,18 +1663,18 @@ make it up-to-date automatically." "Indent region ridigly, by two characters to the right." (interactive) (indent-rigidly (region-beginning) (region-end) 2)) - + (defun rst-find-leftmost-column (beg end) "Finds the leftmost column in the region." (let ((mincol 1000)) (save-excursion (goto-char beg) (while (< (point) end) - (back-to-indentation) - (if (not (looking-at "[ \t]*$")) - (setq mincol (min mincol (current-column)))) - (forward-line 1) - )) + (back-to-indentation) + (if (not (looking-at "[ \t]*$")) + (setq mincol (min mincol (current-column)))) + (forward-line 1) + )) mincol)) (defun rst-shift-region-left (pfxarg) @@ -1683,9 +1683,9 @@ If invoked with a prefix arg, the entire indentation is removed, up to the leftmost character in the region." (interactive "P") (let ((chars - (if pfxarg - (- (rst-find-leftmost-column (region-beginning) (region-end))) - -2))) + (if pfxarg + (- (rst-find-leftmost-column (region-beginning) (region-end))) + -2))) (indent-rigidly (region-beginning) (region-end) chars))) @@ -1794,11 +1794,11 @@ The value of this variable is used when Rst Mode is turned on." (let ((i 1)) (while (<= i rst-level-face-max) (let ((sym (intern (format "rst-level-%d-face" i))) - (doc (format "Face for showing section title text at level %d" i)) - (col (format (concat "%s" rst-level-face-format-light) - rst-level-face-base-color - (+ (* (1- i) rst-level-face-step-light) - rst-level-face-base-light)))) + (doc (format "Face for showing section title text at level %d" i)) + (col (format (concat "%s" rst-level-face-format-light) + rst-level-face-base-color + (+ (* (1- i) rst-level-face-step-light) + rst-level-face-base-light)))) (make-empty-face sym) (set-face-doc-string sym doc) (set-face-background sym col) @@ -1819,8 +1819,8 @@ section title text of that level), t (for transitions) or nil (for section title adornment)." :group 'rst-faces :type '(alist :key-type (choice (integer :tag "Section level") - (boolean :tag "transitions (on) / section title adornment (off)")) - :value-type (face))) + (boolean :tag "transitions (on) / section title adornment (off)")) + :value-type (face))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1896,9 +1896,9 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and ;; Font lock (set (make-local-variable 'font-lock-defaults) '(rst-font-lock-keywords-function - t nil nil nil - (font-lock-multiline . t) - (font-lock-mark-block-function . mark-paragraph))) + t nil nil nil + (font-lock-multiline . t) + (font-lock-mark-block-function . mark-paragraph))) (when (boundp 'font-lock-support-mode) ;; rst-mode has its own mind about font-lock-support-mode (make-local-variable 'font-lock-support-mode) @@ -1906,16 +1906,16 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and ((and (not rst-mode-lazy) (not font-lock-support-mode))) ;; No support mode set and none required - leave it alone ((or (not font-lock-support-mode) ;; No support mode set (but required) - (symbolp font-lock-support-mode)) ;; or a fixed mode for all + (symbolp font-lock-support-mode)) ;; or a fixed mode for all (setq font-lock-support-mode - (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) - (cons t font-lock-support-mode)))) + (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) + (cons t font-lock-support-mode)))) ((and (listp font-lock-support-mode) - (not (assoc 'rst-mode font-lock-support-mode))) + (not (assoc 'rst-mode font-lock-support-mode))) ;; A list of modes missing rst-mode (setq font-lock-support-mode - (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) - font-lock-support-mode))))) + (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) + font-lock-support-mode))))) ;; Names and hooks (setq mode-name "reST") @@ -1931,54 +1931,54 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and ;; The reST links in the comments below all relate to sections in ;; http://docutils.sourceforge.net/rst.html (let* ( ;; This gets big - so let's define some abbreviations - ;; horizontal white space - (re-hws "[\t ]") - ;; beginning of line with possible indentation - (re-bol (concat "^" re-hws "*")) - ;; Separates block lead-ins from their content - (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) - ;; explicit markup tag - (re-emt "\\.\\.") - ;; explicit markup start - (re-ems (concat re-emt re-hws "+")) - ;; inline markup prefix - (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) - ;; symbol character - (re-sym1 "\\(\\sw\\|\\s_\\)") - ;; inline markup content begin - (re-imbeg2 "\\(\\S \\|\\S \\([^") - - ;; There seems to be a bug leading to error "Stack overflow in regexp - ;; matcher" when "|" or "\\*" are the characters searched for - (re-imendbeg - (if (< emacs-major-version 21) - "]" - "\\]\\|\\\\.")) - ;; inline markup content end - (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) - ;; inline markup content without asterisk - (re-ima2 (concat re-imbeg2 "*" re-imend)) - ;; inline markup content without backquote - (re-imb2 (concat re-imbeg2 "`" re-imend)) - ;; inline markup content without vertical bar - (re-imv2 (concat re-imbeg2 "|" re-imend)) - ;; Supported URI schemes - (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") - ;; Line starting with adornment and optional whitespace; complete - ;; adornment is in (match-string 1); there must be at least 3 - ;; characters because otherwise explicit markup start would be - ;; recognized - (re-ado2 (concat "^\\(\\([" - (if (or - (< emacs-major-version 21) - (save-match-data - (string-match "XEmacs\\|Lucid" emacs-version))) - "^a-zA-Z0-9 \t\x00-\x1F" - "^[:word:][:space:][:cntrl:]") - "]\\)\\2\\2+\\)" re-hws "*$")) - ) + ;; horizontal white space + (re-hws "[\t ]") + ;; beginning of line with possible indentation + (re-bol (concat "^" re-hws "*")) + ;; Separates block lead-ins from their content + (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) + ;; explicit markup tag + (re-emt "\\.\\.") + ;; explicit markup start + (re-ems (concat re-emt re-hws "+")) + ;; inline markup prefix + (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) + ;; symbol character + (re-sym1 "\\(\\sw\\|\\s_\\)") + ;; inline markup content begin + (re-imbeg2 "\\(\\S \\|\\S \\([^") + + ;; There seems to be a bug leading to error "Stack overflow in regexp + ;; matcher" when "|" or "\\*" are the characters searched for + (re-imendbeg + (if (< emacs-major-version 21) + "]" + "\\]\\|\\\\.")) + ;; inline markup content end + (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) + ;; inline markup content without asterisk + (re-ima2 (concat re-imbeg2 "*" re-imend)) + ;; inline markup content without backquote + (re-imb2 (concat re-imbeg2 "`" re-imend)) + ;; inline markup content without vertical bar + (re-imv2 (concat re-imbeg2 "|" re-imend)) + ;; Supported URI schemes + (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") + ;; Line starting with adornment and optional whitespace; complete + ;; adornment is in (match-string 1); there must be at least 3 + ;; characters because otherwise explicit markup start would be + ;; recognized + (re-ado2 (concat "^\\(\\([" + (if (or + (< emacs-major-version 21) + (save-match-data + (string-match "XEmacs\\|Lucid" emacs-version))) + "^a-zA-Z0-9 \t\x00-\x1F" + "^[:word:][:space:][:cntrl:]") + "]\\)\\2\\2+\\)" re-hws "*$")) + ) (list ;; FIXME: Block markup is not recognized in blocks after explicit markup ;; start @@ -2076,19 +2076,19 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (list re-ado2) (if (not rst-mode-lazy) - (list 1 rst-block-face) - (list - (list 'rst-font-lock-handle-adornment - '(progn - (setq rst-font-lock-adornment-point (match-end 1)) - (point-max)) - nil - (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t) - (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) - 'append t) - (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t))))) + (list 1 rst-block-face) + (list + (list 'rst-font-lock-handle-adornment + '(progn + (setq rst-font-lock-adornment-point (match-end 1)) + (point-max)) + nil + (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t) + (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) + 'append t) + (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t))))) ;; `Comments`_ (append @@ -2096,26 +2096,26 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (concat re-bol "\\(" re-ems "\\)\[^[|_]\\([^:]\\|:\\([^:]\\|$\\)\\)*$") (list 1 rst-comment-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point (match-end 1)) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point (match-end 1)) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) (append (list (concat re-bol "\\(" re-emt "\\)\\(\\s *\\)$") (list 1 rst-comment-face) (list 2 rst-comment-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point 'next) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point 'next) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) ;; `Literal Blocks`_ (append @@ -2123,13 +2123,13 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (concat re-bol "\\(\\([^.\n]\\|\\.[^.\n]\\).*\\)?\\(::\\)$") (list 3 rst-block-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point t) - (point-max)) - nil - (list 0 rst-literal-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point t) + (point-max)) + nil + (list 0 rst-literal-face 'append))))) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2144,24 +2144,24 @@ no such line before LIMIT (defaults to the end of the buffer) returns nil and point is not moved." (interactive) (let ((clm (or column (current-column))) - (start (point)) - fnd beg cand) + (start (point)) + fnd beg cand) (if (not limit) - (setq limit (point-max))) + (setq limit (point-max))) (save-match-data (while (and (not fnd) (< (point) limit)) - (forward-line 1) - (when (< (point) limit) - (setq beg (point)) - (if (looking-at "\\s *$") - (setq cand (or cand beg)) ; An empty line is a candidate - (move-to-column clm) - ;; FIXME: No indentation [(zerop clm)] must be handled in some - ;; useful way - though it is not clear what this should mean at all - (if (string-match - "^\\s *$" (buffer-substring-no-properties beg (point))) - (setq cand nil) ; An indented line resets a candidate - (setq fnd (or cand beg))))))) + (forward-line 1) + (when (< (point) limit) + (setq beg (point)) + (if (looking-at "\\s *$") + (setq cand (or cand beg)) ; An empty line is a candidate + (move-to-column clm) + ;; FIXME: No indentation [(zerop clm)] must be handled in some + ;; useful way - though it is not clear what this should mean at all + (if (string-match + "^\\s *$" (buffer-substring-no-properties beg (point))) + (setq cand nil) ; An indented line resets a candidate + (setq fnd (or cand beg))))))) (goto-char (or fnd start)) fnd)) @@ -2175,26 +2175,26 @@ point is not moved." (defun rst-font-lock-find-unindented-line (limit) (let* ((ind-pnt rst-font-lock-indentation-point) - (beg-pnt ind-pnt)) + (beg-pnt ind-pnt)) ;; May run only once - enforce this (setq rst-font-lock-indentation-point nil) (when (and ind-pnt (not (numberp ind-pnt))) ;; Find indentation point in next line if any (setq ind-pnt - (save-excursion - (save-match-data - (if (eq ind-pnt 'next) - (when (and (zerop (forward-line 1)) (< (point) limit)) - (setq beg-pnt (point)) - (when (not (looking-at "\\s *$")) - (looking-at "\\s *") - (match-end 0))) - (while (and (zerop (forward-line 1)) (< (point) limit) - (looking-at "\\s *$"))) - (when (< (point) limit) - (setq beg-pnt (point)) - (looking-at "\\s *") - (match-end 0))))))) + (save-excursion + (save-match-data + (if (eq ind-pnt 'next) + (when (and (zerop (forward-line 1)) (< (point) limit)) + (setq beg-pnt (point)) + (when (not (looking-at "\\s *$")) + (looking-at "\\s *") + (match-end 0))) + (while (and (zerop (forward-line 1)) (< (point) limit) + (looking-at "\\s *$"))) + (when (< (point) limit) + (setq beg-pnt (point)) + (looking-at "\\s *") + (match-end 0))))))) (when ind-pnt (goto-char ind-pnt) ;; Always succeeds because the limit set by PRE-MATCH-FORM is the @@ -2236,7 +2236,7 @@ entered.") ;; is not found and ADD. If KEY is not a string it is simply returned. (defun rst-adornment-level (key &optional add) (let ((fnd (assoc key rst-adornment-level-alist)) - (new 1)) + (new 1)) (cond ((not (stringp key)) key) @@ -2244,9 +2244,9 @@ entered.") (cdr fnd)) (add (while (rassoc new rst-adornment-level-alist) - (setq new (1+ new))) + (setq new (1+ new))) (setq rst-adornment-level-alist - (append rst-adornment-level-alist (list (cons key new)))) + (append rst-adornment-level-alist (list (cons key new)))) new)))) ;; Classifies adornment for section titles and transitions. ADORNMENT is the @@ -2264,56 +2264,56 @@ entered.") (save-match-data (goto-char end) (let ((ado-ch (aref adornment 0)) - (ado-re (regexp-quote adornment)) - (end-pnt (point)) - (beg-pnt (progn - (forward-line 0) - (point))) - (nxt-emp - (save-excursion - (or (not (zerop (forward-line 1))) - (looking-at "\\s *$")))) - (prv-emp - (save-excursion - (or (not (zerop (forward-line -1))) - (looking-at "\\s *$")))) - key beg-ovr end-ovr beg-txt end-txt beg-und end-und) - (cond - ((and nxt-emp prv-emp) - ;; A transition - (setq key t) - (setq beg-txt beg-pnt) - (setq end-txt end-pnt)) - (prv-emp - ;; An overline - (setq key (concat (list ado-ch) "o")) - (setq beg-ovr beg-pnt) - (setq end-ovr end-pnt) - (forward-line 1) - (setq beg-txt (point)) - (while (and (< (point) limit) (not end-txt)) - (if (looking-at "\\s *$") - ;; No underline found - (setq end-txt (1- (point))) - (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) - (setq end-und (match-end 1)) - (setq beg-und (point)) - (setq end-txt (1- beg-und)))) - (forward-line 1))) - (t - ;; An underline - (setq key (concat (list ado-ch) "u")) - (setq beg-und beg-pnt) - (setq end-und end-pnt) - (setq end-txt (1- beg-und)) - (setq beg-txt (progn - (if (re-search-backward "^\\s *$" 1 'move) - (forward-line 1)) - (point))))) - (list key - (or beg-ovr beg-txt beg-und) - (or end-und end-txt end-und) - beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) + (ado-re (regexp-quote adornment)) + (end-pnt (point)) + (beg-pnt (progn + (forward-line 0) + (point))) + (nxt-emp + (save-excursion + (or (not (zerop (forward-line 1))) + (looking-at "\\s *$")))) + (prv-emp + (save-excursion + (or (not (zerop (forward-line -1))) + (looking-at "\\s *$")))) + key beg-ovr end-ovr beg-txt end-txt beg-und end-und) + (cond + ((and nxt-emp prv-emp) + ;; A transition + (setq key t) + (setq beg-txt beg-pnt) + (setq end-txt end-pnt)) + (prv-emp + ;; An overline + (setq key (concat (list ado-ch) "o")) + (setq beg-ovr beg-pnt) + (setq end-ovr end-pnt) + (forward-line 1) + (setq beg-txt (point)) + (while (and (< (point) limit) (not end-txt)) + (if (looking-at "\\s *$") + ;; No underline found + (setq end-txt (1- (point))) + (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) + (setq end-und (match-end 1)) + (setq beg-und (point)) + (setq end-txt (1- beg-und)))) + (forward-line 1))) + (t + ;; An underline + (setq key (concat (list ado-ch) "u")) + (setq beg-und beg-pnt) + (setq end-und end-pnt) + (setq end-txt (1- beg-und)) + (setq beg-txt (progn + (if (re-search-backward "^\\s *$" 1 'move) + (forward-line 1)) + (point))))) + (list key + (or beg-ovr beg-txt beg-und) + (or end-und end-txt end-und) + beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) ;; Handles adornments for font-locking section titles and transitions. Returns ;; three match groups. First and last match group matched pure overline / @@ -2325,80 +2325,95 @@ entered.") (setq rst-font-lock-adornment-point nil) (if ado-pnt (let* ((ado (rst-classify-adornment (match-string-no-properties 1) - ado-pnt limit)) - (key (car ado)) - (mtc (cdr ado))) - (setq rst-font-lock-level (rst-adornment-level key t)) - (goto-char (nth 1 mtc)) - (set-match-data mtc) - t)))) + ado-pnt limit)) + (key (car ado)) + (mtc (cdr ado))) + (setq rst-font-lock-level (rst-adornment-level key t)) + (goto-char (nth 1 mtc)) + (set-match-data mtc) + t)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Support for conversion from within Emacs -(defgroup rst-html nil - "Settings for conversion to HTML available by \\[rst-html-compile]." +(defgroup rst-compile nil + "Settings for support of conversion of reStructuredText +document with \\[rst-compile]." :group 'rst :version "21.1") -(defcustom rst-html-command "rst2html.py" - "Command to convert an reST file to HTML." - :group 'rst-html - :type '(string)) +(defvar rst-compile-toolsets + '((html . ("rst2html.py" ".html" nil)) + (latex . ("rst2latex.py" ".tex" nil)) + (newlatex . ("rst2newlatex.py" ".tex" nil)) + (pseudoxml . ("rst2pseudoxml.py" ".xml" nil)) + (xml . ("rst2xml.py" ".xml" nil))) + "An association list of the toolset to a list of the (command to use, +extension of produced filename, options to the tool (nil or a +string)) to be used for converting the document.") + +;; Note for Python programmers not familiar with association lists: you can set +;; values in an alists like this, e.g. : +;; (setcdr (assq 'html rst-compile-toolsets) +;; '("rst2html.py" ".htm" "--stylesheet=/docutils.css")) + -(defcustom rst-html-options "" - "Local file options for reST to HTML conversion. -Stylesheets are set by an own option." - :group 'rst-html - :type '(string)) +(defvar rst-compile-primary-toolset 'html + "The default toolset for rst-compile.") -(defcustom rst-html-extension ".html" - "Extension for HTML output file." - :group 'rst-html - :type '(string)) +(defvar rst-compile-secondary-toolset 'latex + "The default toolset for rst-compile with a prefix argument.") -(defun rst-html-find-conf () +(defun rst-compile-find-conf () "Look for the configuration file in the parents of the current path." (interactive) (let ((file-name "docutils.conf") - (buffer-file (buffer-file-name))) + (buffer-file (buffer-file-name))) ;; Move up in the dir hierarchy till we find a change log file. (let ((dir (file-name-directory buffer-file))) (while (and (or (not (string= "/" dir)) (setq dir nil) nil) - (not (file-exists-p (concat dir file-name)))) - ;; Move up to the parent dir and try again. - (setq dir (expand-file-name (file-name-directory - (directory-file-name - (file-name-directory dir))))) ) + (not (file-exists-p (concat dir file-name)))) + ;; Move up to the parent dir and try again. + (setq dir (expand-file-name (file-name-directory + (directory-file-name + (file-name-directory dir))))) ) (or (and dir (concat dir file-name)) nil) ))) -(defun rst-html-compile () - "Compile command to convert reST document into HTML. -Attempts to find configuration file, if it can, overrides the options." - (interactive) +(defun rst-compile (&optional pfxarg) + "Compile command to convert reST document into some output file. +Attempts to find configuration file, if it can, overrides the +options." + (interactive "P") ;; Note: maybe we want to check if there is a Makefile too and not do anything ;; if that is the case. I dunno. - (let* ((conffile (rst-html-find-conf)) - (bufname (file-name-nondirectory buffer-file-name)) - (outname (file-name-sans-extension bufname))) + (let* ((toolset (cdr (assq (if pfxarg + rst-compile-secondary-toolset + rst-compile-primary-toolset) + rst-compile-toolsets))) + (command (car toolset)) + (extension (cadr toolset)) + (options (caddr toolset)) + (conffile (rst-compile-find-conf)) + (bufname (file-name-nondirectory buffer-file-name)) + (outname (file-name-sans-extension bufname))) ;; Set compile-command before invocation of compile. (set (make-local-variable 'compile-command) - (mapconcat 'identity - (list rst-html-command - rst-html-options - (if conffile - (concat "--config=\"" conffile "\"") - "") - bufname - (concat outname rst-html-extension)) - " ")) + (mapconcat 'identity + (list command + (or options "") + (if conffile + (concat "--config=\"" conffile "\"") + "") + bufname + (concat outname extension)) + " ")) ;; Invoke the compile command. (if (or compilation-read-command current-prefix-arg) - (call-interactively 'compile) + (call-interactively 'compile) (compile compile-command)) )) -- cgit v1.2.1 From c2c4c2c253bb89375e71288cba91ef28c6d10046 Mon Sep 17 00:00:00 2001 From: blais Date: Mon, 31 Oct 2005 00:32:13 +0000 Subject: Fixed minor bug with underlining function invoked at the end of the document. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3989 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 68179e73c..d2ee8c225 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -418,7 +418,8 @@ have been seen. (defun rst-delete-line () "A version of kill-line that does not use the kill-ring." - (delete-region (line-beginning-position) (+ 1 (line-end-position)))) + (delete-region (line-beginning-position) (min (+ 1 (line-end-position)) + (point-max)))) (defun rst-update-section (char style &optional indent) "Unconditionally updates the style of a section decoration -- cgit v1.2.1 From 034774dae47a063345a99ac6e91d8647720a9e9a Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 31 Oct 2005 03:22:45 +0000 Subject: minor edits for consistency, typos, links, etc. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3990 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 46 +++++++++++++++++++++++------------------- tools/editors/emacs/README.txt | 19 +++++++++-------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index ba21da05f..9c399af45 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -1,3 +1,5 @@ +.. -*- coding: utf-8 -*- + ======================================== Emacs Support for reStructuredText ======================================== @@ -75,8 +77,8 @@ the hierarchy of the document. What we call section decorations or adornments are the underlines or under- and overlines used to mark a section title. There is a function that helps a great deal to maintain these decorations: -``rst-adjust`` (bound on ``C-=`` by default). This function is a swiss knife -that can be invoked repeatedly and whose behaviour depends on context: +``rst-adjust`` (bound on ``C-=`` by default). This function is a Swiss army +knife that can be invoked repeatedly and whose behaviour depends on context: #. If there is an incomplete underline, e.g.:: @@ -117,8 +119,8 @@ Customizations You can set the variable ``rst-preferred-decorations`` to a list of the decorations that you like to use for documents. Everyone has their preference. -``rst-default-indent`` can be set to the number of characters preferred for the -over-and-under decoration style. +``rst-default-indent`` can be set to the number of indent spaces preferred for +the over-and-under decoration style. Viewing the Hierarchy of Section Decorations @@ -138,10 +140,10 @@ When you are editing long documents, it can be a bit difficult to orient yourself in the structure of your text. To that effect, a function is provided that quickly parses the document and presents a hierarchically indented table of contents of the document in a temporary buffer, in which you can navigate and -press ``Ret`` to go to a specific section. +press ``Return`` to go to a specific section. Invoke this function (``rst-toc``) with ``C-x C-=``. It should present a -temporary buffer that looks somewhat like this:: +temporary buffer that looks something like this:: Table of Contents: Debugging Meta-Techniques @@ -160,7 +162,6 @@ temporary buffer that looks somewhat like this:: Good Feelings References - When you select a section title, the temporary buffer disappears and you are left with the cursor positioned at the chosen section. @@ -177,9 +178,9 @@ their source documents, and partly because it is too much trouble to edit and maintain. The emacs support for reStructuredText_ provides a function to insert such a -table of contents in your document. Since it gets computed automatically by -docutils, you should place such a table of contents within a contents, so that -it gets ignored by docutils, e.g. this is the favoured usage:: +table of contents in your document. Since it is not meant to be part of the +document text, you should place such a table of contents within a comment, so +that it is ignored by the parser. This is the favoured usage:: .. contents:: .. @@ -202,7 +203,7 @@ Just place the cursor at the top-left corner where you want to insert the TOC and invoke the function with ``C-x +``. If there is a single top-level section level (i.e. the document title), by default it is ignored. If you have deep nesting of sections, you can use a numeric prefix argument to limit the depth of -rendenring of the TOC. +rendering of the TOC. You can also customize the look of the TOC by setting the values of the following variables:: ``rst-toc-indent``, @@ -216,7 +217,7 @@ Maintaining the Table of Contents Up-to-date One issue is that you will probably want to maintain the inserted table of contents up-to-date. There is a function that will automatically look for the inserted TOC (``rst-toc-insert-update``) and it can be added to a hook on the -section decoration adjustment function, so that everytime you adjust a section +section decoration adjustment function, so that every time you adjust a section title, the TOC is updated. Add this functionality with the following emacs configuration:: @@ -262,7 +263,7 @@ reStructuredText_ constructs. This mode was written by Stefan Merten [#]. It mostly provides lazy syntax coloring for many of the constructs that reStructuredText_ prescribes. -To enable this mode, type ``M-x rst-mode`` or you can setup an +To enable this mode, type ``M-x rst-mode`` or you can set up an ``auto-mode-alist`` to automatically turn it on whenever you visit reStructuredText_ documents:: @@ -274,6 +275,12 @@ rst-mode:: .. -*- mode: rst -*- +Or add this at the end of your documents: + + .. + Local Variables: + mode: rst + By default, the font-lock colouring is performed lazily. If you don't like this, you can turn this off by setting the value of ``rst-mode-lazy``. You can also change the various colours (see the source file for the whole list of @@ -344,7 +351,7 @@ The problem is that emacs does not recognize the various consecutive items as forming paragraph boundaries. You can fix this easily by changing the global value of the parapraph boundary detection to recognize such lists, like this:: - (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-*] ")) + (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-+*] ")) ``text-mode`` Settings @@ -370,7 +377,6 @@ allows creating ascii tables compatible with reStructuredText_. .. _Emacs table mode: http://table.sourceforge.net/ - Character Processing -------------------- @@ -387,7 +393,7 @@ here are some useful resources for Emacs users in the Unicode world: to your .emacs file. - To get direct keyboard input of non-ASCII characters (like - "option-e e" resulting in "" [eacute]), first enable the option + "option-e e" resulting in "é" [eacute]), first enable the option key by setting the command key as your meta key:: (setq mac-command-key-is-meta t) ;; nil for option key @@ -433,8 +439,6 @@ and ".,:;"), and free. __ http://www.tobias-jung.de/seekingprofont/ - - Credits ======= @@ -456,13 +460,13 @@ Future Work =========== Here are some features and ideas that will be worked on in the future, in those -frenzy morning of excitement over the virtues of the one-true-way kitchen sink -of editors: +frenzied mornings of excitement over the virtues of the one-true-way kitchen +sink of editors: - It would be nice to differentiate between text files using reStructuredText_ and other general text files. If we had a function to automatically guess whether a .txt file is following the reStructuredText_ conventions, we could - trigger rst-mode without having to hardcode this on every text file, nor + trigger rst-mode without having to hard-code this in every text file, nor forcing the user to add a local mode variable at the top of the file. We could perform this guessing by searching for a valid decoration at the top diff --git a/tools/editors/emacs/README.txt b/tools/editors/emacs/README.txt index 6f0f72891..2c3e32ce5 100644 --- a/tools/editors/emacs/README.txt +++ b/tools/editors/emacs/README.txt @@ -1,20 +1,14 @@ .. -*- coding: utf-8 -*- -===================================== - Emacs Support for reStructuredText_ -===================================== +===================== + Emacs Support Files +===================== :Date: $Date$ -.. _reStructuredText: http://docutils.sourceforge.net/rst.html - - -Directory Contents -================== - This directory contains the following Emacs lisp package files: -* rst.el : Emacs support for ReStructuredText. This file contains +* rst.el: Emacs support for reStructuredText_. This file contains * Section decoration/adornment creation and updating (M. Blais); * Table-of-contents mode and insertion (M. Blais); @@ -28,3 +22,8 @@ This directory contains the following Emacs lisp package files: To install the package, put a copy of the package file in a directory on your ``load-path`` (use ``C-h v load-path`` to check). + +For setup and usage details, see `Emacs Support for reStructuredText +<../../../docs/user/emacs.html>`_. + +.. _reStructuredText: http://docutils.sourceforge.net/rst.html -- cgit v1.2.1 From b72350577e014df33d3d3fe8bab07720cbbeb859 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 1 Nov 2005 01:54:46 +0000 Subject: dynamic date git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3991 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 9c399af45..3d771f6dd 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -5,7 +5,7 @@ ======================================== :Author: Martin Blais -:Date: 2005-10-29 +:Date: $Date$ :Abstract: High-level description of the existing emacs support for editing -- cgit v1.2.1 From 4ff2ec740b6b5ade27810801beebbfc1d87f010d Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 1 Nov 2005 01:55:32 +0000 Subject: restored some deleted parts from r3976, & updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3992 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index bc5ce93ac..0b3fd757e 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -29,9 +29,6 @@ his essay `The Magic Cauldron`_: correlated with the number of hoops each project makes a user go through to contribute. -.. _The Magic Cauldron: - http://www.catb.org/~esr/writings/magic-cauldron/ - We will endeavour to keep the barrier to entry as low as possible. The policies below should not be thought of as barriers, but merely as a codification of experience to date. These are "best practices"; @@ -47,6 +44,9 @@ originators of Ogg Vorbis) put it well when he said: .. [#bcs] Phrase borrowed from `Ben Collins-Sussman of the Subversion project `__. +.. _The Magic Cauldron: + http://www.catb.org/~esr/writings/magic-cauldron/ + Python Coding Conventions ========================= @@ -59,10 +59,13 @@ conform to these conventions. The Docutils project shall follow the generic coding conventions as specified in the `Style Guide for Python Code`_ and `Docstring -Conventions`_ PEPs, with the following clarifications and extensions: +Conventions`_ PEPs, summarized, clarified, and extended as follows: * 4 spaces per indentation level. No hard tabs. +* Use only 7-bit ASCII, no 8-bit strings. See `Docutils + Internationalization`_. + * No one-liner compound statements (i.e., no ``if x: return``: use two lines & indentation), except for degenerate class or method definitions (i.e., ``class X: pass`` is OK.). @@ -72,6 +75,14 @@ Conventions`_ PEPs, with the following clarifications and extensions: * Use "StudlyCaps" for class names (except for element classes in docutils.nodes). +* Use "lowercase" or "lowercase_with_underscores" for function, + method, and variable names. For short names, maximum two words, + joined lowercase may be used (e.g. "tagname"). For long names with + three or more words, or where it's hard to parse the split between + two words, use lowercase_with_underscores (e.g., + "note_explicit_target", "explicit_target"). If in doubt, use + underscores. + * Avoid lambda expressions, which are inherently difficult to understand. Named functions are preferable and superior: they're faster (no run-time compilation), and well-chosen names serve to @@ -106,9 +117,9 @@ Documentation Conventions Document Title ================ - ------------------------------ - Document Subtitle (optional) - ------------------------------ + -------------------------------------------- + Document Subtitle, or Major Division Title + -------------------------------------------- Section ======= @@ -183,6 +194,8 @@ import. Branches -------- +(These branch policies go into effect with Docutils 0.4.) + The "docutils" directory of the **trunk** (a.k.a. the **Docutils core**) is used for active -- but stable, fully tested, and reviewed -- development. @@ -258,7 +271,8 @@ tested_, and `reasonably complete`_. Modules & files must be at least minimally documented internally. `Docutils Front-End Tools`_ should have a new section for any front-end tool that is added. `Docutils Configuration Files`_ - should be modified with any settings/options defined. + should be modified with any settings/options defined. For any + non-trivial change, the `HISTORY.txt`_ file should be updated. * _`Tested` means that unit and/or functional tests, that catch all bugs fixed and/or cover all new functionality, have been added to -- cgit v1.2.1 From c4da374a0e2c4a5d6f455382f6a05348596681d3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 1 Nov 2005 14:09:07 +0000 Subject: added missing target git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3993 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 0b3fd757e..3bf3914d0 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -272,7 +272,7 @@ tested_, and `reasonably complete`_. `Docutils Front-End Tools`_ should have a new section for any front-end tool that is added. `Docutils Configuration Files`_ should be modified with any settings/options defined. For any - non-trivial change, the `HISTORY.txt`_ file should be updated. + non-trivial change, the HISTORY.txt_ file should be updated. * _`Tested` means that unit and/or functional tests, that catch all bugs fixed and/or cover all new functionality, have been added to @@ -311,8 +311,7 @@ mistake is easy to fix. That's what Subversion is for! .. _Docutils Front-End Tools: ../user/tools.html .. _Docutils Configuration Files: ../user/config.html -.. _nightly repository tarball: - http://svn.berlios.de/svndumps/docutils-repos.gz +.. _HISTORY.txt: ../../HISTORY.txt Version Numbering -- cgit v1.2.1 From d2fbea7bc8bdf75fe9a57b67062f688ea8ffae47 Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 1 Nov 2005 19:47:32 +0000 Subject: Updated rst.el with rst-mode.el 0.2.9 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3994 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 592 ++++++++++++++++++++++++++++----------------- 1 file changed, 369 insertions(+), 223 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index d2ee8c225..43f3c380c 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -138,6 +138,11 @@ ;; automatic toc update. The cursor ends up in the TOC and this is ;; annoying. Gotta fix that. ;; +;; rst-mode +;; -------- +;; - Look at the possibility of converting rst-mode from a Major mode to a Minor +;; mode of text-mode. +;; ;; Other ;; ----- ;; - We should rename "adornment" to "decoration" or vice-versa in this @@ -1692,9 +1697,91 @@ up to the leftmost character in the region." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; rst-mode -;; ======== +;;; rst-mode.el --- Mode for viewing and editing reStructuredText-documents. +;; +;; Copyright 2003 Stefan Merten +;; +;; Note: this is an update from version 0.2.9 of rst-mode.el +;; +;; DESCRIPTION +;; +;; This package provides support for documents marked up using the +;; reStructuredText format. Support includes font locking as well as some +;; convenience functions for editing. It does this by defining a Emacs major +;; mode. +;; +;; The package is based on text-mode and inherits some things from it. +;; Particularly text-mode-hook is run before rst-mode-hook. +;; +;; OPTIONS +;; +;; There are a number of things which can be customized using the standard +;; Emacs customization features. There are two customization groups for this +;; mode. +;; +;; Customization +;; ============= +;; +;; rst +;; --- +;; This group contains some general customizable features. +;; +;; The group is contained in the wp group. +;; +;; rst-faces +;; --------- +;; This group contains all necessary for customizing fonts. The default +;; settings use standard font-lock-*-face's so if you set these to your +;; liking they are probably good in rst-mode also. +;; +;; The group is contained in the faces group as well as in the rst group. +;; +;; rst-faces-defaults +;; ------------------ +;; This group contains all necessary for customizing the default fonts used for +;; section title faces. +;; +;; The general idea for section title faces is to have a non-default background +;; but do not change the background. The section level is shown by the +;; lightness of the background color. If you like this general idea of +;; generating faces for section titles but do not like the details this group +;; is the point where you can customize the details. If you do not like the +;; general idea, however, you should customize the faces used in +;; rst-adornment-faces-alist. +;; +;; Note: If you are using a dark background please make sure the variable +;; frame-background-mode is set to the symbol dark. This triggers +;; some default values which are probably right for you. +;; +;; The group is contained in the rst-faces group. +;; +;; All customizable features have a comment explaining their meaning. Refer to +;; the customization of your Emacs (try ``M-x customize``). + +;; SEE ALSO +;; +;; http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html + +;; AUTHOR +;; +;; Stefan Merten + +;; LICENSE +;; +;; This program is licensed under the terms of the GPL. See +;; +;; http://www.gnu.org/licenses/gpl.txt + +;; AVAILABILITY ;; +;; See +;; +;; http://www.merten-home.de/FreeSoftware/rst-mode/ + + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Customization: (defcustom rst-mode-hook nil @@ -1778,50 +1865,106 @@ The value of this variable is used when Rst Mode is turned on." :group 'rst-faces :type '(face)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgroup rst-faces-defaults nil + "Values used to generate default faces for section titles on all levels. +Tweak these if you are content with how section title faces are built in +general but you do not like the details." + :group 'rst-faces + :version "21.1") + +(defun rst-define-level-faces () + "Define the faces for the section title text faces from the values." + ;; All variables used here must be checked in `rst-set-level-default' + (let ((i 1)) + (while (<= i rst-level-face-max) + (let ((sym (intern (format "rst-level-%d-face" i))) + (doc (format "Face for showing section title text at level %d" i)) + (col (format (concat "%s" rst-level-face-format-light) + rst-level-face-base-color + (+ (* (1- i) rst-level-face-step-light) + rst-level-face-base-light)))) + (make-empty-face sym) + (set-face-doc-string sym doc) + (set-face-background sym col) + (set sym sym) + (setq i (1+ i)))))) + +(defun rst-set-level-default (sym val) + "Set a customized value affecting section title text face and recompute the +faces." + (custom-set-default sym val) + ;; Also defines the faces initially when all values are available + (and (boundp 'rst-level-face-max) + (boundp 'rst-level-face-format-light) + (boundp 'rst-level-face-base-color) + (boundp 'rst-level-face-step-light) + (boundp 'rst-level-face-base-light) + (rst-define-level-faces))) + ;; Faces for displaying items on several levels; these definitions define -;; different shades of grey where the lightest one is used for level 1 -(defconst rst-level-face-max 6 - "Maximum depth of level faces defined") -(defconst rst-level-face-base-color "grey" - "The base color to be used for creating level faces") -(defconst rst-level-face-base-light 85 - "The lightness factor for the base color") -(defconst rst-level-face-format-light "%2d" - "The format for the lightness factor for the base color") -(defconst rst-level-face-step-light -7 - "The step width to use for next color") - -;; Define the faces -(let ((i 1)) - (while (<= i rst-level-face-max) - (let ((sym (intern (format "rst-level-%d-face" i))) - (doc (format "Face for showing section title text at level %d" i)) - (col (format (concat "%s" rst-level-face-format-light) - rst-level-face-base-color - (+ (* (1- i) rst-level-face-step-light) - rst-level-face-base-light)))) - (make-empty-face sym) - (set-face-doc-string sym doc) - (set-face-background sym col) - (set sym sym) - (setq i (1+ i))))) +;; different shades of grey where the lightest one (i.e. least contrasting) is +;; used for level 1 +(defcustom rst-level-face-max 6 + "Maximum depth of levels for which section title faces are defined." + :group 'rst-faces-defaults + :type '(integer) + :set 'rst-set-level-default) +(defcustom rst-level-face-base-color "grey" + "The base name of the color to be used for creating background colors in +ection title faces for all levels." + :group 'rst-faces-defaults + :type '(string) + :set 'rst-set-level-default) +(defcustom rst-level-face-base-light + (if (eq frame-background-mode 'dark) + 15 + 85) + "The lightness factor for the base color. This value is used for level 1. The +default depends on whether the value of `frame-background-mode' is `dark' or +not." + :group 'rst-faces-defaults + :type '(integer) + :set 'rst-set-level-default) +(defcustom rst-level-face-format-light "%2d" + "The format for the lightness factor appended to the base name of the color. +This value is expanded by `format' with an integer." + :group 'rst-faces-defaults + :type '(string) + :set 'rst-set-level-default) +(defcustom rst-level-face-step-light + (if (eq frame-background-mode 'dark) + 7 + -7) + "The step width to use for the next color. The formula +`rst-level-face-base-light' + (`rst-level-face-max' - 1) * `rst-level-face-step-light' +must result in a color level which appended to `rst-level-face-base-color' +using `rst-level-face-format-light' results in a valid color such as `grey50'. +This color is used as background for section title text on level +`rst-level-face-max'." + :group 'rst-faces-defaults + :type '(integer) + :set 'rst-set-level-default) (defcustom rst-adornment-faces-alist - '((1 . rst-level-1-face) - (2 . rst-level-2-face) - (3 . rst-level-3-face) - (4 . rst-level-4-face) - (5 . rst-level-5-face) - (6 . rst-level-6-face) - (t . font-lock-keyword-face) - (nil . font-lock-keyword-face)) + (let ((alist '((t . font-lock-keyword-face) + (nil . font-lock-keyword-face))) + (i 1)) + (while (<= i rst-level-face-max) + (nconc alist (list (cons i (intern (format "rst-level-%d-face" i))))) + (setq i (1+ i))) + alist) "Provides faces for the various adornment types. Key is a number (for the section title text of that level), t (for transitions) or nil (for section -title adornment)." +title adornment). If you generally do not like how section title text faces are +set up tweak here. If the general idea is ok for you but you do not like the +details check the Rst Faces Defaults group." :group 'rst-faces - :type '(alist :key-type (choice (integer :tag "Section level") - (boolean :tag "transitions (on) / section title adornment (off)")) - :value-type (face))) + :type '(alist :key-type (choice (integer :tag "Section level (may not be bigger than `rst-level-face-max')") + (boolean :tag "transitions (on) / section title adornment (off)")) + :value-type (face)) + :set-after '(rst-level-face-max)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1897,9 +2040,9 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and ;; Font lock (set (make-local-variable 'font-lock-defaults) '(rst-font-lock-keywords-function - t nil nil nil - (font-lock-multiline . t) - (font-lock-mark-block-function . mark-paragraph))) + t nil nil nil + (font-lock-multiline . t) + (font-lock-mark-block-function . mark-paragraph))) (when (boundp 'font-lock-support-mode) ;; rst-mode has its own mind about font-lock-support-mode (make-local-variable 'font-lock-support-mode) @@ -1907,16 +2050,16 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and ((and (not rst-mode-lazy) (not font-lock-support-mode))) ;; No support mode set and none required - leave it alone ((or (not font-lock-support-mode) ;; No support mode set (but required) - (symbolp font-lock-support-mode)) ;; or a fixed mode for all + (symbolp font-lock-support-mode)) ;; or a fixed mode for all (setq font-lock-support-mode - (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) - (cons t font-lock-support-mode)))) + (list (cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode)) + (cons t font-lock-support-mode)))) ((and (listp font-lock-support-mode) - (not (assoc 'rst-mode font-lock-support-mode))) + (not (assoc 'rst-mode font-lock-support-mode))) ;; A list of modes missing rst-mode (setq font-lock-support-mode - (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) - font-lock-support-mode))))) + (append '((cons 'rst-mode (and rst-mode-lazy 'lazy-lock-mode))) + font-lock-support-mode))))) ;; Names and hooks (setq mode-name "reST") @@ -1929,57 +2072,57 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (defun rst-font-lock-keywords-function () "Returns keywords to highlight in rst mode according to current settings." - ;; The reST links in the comments below all relate to sections in - ;; http://docutils.sourceforge.net/rst.html + ;; The reST-links in the comments below all relate to sections in + ;; http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html (let* ( ;; This gets big - so let's define some abbreviations - ;; horizontal white space - (re-hws "[\t ]") - ;; beginning of line with possible indentation - (re-bol (concat "^" re-hws "*")) - ;; Separates block lead-ins from their content - (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) - ;; explicit markup tag - (re-emt "\\.\\.") - ;; explicit markup start - (re-ems (concat re-emt re-hws "+")) - ;; inline markup prefix - (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) - ;; symbol character - (re-sym1 "\\(\\sw\\|\\s_\\)") - ;; inline markup content begin - (re-imbeg2 "\\(\\S \\|\\S \\([^") - - ;; There seems to be a bug leading to error "Stack overflow in regexp - ;; matcher" when "|" or "\\*" are the characters searched for - (re-imendbeg - (if (< emacs-major-version 21) - "]" - "\\]\\|\\\\.")) - ;; inline markup content end - (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) - ;; inline markup content without asterisk - (re-ima2 (concat re-imbeg2 "*" re-imend)) - ;; inline markup content without backquote - (re-imb2 (concat re-imbeg2 "`" re-imend)) - ;; inline markup content without vertical bar - (re-imv2 (concat re-imbeg2 "|" re-imend)) - ;; Supported URI schemes - (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") - ;; Line starting with adornment and optional whitespace; complete - ;; adornment is in (match-string 1); there must be at least 3 - ;; characters because otherwise explicit markup start would be - ;; recognized - (re-ado2 (concat "^\\(\\([" - (if (or - (< emacs-major-version 21) - (save-match-data - (string-match "XEmacs\\|Lucid" emacs-version))) - "^a-zA-Z0-9 \t\x00-\x1F" - "^[:word:][:space:][:cntrl:]") - "]\\)\\2\\2+\\)" re-hws "*$")) - ) + ;; horizontal white space + (re-hws "[\t ]") + ;; beginning of line with possible indentation + (re-bol (concat "^" re-hws "*")) + ;; Separates block lead-ins from their content + (re-blksep1 (concat "\\(" re-hws "+\\|$\\)")) + ;; explicit markup tag + (re-emt "\\.\\.") + ;; explicit markup start + (re-ems (concat re-emt re-hws "+")) + ;; inline markup prefix + (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{/:.,;!?\\]\\|$\\)")) + ;; symbol character + (re-sym1 "\\(\\sw\\|\\s_\\)") + ;; inline markup content begin + (re-imbeg2 "\\(\\S \\|\\S \\([^") + + ;; There seems to be a bug leading to error "Stack overflow in regexp + ;; matcher" when "|" or "\\*" are the characters searched for + (re-imendbeg + (if (< emacs-major-version 21) + "]" + "\\]\\|\\\\.")) + ;; inline markup content end + (re-imend (concat re-imendbeg "\\)*[^\t \\\\]\\)")) + ;; inline markup content without asterisk + (re-ima2 (concat re-imbeg2 "*" re-imend)) + ;; inline markup content without backquote + (re-imb2 (concat re-imbeg2 "`" re-imend)) + ;; inline markup content without vertical bar + (re-imv2 (concat re-imbeg2 "|" re-imend)) + ;; Supported URI schemes + (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)") + ;; Line starting with adornment and optional whitespace; complete + ;; adornment is in (match-string 1); there must be at least 3 + ;; characters because otherwise explicit markup start would be + ;; recognized + (re-ado2 (concat "^\\(\\([" + (if (or + (< emacs-major-version 21) + (save-match-data + (string-match "XEmacs\\|Lucid" emacs-version))) + "^a-zA-Z0-9 \t\x00-\x1F" + "^[:word:][:space:][:cntrl:]") + "]\\)\\2\\2+\\)" re-hws "*$")) + ) (list ;; FIXME: Block markup is not recognized in blocks after explicit markup ;; start @@ -2077,19 +2220,19 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (list re-ado2) (if (not rst-mode-lazy) - (list 1 rst-block-face) - (list - (list 'rst-font-lock-handle-adornment - '(progn - (setq rst-font-lock-adornment-point (match-end 1)) - (point-max)) - nil - (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t) - (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) - 'append t) - (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) - 'append t))))) + (list 1 rst-block-face) + (list + (list 'rst-font-lock-handle-adornment + '(progn + (setq rst-font-lock-adornment-point (match-end 1)) + (point-max)) + nil + (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t) + (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) + 'append t) + (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) + 'append t))))) ;; `Comments`_ (append @@ -2097,26 +2240,26 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (concat re-bol "\\(" re-ems "\\)\[^[|_]\\([^:]\\|:\\([^:]\\|$\\)\\)*$") (list 1 rst-comment-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point (match-end 1)) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point (match-end 1)) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) (append (list (concat re-bol "\\(" re-emt "\\)\\(\\s *\\)$") (list 1 rst-comment-face) (list 2 rst-comment-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point 'next) - (point-max)) - nil - (list 0 rst-comment-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point 'next) + (point-max)) + nil + (list 0 rst-comment-face 'append))))) ;; `Literal Blocks`_ (append @@ -2124,13 +2267,13 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and (concat re-bol "\\(\\([^.\n]\\|\\.[^.\n]\\).*\\)?\\(::\\)$") (list 3 rst-block-face)) (if rst-mode-lazy - (list - (list 'rst-font-lock-find-unindented-line - '(progn - (setq rst-font-lock-indentation-point t) - (point-max)) - nil - (list 0 rst-literal-face 'append))))) + (list + (list 'rst-font-lock-find-unindented-line + '(progn + (setq rst-font-lock-indentation-point t) + (point-max)) + nil + (list 0 rst-literal-face 'append))))) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2145,24 +2288,24 @@ no such line before LIMIT (defaults to the end of the buffer) returns nil and point is not moved." (interactive) (let ((clm (or column (current-column))) - (start (point)) - fnd beg cand) + (start (point)) + fnd beg cand) (if (not limit) - (setq limit (point-max))) + (setq limit (point-max))) (save-match-data (while (and (not fnd) (< (point) limit)) - (forward-line 1) - (when (< (point) limit) - (setq beg (point)) - (if (looking-at "\\s *$") - (setq cand (or cand beg)) ; An empty line is a candidate - (move-to-column clm) - ;; FIXME: No indentation [(zerop clm)] must be handled in some - ;; useful way - though it is not clear what this should mean at all - (if (string-match - "^\\s *$" (buffer-substring-no-properties beg (point))) - (setq cand nil) ; An indented line resets a candidate - (setq fnd (or cand beg))))))) + (forward-line 1) + (when (< (point) limit) + (setq beg (point)) + (if (looking-at "\\s *$") + (setq cand (or cand beg)) ; An empty line is a candidate + (move-to-column clm) + ;; FIXME: No indentation [(zerop clm)] must be handled in some + ;; useful way - though it is not clear what this should mean at all + (if (string-match + "^\\s *$" (buffer-substring-no-properties beg (point))) + (setq cand nil) ; An indented line resets a candidate + (setq fnd (or cand beg))))))) (goto-char (or fnd start)) fnd)) @@ -2176,26 +2319,26 @@ point is not moved." (defun rst-font-lock-find-unindented-line (limit) (let* ((ind-pnt rst-font-lock-indentation-point) - (beg-pnt ind-pnt)) + (beg-pnt ind-pnt)) ;; May run only once - enforce this (setq rst-font-lock-indentation-point nil) (when (and ind-pnt (not (numberp ind-pnt))) ;; Find indentation point in next line if any (setq ind-pnt - (save-excursion - (save-match-data - (if (eq ind-pnt 'next) - (when (and (zerop (forward-line 1)) (< (point) limit)) - (setq beg-pnt (point)) - (when (not (looking-at "\\s *$")) - (looking-at "\\s *") - (match-end 0))) - (while (and (zerop (forward-line 1)) (< (point) limit) - (looking-at "\\s *$"))) - (when (< (point) limit) - (setq beg-pnt (point)) - (looking-at "\\s *") - (match-end 0))))))) + (save-excursion + (save-match-data + (if (eq ind-pnt 'next) + (when (and (zerop (forward-line 1)) (< (point) limit)) + (setq beg-pnt (point)) + (when (not (looking-at "\\s *$")) + (looking-at "\\s *") + (match-end 0))) + (while (and (zerop (forward-line 1)) (< (point) limit) + (looking-at "\\s *$"))) + (when (< (point) limit) + (setq beg-pnt (point)) + (looking-at "\\s *") + (match-end 0))))))) (when ind-pnt (goto-char ind-pnt) ;; Always succeeds because the limit set by PRE-MATCH-FORM is the @@ -2237,7 +2380,7 @@ entered.") ;; is not found and ADD. If KEY is not a string it is simply returned. (defun rst-adornment-level (key &optional add) (let ((fnd (assoc key rst-adornment-level-alist)) - (new 1)) + (new 1)) (cond ((not (stringp key)) key) @@ -2245,9 +2388,9 @@ entered.") (cdr fnd)) (add (while (rassoc new rst-adornment-level-alist) - (setq new (1+ new))) + (setq new (1+ new))) (setq rst-adornment-level-alist - (append rst-adornment-level-alist (list (cons key new)))) + (append rst-adornment-level-alist (list (cons key new)))) new)))) ;; Classifies adornment for section titles and transitions. ADORNMENT is the @@ -2265,56 +2408,56 @@ entered.") (save-match-data (goto-char end) (let ((ado-ch (aref adornment 0)) - (ado-re (regexp-quote adornment)) - (end-pnt (point)) - (beg-pnt (progn - (forward-line 0) - (point))) - (nxt-emp - (save-excursion - (or (not (zerop (forward-line 1))) - (looking-at "\\s *$")))) - (prv-emp - (save-excursion - (or (not (zerop (forward-line -1))) - (looking-at "\\s *$")))) - key beg-ovr end-ovr beg-txt end-txt beg-und end-und) - (cond - ((and nxt-emp prv-emp) - ;; A transition - (setq key t) - (setq beg-txt beg-pnt) - (setq end-txt end-pnt)) - (prv-emp - ;; An overline - (setq key (concat (list ado-ch) "o")) - (setq beg-ovr beg-pnt) - (setq end-ovr end-pnt) - (forward-line 1) - (setq beg-txt (point)) - (while (and (< (point) limit) (not end-txt)) - (if (looking-at "\\s *$") - ;; No underline found - (setq end-txt (1- (point))) - (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) - (setq end-und (match-end 1)) - (setq beg-und (point)) - (setq end-txt (1- beg-und)))) - (forward-line 1))) - (t - ;; An underline - (setq key (concat (list ado-ch) "u")) - (setq beg-und beg-pnt) - (setq end-und end-pnt) - (setq end-txt (1- beg-und)) - (setq beg-txt (progn - (if (re-search-backward "^\\s *$" 1 'move) - (forward-line 1)) - (point))))) - (list key - (or beg-ovr beg-txt beg-und) - (or end-und end-txt end-und) - beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) + (ado-re (regexp-quote adornment)) + (end-pnt (point)) + (beg-pnt (progn + (forward-line 0) + (point))) + (nxt-emp + (save-excursion + (or (not (zerop (forward-line 1))) + (looking-at "\\s *$")))) + (prv-emp + (save-excursion + (or (not (zerop (forward-line -1))) + (looking-at "\\s *$")))) + key beg-ovr end-ovr beg-txt end-txt beg-und end-und) + (cond + ((and nxt-emp prv-emp) + ;; A transition + (setq key t) + (setq beg-txt beg-pnt) + (setq end-txt end-pnt)) + (prv-emp + ;; An overline + (setq key (concat (list ado-ch) "o")) + (setq beg-ovr beg-pnt) + (setq end-ovr end-pnt) + (forward-line 1) + (setq beg-txt (point)) + (while (and (< (point) limit) (not end-txt)) + (if (looking-at "\\s *$") + ;; No underline found + (setq end-txt (1- (point))) + (when (looking-at (concat "\\(" ado-re "\\)\\s *$")) + (setq end-und (match-end 1)) + (setq beg-und (point)) + (setq end-txt (1- beg-und)))) + (forward-line 1))) + (t + ;; An underline + (setq key (concat (list ado-ch) "u")) + (setq beg-und beg-pnt) + (setq end-und end-pnt) + (setq end-txt (1- beg-und)) + (setq beg-txt (progn + (if (re-search-backward "^\\s *$" 1 'move) + (forward-line 1)) + (point))))) + (list key + (or beg-ovr beg-txt beg-und) + (or end-und end-txt end-und) + beg-ovr end-ovr beg-txt end-txt beg-und end-und))))) ;; Handles adornments for font-locking section titles and transitions. Returns ;; three match groups. First and last match group matched pure overline / @@ -2326,13 +2469,16 @@ entered.") (setq rst-font-lock-adornment-point nil) (if ado-pnt (let* ((ado (rst-classify-adornment (match-string-no-properties 1) - ado-pnt limit)) - (key (car ado)) - (mtc (cdr ado))) - (setq rst-font-lock-level (rst-adornment-level key t)) - (goto-char (nth 1 mtc)) - (set-match-data mtc) - t)))) + ado-pnt limit)) + (key (car ado)) + (mtc (cdr ado))) + (setq rst-font-lock-level (rst-adornment-level key t)) + (goto-char (nth 1 mtc)) + (set-match-data mtc) + t)))) + +;;; rst-mode.el ends here + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- cgit v1.2.1 From a5566f410d97bd17a755c2bee5ffbdd2bbe72deb Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 2 Nov 2005 01:55:30 +0000 Subject: completed example local variables stanza, and added a real one git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3995 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 3d771f6dd..80c47c2d4 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -280,6 +280,7 @@ Or add this at the end of your documents: .. Local Variables: mode: rst + End: By default, the font-lock colouring is performed lazily. If you don't like this, you can turn this off by setting the value of ``rst-mode-lazy``. You can @@ -481,3 +482,12 @@ sink of editors: .. _Emacs: http://www.gnu.org/emacs FIXME check .. _reStructuredText: http://docutils.sf.net/rst.html + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: -- cgit v1.2.1 From 01e516e6af7eb77d8123e3abc51d435183d199e2 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 2 Nov 2005 02:35:04 +0000 Subject: fixed markup git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3996 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 80c47c2d4..93475f3e5 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -275,7 +275,7 @@ rst-mode:: .. -*- mode: rst -*- -Or add this at the end of your documents: +Or add this at the end of your documents:: .. Local Variables: -- cgit v1.2.1 From d153de49b8e07c972d2e7f721e56b30f82e64ea8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 3 Nov 2005 22:21:13 +0000 Subject: added more accurate instructions about installing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3997 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- README.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 15205d36c..1e4bd7cc2 100644 --- a/README.txt +++ b/README.txt @@ -32,7 +32,13 @@ complete details. See `Releases & Snapshots`_ below for details. 3. Unpack the tarball in a temporary directory (**not** directly in - Python's ``site-packages``) and run ``install.py``. + Python's ``site-packages``) and run ``install.py`` with admin + rights. On Windows systems it may be sufficient to double-click + ``install.py``. On Unix or Mac OS X, type:: + + su + (enter admin password) + ./install.py See Installation_ below for details. -- cgit v1.2.1 From 9cb76ea8dfc48a41b2a45e04d13ffa9b9d370f6d Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 3 Nov 2005 23:16:02 +0000 Subject: fixed links git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3998 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/ref/rst/substitutions.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/ref/rst/substitutions.txt b/docs/ref/rst/substitutions.txt index 882239086..5ea9562f2 100644 --- a/docs/ref/rst/substitutions.txt +++ b/docs/ref/rst/substitutions.txt @@ -106,9 +106,9 @@ isopub.txt_ Publishing isotech.txt_ General Technical mmlalias.txt_ MathML aliases for entities from other sets mmlextra.txt_ [1]_ Extra names added by MathML -xhtml4-lat1.txt_ XHTML Latin 1 -xhtml4-special.txt_ XHTML Special Characters -xhtml4-symbol.txt_ XHTML Mathematical, Greek and Symbolic Characters +xhtml1-lat1.txt_ XHTML Latin 1 +xhtml1-special.txt_ XHTML Special Characters +xhtml1-symbol.txt_ XHTML Mathematical, Greek and Symbolic Characters =================== ================================================= .. [1] There are ``*-wide.txt`` variants for each of these character @@ -148,9 +148,9 @@ reference (defined in both ``isonum.txt`` and ``xhtml1-lat1.txt``) is .. _isotech.txt: ../../../docutils/parsers/rst/include/isotech.txt .. _mmlalias.txt: ../../../docutils/parsers/rst/include/mmlalias.txt .. _mmlextra.txt: ../../../docutils/parsers/rst/include/mmlextra.txt -.. _xhtml4-lat1.txt: ../../../docutils/parsers/rst/include/xhtml4-lat1.txt -.. _xhtml4-special.txt: ../../../docutils/parsers/rst/include/xhtml4-special.txt -.. _xhtml4-symbol.txt: ../../../docutils/parsers/rst/include/xhtml4-symbol.txt +.. _xhtml1-lat1.txt: ../../../docutils/parsers/rst/include/xhtml1-lat1.txt +.. _xhtml1-special.txt: ../../../docutils/parsers/rst/include/xhtml1-special.txt +.. _xhtml1-symbol.txt: ../../../docutils/parsers/rst/include/xhtml1-symbol.txt .. -- cgit v1.2.1 From 7efb57643bcde8d50755fa4c971fc630e2330ef8 Mon Sep 17 00:00:00 2001 From: blais Date: Fri, 4 Nov 2005 19:18:35 +0000 Subject: Fixed link in emacs file. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3999 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 93475f3e5..64daf07ac 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -480,7 +480,7 @@ sink of editors: that. -.. _Emacs: http://www.gnu.org/emacs FIXME check +.. _Emacs: http://www.gnu.org/software/emacs/emacs.html .. _reStructuredText: http://docutils.sf.net/rst.html -- cgit v1.2.1 From 3fd593f2ae8eac1f19b55a5cc02e786058866f80 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 6 Nov 2005 16:17:56 +0000 Subject: added a link to Alberto's OpenDocument writer git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4000 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/user/links.txt b/docs/user/links.txt index d2127d3dc..4cc8df8cf 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -33,6 +33,8 @@ the box. * For Blogs (Weblogs), please see the `FAQ entry about Blogs`_. +* Alberto Berti is developing an `OpenDocument writer`_. + * xml2rst_, an XSLT stylesheet written by Stefan Merten, converts XML dumps of the document tree (e.g. created with rst2xml.py) back to reStructuredText. @@ -108,6 +110,7 @@ code base. .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax +.. _OpenDocument writer: http://article.gmane.org/gmane.text.docutils.devel/3388 .. _xml2rst: http://www.merten-home.de/FreeSoftware/xml2rst/index.html .. _rst2ht: http://www.rutherfurd.net/articles/rst-ht2html.html .. _ht2html: http://ht2html.sourceforge.net/ -- cgit v1.2.1 From 7ed7500d9d9bbf4285b8646ed79d77aaf9872ea7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 6 Nov 2005 16:23:21 +0000 Subject: link to full thread git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4001 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/links.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/links.txt b/docs/user/links.txt index 4cc8df8cf..75c0fae0e 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -110,7 +110,7 @@ code base. .. _Docutils: http://docutils.sourceforge.net/ .. _FAQ entry about Wikis: http://docutils.sf.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax .. _FAQ entry about Blogs: http://docutils.sf.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax -.. _OpenDocument writer: http://article.gmane.org/gmane.text.docutils.devel/3388 +.. _OpenDocument writer: http://thread.gmane.org/gmane.text.docutils.devel/3388 .. _xml2rst: http://www.merten-home.de/FreeSoftware/xml2rst/index.html .. _rst2ht: http://www.rutherfurd.net/articles/rst-ht2html.html .. _ht2html: http://ht2html.sourceforge.net/ -- cgit v1.2.1 From 3bf78b13e2d2829a4aa33f5e0c875f4206dded9f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 6 Nov 2005 16:50:19 +0000 Subject: added note about HTTP access to the repository git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4002 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/repository.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/dev/repository.txt b/docs/dev/repository.txt index 568e3c6c9..2c613b10e 100644 --- a/docs/dev/repository.txt +++ b/docs/dev/repository.txt @@ -57,10 +57,14 @@ To check out everything (main tree, sandboxes, and web site), type :: This will create a working copy of the whole trunk in a new directory called ``docutils``. -Note that you should *never* check out -``svn://svn.berlios.de/docutils`` (without "trunk"), because then -you'd end up fetching the whole Docutils tree for every branch and tag -over and over again, wasting your and BerliOS's bandwidth. +If you cannot use the ``svn`` port, you can also use the HTTP access +method by substituting "http://svn.berlios.de/svnroot/repos" for +"svn://svn.berlios.de". + +Note that you should *not* check out ``svn://svn.berlios.de/docutils`` +(without "trunk"), because then you'd end up fetching the whole +Docutils tree for every branch and tag over and over again, wasting +your and BerliOS's bandwidth. To update your working copy later on, cd into the working copy and type :: @@ -94,6 +98,10 @@ typing :: (Again, ```` is your BerliOS user account name.) +If you cannot use the ``ssh`` port, you can also use the HTTPS access +method by substituting "https://svn.berlios.de" for +"svn+ssh://svn.berlios.de". + Setting Up Your Subversion Client For Development ````````````````````````````````````````````````` -- cgit v1.2.1 From 6f185bf33fee23aab3ba57a78eeeaeb69867e400 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 6 Nov 2005 19:18:54 +0000 Subject: added possible inline node in raw-wrap role output git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4003 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index ccda16513..f4e9948a6 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1437,12 +1437,15 @@ any knowledge of the Python-Reader origin of these elements. {\color{red} - text + + text } + Possibly without the intermediate "inline" node. + - "acronym" and "abbreviation": Associate the full text with a short form. Jason Diamond's description: -- cgit v1.2.1 From 747b9ac9bdb4d54a7eacca166ad3865c89bf93e7 Mon Sep 17 00:00:00 2001 From: blais Date: Mon, 7 Nov 2005 14:35:10 +0000 Subject: - Changed the default bindings due to the explosion of new feature: we now have a prefix-map, which is bound to 'C-c p', so the 'C-x p XXXX' commands are all for the rst.el file functions. I left a few bindings: * C-= is still there, because it is the single most useful command and it should be invoked with one key (you can get to it with 'C-c p a' too). * I moved 'C-M-{' to 'C-c n' or 'C-c p n' and did the same for the forward movement commands. * 'C-c C-l' and 'C-c C-r' have been kept, since they have a similar role than those bindings have in progmodes. - I removed all the bindings from 'C-x ...' prefix map, since we should be using the mode-specific map, which is 'C-c ...'. I'm also now using the mode-prefix-map variable, so people who have rebound theirs will get the benefits of their customization. - Started defining some abbrevs, e.g. 'con' for ''.. contents::' - Changed a lot of 'if's to 'when' and 'unless' clauses. - I added a function to find the node within the section subtree where the cursor lives. This function is used to compute the desired location of point in the toc table, which fixes a bug with the cursor being off when there were missing nodes. - The toc insertion now uses the insertion point to determine where to start rendering the TOC. This fixes a problem with guessing the titles and subtitles and heuristically removing them, simplifies the rst-toc-insert function and this new choices automatically supports local tocs. - Fixed the shifting functions to use markers, so that they can be used repeatedly with my repeat-repeatable-command advice. This just makes the functions more robust. - Added an option to automatically fill on shifting a region left or right (this needs more work). git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4004 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 41 +++-- tools/editors/emacs/rst.el | 438 ++++++++++++++++++++++++++++----------------- 2 files changed, 298 insertions(+), 181 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 64daf07ac..219e8e250 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -67,6 +67,9 @@ this use, set it up like this:: (add-hook 'text-mode-hook 'rst-text-mode-bindings) +A prefix map is defined for all the ``rst.el`` commands. By default, +it is bound to the mode-specific-map and ``p``, e.g. ``C-c p ...``. + Section Decoration Adjustment ============================= @@ -76,9 +79,10 @@ but it contains the ability to recognize the section decorations and to build the hierarchy of the document. What we call section decorations or adornments are the underlines or under- and overlines used to mark a section title. -There is a function that helps a great deal to maintain these decorations: -``rst-adjust`` (bound on ``C-=`` by default). This function is a Swiss army -knife that can be invoked repeatedly and whose behaviour depends on context: +There is a function that helps a great deal to maintain these +decorations: ``rst-adjust`` (bound on ``C-c p a``, ``C-c p =`` or +``C-=`` by default). This function is a Swiss army knife that can be +invoked repeatedly and whose behaviour depends on context: #. If there is an incomplete underline, e.g.:: @@ -127,7 +131,7 @@ Viewing the Hierarchy of Section Decorations ============================================ You can visualize the hierarchy of the section decorations in the current buffer -by invoking ``rst-display-decorations-hierarchy``, bound on ``C-u C-x C-=``. A +by invoking ``rst-display-decorations-hierarchy``, bound on ``C-c p h``. A temporary buffer will appear with fake section titles rendered in the style of the current document. This can be useful when editing other people's documents to find out which section decorations correspond to which levels. @@ -142,7 +146,7 @@ that quickly parses the document and presents a hierarchically indented table of contents of the document in a temporary buffer, in which you can navigate and press ``Return`` to go to a specific section. -Invoke this function (``rst-toc``) with ``C-x C-=``. It should present a +Invoke this function (``rst-toc``) with ``C-c p t``. It should present a temporary buffer that looks something like this:: Table of Contents: @@ -199,16 +203,18 @@ that it is ignored by the parser. This is the favoured usage:: 5.2 Good Feelings 6 References -Just place the cursor at the top-left corner where you want to insert the TOC -and invoke the function with ``C-x +``. If there is a single top-level section -level (i.e. the document title), by default it is ignored. If you have deep -nesting of sections, you can use a numeric prefix argument to limit the depth of -rendering of the TOC. +Just place the cursor at the top-left corner where you want to insert +the TOC and invoke the function with ``C-c p i``. The table of +contents will display all the section titles that are under the +location where the insertion occurs. This way you can insert local +table of contents by placing them in the appropriate location. + +If you have deep nesting of sections, you can use a numeric prefix +argument to limit the depth of rendering of the TOC. -You can also customize the look of the TOC by setting the values of the -following variables:: ``rst-toc-indent``, -``rst-toc-insert-always-include-top``, ``rst-toc-insert-style``, -``rst-toc-insert-max-level``. +You can also customize the look of the TOC by setting the values of +the following variables:: ``rst-toc-indent``, +``rst-toc-insert-style``, ``rst-toc-insert-max-level``. Maintaining the Table of Contents Up-to-date @@ -223,13 +229,16 @@ configuration:: (add-hook 'rst-adjust-hook 'rst-toc-insert-update) +You can invoke the update on the current buffer with ``C-c p u``. + Navigating Between the Section Titles ===================================== You can move the cursor between the different sections by using the -``rst-backward-section`` and ``rst-forward-section`` functions, by default bound -to the ``C-M-{`` and ``C-M-}`` keys. +``rst-backward-section`` and ``rst-forward-section`` functions, by +default bound to the ``C-c p p`` and ``C-c p n`` keys (also ``C-c +C-p`` and ``C-c C-n``). Shifting Bulleted List Levels diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 43f3c380c..143c7f688 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -60,25 +60,47 @@ ;; (require 'rst) ;; (add-hook 'text-mode-hook 'rst-text-mode-bindings) ;; -;; The keys it defines are: +;; rst-prefix-map is the prefix map for all the functionality provide by this +;; module. In addition, other shorter bindings are also provided on the +;; mode-specific-map prefix (i.e C-c). ;; -;; C-= : updates or rotates the section title around point or -;; promotes/demotes the decorations within the region (see full details -;; below). ;; -;; Note that C-= is a good binding, since it allows you to specify a -;; negative arg easily with C-- C-= (easy to type), as well as ordinary -;; prefix arg with C-u C-=. +;; C-c p a (also C-=): rst-adjust ;; -;; C-x C-= : displays the hierarchical table-of-contents of the document and -;; allows you to jump to any section from it. +;; Updates or rotates the section title around point or promotes/demotes +;; the decorations within the region (see full details below). ;; -;; C-u C-x C-= : displays the title decorations from this file. +;; Note that C-= is a good binding, since it allows you to specify a +;; negative arg easily with C-- C-= (easy to type), as well as ordinary +;; prefix arg with C-u C-=. ;; -;; C-x + : insert the table of contents in the text. See the many options -;; for customizing how it will look. +;; C-c p h: rst-display-decorations-hierarchy +;; +;; Displays the level decorations that are available in the file. +;; +;; C-c p t: rst-toc +;; +;; Displays the hierarchical table-of-contents of the document and allows +;; you to jump to any section from it. +;; +;; C-c p i: rst-toc-insert +;; +;; Inserts a table-of-contents in the document at the column where the +;; cursor is. +;; +;; C-c p u: rst-toc-insert-update +;; +;; Find an existing inserted table-of-contents in the document an updates it. +;; +;; C-c p p, C-c p n (C-c C-p, C-c C-n): rst-backward-section, rst-forward-section +;; +;; Navigate between section titles. +;; +;; C-c p l, C-c p r (C-c C-l, C-c C-r): rst-shift-region-left, rst-shift-region-right +;; +;; Shift the region left or right by two-char increments, which is perfect +;; for bulleted lists. ;; -;; C-M-{, C-M-} : navigate between section titles. ;; ;; Other specialized and more generic functions are also available (see source ;; code). The most important function provided by this file for section title @@ -129,7 +151,8 @@ ;; ;; rst-toc-insert features ;; ------------------------ -;; - Support local table of contents, like in doctree.txt. +;; - rst-toc-insert: We should parse the contents:: options to figure out how +;; deep to render the inserted TOC. ;; - On load, detect any existing TOCs and set the properties for links. ;; - TOC insertion should have an option to add empty lines. ;; - TOC insertion should deal with multiple lines @@ -167,17 +190,37 @@ (rst-toc) (rst-display-decorations-hierarchy))) +;; Define a prefix map for the long form of key combinations. +(defvar rst-prefix-map (make-sparse-keymap) + "Keymap for rst commands.") +(define-key rst-prefix-map "a" 'rst-adjust) +(define-key rst-prefix-map "=" 'rst-adjust) +(define-key rst-prefix-map "t" 'rst-toc) +(define-key rst-prefix-map "h" 'rst-display-decorations-hierarchy) +(define-key rst-prefix-map "i" 'rst-toc-insert) +(define-key rst-prefix-map "+" 'rst-toc-insert) +(define-key rst-prefix-map "p" 'rst-backward-section) +(define-key rst-prefix-map "n" 'rst-forward-section) +(define-key rst-prefix-map "r" 'rst-shift-region-right) +(define-key rst-prefix-map "l" 'rst-shift-region-left) +(define-key rst-prefix-map "u" 'rst-toc-insert-update) + (defun rst-text-mode-bindings () "Default text mode hook for rest." + + ;; Direct command (somehow this one does not work on the Mac). (local-set-key [(control ?=)] 'rst-adjust) - (local-set-key [(control x)(control ?=)] 'rst-toc-or-hierarchy) - (local-set-key [(control x)(?+)] 'rst-toc-insert) - (local-set-key [(control meta ?{)] 'rst-backward-section) - (local-set-key [(control meta ?})] 'rst-forward-section) - (local-set-key [(control c)(control r)] 'rst-shift-region-right) - (local-set-key [(control c)(control l)] 'rst-shift-region-left) + + (define-key mode-specific-map [(control p)] 'rst-backward-section) + (define-key mode-specific-map [(control n)] 'rst-forward-section) + (define-key mode-specific-map [(control r)] 'rst-shift-region-right) + (define-key mode-specific-map [(control l)] 'rst-shift-region-left) + + ;; Bind the rst commands on the C-c p prefix. + (define-key mode-specific-map [(p)] rst-prefix-map) ) + ;; Note: we cannot bind the TOC update on file write because it messes with ;; undo. If we disable undo, since it adds and removes characters, the ;; positions in the undo list are not making sense anymore. Dunno what to do @@ -189,6 +232,11 @@ ;; (let ((buffer-undo-list t)) (rst-toc-insert-update) )) +;; Additional abbreviations for text-mode. +(define-abbrev text-mode-abbrev-table + "con" ".. contents::\n..\n " nil 0) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -197,30 +245,30 @@ (require 'cl) ;; Generic Filter function. -(if (not (fboundp 'filter)) - (defun filter (pred list) - "Returns a list of all the elements fulfilling the pred requirement (that +(unless (fboundp 'filter) + (defun filter (pred list) + "Returns a list of all the elements fulfilling the pred requirement (that is for which (pred elem) is true)" - (if list - (let ((head (car list)) - (tail (filter pred (cdr list)))) - (if (funcall pred head) - (cons head tail) - tail))))) + (if list + (let ((head (car list)) + (tail (filter pred (cdr list)))) + (if (funcall pred head) + (cons head tail) + tail))))) ;; From emacs-22 -(if (not (fboundp 'line-number-at-pos)) - (defun line-number-at-pos (&optional pos) - "Return (narrowed) buffer line number at position POS. +(unless (fboundp 'line-number-at-pos) + (defun line-number-at-pos (&optional pos) + "Return (narrowed) buffer line number at position POS. If POS is nil, use current buffer location." - (let ((opoint (or pos (point))) start) - (save-excursion - (goto-char (point-min)) - (setq start (point)) - (goto-char opoint) - (forward-line 0) - (1+ (count-lines start (point)))))) ) + (let ((opoint (or pos (point))) start) + (save-excursion + (goto-char (point-min)) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines start (point)))))) ) @@ -346,19 +394,19 @@ decorations." patterns, such as :: or ...; with the flag do not ignore them." (save-excursion (back-to-indentation) - (if (not (looking-at "\n")) - (let ((c (thing-at-point 'char))) - (if (and (looking-at (format "[%s]+[ \t]*$" c)) - (or accept-special - (and - ;; Common patterns. - (not (looking-at "::[ \t]*$")) - (not (looking-at "\\.\\.\\.[ \t]*$")) - ;; Discard one char line - (not (looking-at ".[ \t]*$")) - ))) - (string-to-char c)) - )) + (unless (looking-at "\n") + (let ((c (thing-at-point 'char))) + (if (and (looking-at (format "[%s]+[ \t]*$" c)) + (or accept-special + (and + ;; Common patterns. + (not (looking-at "::[ \t]*$")) + (not (looking-at "\\.\\.\\.[ \t]*$")) + ;; Discard one char line + (not (looking-at ".[ \t]*$")) + ))) + (string-to-char c)) + )) )) (defun rst-line-homogeneous-nodent-p (&optional accept-special) @@ -575,12 +623,10 @@ have been seen. (let ((char (car x)) (style (cadr x)) (indent (caddr x))) - (if (not (assoc (cons char style) hierarchy-alist)) - (progn - (setq hierarchy-alist - (append hierarchy-alist - (list (cons (cons char style) x)))) - )) + (unless (assoc (cons char style) hierarchy-alist) + (setq hierarchy-alist + (append hierarchy-alist + (list (cons (cons char style) x)))) ) )) (mapcar 'cdr hierarchy-alist) )) @@ -1084,9 +1130,9 @@ of the right hand fingers and the binding is unused in text-mode." ;; Correct the position of the cursor to more accurately reflect where it ;; was located when the function was invoked. - (if (not (= moved 0)) - (progn (forward-line (- moved)) - (end-of-line))) + (unless (= moved 0) + (forward-line (- moved)) + (end-of-line)) )) @@ -1184,16 +1230,21 @@ the hierarchy is similar to that used by rst-adjust-decoration." (match-end 0)) ) (defun rst-section-tree (alldecos) - "Returns a pair of a hierarchical tree of the sections titles -in the document, and a reference to the node where the cursor -lives. This can be used to generate a table of contents for the -document. + "Returns a hierarchical tree of the sections titles in the +document. This can be used to generate a table of contents for +the document. The top node will always be a nil node, with the +top-level titles as children (there may potentially be more than +one). Each section title consists in a cons of the stripped title string and a marker to the section in the original text document. If there are missing section levels, the section titles are -inserted automatically, and are set to nil." +inserted automatically, and the title string is set to nil, and +the marker set to the first non-nil child of itself. +Conceptually, the nil nodes--i.e. those which have no title--are +to be considered as being the same line as their first non-nil +child. This has advantages later in processing the graph." (let* (thelist (hier (rst-get-hierarchy alldecos)) @@ -1235,21 +1286,62 @@ inserted automatically, and are set to nil." node children) ;; If the next decoration matches our level - (if (= (car ndeco) lev) - (progn - ;; Pop the next decoration and create the current node with it - (setcdr decos (cddr decos)) - (setq node (cdr ndeco)) )) - ;; Else we let the node title/marker be unset. + (when (= (car ndeco) lev) + ;; Pop the next decoration and create the current node with it + (setcdr decos (cddr decos)) + (setq node (cdr ndeco)) ) + ;; Else we let the node title/marker be unset. ;; Build the child nodes (while (and (cdr decos) (> (caadr decos) lev)) (setq children (cons (rst-section-tree-rec decos (1+ lev)) children))) + (setq children (reverse children)) + ;; If node is still unset, we use the marker of the first child. + (when (eq node nil) + (setq node (cons nil (cdaar children)))) + ;; Return this node with its children. - (cons node (reverse children)) + (cons node children) + )) + + +(defun rst-section-tree-point (node &optional point) + "Given a computed and valid section tree SECTREE and a point + POINT (default being the current point in the current buffer), + find and return the node within the sectree where the cursor + lives. + + Return values: a pair of (parent path, container subtree). The + parent path is simply a list of the nodes above the container + subtree node that we're returning." + + (let (path outtree) + + (let* ((curpoint (or point (point)))) + + ;; Check if we are before the current node. + (if (> curpoint (cadar node)) + + ;; Iterate all the children, looking for one that might contain the + ;; current section. + (let ((curnode (cdr node)) + last) + + (while (and curnode (> curpoint (cadaar curnode))) + (setq last curnode + curnode (cdr curnode))) + + (if last + (let ((sub (rst-section-tree-point (car last) curpoint))) + (setq path (car sub) + outtree (cdr sub))) + (setq outtree node)) + + ))) + (cons (cons (car node) path) outtree) )) @@ -1258,9 +1350,8 @@ inserted automatically, and are set to nil." By default the top level is ignored if there is only one, because we assume that the document will have a single title. -If a numeric prefix argument is given, -- if it is zero or generic, include the top level titles; -- otherwise insert the TOC up to the specified level. +If a numeric prefix argument is given, insert the TOC up to the +specified level. The TOC is inserted indented at the current column." @@ -1271,31 +1362,24 @@ The TOC is inserted indented at the current column." (if (and (integerp pfxarg) (> (prefix-numeric-value pfxarg) 0)) (prefix-numeric-value pfxarg) rst-toc-insert-max-level)) - ;; Get the section tree. - (sectree (rst-section-tree (rst-find-all-decorations))) - - ;; If there is only one top-level title, remove it by starting to print - ;; one index lower (revert this behaviour with the prefix arg), - ;; otherwise print all. - (gen-pfx-arg (or (and pfxarg (listp pfxarg)) - (and (integerp pfxarg) - (= (prefix-numeric-value pfxarg) 0)))) - (start-lev (if (and (not rst-toc-insert-always-include-top) - (= (length (cdr sectree)) 1) - (not gen-pfx-arg)) -1 0)) + ;; Get the section tree for the current cursor point. + (sectree-pair + (rst-section-tree-point + (rst-section-tree (rst-find-all-decorations)))) ;; Figure out initial indent. (initial-indent (make-string (current-column) ? )) (init-point (point))) - (rst-toc-insert-node sectree start-lev initial-indent "") - - ;; Fixup for the first line. - (delete-region init-point (+ init-point (length initial-indent))) + (when (cddr sectree-pair) + (rst-toc-insert-node (cdr sectree-pair) 0 initial-indent "") - ;; Delete the last newline added. - (delete-backward-char 1) - )) + ;; Fixup for the first line. + (delete-region init-point (+ init-point (length initial-indent))) + + ;; Delete the last newline added. + (delete-backward-char 1) + ))) (defgroup rst-toc nil @@ -1308,11 +1392,6 @@ The TOC is inserted indented at the current column." formatting insertion, when numbering is disabled)." :group 'rst-toc) -(defcustom rst-toc-insert-always-include-top nil - "Set this to 't if you want to always include top-level titles, - even when there is only one." - :group 'rst-toc) - (defcustom rst-toc-insert-style 'fixed "Set this to one of the following values to determine numbering and indentation style: @@ -1342,45 +1421,46 @@ indentation style: "Recursive function that does the print of the inserted toc. PFX is the prefix numbering, that includes the alignment necessary for all the children of this level to align." + + ;; Note: we do child numbering from the parent, so we start number the + ;; children one level before we print them. (let ((do-print (> level 0)) (count 1) b) - (if do-print - (progn - (insert indent) - (let ((b (point))) - (if (not (equal rst-toc-insert-style 'plain)) - (insert pfx rst-toc-insert-number-separator)) - (insert (or (caar node) "[missing node]")) - ;; Add properties to the text, even though in normal text mode it - ;; won't be doing anything for now. Not sure that I want to change - ;; mode stuff. At least the highlighting gives the idea that this - ;; is generated automatically. - (put-text-property b (point) 'mouse-face 'highlight) - (put-text-property b (point) 'rst-toc-target (cadar node)) - (put-text-property b (point) 'keymap rst-toc-insert-click-keymap) - - ) - (insert "\n") - - ;; Prepare indent for children. - (setq indent - (cond - ((eq rst-toc-insert-style 'plain) - (concat indent rst-toc-indent)) - - ((eq rst-toc-insert-style 'fixed) - (concat indent (make-string rst-toc-indent ? ))) - - ((eq rst-toc-insert-style 'aligned) - (concat indent (make-string (+ (length pfx) 2) ? ))) - - ((eq rst-toc-insert-style 'listed) - (concat (substring indent 0 -3) - (concat (make-string (+ (length pfx) 2) ? ) " - "))) - )) - - )) + (when do-print + (insert indent) + (let ((b (point))) + (unless (equal rst-toc-insert-style 'plain) + (insert pfx rst-toc-insert-number-separator)) + (insert (or (caar node) "[missing node]")) + ;; Add properties to the text, even though in normal text mode it + ;; won't be doing anything for now. Not sure that I want to change + ;; mode stuff. At least the highlighting gives the idea that this + ;; is generated automatically. + (put-text-property b (point) 'mouse-face 'highlight) + (put-text-property b (point) 'rst-toc-target (cadar node)) + (put-text-property b (point) 'keymap rst-toc-insert-click-keymap) + + ) + (insert "\n") + + ;; Prepare indent for children. + (setq indent + (cond + ((eq rst-toc-insert-style 'plain) + (concat indent rst-toc-indent)) + + ((eq rst-toc-insert-style 'fixed) + (concat indent (make-string rst-toc-indent ? ))) + + ((eq rst-toc-insert-style 'aligned) + (concat indent (make-string (+ (length pfx) 2) ? ))) + + ((eq rst-toc-insert-style 'listed) + (concat (substring indent 0 -3) + (concat (make-string (+ (length pfx) 2) ? ) " - "))) + )) + ) (if (or (eq rst-toc-insert-max-level nil) (< level rst-toc-insert-max-level)) @@ -1401,12 +1481,12 @@ necessary for all the children of this level to align." (dolist (child (cdr node)) (rst-toc-insert-node child - (1+ level) - indent - (if do-child-numbering - (concat pfx (format fmt count)) pfx)) + (1+ level) + indent + (if do-child-numbering + (concat pfx (format fmt count)) pfx)) (incf count))) - + ))) @@ -1469,7 +1549,7 @@ make it up-to-date automatically." (let ((b (point))) ;; Insert line text. (insert (make-string (* rst-toc-indent (1- level)) ? )) - (insert (if (car node) (caar node) "[missing node]")) + (insert (or (caar node) "[missing node]")) ;; Highlight lines. (put-text-property b (point) 'mouse-face 'highlight) @@ -1477,11 +1557,30 @@ make it up-to-date automatically." ;; Add link on lines. (put-text-property b (point) 'rst-toc-target (cadar node)) - (insert "\n"))) + (insert "\n") + )) (dolist (child (cdr node)) (rst-toc-node child (1+ level)))) +(defun rst-toc-count-lines (node target-node) + "Count the number of lines to the TARGET-NODE node. This +recursive function returns a cons of the number of additional +lines that have been counted for its node and children and 't if +the node has been found." + + (let ((count 1) + found) + (if (eq node target-node) + (setq found t) + (let ((child (cdr node))) + (while (and child (not found)) + (let ((cl (rst-toc-count-lines (car child) target-node))) + (setq count (+ count (car cl)) + found (cdr cl) + child (cdr child)))))) + (cons count found))) + (defun rst-toc () "Finds all the section titles and their decorations in the @@ -1493,29 +1592,18 @@ make it up-to-date automatically." brings the cursor in that section." (interactive) (let* ((curbuf (current-buffer)) - outline - + ;; Get the section tree (alldecos (rst-find-all-decorations)) (sectree (rst-section-tree alldecos)) + (our-node (cdr (rst-section-tree-point sectree))) + line + ;; Create a temporary buffer. (buf (get-buffer-create rst-toc-buffer-name)) ) - ;; Find the index of the section where the cursor currently is. - (setq outline (let ((idx 1) - (curline (line-number-at-pos (point))) - (decos alldecos)) - (while (and decos (<= (caar decos) curline)) - (setq decos (cdr decos)) - (incf idx)) - idx)) - ;; FIXME: if there is a missing node inserted, the calculation of the - ;; current line will be off. You need to fix this by moving the finding of - ;; the current line somewhere else. - - (with-current-buffer buf (let ((inhibit-read-only t)) (rst-toc-mode) @@ -1524,6 +1612,9 @@ make it up-to-date automatically." (put-text-property (point-min) (point) 'face (list '(background-color . "lightgray"))) (rst-toc-node sectree 0) + + ;; Count the lines to our found node. + (setq line (car (rst-toc-count-lines sectree our-node))) )) (display-buffer buf) (pop-to-buffer buf) @@ -1532,7 +1623,7 @@ make it up-to-date automatically." (set (make-local-variable 'rst-toc-return-buffer) curbuf) ;; Move the cursor near the right section in the TOC. - (goto-line outline) + (goto-line line) )) @@ -1660,15 +1751,26 @@ make it up-to-date automatically." - + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Functions to indent/dedent item lists, which are always two-characters apart ;; horizontally with rest. +(defvar rst-shift-fill-region nil + "Set to true if you want to automatically re-fill the region that is being +shifted.") +;; FIXME: need to finish this feature properly. + + (defun rst-shift-region-right () "Indent region ridigly, by two characters to the right." (interactive) - (indent-rigidly (region-beginning) (region-end) 2)) + (let ((mbeg (set-marker (make-marker) (region-beginning))) + (mend (set-marker (make-marker) (region-end)))) + (indent-rigidly mbeg mend 2) + (when rst-shift-fill-region + (fill-region mbeg mend)) + )) (defun rst-find-leftmost-column (beg end) "Finds the leftmost column in the region." @@ -1677,8 +1779,8 @@ make it up-to-date automatically." (goto-char beg) (while (< (point) end) (back-to-indentation) - (if (not (looking-at "[ \t]*$")) - (setq mincol (min mincol (current-column)))) + (unless (looking-at "[ \t]*$") + (setq mincol (min mincol (current-column)))) (forward-line 1) )) mincol)) @@ -1691,8 +1793,14 @@ up to the leftmost character in the region." (let ((chars (if pfxarg (- (rst-find-leftmost-column (region-beginning) (region-end))) - -2))) - (indent-rigidly (region-beginning) (region-end) chars))) + -2)) + (mbeg (set-marker (make-marker) (region-beginning))) + (mend (set-marker (make-marker) (region-end))) + ) + (indent-rigidly mbeg mend chars) + (when rst-shift-fill-region + (fill-region mbeg mend)) + )) -- cgit v1.2.1 From 802bf9dd04a354ee3e32293adce30a910bf2389b Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 8 Nov 2005 02:36:28 +0000 Subject: added end to Emacs stanza git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4005 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/nodes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docutils/nodes.py b/docutils/nodes.py index b45cd1bcf..0eff86aab 100644 --- a/docutils/nodes.py +++ b/docutils/nodes.py @@ -1741,3 +1741,4 @@ def serial_escape(value): # indent-tabs-mode: nil # sentence-end-double-space: t # fill-column: 78 +# End: -- cgit v1.2.1 From 5a2fe25641fb8bccf11187fd9e5e6926cfe2f2c2 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 8 Nov 2005 02:38:20 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4006 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/readers/doctree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docutils/readers/doctree.py b/docutils/readers/doctree.py index a1984e966..4138fb51e 100644 --- a/docutils/readers/doctree.py +++ b/docutils/readers/doctree.py @@ -16,10 +16,10 @@ class Reader(readers.ReReader): The existing document tree must be passed as the ``source`` parameter to the `docutils.core.Publisher` initializer, wrapped in a - `docutils.io.DoctreeInput` object:: + `docutils.io.DocTreeInput` object:: pub = docutils.core.Publisher( - ..., source=docutils.io.DoctreeInput(document), ...) + ..., source=docutils.io.DocTreeInput(document), ...) The original document settings are overridden; if you want to use the settings of the original document, pass ``settings=document.settings`` to -- cgit v1.2.1 From 1c513403e0ba8b3e011653c35bb4b94bf672cfc8 Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 8 Nov 2005 14:28:52 +0000 Subject: Fixed minor bug in rst-toc. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4014 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 143c7f688..041ba223e 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -1323,14 +1323,14 @@ child. This has advantages later in processing the graph." (let* ((curpoint (or point (point)))) ;; Check if we are before the current node. - (if (> curpoint (cadar node)) + (if (>= curpoint (cadar node)) ;; Iterate all the children, looking for one that might contain the ;; current section. (let ((curnode (cdr node)) last) - (while (and curnode (> curpoint (cadaar curnode))) + (while (and curnode (>= curpoint (cadaar curnode))) (setq last curnode curnode (cdr curnode))) @@ -1614,7 +1614,8 @@ the node has been found." (rst-toc-node sectree 0) ;; Count the lines to our found node. - (setq line (car (rst-toc-count-lines sectree our-node))) + (let ((linefound (rst-toc-count-lines sectree our-node))) + (setq line (if (cdr linefound) (car linefound) 0))) )) (display-buffer buf) (pop-to-buffer buf) -- cgit v1.2.1 From faea343429656d64f59c3a63f5de700fbdd73449 Mon Sep 17 00:00:00 2001 From: blais Date: Tue, 8 Nov 2005 16:49:03 +0000 Subject: Removed obsolete comment in emacs description. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4015 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 219e8e250..20edbb6fa 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -482,8 +482,6 @@ sink of editors: We could perform this guessing by searching for a valid decoration at the top of the document or searching for reStructuredText_ directives further on. -- We would like to support local table of contents insertion. - - The suggested decorations when adjusting should not have to cycle below one below the last section decoration level preceding the cursor. We need to fix that. -- cgit v1.2.1 From 8e3232334aa306645df2d8cfbd24a166c6971d76 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 8 Nov 2005 19:30:03 +0000 Subject: typo git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4016 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 20edbb6fa..971b61638 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -268,7 +268,7 @@ Major Mode for Editing reStructuredText Documents ================================================= There is a major mode available for editing and syntax highlighting -reStructuredText_ constructs. This mode was written by Stefan Merten [#]. It +reStructuredText_ constructs. This mode was written by Stefan Merten [#]_. It mostly provides lazy syntax coloring for many of the constructs that reStructuredText_ prescribes. -- cgit v1.2.1 From 8394b9a6ca28be76427354ccc492bc79697b0c34 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 8 Nov 2005 19:34:43 +0000 Subject: refilled at column 70 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4017 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 299 +++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 141 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 971b61638..119bf2b41 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -40,30 +40,31 @@ Introduction ============ -reStructuredText_ is a series of conventions that allows a toolset--docutils--to -extract generic document structure from simple text files. For people who use -Emacs_, there is a package that adds some support for the conventions that -reStructuredText_ specifies: ``rst.el``. +reStructuredText_ is a series of conventions that allows a +toolset--docutils--to extract generic document structure from simple +text files. For people who use Emacs_, there is a package that adds +some support for the conventions that reStructuredText_ specifies: +``rst.el``. -This document describes the most important features that it provides, how to -setup your emacs to use them and how to invoke them. +This document describes the most important features that it provides, +how to setup your emacs to use them and how to invoke them. Basic Setup =========== -The emacs support is completely provided by the ``rst.el`` emacs package. In -order to use these features, you need to put the file in your emacs load-path, -and to load it with:: +The emacs support is completely provided by the ``rst.el`` emacs +package. In order to use these features, you need to put the file in +your emacs load-path, and to load it with:: (require 'rst) ;; or (load "rst") -Additional configuration variables can be customized and can be found by -browsing the source code for ``rst.el``. +Additional configuration variables can be customized and can be found +by browsing the source code for ``rst.el``. -Then you will want to bind keys to the most common commands it provides. A -standard text-mode hook function is maintained and provided by the package for -this use, set it up like this:: +Then you will want to bind keys to the most common commands it +provides. A standard text-mode hook function is maintained and +provided by the package for this use, set it up like this:: (add-hook 'text-mode-hook 'rst-text-mode-bindings) @@ -74,13 +75,14 @@ it is bound to the mode-specific-map and ``p``, e.g. ``C-c p ...``. Section Decoration Adjustment ============================= -The rst package does not completely parse all the reStructuredText_ constructs, -but it contains the ability to recognize the section decorations and to build -the hierarchy of the document. What we call section decorations or adornments -are the underlines or under- and overlines used to mark a section title. +The rst package does not completely parse all the reStructuredText_ +constructs, but it contains the ability to recognize the section +decorations and to build the hierarchy of the document. What we call +section decorations or adornments are the underlines or under- and +overlines used to mark a section title. There is a function that helps a great deal to maintain these -decorations: ``rst-adjust`` (bound on ``C-c p a``, ``C-c p =`` or +decorations: ``rst-adjust`` (bound on ``C-c p a``, ``C-c p =`` or ``C-=`` by default). This function is a Swiss army knife that can be invoked repeatedly and whose behaviour depends on context: @@ -89,65 +91,68 @@ invoked repeatedly and whose behaviour depends on context: My Section Title ^^ - Invocation will complete the section title. You can simply enter a few - characters of the title and invoke the function to complete it. It can also - be used to adjust the length of the existing decoration when you need to edit - the title. + Invocation will complete the section title. You can simply enter a + few characters of the title and invoke the function to complete it. + It can also be used to adjust the length of the existing decoration + when you need to edit the title. -#. If there is no section decoration, a decoration one level under the last - encountered section level is added; +#. If there is no section decoration, a decoration one level under the + last encountered section level is added; -#. If there is already a section decoration, it is promoted to the next level. - You can invoke it like this repeatedly to cycle the title through the - hierarchy of existing decorations. +#. If there is already a section decoration, it is promoted to the + next level. You can invoke it like this repeatedly to cycle the + title through the hierarchy of existing decorations. -Invoking the function with a negative prefix argument, e.g. ``C-- C-=``, will -effectively reverse the direction of decoration cycling. To alternate between -underline-only and over-and-under styles, you can use a regular prefix argument, -e.g. ``C-u C-=``. See the documentation of ``rst-adjust`` for more description -of the prefix arguments to alter the behaviour of the function. +Invoking the function with a negative prefix argument, e.g. ``C-- +C-=``, will effectively reverse the direction of decoration cycling. +To alternate between underline-only and over-and-under styles, you can +use a regular prefix argument, e.g. ``C-u C-=``. See the +documentation of ``rst-adjust`` for more description of the prefix +arguments to alter the behaviour of the function. Promoting and Demoting Many Sections ------------------------------------ -When you are re-organizing the structure of a document, it can be useful to -change the level of a number of section titles. The same key binding can be -used to do that: if the region is active when the binding is invoked, all the -section titles that are within the region are promoted accordingly (or demoted, -with negative prefix arg). +When you are re-organizing the structure of a document, it can be +useful to change the level of a number of section titles. The same +key binding can be used to do that: if the region is active when the +binding is invoked, all the section titles that are within the region +are promoted accordingly (or demoted, with negative prefix arg). Customizations -------------- -You can set the variable ``rst-preferred-decorations`` to a list of the -decorations that you like to use for documents. Everyone has their preference. -``rst-default-indent`` can be set to the number of indent spaces preferred for -the over-and-under decoration style. +You can set the variable ``rst-preferred-decorations`` to a list of +the decorations that you like to use for documents. Everyone has +their preference. ``rst-default-indent`` can be set to the number of +indent spaces preferred for the over-and-under decoration style. Viewing the Hierarchy of Section Decorations ============================================ -You can visualize the hierarchy of the section decorations in the current buffer -by invoking ``rst-display-decorations-hierarchy``, bound on ``C-c p h``. A -temporary buffer will appear with fake section titles rendered in the style of -the current document. This can be useful when editing other people's documents -to find out which section decorations correspond to which levels. +You can visualize the hierarchy of the section decorations in the +current buffer by invoking ``rst-display-decorations-hierarchy``, +bound on ``C-c p h``. A temporary buffer will appear with fake +section titles rendered in the style of the current document. This +can be useful when editing other people's documents to find out which +section decorations correspond to which levels. Table of Contents ================= -When you are editing long documents, it can be a bit difficult to orient -yourself in the structure of your text. To that effect, a function is provided -that quickly parses the document and presents a hierarchically indented table of -contents of the document in a temporary buffer, in which you can navigate and -press ``Return`` to go to a specific section. +When you are editing long documents, it can be a bit difficult to +orient yourself in the structure of your text. To that effect, a +function is provided that quickly parses the document and presents a +hierarchically indented table of contents of the document in a +temporary buffer, in which you can navigate and press ``Return`` to go +to a specific section. -Invoke this function (``rst-toc``) with ``C-c p t``. It should present a -temporary buffer that looks something like this:: +Invoke this function (``rst-toc``) with ``C-c p t``. It should +present a temporary buffer that looks something like this:: Table of Contents: Debugging Meta-Techniques @@ -166,25 +171,26 @@ temporary buffer that looks something like this:: Good Feelings References -When you select a section title, the temporary buffer disappears and you are -left with the cursor positioned at the chosen section. +When you select a section title, the temporary buffer disappears and +you are left with the cursor positioned at the chosen section. Inserting a Table of Contents ----------------------------- -Oftentimes in long text documents that are meant to be read directly, a Table of -Contents is inserted at the beginning of the text. This is the case for most -internet FAQs, for example. In reStructuredText_ documents, since the table of -contents is automatically generated by the parser with the ``.. contents::`` -directive, people generally have not been adding a text table of contents to -their source documents, and partly because it is too much trouble to edit and -maintain. +Oftentimes in long text documents that are meant to be read directly, +a Table of Contents is inserted at the beginning of the text. This is +the case for most internet FAQs, for example. In reStructuredText_ +documents, since the table of contents is automatically generated by +the parser with the ``.. contents::`` directive, people generally have +not been adding a text table of contents to their source documents, +and partly because it is too much trouble to edit and maintain. -The emacs support for reStructuredText_ provides a function to insert such a -table of contents in your document. Since it is not meant to be part of the -document text, you should place such a table of contents within a comment, so -that it is ignored by the parser. This is the favoured usage:: +The emacs support for reStructuredText_ provides a function to insert +such a table of contents in your document. Since it is not meant to +be part of the document text, you should place such a table of +contents within a comment, so that it is ignored by the parser. This +is the favoured usage:: .. contents:: .. @@ -220,11 +226,12 @@ the following variables:: ``rst-toc-indent``, Maintaining the Table of Contents Up-to-date -------------------------------------------- -One issue is that you will probably want to maintain the inserted table of -contents up-to-date. There is a function that will automatically look for the -inserted TOC (``rst-toc-insert-update``) and it can be added to a hook on the -section decoration adjustment function, so that every time you adjust a section -title, the TOC is updated. Add this functionality with the following emacs +One issue is that you will probably want to maintain the inserted +table of contents up-to-date. There is a function that will +automatically look for the inserted TOC (``rst-toc-insert-update``) +and it can be added to a hook on the section decoration adjustment +function, so that every time you adjust a section title, the TOC is +updated. Add this functionality with the following emacs configuration:: (add-hook 'rst-adjust-hook 'rst-toc-insert-update) @@ -244,8 +251,9 @@ C-p`` and ``C-c C-n``). Shifting Bulleted List Levels ============================= -Due to the nature of reStructuredText_, bulleted lists are always indented by -two characters (unless they are part of a blockquote), e.g. :: +Due to the nature of reStructuredText_, bulleted lists are always +indented by two characters (unless they are part of a blockquote), +e.g. :: - Fruits @@ -258,19 +266,20 @@ two characters (unless they are part of a blockquote), e.g. :: - Zucchini - Chick Peas -To this effect, when re-organizing bulleted lists, it can be useful to shift -regions of text by indents of two characters. You can use the ``C-c C-r`` and -``C-c C-l`` to shift the current region. These bindings are similar to the ones -provided by python-mode for editing python code and behave similarly. +To this effect, when re-organizing bulleted lists, it can be useful to +shift regions of text by indents of two characters. You can use the +``C-c C-r`` and ``C-c C-l`` to shift the current region. These +bindings are similar to the ones provided by python-mode for editing +python code and behave similarly. Major Mode for Editing reStructuredText Documents ================================================= There is a major mode available for editing and syntax highlighting -reStructuredText_ constructs. This mode was written by Stefan Merten [#]_. It -mostly provides lazy syntax coloring for many of the constructs that -reStructuredText_ prescribes. +reStructuredText_ constructs. This mode was written by Stefan Merten +[#]_. It mostly provides lazy syntax coloring for many of the +constructs that reStructuredText_ prescribes. To enable this mode, type ``M-x rst-mode`` or you can set up an ``auto-mode-alist`` to automatically turn it on whenever you visit @@ -278,9 +287,9 @@ reStructuredText_ documents:: (add-to-list 'auto-mode-alist '("\\.rst$" . rst-mode) ) -If have local variables enabled (see ``enable-local-variables`` in the Emacs -manual), you can also add the following at the top of your documents to trigger -rst-mode:: +If have local variables enabled (see ``enable-local-variables`` in the +Emacs manual), you can also add the following at the top of your +documents to trigger rst-mode:: .. -*- mode: rst -*- @@ -291,55 +300,58 @@ Or add this at the end of your documents:: mode: rst End: -By default, the font-lock colouring is performed lazily. If you don't like -this, you can turn this off by setting the value of ``rst-mode-lazy``. You can -also change the various colours (see the source file for the whole list of -customizable faces). +By default, the font-lock colouring is performed lazily. If you don't +like this, you can turn this off by setting the value of +``rst-mode-lazy``. You can also change the various colours (see the +source file for the whole list of customizable faces). -.. [#] This mode used to be provided by the file ``rst-mode.el`` and has now - been integrated with the rest of the emacs code. +.. [#] This mode used to be provided by the file ``rst-mode.el`` and + has now been integrated with the rest of the emacs code. Converting Documents from Emacs =============================== -At the moment there is minimal support for calling the conversion tools from -within Emacs. You can add a key binding like this to invoke it:: +At the moment there is minimal support for calling the conversion +tools from within Emacs. You can add a key binding like this to +invoke it:: (local-set-key [(control c)(?9)] 'rst-compile) -This function basically creates a compilation command with the correct output -name for the current buffer and then invokes Emacs' compile function. It also -looks for the presence of a ``docutils.conf`` configuration file in the parent -directories and adds it to the cmdline options. You can customize which tool is -used to perform the conversion and some standard options to always be added as -well. +This function basically creates a compilation command with the correct +output name for the current buffer and then invokes Emacs' compile +function. It also looks for the presence of a ``docutils.conf`` +configuration file in the parent directories and adds it to the +cmdline options. You can customize which tool is used to perform the +conversion and some standard options to always be added as well. -Invocation uses the toolset indicated by ``rst-compile-primary-toolset`` -(default is ``'html``). Invocation with a prefix argument uses -``rst-compile-secondary-toolset``. +Invocation uses the toolset indicated by +``rst-compile-primary-toolset`` (default is ``'html``). Invocation +with a prefix argument uses ``rst-compile-secondary-toolset``. .. note:: - In general it is preferred to use a Makefile to automate the conversion of - many documents or a hierarchy of documents. The functionality presented - above is meant to be convenient for use on single files. + In general it is preferred to use a Makefile to automate the + conversion of many documents or a hierarchy of documents. The + functionality presented above is meant to be convenient for use on + single files. Other / External Useful Emacs Settings ====================================== -This section covers general emacs text-mode settings that are useful in the -context of reStructuredText_ conventions. These are not provided by ``rst.el`` -but you may find them useful specifically for reStructuredText_ documents. +This section covers general emacs text-mode settings that are useful +in the context of reStructuredText_ conventions. These are not +provided by ``rst.el`` but you may find them useful specifically for +reStructuredText_ documents. Settings for Filling Bulleted Lists ----------------------------------- -One problem with the default text-mode settings is that *filling* long lines in -bulleted lists that do not have an empty line between them merges them together, -e.g.:: +One problem with the default text-mode settings is that *filling* long +lines in bulleted lists that do not have an empty line between them +merges them together, e.g.:: - Bananas; - One Apple a day keeps the doctor away, and eating more keeps the pirates at bay; @@ -347,19 +359,20 @@ e.g.:: Becomes:: - - Bananas; One Apple a day keeps the doctor away, and - - eating more keeps the pirates at bay; Oranges; + - Bananas; One Apple a day keeps the doctor away, and eating more + - keeps the pirates at bay; Oranges; This is usually not what you want. What you want is this:: - Bananas; - - One Apple a day keeps the doctor away, and eating more - keeps the pirates at bay; + - One Apple a day keeps the doctor away, and eating more keeps + the pirates at bay; - Oranges; -The problem is that emacs does not recognize the various consecutive items as -forming paragraph boundaries. You can fix this easily by changing the global -value of the parapraph boundary detection to recognize such lists, like this:: +The problem is that emacs does not recognize the various consecutive +items as forming paragraph boundaries. You can fix this easily by +changing the global value of the parapraph boundary detection to +recognize such lists, like this:: (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-+*] ")) @@ -367,9 +380,9 @@ value of the parapraph boundary detection to recognize such lists, like this:: ``text-mode`` Settings ---------------------- -Consult the Emacs manual for more text-mode customizations. In particular, you -may be interested in setting the following variables, functions and modes that -pertain somewhat to text-mode: +Consult the Emacs manual for more text-mode customizations. In +particular, you may be interested in setting the following variables, +functions and modes that pertain somewhat to text-mode: - indent-tabs-mode - colon-double-space @@ -381,8 +394,9 @@ pertain somewhat to text-mode: Editing Tables: Emacs table mode -------------------------------- -You may want to check out `Emacs table mode`_ to create an edit tables, it -allows creating ascii tables compatible with reStructuredText_. +You may want to check out `Emacs table mode`_ to create an edit +tables, it allows creating ascii tables compatible with +reStructuredText_. .. _Emacs table mode: http://table.sourceforge.net/ @@ -452,39 +466,42 @@ __ http://www.tobias-jung.de/seekingprofont/ Credits ======= -- The automatic section adjustment and table of contents features were written - by Martin Blais; -- ``rst-mode`` and its syntax highlighting was implemented by Stefan Merten; +- The automatic section adjustment and table of contents features were + written by Martin Blais; +- ``rst-mode`` and its syntax highlighting was implemented by Stefan + Merten; - Various other functions were implemented by David Goodger. Obsolete Files ============== -On 2005-10-30, ``restructuredtext.el``, ``rst-html.el`` and ``rst-mode.el`` were -merged to form the new ``rst.el``. You can consider the old files obsolete and -remove them. +On 2005-10-30, ``restructuredtext.el``, ``rst-html.el`` and +``rst-mode.el`` were merged to form the new ``rst.el``. You can +consider the old files obsolete and remove them. Future Work =========== -Here are some features and ideas that will be worked on in the future, in those -frenzied mornings of excitement over the virtues of the one-true-way kitchen -sink of editors: +Here are some features and ideas that will be worked on in the future, +in those frenzied mornings of excitement over the virtues of the +one-true-way kitchen sink of editors: -- It would be nice to differentiate between text files using reStructuredText_ - and other general text files. If we had a function to automatically guess - whether a .txt file is following the reStructuredText_ conventions, we could - trigger rst-mode without having to hard-code this in every text file, nor - forcing the user to add a local mode variable at the top of the file. +- It would be nice to differentiate between text files using + reStructuredText_ and other general text files. If we had a + function to automatically guess whether a .txt file is following the + reStructuredText_ conventions, we could trigger rst-mode without + having to hard-code this in every text file, nor forcing the user to + add a local mode variable at the top of the file. - We could perform this guessing by searching for a valid decoration at the top - of the document or searching for reStructuredText_ directives further on. + We could perform this guessing by searching for a valid decoration + at the top of the document or searching for reStructuredText_ + directives further on. -- The suggested decorations when adjusting should not have to cycle below one - below the last section decoration level preceding the cursor. We need to fix - that. +- The suggested decorations when adjusting should not have to cycle + below one below the last section decoration level preceding the + cursor. We need to fix that. .. _Emacs: http://www.gnu.org/software/emacs/emacs.html -- cgit v1.2.1 From d02faf5adc38eec669a143d8a224c53d9c664b3d Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 8 Nov 2005 21:48:57 +0000 Subject: replaced "felixwiemann" with "fwiemann" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4020 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/release.txt | 6 +++--- docs/dev/website.txt | 12 ++++++------ docs/user/links.txt | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/dev/release.txt b/docs/dev/release.txt index b242720d0..fa58bc46f 100644 --- a/docs/dev/release.txt +++ b/docs/dev/release.txt @@ -11,9 +11,9 @@ (Steps in boldface text are *not* covered by the release script at -sandbox/felixwiemann/release.sh. "Not covered" means that you aren't -even reminded of them. Note: The release.sh script needs to be -updated to reflect the recent move to Subversion!) +sandbox/fwiemann/release.sh. "Not covered" means that you aren't even +reminded of them. Note: The release.sh script needs to be updated to +reflect the recent move to Subversion!) * **Announce a check-in freeze on Docutils-develop. Post a list of major changes since the last release and ask for additions.** diff --git a/docs/dev/website.txt b/docs/dev/website.txt index 193e9c0f2..d374b1004 100644 --- a/docs/dev/website.txt +++ b/docs/dev/website.txt @@ -10,12 +10,12 @@ The Docutils web site, , is maintained automatically by the ``docutils-update`` script, run as an -hourly cron job on shell.berlios.de (by user "felixwiemann"). The -script will process any .txt file which is newer than the -corresponding .html file in the project's web directory on -shell.berlios.de (``/home/groups/docutils/htdocs/aux/htdocs/``) and -upload the changes to the web site at SourceForge. For a new .txt -file, just SSH to ``@shell.berlios.de`` and :: +hourly cron job on shell.berlios.de (by user "fwiemann"). The script +will process any .txt file which is newer than the corresponding .html +file in the project's web directory on shell.berlios.de +(``/home/groups/docutils/htdocs/aux/htdocs/``) and upload the changes +to the web site at SourceForge. For a new .txt file, just SSH to +``@shell.berlios.de`` and :: cd /home/groups/docutils/htdocs/aux/htdocs/ touch filename.html diff --git a/docs/user/links.txt b/docs/user/links.txt index 75c0fae0e..3bb2aaa70 100644 --- a/docs/user/links.txt +++ b/docs/user/links.txt @@ -115,7 +115,7 @@ code base. .. _rst2ht: http://www.rutherfurd.net/articles/rst-ht2html.html .. _ht2html: http://ht2html.sourceforge.net/ .. _htmlnav: http://docutils.sf.net/sandbox/gschwant/htmlnav/ -.. _xhtml2rest: http://docutils.sf.net/sandbox/felixwiemann/xhtml2rest/ +.. _xhtml2rest: http://docutils.sf.net/sandbox/fwiemann/xhtml2rest/ .. _rst2chm: http://www.rutherfurd.net/software/rst2chm/ .. _rest2web: http://www.voidspace.org.uk/python/rest2web/ .. _Docutils Sandbox: http://docutils.sf.net/sandbox/README.html -- cgit v1.2.1 From c04b23630d974d9c6878e84348a0c5e23280f3aa Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 8 Nov 2005 21:51:31 +0000 Subject: partial revert -- the website cron job is still run by felixwiemann; sorry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4021 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/website.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/dev/website.txt b/docs/dev/website.txt index d374b1004..193e9c0f2 100644 --- a/docs/dev/website.txt +++ b/docs/dev/website.txt @@ -10,12 +10,12 @@ The Docutils web site, , is maintained automatically by the ``docutils-update`` script, run as an -hourly cron job on shell.berlios.de (by user "fwiemann"). The script -will process any .txt file which is newer than the corresponding .html -file in the project's web directory on shell.berlios.de -(``/home/groups/docutils/htdocs/aux/htdocs/``) and upload the changes -to the web site at SourceForge. For a new .txt file, just SSH to -``@shell.berlios.de`` and :: +hourly cron job on shell.berlios.de (by user "felixwiemann"). The +script will process any .txt file which is newer than the +corresponding .html file in the project's web directory on +shell.berlios.de (``/home/groups/docutils/htdocs/aux/htdocs/``) and +upload the changes to the web site at SourceForge. For a new .txt +file, just SSH to ``@shell.berlios.de`` and :: cd /home/groups/docutils/htdocs/aux/htdocs/ touch filename.html -- cgit v1.2.1 From d66e00e85902ec5667ba03392be74c625c4efeb3 Mon Sep 17 00:00:00 2001 From: wiemann Date: Tue, 8 Nov 2005 22:06:36 +0000 Subject: added to do list entry about redundancy in pep.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4022 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index f4e9948a6..9ac05be2a 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1657,6 +1657,15 @@ HTML Writer identifying them as such. Text in Docutils language module. +PEP/HTML Writer +=============== + +* ``@import`` html4css1.css instead of duplicating it in ``pep.css``. + + Problem: If the stylesheet is embedded, the reference to + html4css1.css will break. + + LaTeX writer ============ -- cgit v1.2.1 From ee0347212ded62289dcaaa63c5b208c1c3fc97f7 Mon Sep 17 00:00:00 2001 From: blais Date: Wed, 9 Nov 2005 18:33:49 +0000 Subject: Added revision field to rst.el since it is likely it will be copied around git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4023 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 041ba223e..c9f597753 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -5,6 +5,7 @@ ;;; :Authors: Martin Blais , ;;; Stefan Merten , ;;; David Goodger +;;; :Revision: $Revision$ ;;; :Date: $Date$ ;;; :Copyright: This module has been placed in the public domain. ;;; :Abstract: -- cgit v1.2.1 From ca0592c455966c669c7258a559fc8e032381d210 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 10 Nov 2005 04:38:48 +0000 Subject: added & modified some entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4024 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 9ac05be2a..b79224b6e 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -478,6 +478,17 @@ General Seems like a bad idea as long as it isn't independent from the ouput format (for example, navigation bars are only useful for web pages). +* docutils_update: Check for a ``Makefile`` in a directory, and run + ``make`` if found? This would allow for variant processing on + specific source files, such as running rst2s5.py instead of + rst2html.py. + +* Improve handing of RCS/CVS/SVN keywords, especially "Date". Under + SVN, the "Date" keyword expands to a huge string: ``2005-11-08 + 00:22:00 -0500 (Tue, 08 Nov 2005)``. This should be reduced to the + IS0 8601 standard ``2005-11-08``, or (perhaps optionally) some other + short form. + Documentation ============= @@ -1660,11 +1671,16 @@ HTML Writer PEP/HTML Writer =============== -* ``@import`` html4css1.css instead of duplicating it in ``pep.css``. +* ``@import`` html4css1.css instead of duplicating it in ``pep.css``? Problem: If the stylesheet is embedded, the reference to html4css1.css will break. + Also, ``pep.css`` really has only one major customer: python.org. + The PEP stylesheet serves its purpose well for them. They have no + use for modular, imported stylesheets, which would only increase + bandwidth and add complexity. + LaTeX writer ============ @@ -1808,6 +1824,9 @@ Features & issues: * Directive to begin a new slide, continuation, using the same title as the previous slide? (Unnecessary?) +* Have a timeout on incremental items, so the colour goes away after 1 + second. + Here's an example that I was hoping to show at PyCon DC 2005:: ======================== -- cgit v1.2.1 From 08e27cd7865ce0940b2f04e42dba24a38a491a7d Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 10 Nov 2005 18:16:31 +0000 Subject: added comments to to-do list entry about pep.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4041 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index b79224b6e..c23c90719 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1674,13 +1674,22 @@ PEP/HTML Writer * ``@import`` html4css1.css instead of duplicating it in ``pep.css``? Problem: If the stylesheet is embedded, the reference to - html4css1.css will break. + html4css1.css will break. So it might be better to use a secondary + stylesheet for the PEP writer. I.e., the PEP writer uses the HTML + writer's standard stylesheet *plus* the ``pep.css`` stylesheet. + (Driving this concept even further, we could allow for three + stylesheets [HTML writer, PEP writer, user] or any number of + stylesheets. It's just a bit difficult to come up with a proper + option syntax for that.) Also, ``pep.css`` really has only one major customer: python.org. The PEP stylesheet serves its purpose well for them. They have no use for modular, imported stylesheets, which would only increase bandwidth and add complexity. + On the other hand, we don't really want to maintain two stylesheets + in parallel. The redundancy inevitably causes errors. + LaTeX writer ============ -- cgit v1.2.1 From 2dd0fe3fe16bbad8951e92efee11e23601240e6a Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Nov 2005 14:37:18 +0000 Subject: Fixed the DocInfo transform to handle SVN-style expansion of the "Date" keyword (this was actually a bug, not a to-do; the correct behavior was specified in the docs) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4042 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 5 +++++ docs/dev/todo.txt | 6 ------ docutils/transforms/frontmatter.py | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 86250b48b..82c9e26aa 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -94,6 +94,11 @@ Changes Since 0.3.9 * 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. + * docutils/transforms/misc.py: - Added misc.Transitions transform, extracted from diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index c23c90719..9e598f205 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -483,12 +483,6 @@ General specific source files, such as running rst2s5.py instead of rst2html.py. -* Improve handing of RCS/CVS/SVN keywords, especially "Date". Under - SVN, the "Date" keyword expands to a huge string: ``2005-11-08 - 00:22:00 -0500 (Tue, 08 Nov 2005)``. This should be reduced to the - IS0 8601 standard ``2005-11-08``, or (perhaps optionally) some other - short form. - Documentation ============= diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index b03388f72..a05ec3dbd 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -445,8 +445,8 @@ class DocInfo(Transform): return 1 rcs_keyword_substitutions = [ - (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$', - re.IGNORECASE), r'\1-\2-\3'), + (re.compile(r'\$' r'Date: (\d\d\d\d)[-/](\d\d)[-/](\d\d) [\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'),] -- cgit v1.2.1 From f9f81d1faa5dc25f320f3eec244dd46182dbc9c0 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 11 Nov 2005 16:03:42 +0000 Subject: simplified test git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4043 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/test_transforms/test_docinfo.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index d14d2c48f..b2b968391 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -305,32 +305,22 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ ["""\ .. RCS keyword extraction. -:Status: $""" + """RCSfile: test_docinfo.py,v $ +:Status: (some text) $""" + """RCSfile: test_docinfo.py,v $ (more text) :Date: (some text) $""" + """Date: 2002/10/08 01:34:23 $ (more text) -:Version: $""" + """Revision: 1.1 $ (still more text) - -RCS keyword 'RCSfile' doesn't change unless the file name changes, -so it's safe. The 'Date' keyword changes every time the file is -checked in to CVS, so the test's expected output text has to be -derived (hacked) in parallel in order to stay in sync. +:Version: (some text) $""" + """Revision: 1.1 $ (more text) """, """\ - test_docinfo.py + (some text) test_docinfo.py (more text) - (some text) %s (more text) + (some text) 2002-10-08 (more text) - 1.1 (still more text) + (some text) 1.1 (more text) RCS keyword extraction. - - RCS keyword 'RCSfile' doesn't change unless the file name changes, - so it's safe. The 'Date' keyword changes every time the file is - checked in to CVS, so the test's expected output text has to be - derived (hacked) in parallel in order to stay in sync. -""" % (('$' 'Date: 2002/10/08 01:34:23 $')[7:17].replace('/', '-'),)], +"""], ]) -- cgit v1.2.1 From 0a2380fb0d3ed4244b6b6b05f6b3fb1236556652 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 11 Nov 2005 16:10:03 +0000 Subject: fixed Subversion Date keyword parsing git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4044 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/transforms/frontmatter.py | 2 +- test/test_transforms/test_docinfo.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py index a05ec3dbd..d7d954306 100644 --- a/docutils/transforms/frontmatter.py +++ b/docutils/transforms/frontmatter.py @@ -445,7 +445,7 @@ class DocInfo(Transform): return 1 rcs_keyword_substitutions = [ - (re.compile(r'\$' r'Date: (\d\d\d\d)[-/](\d\d)[-/](\d\d) [\d:]+' + (re.compile(r'\$' r'Date: (\d\d\d\d)[-/](\d\d)[-/](\d\d)[ 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'),] diff --git a/test/test_transforms/test_docinfo.py b/test/test_transforms/test_docinfo.py index b2b968391..b77c568ff 100755 --- a/test/test_transforms/test_docinfo.py +++ b/test/test_transforms/test_docinfo.py @@ -307,6 +307,7 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ :Status: (some text) $""" + """RCSfile: test_docinfo.py,v $ (more text) :Date: (some text) $""" + """Date: 2002/10/08 01:34:23 $ (more text) +:Date: (some text) $""" + """Date: 2005-03-26T16:21:28.693201Z $ (more text) :Version: (some text) $""" + """Revision: 1.1 $ (more text) """, """\ @@ -316,6 +317,8 @@ totest['bibliographic_field_lists'] = ((DocInfo,), [ (some text) test_docinfo.py (more text) (some text) 2002-10-08 (more text) + + (some text) 2005-03-26 (more text) (some text) 1.1 (more text) -- cgit v1.2.1 From 733eed7d7052687ac904b32406d7359aa01bfb70 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 13 Nov 2005 23:07:31 +0000 Subject: make alltests runnable with "unittestgui.py alltests.suite" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4045 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/alltests.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/test/alltests.py b/test/alltests.py index 9c5d8b0aa..c6a44e003 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -68,25 +68,27 @@ def pformat(suite): indent -= step return '\n'.join(output) +def suite(): + path, script = os.path.split(sys.argv[0]) + suite = package_unittest.loadTestModules(path, 'test_', packages=1) + sys.stdout.flush() + return suite # must redirect stderr *before* first import of unittest sys.stdout = sys.stderr = Tee('alltests.out') import package_unittest -print ('Testing Docutils %s [%s] with Python %s on %s at %s' - % (docutils.__version__, docutils.__version_details__, - sys.version.split()[0], - time.strftime('%Y-%m-%d'), time.strftime('%H:%M:%S'))) -sys.stdout.flush() -path, script = os.path.split(sys.argv[0]) -suite = package_unittest.loadTestModules(path, 'test_', packages=1) -sys.stdout.flush() - -package_unittest.main(suite) -#if package_unittest.verbosity > 1: -# print >>sys.stderr, pformat(suite) # check the test suite -finish = time.time() - -print 'Elapsed time: %.3f seconds' % (finish - start) +if __name__ == '__main__': + suite = suite() + print ('Testing Docutils %s [%s] with Python %s on %s at %s' + % (docutils.__version__, docutils.__version_details__, + sys.version.split()[0], + time.strftime('%Y-%m-%d'), time.strftime('%H:%M:%S'))) + sys.stdout.flush() + package_unittest.main(suite) + #if package_unittest.verbosity > 1: + # print >>sys.stderr, pformat(suite) # check the test suite + finish = time.time() + print 'Elapsed time: %.3f seconds' % (finish - start) -- cgit v1.2.1 From 9b72c761dd04281a1fbaa4cf54d5e25a44045bf8 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Nov 2005 00:56:11 +0000 Subject: added bug with non-existent working directory git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4046 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index f0ee7f202..a3f4445bd 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -111,6 +111,35 @@ Known Bugs Also see the `SourceForge Bug Tracker`_. +* .. _non-existent working directory: + + Running Docutils in a no-longer existent working directory causes a + crash:: + + $ rst2pseudoxml.py + Traceback (most recent call last): + File "/home/felix/bin/rst2pseudoxml.py", line 25, in ? + publish_cmdline(description=description) + File "/home/felix/.python/lib/docutils/core.py", line 329, in publish_cmdline + config_section=config_section, enable_exit_status=enable_exit_status) + File "/home/felix/.python/lib/docutils/core.py", line 197, in publish + self.process_command_line( + File "/home/felix/.python/lib/docutils/core.py", line 155, in process_command_line + self.settings = option_parser.parse_args(argv) + File "/usr/lib/python2.4/optparse.py", line 1280, in parse_args + return self.check_values(values, args) + File "/home/felix/.python/lib/docutils/frontend.py", line 577, in check_values + os.getcwd()) + OSError: [Errno 2] No such file or directory + + Reproduce by creating a directory, cd'ing into it, rd'ing the + directory in a separate shell and running "rst2pseudoxml.py" in the + original shell. + + To fix this, we'd need to fix all occurences of os.getcwd(). Maybe + add a docutils.utils.getcwd() function which returns an empty string + on OSError? + * The "stylesheet" setting (a URL, to be used verbatim) should be allowed to be combined with "embed_stylesheet". The stylesheet data should be read in using urllib. There was an assumption that a -- cgit v1.2.1 From ec0122cc48a0d2dbd664c1f2150d0e89387eb9c2 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Nov 2005 01:40:54 +0000 Subject: made a list item out of a history paragraph so that the list is compacted git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4047 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 82c9e26aa..f6bcc741b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -162,12 +162,12 @@ Changes Since 0.3.9 * docutils/writers/support/: Directory added to project. Modules and data files that support writers have been moved here. - The stylesheets are now installed along with the code, the code now - knows where to find them, and the default is now to use (actually, - to embed) the built-in stylesheets. 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". + * The stylesheets are now installed along with the code, the code + now knows where to find them, and the default is now to use + (actually, to embed) the built-in stylesheets. 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/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. -- cgit v1.2.1 From c2ecc8e9779eb6f004a7e35fd5160669723cd813 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 14 Nov 2005 18:11:32 +0000 Subject: small addition git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4048 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/policies.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/dev/policies.txt b/docs/dev/policies.txt index 3bf3914d0..25fb4f2e9 100644 --- a/docs/dev/policies.txt +++ b/docs/dev/policies.txt @@ -415,6 +415,21 @@ ways to keep the Docutils code accessible during development: reinstall the "docutils" package, Python won't see your latest changes. +A useful addition to the ``docutils`` top-level directory in branches +and alternate copies of the code is a ``set-PATHS`` file +containing the following lines:: + + # source this file + export PYTHONPATH=$PWD:$PWD/extras + export PATH=$PWD/tools:$PATH + +Open a shell for this branch, ``cd`` to the ``docutils`` top-level +directory, and "source" this file. For example, using the bash +shell:: + + $ cd some-branch/docutils + $ . set-PATHS + Mailing Lists ============= -- cgit v1.2.1 From 976c10fa68fc7259c79ba878f947be0db7f0a66e Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Nov 2005 18:53:41 +0000 Subject: added item about citation enhancements; marked item about branch policy as done git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4049 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 9e598f205..34e8fa7a1 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -47,7 +47,7 @@ the short term) to include: * [DONE in rev. 3901] Remove docutils.transforms.html.StylesheetCheck (no longer needed because of the above change). -* Incorporate new branch policy into the docs. [DavidG] +* [DONE in rev. 3962] Incorporate new branch policy into the docs. ("Development strategy" thread on Docutils-develop) * Fix East-Asian `double-width characters`_ issue. [DavidG] @@ -680,6 +680,9 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* The citation syntax could use some enhancements. See + . + * The current list-recognition logic has too many false positives, as in :: -- cgit v1.2.1 From 4c6e12f22380c422aabc8f34b0f1409f4a60229f Mon Sep 17 00:00:00 2001 From: blais Date: Mon, 14 Nov 2005 19:18:01 +0000 Subject: - Added default bindings for rst-compile - Added constants for paragraph-{start,separate} - Fixed bug with rst-toc when the file was empty. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4050 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index c9f597753..692bf5075 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -205,6 +205,8 @@ (define-key rst-prefix-map "r" 'rst-shift-region-right) (define-key rst-prefix-map "l" 'rst-shift-region-left) (define-key rst-prefix-map "u" 'rst-toc-insert-update) +(define-key rst-prefix-map "c" 'rst-compile) +(define-key rst-prefix-map "C" (lambda () (interactive) (rst-compile t))) (defun rst-text-mode-bindings () "Default text mode hook for rest." @@ -238,6 +240,20 @@ "con" ".. contents::\n..\n " nil 0) +;; Paragraph separation customization. Set those to replace the default values +;; of text-mode. These will work better in restructuredtext documents and should +;; not affect filling for other documents too much. Set it up like this: +;; +;; (setq paragraph-start rst-paragraph-start +;; paragraph-separate rst-paragraph-separate) +(defvar rst-paragraph-separate + "\f\\|>*[ \t]*$" + "Extra parapraph-separate patterns to add for text-mode.") + +(defvar rst-paragraph-start + "\f\\|>*[ \t]*$\\|>*[ \t]*[-+*] \\|>*[ \t]*[0-9]+\\. " + "Extra parapraph-start patterns to add for text-mode.") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1286,8 +1302,9 @@ child. This has advantages later in processing the graph." (let ((ndeco (cadr decos)) node children) + ;; If the next decoration matches our level - (when (= (car ndeco) lev) + (when (and ndeco (= (car ndeco) lev)) ;; Pop the next decoration and create the current node with it (setcdr decos (cddr decos)) (setq node (cdr ndeco)) ) @@ -1324,7 +1341,7 @@ child. This has advantages later in processing the graph." (let* ((curpoint (or point (point)))) ;; Check if we are before the current node. - (if (>= curpoint (cadar node)) + (if (and (cadar node) (>= curpoint (cadar node))) ;; Iterate all the children, looking for one that might contain the ;; current section. -- cgit v1.2.1 From 79508c7cfb55418cfd6c7030c99c42b3758dfa20 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 15 Nov 2005 23:59:26 +0000 Subject: minor edits & corrections git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4057 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/config.txt | 5 ++--- docutils/writers/html4css1.py | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/user/config.txt b/docs/user/config.txt index db38ac1ab..2f6fa40c8 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -324,9 +324,8 @@ _`output_encoding_error_handler` --output-encoding, -o``. _`record_dependencies` - - Path to a file to which Docutils writes a list of files the input - file(s) depends on [#dependencies]_, e.g. due to file + Path to a file where Docutils will write a list of files that the + input and output depend on [#dependencies]_, e.g. due to file inclusion. [#pwd]_ The format is one filename per line. This option is particularly useful in conjunction with programs like ``make``. diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index 380d648af..a53bda2ca 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -45,8 +45,7 @@ class Writer(writers.Writer): 'HTML-Specific Options', None, (('Specify a stylesheet URL, used verbatim. Overrides ' - '--stylesheet-path. Either --stylesheet or --stylesheet-path ' - 'must be specified.', + '--stylesheet-path.', ['--stylesheet'], {'metavar': '', 'overrides': 'stylesheet_path'}), ('Specify a stylesheet file, relative to the current working ' -- cgit v1.2.1 From 5fe7c5067c6c5a2512c4d8747292041247ed4035 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 19:02:41 +0000 Subject: removed to-do list entry about redundancy in pep.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4061 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 34e8fa7a1..4db433631 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1665,29 +1665,6 @@ HTML Writer identifying them as such. Text in Docutils language module. -PEP/HTML Writer -=============== - -* ``@import`` html4css1.css instead of duplicating it in ``pep.css``? - - Problem: If the stylesheet is embedded, the reference to - html4css1.css will break. So it might be better to use a secondary - stylesheet for the PEP writer. I.e., the PEP writer uses the HTML - writer's standard stylesheet *plus* the ``pep.css`` stylesheet. - (Driving this concept even further, we could allow for three - stylesheets [HTML writer, PEP writer, user] or any number of - stylesheets. It's just a bit difficult to come up with a proper - option syntax for that.) - - Also, ``pep.css`` really has only one major customer: python.org. - The PEP stylesheet serves its purpose well for them. They have no - use for modular, imported stylesheets, which would only increase - bandwidth and add complexity. - - On the other hand, we don't really want to maintain two stylesheets - in parallel. The redundancy inevitably causes errors. - - LaTeX writer ============ -- cgit v1.2.1 From 906d3ce3a4f095cc123758ae8c31dbb4d4fa59c6 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 19:31:47 +0000 Subject: add zh_cn (simplified Chinese) language mappings; thanks to Panjunyong! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4062 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 3 +- docutils/languages/zh_cn.py | 76 ++++++++++++++++++++++ docutils/parsers/rst/languages/zh_cn.py | 108 ++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 docutils/languages/zh_cn.py create mode 100644 docutils/parsers/rst/languages/zh_cn.py diff --git a/THANKS.txt b/THANKS.txt index c326be75d..f0d38afcc 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -98,8 +98,9 @@ donations, tasty treats, and related projects: * Paul Moore * Nigel W. Moriarty * Mark Nodine -* Patrick K. O'Brien * Omidyar Network (Pierre Omidyar & Doug Solomon) +* Panjunyong +* Patrick K. O'Brien * Michel Pelletier * Sam Penrose * Tim Peters diff --git a/docutils/languages/zh_cn.py b/docutils/languages/zh_cn.py new file mode 100644 index 000000000..d5ab5865b --- /dev/null +++ b/docutils/languages/zh_cn.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Author: Pan Junyong +# Contact: panjy@zopechina.com +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read . Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Simplified Chinese language mappings for language-dependent features +of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': '作者', + 'authors': '作者群', + 'organization': '组织', + 'address': '地址', + 'contact': '联系', + 'version': '版本', + 'revision': '修订', + 'status': '状态', + 'date': '日期', + 'copyright': '版权', + 'dedication': '献辞', + 'abstract': '摘要', + 'attention': '注意', + 'caution': '小心', + 'danger': '危险', + 'error': '错误', + 'hint': '提示', + 'important': '重要', + 'note': '注解', + 'tip': '技巧', + 'warning': '警告', + 'contents': '目录', +} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + '作者': 'author', + '作者群': 'authors', + '组织': 'organization', + '地址': 'address', + '联系': 'contact', + '版本': 'version', + '修订': 'revision', + '状态': 'status', + '时间': 'date', + '版权': 'copyright', + '献辞': 'dedication', + '摘要': 'abstract'} +"""Traditional Chinese to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ',', + u'\uff1b', # ';' + u'\uff0c', # ',' + u'\u3001', # '、' + ] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" + +# Decode UTF-8 strings. (We cannot use unicode literals directly for +# Python 2.1 compatibility.) +for mapping in labels, bibliographic_fields: + for key, value in mapping.items(): + del mapping[key] + mapping[unicode(key, 'utf8')] = unicode(value, 'utf8') diff --git a/docutils/parsers/rst/languages/zh_cn.py b/docutils/parsers/rst/languages/zh_cn.py new file mode 100644 index 000000000..a8cf20f29 --- /dev/null +++ b/docutils/parsers/rst/languages/zh_cn.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Author: Panjunyong +# Contact: panjy@zopechina.com +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read . Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Simplified Chinese language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + '注意': 'attention', + '小心': 'caution', + '危险': 'danger', + '错误': 'error', + '提示': 'hint', + '重要': 'important', + '注解': 'note', + '技巧': 'tip', + '警告': 'warning', + '忠告': 'admonition', + '侧框': 'sidebar', + '主题': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', + '醒目': 'rubric', + '铭文': 'epigraph', + '要点': 'highlights', + 'pull-quote (translation required)': 'pull-quote', + '复合': 'compound', + '容器': 'container', + #'questions (translation required)': 'questions', + '表格': 'table', + 'csv表格': 'csv-table', + '列表表格': 'list-table', + #'qa (translation required)': 'questions', + #'faq (translation required)': 'questions', + '元数据': 'meta', + #'imagemap (translation required)': 'imagemap', + '图象': 'image', + '图例': 'figure', + '包含': 'include', + '原文': 'raw', + '代替': 'replace', + '统一码': 'unicode', + '类型': 'class', + '角色': 'role', + '默认角色': 'default-role', + '标题': 'title', + '目录': 'contents', + '章节序号': 'sectnum', + '题头': 'header', + '页脚': 'footer', + #'footnotes (translation required)': 'footnotes', + #'citations (translation required)': 'citations', + 'target-notes (translation required)': 'target-notes', + 'restructuredtext-test-directive': 'restructuredtext-test-directive'} +"""Traditional Chinese name to registered (in directives/__init__.py) +directive name mapping.""" + +roles = { + # language-dependent: fixed + '缩写': 'abbreviation', + '简称': 'acronym', + 'index (translation required)': 'index', + 'i (translation required)': 'index', + '下标': 'subscript', + '上标': 'superscript', + 'title-reference (translation required)': 'title-reference', + 'title (translation required)': 'title-reference', + 't (translation required)': 'title-reference', + 'pep-reference (translation required)': 'pep-reference', + 'pep (translation required)': 'pep-reference', + 'rfc-reference (translation required)': 'rfc-reference', + 'rfc (translation required)': 'rfc-reference', + '强调': 'emphasis', + '加粗': 'strong', + '字面': 'literal', + 'named-reference (translation required)': 'named-reference', + 'anonymous-reference (translation required)': 'anonymous-reference', + 'footnote-reference (translation required)': 'footnote-reference', + 'citation-reference (translation required)': 'citation-reference', + 'substitution-reference (translation required)': 'substitution-reference', + 'target (translation required)': 'target', + 'uri-reference (translation required)': 'uri-reference', + 'uri (translation required)': 'uri-reference', + 'url (translation required)': 'uri-reference', + 'raw (translation required)': 'raw',} +"""Mapping of Traditional Chinese role names to canonical role names for +interpreted text.""" + +# Decode UTF-8 strings. (We cannot use unicode literals directly for +# Python 2.1 compatibility.) +for mapping in directives, roles: + for key, value in mapping.items(): + del mapping[key] + mapping[unicode(key, 'utf8')] = unicode(value, 'utf8') -- cgit v1.2.1 From 36c37e0532a5e7c81d6104399c53d22525b40030 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 19:48:52 +0000 Subject: documented default 'latex of rst-compile-secondary-toolset git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4063 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 119bf2b41..d5e0ad27b 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -327,7 +327,8 @@ conversion and some standard options to always be added as well. Invocation uses the toolset indicated by ``rst-compile-primary-toolset`` (default is ``'html``). Invocation -with a prefix argument uses ``rst-compile-secondary-toolset``. +with a prefix argument uses ``rst-compile-secondary-toolset`` (default +is ``'latex``). .. note:: -- cgit v1.2.1 From 1f68707289264e7fd291feda677af3a85d37fc04 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 20:12:33 +0000 Subject: replaced "traditional" with "simplified" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4064 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/languages/zh_cn.py | 2 +- docutils/parsers/rst/languages/zh_cn.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docutils/languages/zh_cn.py b/docutils/languages/zh_cn.py index d5ab5865b..e3b7e3cd5 100644 --- a/docutils/languages/zh_cn.py +++ b/docutils/languages/zh_cn.py @@ -58,7 +58,7 @@ bibliographic_fields = { '版权': 'copyright', '献辞': 'dedication', '摘要': 'abstract'} -"""Traditional Chinese to canonical name mapping for bibliographic fields.""" +"""Simplified Chinese to canonical name mapping for bibliographic fields.""" author_separators = [';', ',', u'\uff1b', # ';' diff --git a/docutils/parsers/rst/languages/zh_cn.py b/docutils/parsers/rst/languages/zh_cn.py index a8cf20f29..2d3a4679b 100644 --- a/docutils/parsers/rst/languages/zh_cn.py +++ b/docutils/parsers/rst/languages/zh_cn.py @@ -66,7 +66,7 @@ directives = { #'citations (translation required)': 'citations', 'target-notes (translation required)': 'target-notes', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} -"""Traditional Chinese name to registered (in directives/__init__.py) +"""Simplified Chinese name to registered (in directives/__init__.py) directive name mapping.""" roles = { @@ -97,8 +97,8 @@ roles = { 'uri (translation required)': 'uri-reference', 'url (translation required)': 'uri-reference', 'raw (translation required)': 'raw',} -"""Mapping of Traditional Chinese role names to canonical role names for -interpreted text.""" +"""Mapping of Simplified Chinese role names to canonical role names +for interpreted text.""" # Decode UTF-8 strings. (We cannot use unicode literals directly for # Python 2.1 compatibility.) -- cgit v1.2.1 From 418442c57a552004a711983f75abebd8e3ec9da7 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 20:32:29 +0000 Subject: added Japanese language files; thanks Hisashi Morita! git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4065 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- THANKS.txt | 1 + docutils/languages/ja.py | 62 +++++++++++++++++++++ docutils/parsers/rst/languages/ja.py | 104 +++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 docutils/languages/ja.py create mode 100644 docutils/parsers/rst/languages/ja.py diff --git a/THANKS.txt b/THANKS.txt index f0d38afcc..5917a3b03 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -97,6 +97,7 @@ donations, tasty treats, and related projects: * Skip Montanaro * Paul Moore * Nigel W. Moriarty +* Hisashi Morita * Mark Nodine * Omidyar Network (Pierre Omidyar & Doug Solomon) * Panjunyong diff --git a/docutils/languages/ja.py b/docutils/languages/ja.py new file mode 100644 index 000000000..ee0ed4749 --- /dev/null +++ b/docutils/languages/ja.py @@ -0,0 +1,62 @@ +# Author: Hisashi Morita +# Contact: hisashim@kt.rim.or.jp +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read . Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Japanese-language mappings for language-dependent features of Docutils. +""" + +__docformat__ = 'reStructuredText' + +labels = { + # fixed: language-dependent + 'author': u'\u8457\u8005', + 'authors': u'\u8457\u8005', + 'organization': u'\u7d44\u7e54', + 'address': u'\u4f4f\u6240', + 'contact': u'\u9023\u7d61\u5148', + 'version': u'\u30d0\u30fc\u30b8\u30e7\u30f3', + 'revision': u'\u30ea\u30d3\u30b8\u30e7\u30f3', + 'status': u'30b9\u30c6\u30fc\u30bf\u30b9', + 'date': u'\u65e5\u4ed8', + 'copyright': u'\u8457\u4f5c\u6a29', + 'dedication': u'\u732e\u8f9e', + 'abstract': u'\u6982\u8981', + 'attention': u'\u6ce8\u76ee\u0021', + 'caution': u'\u6ce8\u610f\u0021', + 'danger': u'\u0021\u5371\u967a\u0021', + 'error': u'\u30a8\u30e9\u30fc', + 'hint': u'\u30d2\u30f3\u30c8', + 'important': u'\u91cd\u8981', + 'note': u'\u5099\u8003', + 'tip': u'\u0054\u0069\u0070', + 'warning': u'\ufeff\u8b66\u544a', + 'contents': u'\u76ee\u6b21'} +"""Mapping of node class name to label text.""" + +bibliographic_fields = { + # language-dependent: fixed + 'author (translation required)': 'author', + 'authors (translation required)': 'authors', + 'organization (translation required)': 'organization', + 'address (translation required)': 'address', + 'contact (translation required)': 'contact', + 'version (translation required)': 'version', + 'revision (translation required)': 'revision', + 'status (translation required)': 'status', + 'date (translation required)': 'date', + 'copyright (translation required)': 'copyright', + 'dedication (translation required)': 'dedication', + 'abstract (translation required)': 'abstract'} +"""Japanese (lowcased) to canonical name mapping for bibliographic fields.""" + +author_separators = [';', ','] +"""List of separator strings for the 'Authors' bibliographic field. Tried in +order.""" diff --git a/docutils/parsers/rst/languages/ja.py b/docutils/parsers/rst/languages/ja.py new file mode 100644 index 000000000..8131d94f9 --- /dev/null +++ b/docutils/parsers/rst/languages/ja.py @@ -0,0 +1,104 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +# New language mappings are welcome. Before doing a new translation, please +# read . Two files must be +# translated for each language: one in docutils/languages, the other in +# docutils/parsers/rst/languages. + +""" +Japanese-language mappings for language-dependent features of +reStructuredText. +""" + +__docformat__ = 'reStructuredText' + + +directives = { + # language-dependent: fixed + 'attention (translation required)': 'attention', + 'caution (translation required)': 'caution', + 'danger (translation required)': 'danger', + 'error (translation required)': 'error', + 'hint (translation required)': 'hint', + 'important (translation required)': 'important', + 'note (translation required)': 'note', + 'tip (translation required)': 'tip', + 'warning (translation required)': 'warning', + 'admonition (translation required)': 'admonition', + 'sidebar (translation required)': 'sidebar', + 'topic (translation required)': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', + 'rubric (translation required)': 'rubric', + 'epigraph (translation required)': 'epigraph', + 'highlights (translation required)': 'highlights', + 'pull-quote (translation required)': 'pull-quote', + 'compound (translation required)': 'compound', + 'container (translation required)': 'container', + #'questions (translation required)': 'questions', + 'table (translation required)': 'table', + 'csv-table (translation required)': 'csv-table', + 'list-table (translation required)': 'list-table', + #'qa (translation required)': 'questions', + #'faq (translation required)': 'questions', + 'meta (translation required)': 'meta', + #'imagemap (translation required)': 'imagemap', + 'image (translation required)': 'image', + 'figure (translation required)': 'figure', + 'include (translation required)': 'include', + 'raw (translation required)': 'raw', + 'replace (translation required)': 'replace', + 'unicode (translation required)': 'unicode', + 'class (translation required)': 'class', + 'role (translation required)': 'role', + 'default-role (translation required)': 'default-role', + 'title (translation required)': 'title', + 'contents (translation required)': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + 'header (translation required)': 'header', + 'footer (translation required)': 'footer', + #'footnotes (translation required)': 'footnotes', + #'citations (translation required)': 'citations', + 'target-notes (translation required)': 'target-notes',} +"""Japanese name to registered (in directives/__init__.py) directive name +mapping.""" + +roles = { + # language-dependent: fixed + 'abbreviation (translation required)': 'abbreviation', + 'ab (translation required)': 'abbreviation', + 'acronym (translation required)': 'acronym', + 'ac (translation required)': 'acronym', + 'index (translation required)': 'index', + 'i (translation required)': 'index', + 'subscript (translation required)': 'subscript', + 'sub (translation required)': 'subscript', + 'superscript (translation required)': 'superscript', + 'sup (translation required)': 'superscript', + 'title-reference (translation required)': 'title-reference', + 'title (translation required)': 'title-reference', + 't (translation required)': 'title-reference', + 'pep-reference (translation required)': 'pep-reference', + 'pep (translation required)': 'pep-reference', + 'rfc-reference (translation required)': 'rfc-reference', + 'rfc (translation required)': 'rfc-reference', + 'emphasis (translation required)': 'emphasis', + 'strong (translation required)': 'strong', + 'literal (translation required)': 'literal', + 'named-reference (translation required)': 'named-reference', + 'anonymous-reference (translation required)': 'anonymous-reference', + 'footnote-reference (translation required)': 'footnote-reference', + 'citation-reference (translation required)': 'citation-reference', + 'substitution-reference (translation required)': 'substitution-reference', + 'target (translation required)': 'target', + 'uri-reference (translation required)': 'uri-reference', + 'uri (translation required)': 'uri-reference', + 'url (translation required)': 'uri-reference', + 'raw (translation required)': 'raw',} +"""Mapping of Japanese role names to canonical role names for interpreted +text.""" -- cgit v1.2.1 From 87214f4fbe7b85c6305d5127b7bd672df2b99f3c Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 21:12:36 +0000 Subject: added bug "List items with an empty first line" git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4066 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/BUGS.txt b/BUGS.txt index a3f4445bd..35b8ab51f 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -111,6 +111,31 @@ Known Bugs Also see the `SourceForge Bug Tracker`_. +* _`List items with an empty first line` don't work as expected:: + + 1. + foo + + places "foo" inside a block quote, whereas :: + + 1. + foo + + (which should normally be invalid) causes the "foo" paragraph to + wind up inside the list item. + + The behavior also depends on whether there is a space after the list + marker:: + + 1. + foo + + works as expected. With multiple spaces after the marker, the list + item contents must be indented with mutiple spaces. + + This is bad. Invisible white space at the end of a line shouldn't + impact the parsing results. + * .. _non-existent working directory: Running Docutils in a no-longer existent working directory causes a -- cgit v1.2.1 From b775a81b52fedbb19c60f6b0aff673427eaa0c9e Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 22:57:02 +0000 Subject: added reference to older thread about citations git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4067 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 4db433631..387939224 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -681,7 +681,8 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do * The citation syntax could use some enhancements. See - . + and + . * The current list-recognition logic has too many false positives, as in :: -- cgit v1.2.1 From 64c87695885a0fb6bbab4a6e3579396baa72d21e Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 23:24:52 +0000 Subject: use hook instead of direct setq git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4068 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index d5e0ad27b..512c11fb2 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -13,28 +13,6 @@ instructions are provided. .. contents:: -.. - 1 Introduction - 2 Basic Setup - 3 Section Decoration Adjustment - 3.1 Promoting and Demoting Many Sections - 3.2 Customizations - 4 Viewing the Hierarchy of Section Decorations - 5 Table of Contents - 5.1 Inserting a Table of Contents - 5.2 Maintaining the Table of Contents Up-to-date - 6 Navigating Between the Section Titles - 7 Shifting Bulleted List Levels - 8 Major Mode for Editing reStructuredText Documents - 9 Converting Documents from Emacs - 10 Other / External Useful Emacs Settings - 10.1 Settings for Filling Bulleted Lists - 10.2 ``text-mode`` Settings - 10.3 Editing Tables: Emacs table mode - 10.4 Character Processing - 11 Credits - 12 Obsolete Files - 13 Future Work Introduction @@ -347,12 +325,12 @@ provided by ``rst.el`` but you may find them useful specifically for reStructuredText_ documents. -Settings for Filling Bulleted Lists ------------------------------------ +Settings for Filling Lists +-------------------------- One problem with the default text-mode settings is that *filling* long -lines in bulleted lists that do not have an empty line between them -merges them together, e.g.:: +lines in bullet and enumeration lists that do not have an empty line +between them merges them together, e.g.:: - Bananas; - One Apple a day keeps the doctor away, and eating more keeps the pirates at bay; @@ -375,7 +353,8 @@ items as forming paragraph boundaries. You can fix this easily by changing the global value of the parapraph boundary detection to recognize such lists, like this:: - (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-+*] ")) + (add-hook 'text-mode-hook + (lambda () (setq paragraph-start rst-paragraph-start))) ``text-mode`` Settings -- cgit v1.2.1 From 9c3c37edc8bfbbc040b8d2b7635dcf06d0522210 Mon Sep 17 00:00:00 2001 From: wiemann Date: Thu, 17 Nov 2005 23:36:02 +0000 Subject: use rst-set-paragraph-separation function for setting paragraph-start; removed stuff for filling quoted text -- it breaks for trailing quote signs and after all that's what message-mode is for git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4069 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 8 ++++---- tools/editors/emacs/rst.el | 21 ++++++++------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 512c11fb2..4f44ffaf6 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -329,7 +329,7 @@ Settings for Filling Lists -------------------------- One problem with the default text-mode settings is that *filling* long -lines in bullet and enumeration lists that do not have an empty line +lines in bulleted and enumeration lists that do not have an empty line between them merges them together, e.g.:: - Bananas; @@ -351,10 +351,10 @@ This is usually not what you want. What you want is this:: The problem is that emacs does not recognize the various consecutive items as forming paragraph boundaries. You can fix this easily by changing the global value of the parapraph boundary detection to -recognize such lists, like this:: +recognize such lists, using the ``rst-set-paragraph-separation`` +function:: - (add-hook 'text-mode-hook - (lambda () (setq paragraph-start rst-paragraph-start))) + (add-hook 'text-mode-hook 'rst-set-paragraph-separation) ``text-mode`` Settings diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 692bf5075..65ed2602d 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -240,19 +240,14 @@ "con" ".. contents::\n..\n " nil 0) -;; Paragraph separation customization. Set those to replace the default values -;; of text-mode. These will work better in restructuredtext documents and should -;; not affect filling for other documents too much. Set it up like this: -;; -;; (setq paragraph-start rst-paragraph-start -;; paragraph-separate rst-paragraph-separate) -(defvar rst-paragraph-separate - "\f\\|>*[ \t]*$" - "Extra parapraph-separate patterns to add for text-mode.") - -(defvar rst-paragraph-start - "\f\\|>*[ \t]*$\\|>*[ \t]*[-+*] \\|>*[ \t]*[0-9]+\\. " - "Extra parapraph-start patterns to add for text-mode.") +;; Paragraph separation customization. This will work better for +;; bulleted and enumerated lists in restructuredtext documents and +;; should not affect filling for other documents too much. Set it up +;; like this: +;; +;; (add-hook 'text-mode-hook 'rst-set-paragraph-separation) +(defun rst-set-paragraph-separation () + (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-+*] "))) -- cgit v1.2.1 From 0d6963e76ab125e3fd6a4665dc06453964767f08 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Nov 2005 04:26:30 +0000 Subject: corrected nomenclature git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4070 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/user/emacs.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/user/emacs.txt b/docs/user/emacs.txt index 4f44ffaf6..49687f599 100644 --- a/docs/user/emacs.txt +++ b/docs/user/emacs.txt @@ -226,10 +226,10 @@ default bound to the ``C-c p p`` and ``C-c p n`` keys (also ``C-c C-p`` and ``C-c C-n``). -Shifting Bulleted List Levels -============================= +Shifting Bullet List Levels +=========================== -Due to the nature of reStructuredText_, bulleted lists are always +Due to the nature of reStructuredText_, bullet lists are always indented by two characters (unless they are part of a blockquote), e.g. :: @@ -244,7 +244,7 @@ e.g. :: - Zucchini - Chick Peas -To this effect, when re-organizing bulleted lists, it can be useful to +To this effect, when re-organizing bullet lists, it can be useful to shift regions of text by indents of two characters. You can use the ``C-c C-r`` and ``C-c C-l`` to shift the current region. These bindings are similar to the ones provided by python-mode for editing @@ -329,7 +329,7 @@ Settings for Filling Lists -------------------------- One problem with the default text-mode settings is that *filling* long -lines in bulleted and enumeration lists that do not have an empty line +lines in bullet and enumerated lists that do not have an empty line between them merges them together, e.g.:: - Bananas; -- cgit v1.2.1 From 284948ef75ebb252eee6a827def10adbc11c989e Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Nov 2005 04:26:57 +0000 Subject: restored paragraph start for enumerated lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4071 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 65ed2602d..6b6292cff 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -241,14 +241,14 @@ ;; Paragraph separation customization. This will work better for -;; bulleted and enumerated lists in restructuredtext documents and +;; bullet and enumerated lists in restructuredtext documents and ;; should not affect filling for other documents too much. Set it up ;; like this: ;; ;; (add-hook 'text-mode-hook 'rst-set-paragraph-separation) (defun rst-set-paragraph-separation () - (setq paragraph-start (concat paragraph-start "\\|[ \t]*[-+*] "))) - + (setq paragraph-start (concat paragraph-start + "\\|[ \t]*[-+*] \\|[ \t]*[0-9]+\\. "))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- cgit v1.2.1 From 138b51f47305388e9ea149bb1159d6605e1a46af Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Nov 2005 18:02:08 +0000 Subject: fixed line wrapping git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4072 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 64 +++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 6b6292cff..01c2df9e8 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -22,7 +22,8 @@ ;;; decorations; ;;; - A mode that displays the table of contents and allows you to jump anywhere ;;; from it; -;;; - Functions to insert and automatically update a TOC in your source document; +;;; - Functions to insert and automatically update a TOC in your source +;;; document; ;;; - A mode which supports font-lock highlighting of reStructuredText ;;; structures; ;;; - Some other convenience functions. @@ -91,13 +92,16 @@ ;; ;; C-c p u: rst-toc-insert-update ;; -;; Find an existing inserted table-of-contents in the document an updates it. +;; Find an existing inserted table-of-contents in the document an +;; updates it. ;; -;; C-c p p, C-c p n (C-c C-p, C-c C-n): rst-backward-section, rst-forward-section +;; C-c p p, C-c p n (C-c C-p, C-c C-n): rst-backward-section, +;; rst-forward-section ;; ;; Navigate between section titles. ;; -;; C-c p l, C-c p r (C-c C-l, C-c C-r): rst-shift-region-left, rst-shift-region-right +;; C-c p l, C-c p r (C-c C-l, C-c C-r): rst-shift-region-left, +;; rst-shift-region-right ;; ;; Shift the region left or right by two-char increments, which is perfect ;; for bulleted lists. @@ -698,8 +702,8 @@ have been seen. ;; Overline only, leave all return values nil. ;; - ;; Note: we don't return the overline character, but it could perhaps - ;; in some cases be used to do something. + ;; Note: we don't return the overline character, but it could + ;; perhaps in some cases be used to do something. ((and over (eq under nil))) ;; Underline only. @@ -1052,7 +1056,7 @@ of the right hand fingers and the binding is unused in text-mode." (looking-at rst-section-text-regexp)) (progn (cond - ;;--------------------------------------------------------------------- + ;;------------------------------------------------------------------- ;; Case 1: No Decoration ((and (eq char nil) (eq style nil)) @@ -1085,7 +1089,7 @@ of the right hand fingers and the binding is unused in text-mode." indent-new (caddr cur)) )) - ;;--------------------------------------------------------------------- + ;;------------------------------------------------------------------- ;; Case 2: Incomplete Decoration ((not (rst-decoration-complete-p curdeco)) @@ -1097,7 +1101,7 @@ of the right hand fingers and the binding is unused in text-mode." style-new style indent-new indent)) - ;;--------------------------------------------------------------------- + ;;------------------------------------------------------------------- ;; Case 3: Complete Existing Decoration (t (if toggle-style @@ -1485,11 +1489,12 @@ necessary for all the children of this level to align." (if (> (length pfx) 0) (setq pfx (concat (rst-rstrip pfx) "."))) - ;; Calculate the amount of space that the prefix will require for - ;; the numbers. + ;; Calculate the amount of space that the prefix will require + ;; for the numbers. (if (cdr node) (setq fmt (format "%%-%dd" - (1+ (floor (log10 (length (cdr node)))))))) + (1+ (floor (log10 (length + (cdr node)))))))) )) (dolist (child (cdr node)) @@ -2060,7 +2065,10 @@ This value is expanded by `format' with an integer." 7 -7) "The step width to use for the next color. The formula -`rst-level-face-base-light' + (`rst-level-face-max' - 1) * `rst-level-face-step-light' + + `rst-level-face-base-light' + + (`rst-level-face-max' - 1) * `rst-level-face-step-light' + must result in a color level which appended to `rst-level-face-base-color' using `rst-level-face-format-light' results in a valid color such as `grey50'. This color is used as background for section title text on level @@ -2083,9 +2091,14 @@ title adornment). If you generally do not like how section title text faces are set up tweak here. If the general idea is ok for you but you do not like the details check the Rst Faces Defaults group." :group 'rst-faces - :type '(alist :key-type (choice (integer :tag "Section level (may not be bigger than `rst-level-face-max')") - (boolean :tag "transitions (on) / section title adornment (off)")) - :value-type (face)) + :type '(alist + :key-type + (choice + (integer + :tag + "Section level (may not be bigger than `rst-level-face-max')") + (boolean :tag "transitions (on) / section title adornment (off)")) + :value-type (face)) :set-after '(rst-level-face-max)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2256,7 +2269,8 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 1 rst-block-face) ;; `Enumerated Lists`_ (list - (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" re-blksep1 "\\)") + (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" + re-blksep1 "\\)") 1 rst-block-face) ;; `Definition Lists`_ FIXME: missing ;; `Field Lists`_ @@ -2265,7 +2279,8 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 1 rst-external-face) ;; `Option Lists`_ (list - (concat re-bol "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*\\([ =]\\S +\\)?\\)\\(,[\t ]\\)?\\)+\\)\\($\\|[\t ]\\{2\\}\\)") + (concat re-bol "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*" + "\\([ =]\\S +\\)?\\)\\(,[\t ]\\)?\\)+\\)\\($\\|[\t ]\\{2\\}\\)") 1 rst-block-face) ;; `Tables`_ FIXME: missing @@ -2277,13 +2292,15 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 1 rst-definition-face) ;; `Directives`_ / `Substitution Definitions`_ (list - (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" re-sym1 "+::\\)" re-blksep1) + (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" + re-sym1 "+::\\)" re-blksep1) (list 1 rst-directive-face) (list 2 rst-definition-face) (list 4 rst-directive-face)) ;; `Hyperlink Targets`_ (list - (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" re-blksep1) + (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" + re-blksep1) 1 rst-definition-face) (list (concat re-bol "\\(__\\)" re-blksep1) @@ -2314,7 +2331,8 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 2 rst-reference-face) ;; `Interpreted Text`_ (list - (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" re-sym1 "+:\\)?\\)" re-ims1) + (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" + re-sym1 "+:\\)?\\)" re-ims1) (list 2 rst-directive-face) (list 5 rst-external-face) (list 8 rst-directive-face)) @@ -2351,7 +2369,8 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and nil (list 1 '(cdr (assoc nil rst-adornment-faces-alist)) 'append t) - (list 2 '(cdr (assoc rst-font-lock-level rst-adornment-faces-alist)) + (list 2 '(cdr (assoc rst-font-lock-level + rst-adornment-faces-alist)) 'append t) (list 3 '(cdr (assoc nil rst-adornment-faces-alist)) 'append t))))) @@ -2782,4 +2801,3 @@ column is used (fill-column vs. end of previous/next line)." (provide 'rst) ;;; rst.el ends here - -- cgit v1.2.1 From 10fe81815ee364ef2faf683b4deebe3f2240a5d6 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Nov 2005 18:03:03 +0000 Subject: fixed rst-set-paragraph-separation, added rst-extra-paragraph-separate git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4073 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 01c2df9e8..fa49e1fee 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -250,9 +250,13 @@ ;; like this: ;; ;; (add-hook 'text-mode-hook 'rst-set-paragraph-separation) +(defvar rst-extra-paragraph-separate + "\\|[ \t]*\\([-+*]\\|[0-9]+\\.\\) " + "Extra parapraph-separate patterns to add for text-mode.") + (defun rst-set-paragraph-separation () - (setq paragraph-start (concat paragraph-start - "\\|[ \t]*[-+*] \\|[ \t]*[0-9]+\\. "))) + (make-local-variable 'paragraph-start) ; prevent it growing every time + (setq paragraph-start (concat paragraph-start rst-extra-paragraph-separate))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- cgit v1.2.1 From 5a5fa9fa7f892c5be7626379ff9ca0cdef626da5 Mon Sep 17 00:00:00 2001 From: grubert Date: Fri, 18 Nov 2005 18:20:52 +0000 Subject: Add width option to includegraphics and align to figure. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4074 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 78d8f1e35..21b525d93 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1378,10 +1378,15 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(':]') def visit_figure(self, node): - self.body.append( '\\begin{figure}[htbp]\\begin{center}\n' ) + if not node.attributes.has_key('align'): + align = 'center' + else: + align = 'flush'+node.attributes['align'] + self.body.append( '\\begin{figure}[htbp]\\begin{%s}\n' % align ) + self.context.append( '\\end{%s}\\end{figure}\n' % align ) def depart_figure(self, node): - self.body.append( '\\end{center}\\end{figure}\n' ) + self.body.append( self.context.pop() ) def visit_footer(self, node): self.context.append(len(self.body)) @@ -1484,13 +1489,16 @@ class LaTeXTranslator(nodes.NodeVisitor): # referring to a local file. self.settings.record_dependencies.add(attrs['uri']) pre = [] # in reverse order - post = ['\\includegraphics{%s}' % attrs['uri']] + post = [] + include_graphics_options = "" inline = isinstance(node.parent, nodes.TextElement) if attrs.has_key('scale'): # Could also be done with ``scale`` option to # ``\includegraphics``; doing it this way for consistency. pre.append('\\scalebox{%f}{' % (attrs['scale'] / 100.0,)) post.append('}') + if attrs.has_key('width'): + include_graphics_options = '[width=%s]' % attrs['width'] if attrs.has_key('align'): align_prepost = { # By default latex aligns the top of an image. @@ -1512,7 +1520,10 @@ class LaTeXTranslator(nodes.NodeVisitor): pre.append('\n') post.append('\n') pre.reverse() - self.body.extend(pre + post) + self.body.extend( pre ) + self.body.append( '\\includegraphics%s{%s}' % ( + include_graphics_options, attrs['uri'] ) ) + self.body.extend( post ) def depart_image(self, node): pass -- cgit v1.2.1 From 498f4a1bb34f9b1544e7a1fe502e4f62deffdbc1 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 18 Nov 2005 18:51:36 +0000 Subject: added to do list entry for field lists in list tables git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4075 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 387939224..a4847139b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1035,6 +1035,9 @@ when used in a document. * Make the _`directive interface` object-oriented (http://article.gmane.org/gmane.text.docutils.user/1871). +* Allow for field lists in list tables. See + . + * .. _unify tables: Unify table implementations and unify options of table directives -- cgit v1.2.1 From 510a5a30f076bb454fb0d301820a17fe489f0662 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 18 Nov 2005 19:23:52 +0000 Subject: moved container test to the end of standard.txt test data file; implemented container for latex2e git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4076 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/latex2e.py | 6 ++ .../expected/standalone_rst_html4css1.html | 88 +++++++++--------- test/functional/expected/standalone_rst_latex.tex | 49 ++++++---- .../expected/standalone_rst_pseudoxml.txt | 101 ++++++++++++--------- test/functional/input/data/standard.txt | 9 ++ test/functional/input/standalone_rst_html4css1.txt | 6 -- 6 files changed, 148 insertions(+), 111 deletions(-) diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py index 21b525d93..695160dd4 100644 --- a/docutils/writers/latex2e.py +++ b/docutils/writers/latex2e.py @@ -1060,6 +1060,12 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_contact(self, node): self.depart_docinfo_item(node) + def visit_container(self, node): + pass + + def depart_container(self, node): + pass + def visit_copyright(self, node): self.visit_docinfo_item(node, 'copyright') diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index a898da047..f95d99cb9 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -125,13 +125,14 @@ They are transformed from section titles after parsing. -->
  • 2.15   Substitution Definitions
  • 2.16   Comments
  • 2.17   Raw text
  • -
  • 2.18   Colspanning tables
  • -
  • 2.19   Rowspanning tables
  • -
  • 2.20   Complex tables
  • -
  • 2.21   List Tables
  • +
  • 2.18   Container
  • +
  • 2.19   Colspanning tables
  • +
  • 2.20   Rowspanning tables
  • +
  • 2.21   Complex tables
  • +
  • 2.22   List Tables
  • -
  • 3   Error Handling
  • +
  • 3   Error Handling
  • @@ -476,7 +477,7 @@ Here's a reference to the next footnote:
    +nonexistent footnote: [5]_.
    list table with integral header
    Contact: goodger@users.sourceforge.net
    Author:Me
    Author:Myself
    Author:I
    Authors:Me +
    Myself +
    I
    Organization: humankind
    Date:
    [4]Here's an unreferenced footnote, with a reference to a -nonexistent footnote: [5]_.
    @@ -489,7 +490,7 @@ nonexistent footnote: [CIT2002], and a [nonexistent]_ +

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    @@ -503,7 +504,7 @@ hyperlink targets are also possible.

    "Python [5]".

    Targets may be indirect and anonymous. Thus this phrase may also refer to the Targets section.

    -

    Here's a `hyperlink reference without a target`_, which generates an +

    Here's a `hyperlink reference without a target`_, which generates an error.

    2.13.1   Duplicate Target Names

    @@ -515,34 +516,34 @@ explicit targets will generate "warning" (level-2) system messages.

    2.13.2   Duplicate Target Names

    Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: `Duplicate Target Names`_), an error is generated.

    +this: `Duplicate Target Names`_), an error is generated.

    2.14   Directives

    These are just a sample of the many reStructuredText Directives. For others, please see http://docutils.sourceforge.net/docs/ref/rst/directives.html.

    -

    2.14.1   Document Parts

    +

    2.14.1   Document Parts

    An example of the "contents" directive can be seen above this section (a local, untitled table of contents) and at the beginning of the document (a document-wide table of contents).

    -

    2.14.2   Images

    +

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png

    Image with multiple IDs:

    @@ -610,7 +611,7 @@ document (a document-wide table o ../../../docs/user/rst/images/biohazard.png
    -

    2.14.3   Admonitions

    +

    2.14.3   Admonitions

    Attention!

    Directives at large.

    @@ -659,7 +660,7 @@ Reader discretion is strongly advised.

    -

    2.14.4   Topics, Sidebars, and Rubrics

    +

    2.14.4   Topics, Sidebars, and Rubrics

    -

    2.14.5   Target Footnotes

    +

    2.14.5   Target Footnotes

    @@ -691,11 +692,11 @@ background color.

    -

    2.14.7   Compound Paragraph

    +

    2.14.7   Compound Paragraph

    Compound 1, paragraph 1.

    Compound 1, paragraph 2.

    @@ -763,7 +764,7 @@ paragraph.
    -

    2.14.8   Parsed Literal Blocks

    +

    2.14.8   Parsed Literal Blocks

     This is a parsed literal block.
         This line is indented.  The next line is blank.
    @@ -795,7 +796,14 @@ Double-dashes - - "- -" - - must be escaped somehow in HTML output. -->
     A test.Second test.
    Another test with myclass set.

    This is the fourth test with myrawroleclass set.

    Fifth test in HTML.
    Line two.
    -

    2.18   Colspanning tables

    +

    2.18   Container

    +
    +

    paragraph 1

    +

    paragraph 2

    +
    +
    +
    +

    2.19   Colspanning tables

    This table has a cell spanning two columns:

    @@ -833,7 +841,7 @@ Fifth test in HTML.
    Line two.
    -

    2.19   Rowspanning tables

    +

    2.20   Rowspanning tables

    Here's a table with cells spanning several rows:

    @@ -866,7 +874,7 @@ cell.
    -

    2.20   Complex tables

    +

    2.21   Complex tables

    Here's a complex table, which should test all features.

    @@ -915,7 +923,7 @@ empty: -->
    -

    2.21   List Tables

    +

    2.22   List Tables

    Here's a list table exercising all features:

    @@ -949,32 +957,28 @@ crunchy, now would it?
    -

    3   Error Handling

    +

    3   Error Handling

    Any errors caught during processing will generate system messages.

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    -
    -

    paragraph 1

    -

    paragraph 2

    -

    Docutils System Messages

    System Message: ERROR/3 (functional/input/data/standard.txt, line 100); backlink

    Undefined substitution referenced: "problematic".
    -
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 358); backlink

    +
    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 358); backlink

    Unknown target name: "5".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 367); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 367); backlink

    Unknown target name: "nonexistent".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 394); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 394); backlink

    Unknown target name: "hyperlink reference without a target".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 407); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 407); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 4f318f90a..42cb057a9 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -208,9 +208,11 @@ reStructuredText construct. \item {} \href{\#raw-text}{2.17~~~Raw text} -\item {} \href{\#colspanning-tables}{2.18~~~Colspanning tables} +\item {} \href{\#container}{2.18~~~Container} -\item {} \href{\#rowspanning-tables}{2.19~~~Rowspanning tables} +\item {} \href{\#colspanning-tables}{2.19~~~Colspanning tables} + +\item {} \href{\#rowspanning-tables}{2.20~~~Rowspanning tables} \end{list} @@ -885,9 +887,9 @@ A right-aligned image: {\hfill\includegraphics{../../../docs/user/rst/images/biohazard.png}} A figure directive: -\begin{figure}[htbp]\begin{center} +\begin{figure}[htbp]\begin{flushright} -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=50]{../../../docs/user/rst/images/biohazard.png} \caption{A figure is an image with a caption and/or a legend:}{\small \begin{longtable}[c]{|p{0.16\locallinewidth}|p{0.56\locallinewidth}|} \hline @@ -912,31 +914,31 @@ Well it is, isn't it? \end{longtable} This paragraph is also part of the legend. -}\end{center}\end{figure} +}\end{flushright}\end{figure} This paragraph might flow around the figure... A centered figure: -\begin{figure}[htbp]\begin{center} +\begin{figure}[htbp]\begin{flushcenter} -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=50]{../../../docs/user/rst/images/biohazard.png} \caption{This is the caption.}{\small This is the legend. The legend may consist of several paragraphs. -}\end{center}\end{figure} +}\end{flushcenter}\end{figure} This paragraph might flow around the figure... A left-aligned figure: -\begin{figure}[htbp]\begin{center} +\begin{figure}[htbp]\begin{flushleft} -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=50]{../../../docs/user/rst/images/biohazard.png} \caption{This is the caption.}{\small This is the legend. The legend may consist of several paragraphs. -}\end{center}\end{figure} +}\end{flushleft}\end{figure} This paragraph might flow around the figure... @@ -944,15 +946,15 @@ Now widths: An image 2 em wide: -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=2em]{../../../docs/user/rst/images/biohazard.png} An image 2 em wide and 30 pixel high: -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=2em]{../../../docs/user/rst/images/biohazard.png} An image occupying 70{\%} of the line width: -\includegraphics{../../../docs/user/rst/images/biohazard.png} +\includegraphics[width=70%]{../../../docs/user/rst/images/biohazard.png} An image 3 cm high: @@ -1253,11 +1255,22 @@ A test.Second test.Another test with myclass set. This is the fourth test with myrawroleclass set. Fifth test in LaTeX.\\Line two. +%___________________________________________________________________________ + +\hypertarget{container}{} +\pdfbookmark[1]{2.18~~~Container}{container} +\subsection*{2.18~~~Container} + +paragraph 1 + +paragraph 2 + + %___________________________________________________________________________ \hypertarget{colspanning-tables}{} -\pdfbookmark[1]{2.18~~~Colspanning tables}{colspanning-tables} -\subsection*{2.18~~~Colspanning tables} +\pdfbookmark[1]{2.19~~~Colspanning tables}{colspanning-tables} +\subsection*{2.19~~~Colspanning tables} This table has a cell spanning two columns: @@ -1316,8 +1329,8 @@ True %___________________________________________________________________________ \hypertarget{rowspanning-tables}{} -\pdfbookmark[1]{2.19~~~Rowspanning tables}{rowspanning-tables} -\subsection*{2.19~~~Rowspanning tables} +\pdfbookmark[1]{2.20~~~Rowspanning tables}{rowspanning-tables} +\subsection*{2.20~~~Rowspanning tables} Here's a table with cells spanning several rows: diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index 22c8f4bde..edce5591d 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -294,31 +294,37 @@ Raw text - + 2.18    - Colspanning tables + Container - + 2.19    - Rowspanning tables + Colspanning tables - + 2.20    - Complex tables + Rowspanning tables - + 2.21    + Complex tables + + + + + 2.22    List Tables - + 3    Error Handling @@ -968,7 +974,7 @@ Here's an unreferenced footnote, with a reference to a nonexistent footnote: - + [5]_ .
    @@ -987,7 +993,7 @@ CIT2002 , and a - + [nonexistent]_ citation. @@ -1038,7 +1044,7 @@ Here's a - + `hyperlink reference without a target`_ , which generates an error. @@ -1060,7 +1066,7 @@ Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like this: - + `Duplicate Target Names`_ ), an error is generated.
    @@ -1072,49 +1078,49 @@ - + 2.14.1    Document Parts - + 2.14.2    Images - + 2.14.3    Admonitions - + 2.14.4    Topics, Sidebars, and Rubrics - + 2.14.5    Target Footnotes - + 2.14.6    Replacement Text - + 2.14.7    Compound Paragraph - + 2.14.8    Parsed Literal Blocks @@ -1125,7 +1131,7 @@ http://docutils.sourceforge.net/docs/ref/rst/directives.html .
    - + <title auto="1" refid="id71"> <generated classes="sectnum"> 2.14.1    Document Parts @@ -1140,7 +1146,7 @@ table of contents ). <section ids="images" names="images"> - <title auto="1" refid="id71"> + <title auto="1" refid="id72"> <generated classes="sectnum"> 2.14.2    Images @@ -1241,7 +1247,7 @@ An image 3 cm high: <image height="3cm" uri="../../../docs/user/rst/images/biohazard.png"> <section ids="admonitions" names="admonitions"> - <title auto="1" refid="id72"> + <title auto="1" refid="id73"> <generated classes="sectnum"> 2.14.3    Admonitions @@ -1291,7 +1297,7 @@ You can make up your own admonition too. <target ids="docutils" names="docutils" refuri="http://docutils.sourceforge.net/"> <section ids="topics-sidebars-and-rubrics" names="topics,\ sidebars,\ and\ rubrics"> - <title auto="1" refid="id73"> + <title auto="1" refid="id74"> <generated classes="sectnum"> 2.14.4    Topics, Sidebars, and Rubrics @@ -1316,7 +1322,7 @@ <rubric> This is a rubric <section ids="target-footnotes" names="target\ footnotes"> - <title auto="1" refid="id74"> + <title auto="1" refid="id75"> <generated classes="sectnum"> 2.14.5    Target Footnotes @@ -1333,7 +1339,7 @@ <reference refuri="http://docutils.sourceforge.net/"> http://docutils.sourceforge.net/ <section ids="replacement-text" names="replacement\ text"> - <title auto="1" refid="id75"> + <title auto="1" refid="id76"> <generated classes="sectnum"> 2.14.6    Replacement Text @@ -1354,7 +1360,7 @@ the best language around <section ids="compound-paragraph" names="compound\ paragraph"> - <title auto="1" refid="id76"> + <title auto="1" refid="id77"> <generated classes="sectnum"> 2.14.7    Compound Paragraph @@ -1440,7 +1446,7 @@ <paragraph> Compound 7, another paragraph. <section ids="parsed-literal-blocks" names="parsed\ literal\ blocks"> - <title auto="1" refid="id77"> + <title auto="1" refid="id78"> <generated classes="sectnum"> 2.14.8    Parsed Literal Blocks @@ -1521,10 +1527,20 @@ Fifth test in HTML.<br />Line two. <raw format="latex" xml:space="preserve"> Fifth test in LaTeX.\\Line two. - <section ids="colspanning-tables" names="colspanning\ tables"> + <section ids="container" names="container"> <title auto="1" refid="id65"> <generated classes="sectnum"> 2.18    + Container + <container classes="custom"> + <paragraph> + paragraph 1 + <paragraph> + paragraph 2 + <section ids="colspanning-tables" names="colspanning\ tables"> + <title auto="1" refid="id66"> + <generated classes="sectnum"> + 2.19    Colspanning tables <paragraph> This table has a cell spanning two columns: @@ -1593,9 +1609,9 @@ <paragraph> True <section ids="rowspanning-tables" names="rowspanning\ tables"> - <title auto="1" refid="id66"> + <title auto="1" refid="id67"> <generated classes="sectnum"> - 2.19    + 2.20    Rowspanning tables <paragraph> Here's a table with cells spanning several rows: @@ -1645,9 +1661,9 @@ <paragraph> body row 3 <section ids="complex-tables" names="complex\ tables"> - <title auto="1" refid="id67"> + <title auto="1" refid="id68"> <generated classes="sectnum"> - 2.20    + 2.21    Complex tables <paragraph> Here's a complex table, which should test all features. @@ -1730,9 +1746,9 @@ --> <entry> <section ids="list-tables" names="list\ tables"> - <title auto="1" refid="id68"> + <title auto="1" refid="id69"> <generated classes="sectnum"> - 2.21    + 2.22    List Tables <paragraph> Here's a list table exercising all features: @@ -1787,7 +1803,7 @@ <paragraph> On a stick! <section ids="error-handling" names="error\ handling"> - <title auto="1" refid="id69"> + <title auto="1" refid="id70"> <generated classes="sectnum"> 3    Error Handling @@ -1798,26 +1814,21 @@ section, "Docutils System Messages": <comment xml:space="preserve"> section should be added by Docutils automatically - <container classes="custom"> - <paragraph> - paragraph 1 - <paragraph> - paragraph 2 <section classes="system-messages"> <title> Docutils System Messages <system_message backrefs="id24" ids="id23" level="3" line="100" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Undefined substitution referenced: "problematic". - <system_message backrefs="id79" ids="id78" level="3" line="358" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> + <system_message backrefs="id80" ids="id79" level="3" line="358" source="functional/input/standalone_rst_html4css1.txt" type="ERROR"> <paragraph> Unknown target name: "5". - <system_message backrefs="id81" ids="id80" level="3" line="367" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id82" ids="id81" level="3" line="367" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "nonexistent". - <system_message backrefs="id83" ids="id82" level="3" line="394" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id84" ids="id83" level="3" line="394" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Unknown target name: "hyperlink reference without a target". - <system_message backrefs="id85" ids="id84" level="3" line="407" source="functional/input/data/standard.txt" type="ERROR"> + <system_message backrefs="id86" ids="id85" level="3" line="407" source="functional/input/data/standard.txt" type="ERROR"> <paragraph> Duplicate target name, cannot be used as a unique reference: "duplicate target names". diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index ea904eaec..c3e12d199 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -731,3 +731,12 @@ This is the :raw-role:`fourth test` with myrawroleclass set. .. raw:: latex Fifth test in LaTeX.\\Line two. + +Container +--------- + +.. container:: custom + + paragraph 1 + + paragraph 2 diff --git a/test/functional/input/standalone_rst_html4css1.txt b/test/functional/input/standalone_rst_html4css1.txt index 4b1e2fdda..05f0287d0 100644 --- a/test/functional/input/standalone_rst_html4css1.txt +++ b/test/functional/input/standalone_rst_html4css1.txt @@ -5,9 +5,3 @@ .. include:: data/table_complex.txt .. include:: data/list_table.txt .. include:: data/errors.txt - -.. container:: custom - - paragraph 1 - - paragraph 2 -- cgit v1.2.1 From 297e9964bdfcfd25c26c24668ef2027a3d90a776 Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 00:51:08 +0000 Subject: Fixed bug with incorrect comparison of decorations and added comments. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4077 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 65 +++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index fa49e1fee..efebb349c 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -67,7 +67,7 @@ ;; mode-specific-map prefix (i.e C-c). ;; ;; -;; C-c p a (also C-=): rst-adjust +;; C-c p a (also C-=): rst-adjust ;; ;; Updates or rotates the section title around point or promotes/demotes ;; the decorations within the region (see full details below). @@ -196,7 +196,7 @@ (rst-display-decorations-hierarchy))) ;; Define a prefix map for the long form of key combinations. -(defvar rst-prefix-map (make-sparse-keymap) +(defvar rst-prefix-map (make-sparse-keymap) "Keymap for rst commands.") (define-key rst-prefix-map "a" 'rst-adjust) (define-key rst-prefix-map "=" 'rst-adjust) @@ -253,11 +253,23 @@ (defvar rst-extra-paragraph-separate "\\|[ \t]*\\([-+*]\\|[0-9]+\\.\\) " "Extra parapraph-separate patterns to add for text-mode.") +;; FIXME: What about the missing >? +;; The author uses a hardcoded for paragraph-separate: "\f\\|>*[ \t]*$" (defun rst-set-paragraph-separation () + "Sets the paragraph separation for restructuredtext." + ;; FIXME: the variable should be made automatically buffer local rather than + ;; using a function here, this function is unnecessary. (make-local-variable 'paragraph-start) ; prevent it growing every time (setq paragraph-start (concat paragraph-start rst-extra-paragraph-separate))) +;; FIXME: What about paragraph-separate? paragraph-start and paragraph-separate +;; are different. The author hardcodes the value to +;; "\f\\|>*[ \t]*$\\|>*[ \t]*[-+*] \\|>*[ \t]*[0-9#]+\\. " + +;; FIXME: the variables above are in limbo and need some fixing. + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Support functions @@ -1273,7 +1285,8 @@ child. This has advantages later in processing the graph." (let ((lev 0)) (dolist (deco hier) - (puthash deco lev levels) + ;; Compare just the character and indent in the hash table. + (puthash (cons (car deco) (cadr deco)) lev levels) (incf lev))) ;; Create a list of lines that contains (text, level, marker) for each @@ -1282,7 +1295,7 @@ child. This has advantages later in processing the graph." (setq lines (mapcar (lambda (deco) (goto-line (car deco)) - (list (gethash (cdr deco) levels) + (list (gethash (cons (cadr deco) (caddr deco)) levels) (rst-get-stripped-line) (let ((m (make-marker))) (beginning-of-line 1) @@ -1323,7 +1336,7 @@ child. This has advantages later in processing the graph." ;; If node is still unset, we use the marker of the first child. (when (eq node nil) (setq node (cons nil (cdaar children)))) - + ;; Return this node with its children. (cons node children) )) @@ -1333,34 +1346,34 @@ child. This has advantages later in processing the graph." "Given a computed and valid section tree SECTREE and a point POINT (default being the current point in the current buffer), find and return the node within the sectree where the cursor - lives. + lives. Return values: a pair of (parent path, container subtree). The parent path is simply a list of the nodes above the container subtree node that we're returning." - + (let (path outtree) - + (let* ((curpoint (or point (point)))) - + ;; Check if we are before the current node. (if (and (cadar node) (>= curpoint (cadar node))) - + ;; Iterate all the children, looking for one that might contain the ;; current section. (let ((curnode (cdr node)) last) - + (while (and curnode (>= curpoint (cadaar curnode))) (setq last curnode curnode (cdr curnode))) - - (if last + + (if last (let ((sub (rst-section-tree-point (car last) curpoint))) (setq path (car sub) outtree (cdr sub))) (setq outtree node)) - + ))) (cons (cons (car node) path) outtree) )) @@ -1372,7 +1385,7 @@ By default the top level is ignored if there is only one, because we assume that the document will have a single title. If a numeric prefix argument is given, insert the TOC up to the -specified level. +specified level. The TOC is inserted indented at the current column." @@ -1397,7 +1410,7 @@ The TOC is inserted indented at the current column." ;; Fixup for the first line. (delete-region init-point (+ init-point (length initial-indent))) - + ;; Delete the last newline added. (delete-backward-char 1) ))) @@ -1480,7 +1493,7 @@ necessary for all the children of this level to align." ((eq rst-toc-insert-style 'listed) (concat (substring indent 0 -3) (concat (make-string (+ (length pfx) 2) ? ) " - "))) - )) + )) ) (if (or (eq rst-toc-insert-max-level nil) @@ -1508,7 +1521,7 @@ necessary for all the children of this level to align." (if do-child-numbering (concat pfx (format fmt count)) pfx)) (incf count))) - + ))) @@ -1614,14 +1627,14 @@ the node has been found." brings the cursor in that section." (interactive) (let* ((curbuf (current-buffer)) - + ;; Get the section tree (alldecos (rst-find-all-decorations)) (sectree (rst-section-tree alldecos)) (our-node (cdr (rst-section-tree-point sectree))) line - + ;; Create a temporary buffer. (buf (get-buffer-create rst-toc-buffer-name)) ) @@ -1840,7 +1853,7 @@ up to the leftmost character in the region." ;; reStructuredText format. Support includes font locking as well as some ;; convenience functions for editing. It does this by defining a Emacs major ;; mode. -;; +;; ;; The package is based on text-mode and inherits some things from it. ;; Particularly text-mode-hook is run before rst-mode-hook. ;; @@ -2098,7 +2111,7 @@ details check the Rst Faces Defaults group." :type '(alist :key-type (choice - (integer + (integer :tag "Section level (may not be bigger than `rst-level-face-max')") (boolean :tag "transitions (on) / section title adornment (off)")) @@ -2273,7 +2286,7 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 1 rst-block-face) ;; `Enumerated Lists`_ (list - (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" + (concat re-bol "\\((?\\([0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]" re-blksep1 "\\)") 1 rst-block-face) ;; `Definition Lists`_ FIXME: missing @@ -2296,14 +2309,14 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 1 rst-definition-face) ;; `Directives`_ / `Substitution Definitions`_ (list - (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" + (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|]+|[\t ]+\\)?\\)\\(" re-sym1 "+::\\)" re-blksep1) (list 1 rst-directive-face) (list 2 rst-definition-face) (list 4 rst-directive-face)) ;; `Hyperlink Targets`_ (list - (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" + (concat re-bol "\\(" re-ems "_\\([^:\\`]\\|\\\\.\\|`[^`]+`\\)+:\\)" re-blksep1) 1 rst-definition-face) (list @@ -2335,7 +2348,7 @@ Turning on `rst-mode' calls the normal hooks `text-mode-hook' and 2 rst-reference-face) ;; `Interpreted Text`_ (list - (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" + (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:" re-sym1 "+:\\)?\\)" re-ims1) (list 2 rst-directive-face) (list 5 rst-external-face) -- cgit v1.2.1 From c3f2544cb53a69966f3e57aee2e15f51b4acd7f8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 19:11:37 +0000 Subject: added 1px margin for footnotes so that the thin line on the left aligns with the rest of the text git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4078 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/support/html4css1.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docutils/writers/support/html4css1.css b/docutils/writers/support/html4css1.css index a418a7a00..837fe2b0f 100644 --- a/docutils/writers/support/html4css1.css +++ b/docutils/writers/support/html4css1.css @@ -241,7 +241,8 @@ span.section-subtitle { font-size: 80% } table.citation { - border-left: solid thin gray } + border-left: solid 1px gray; + margin-left: 1px } table.docinfo { margin: 2em 4em } @@ -251,7 +252,8 @@ table.docutils { margin-bottom: 0.5em } table.footnote { - border-left: solid thin black } + border-left: solid 1px black; + margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { -- cgit v1.2.1 From 02dcb45c0ca69fdf43b56bfc24fcd77bcb8af0bc Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 19:14:24 +0000 Subject: merged r4078 to pep.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4079 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/support/pep_html/pep.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docutils/writers/support/pep_html/pep.css b/docutils/writers/support/pep_html/pep.css index a687ee8c8..60140f7be 100644 --- a/docutils/writers/support/pep_html/pep.css +++ b/docutils/writers/support/pep_html/pep.css @@ -311,7 +311,8 @@ span.section-subtitle { font-size: 80% } table.citation { - border-left: solid thin gray } + border-left: solid 1px gray; + margin-left: 1px } table.docinfo { margin: 2em 4em } @@ -321,7 +322,8 @@ table.docutils { margin-bottom: 0.5em } table.footnote { - border-left: solid thin black } + border-left: solid 1px black; + margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { -- cgit v1.2.1 From 27250a4e978bbf3aefad780671b2778e84dfaa5e Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 19:22:56 +0000 Subject: added to-do list entry for different report levels git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4080 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index a4847139b..dded29d0d 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -104,6 +104,9 @@ for inclusion in the Python standard library. General ======= +* Allow different report levels for STDERR and system_messages inside + the document? + * Change the docutils-update script (in sandbox/infrastructure), to support arbitrary branch snapshots. -- cgit v1.2.1 From 1b0ec60ec58759a103692f6ebd276d3738fb4ca2 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 21:47:11 +0000 Subject: added to-do list entry about degenerate lists git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4081 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index dded29d0d..507e688dc 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -683,6 +683,10 @@ Also see the `... Or Not To Do?`__ list. __ rst/alternatives.html#or-not-to-do +* Treat enumerated lists that are not arabic and consist of only one + item in a single line as ordinary paragraphs. See + <http://article.gmane.org/gmane.text.docutils.user/2635>. + * The citation syntax could use some enhancements. See <http://thread.gmane.org/gmane.text.docutils.user/2499> and <http://thread.gmane.org/gmane.text.docutils.user/2443>. -- cgit v1.2.1 From ced6843a40a4b84b50b10c1106edfe80e088fbaa Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sat, 19 Nov 2005 23:48:04 +0000 Subject: allow escaped colons inside of fields git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4083 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 12 +++---- docutils/parsers/rst/states.py | 6 ++-- test/test_parsers/test_rst/test_field_lists.py | 50 ++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 507e688dc..26f9ff237 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -912,13 +912,11 @@ __ rst/alternatives.html#or-not-to-do Is indentation enough to make the separation between a paragraph which contains just a ``::`` and the literal text unambiguous? - There's one problem with this concession. What if one wants a - definition list item which defines the term "::"? We'd have to - escape it. Currenty, ``:\:`` is misinterpreted as a field name - (name ``\``; **bug**). Assuming this bug is squashed, I suppose - it's a useful special case. It would only be reasonable to apply it - to "::"-only paragraphs though. I think the blank line is visually - necessary if there's text before the "::":: + (There's one problem with this concession: If one wants a definition + list item which defines the term "::", we'd have to escape it.) It + would only be reasonable to apply it to "::"-only paragraphs though. + I think the blank line is visually necessary if there's text before + the "::":: The text in this paragraph needs separation from the literal block following:: diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index be064db8a..3a9c49094 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1054,7 +1054,7 @@ class Body(RSTState): patterns = { 'bullet': r'[-+*]( +|$)', 'enumerator': r'(%(parens)s|%(rparen)s|%(period)s)( +|$)' % pats, - 'field_marker': r':[^: ]([^:]*[^: ])?:( +|$)', + 'field_marker': r':(?![: ])([^:\\]|\\.)*(?<! ):( +|$)', 'option_marker': r'%(option)s(, %(option)s)*( +| ?$)' % pats, 'doctest': r'>>>( +|$)', 'line_block': r'\|( +|$)', @@ -1367,8 +1367,8 @@ class Body(RSTState): def parse_field_marker(self, match): """Extract & return field name from a field marker match.""" - field = match.string[1:] # strip off leading ':' - field = field[:field.find(':')] # strip off trailing ':' etc. + field = match.group()[1:] # strip off leading ':' + field = field[:field.rfind(':')] # strip off trailing ':' etc. return field def parse_field_body(self, indented, offset, node): diff --git a/test/test_parsers/test_rst/test_field_lists.py b/test/test_parsers/test_rst/test_field_lists.py index 4bda460bf..2e715770c 100755 --- a/test/test_parsers/test_rst/test_field_lists.py +++ b/test/test_parsers/test_rst/test_field_lists.py @@ -454,8 +454,7 @@ Nested field lists on one line: <paragraph> should generate warning. """], -["""\ -Some edge cases: +[r"""Some edge cases: :Empty: :Author: Me @@ -468,6 +467,21 @@ No blank line before this paragraph. Field: marker is missing its open-colon. :Field marker is missing its close-colon. + +:Field\: names\: with\: colons\:: are possible. + +:\\Field\ names with backslashes\\: are possible, too. + +:\\: A backslash. + +:Not a\\\: field list. + +:Not a \: field list either. + +:\: Not a field list either. + +:\: + A definition list, not a field list. """, """\ <document source="test data"> @@ -497,6 +511,38 @@ Field: marker is missing its open-colon. Field: marker is missing its open-colon. <paragraph> :Field marker is missing its close-colon. + <field_list> + <field> + <field_name> + Field: names: with: colons: + <field_body> + <paragraph> + are possible. + <field> + <field_name> + \\Field names with backslashes\\ + <field_body> + <paragraph> + are possible, too. + <field> + <field_name> + \\ + <field_body> + <paragraph> + A backslash. + <paragraph> + :Not a\\: field list. + <paragraph> + :Not a : field list either. + <paragraph> + :: Not a field list either. + <definition_list> + <definition_list_item> + <term> + :: + <definition> + <paragraph> + A definition list, not a field list. """], ] -- cgit v1.2.1 From 96c5fe444943f9e2d940e12b4a4b0a97d28ae632 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 20 Nov 2005 06:18:08 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4087 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 26f9ff237..05d12007b 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -486,6 +486,9 @@ General specific source files, such as running rst2s5.py instead of rst2html.py. +* Add a "disable table of contents" setting? The S5 writer could set + it as a default. + Documentation ============= -- cgit v1.2.1 From 9a06f1b58bf466eba15dc5b9ebfe1ed4c326f576 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 20 Nov 2005 19:54:07 +0000 Subject: added functional test for left-aligned figure git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4088 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/standalone_rst_html4css1.html | 6 ++++++ test/functional/expected/standalone_rst_latex.tex | 6 ++++++ test/functional/expected/standalone_rst_pseudoxml.txt | 7 +++++++ test/functional/input/data/standard.txt | 11 +++++++++++ 4 files changed, 30 insertions(+) diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index f95d99cb9..dd19f2710 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -579,6 +579,12 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o <p>This paragraph is also part of the legend.</p> </div> </div> +<div align="left" class="figclass1 figclass2 figure"> +<img alt="reStructuredText, the markup syntax" class="class1 class2" src="../../../docs/user/rst/images/biohazard.png" style="width: 50px;" /> +<p class="caption">A left-aligned figure.</p> +<div class="legend"> +This is the legend.</div> +</div> <p>This paragraph might flow around the figure...</p> <p>A centered figure:</p> <div align="center" class="figure"> diff --git a/test/functional/expected/standalone_rst_latex.tex b/test/functional/expected/standalone_rst_latex.tex index 42cb057a9..ba5b63bb0 100644 --- a/test/functional/expected/standalone_rst_latex.tex +++ b/test/functional/expected/standalone_rst_latex.tex @@ -915,6 +915,12 @@ Well it is, isn't it? This paragraph is also part of the legend. }\end{flushright}\end{figure} +\begin{figure}[htbp]\begin{flushleft} + +\includegraphics[width=50]{../../../docs/user/rst/images/biohazard.png} +\caption{A left-aligned figure.}{\small +This is the legend. +}\end{flushleft}\end{figure} This paragraph might flow around the figure... diff --git a/test/functional/expected/standalone_rst_pseudoxml.txt b/test/functional/expected/standalone_rst_pseudoxml.txt index edce5591d..e416c12ab 100644 --- a/test/functional/expected/standalone_rst_pseudoxml.txt +++ b/test/functional/expected/standalone_rst_pseudoxml.txt @@ -1204,6 +1204,13 @@ Well it is, isn't it? <paragraph> This paragraph is also part of the legend. + <figure align="left" classes="figclass1 figclass2"> + <image alt="reStructuredText, the markup syntax" classes="class1 class2" uri="../../../docs/user/rst/images/biohazard.png" width="50"> + <caption> + A left-aligned figure. + <legend> + <paragraph> + This is the legend. <paragraph> This paragraph might flow around the figure... <paragraph> diff --git a/test/functional/input/data/standard.txt b/test/functional/input/data/standard.txt index c3e12d199..a0d1570ed 100644 --- a/test/functional/input/data/standard.txt +++ b/test/functional/input/data/standard.txt @@ -474,6 +474,17 @@ A figure directive: This paragraph is also part of the legend. +.. figure:: ../../../docs/user/rst/images/biohazard.png + :figclass: figclass1 figclass2 + :class: class1 class2 + :alt: reStructuredText, the markup syntax + :align: left + :width: 50 + + A left-aligned figure. + + This is the legend. + This paragraph might flow around the figure... A centered figure: -- cgit v1.2.1 From 184c20058d06fae93850e40a6d695b07b680a7cc Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 20 Nov 2005 21:03:55 +0000 Subject: added right margin to figure in HTML -- otherwise left-aligned and right-aligned figures look unbalanced git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4089 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/support/html4css1.css | 3 ++- docutils/writers/support/pep_html/pep.css | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docutils/writers/support/html4css1.css b/docutils/writers/support/html4css1.css index 837fe2b0f..0d8acfeb7 100644 --- a/docutils/writers/support/html4css1.css +++ b/docutils/writers/support/html4css1.css @@ -83,7 +83,8 @@ div.dedication p.topic-title { font-style: normal } div.figure { - margin-left: 2em } + margin-left: 2em ; + margin-right: 2em } div.footer, div.header { clear: both; diff --git a/docutils/writers/support/pep_html/pep.css b/docutils/writers/support/pep_html/pep.css index 60140f7be..0771c6796 100644 --- a/docutils/writers/support/pep_html/pep.css +++ b/docutils/writers/support/pep_html/pep.css @@ -125,7 +125,8 @@ div.dedication p.topic-title { font-style: normal } div.figure { - margin-left: 2em } + margin-left: 2em ; + margin-right: 2em } div.footer, div.header { clear: both; -- cgit v1.2.1 From b7fab505d144ab05bb37a7f0c5352c1f2cb23150 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Sun, 20 Nov 2005 21:17:24 +0000 Subject: removed style information for pre.line-block -- not used anymore git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4090 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/writers/support/html4css1.css | 4 ---- docutils/writers/support/pep_html/pep.css | 4 ---- 2 files changed, 8 deletions(-) diff --git a/docutils/writers/support/html4css1.css b/docutils/writers/support/html4css1.css index 0d8acfeb7..d477c8053 100644 --- a/docutils/writers/support/html4css1.css +++ b/docutils/writers/support/html4css1.css @@ -208,10 +208,6 @@ pre.address { font-family: serif ; font-size: 100% } -pre.line-block { - font-family: serif ; - font-size: 100% } - pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; diff --git a/docutils/writers/support/pep_html/pep.css b/docutils/writers/support/pep_html/pep.css index 0771c6796..014d3e423 100644 --- a/docutils/writers/support/pep_html/pep.css +++ b/docutils/writers/support/pep_html/pep.css @@ -275,10 +275,6 @@ pre.address { font-family: serif ; font-size: 100% } -pre.line-block { - font-family: serif ; - font-size: 100% } - pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; -- cgit v1.2.1 From 656b4fab28abdf9a2d3361c385fd20b313fd114d Mon Sep 17 00:00:00 2001 From: blais <blais@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 21 Nov 2005 02:43:33 +0000 Subject: Fixed bug with TOC update when it is at the end of a file. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4091 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index efebb349c..5bb8f18bf 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -1548,10 +1548,11 @@ delete that region. Return t if found and the cursor is left after the comment." ;; Look for the first line that starts at the first column. (forward-line 1) (beginning-of-line) - (while (or (and (looking-at "[ \t]+[^ \t]") - (setq last-real (point)) t) - (looking-at "\\s-*$")) - (forward-line 1) + (while (and + (< (point) (point-max)) + (or (and (looking-at "[ \t]+[^ \t]") (setq last-real (point)) t) + (looking-at "\\s-*$"))) + (forward-line 1) ) (if last-real (progn -- cgit v1.2.1 From ccac3b33bd345ea21e0cbbda824f99ddcf11adb1 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 21 Nov 2005 19:50:32 +0000 Subject: updated spec to reflect that escaped colons inside of field names are now allowed; added history entry git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4092 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 1 + docs/ref/rst/restructuredtext.txt | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index f6bcc741b..dbe1920ac 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -61,6 +61,7 @@ Changes Since 0.3.9 - 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. diff --git a/docs/ref/rst/restructuredtext.txt b/docs/ref/rst/restructuredtext.txt index d503d9054..e0cee6031 100644 --- a/docs/ref/rst/restructuredtext.txt +++ b/docs/ref/rst/restructuredtext.txt @@ -813,15 +813,16 @@ see `Bibliographic Fields`_ below, or the "image_" and "meta_" directives in `reStructuredText Directives`_. Field lists are mappings from field names to field bodies, modeled on -RFC822_ headers. A field name is made up of one or more letters, -numbers, whitespace, and punctuation, except colons (":"). Inline -markup is parsed in field names. Field names are case-insensitive -when further processed or transformed. The field name, along with a -single colon prefix and suffix, together form the field marker. The -field marker is followed by whitespace and the field body. The field -body may contain multiple body elements, indented relative to the -field marker. The first line after the field name marker determines -the indentation of the field body. For example:: +RFC822_ headers. A field name may consist of any characters, but +colons (":") inside of field names must be escaped with a backslash. +Inline markup is parsed in field names. Field names are +case-insensitive when further processed or transformed. The field +name, along with a single colon prefix and suffix, together form the +field marker. The field marker is followed by whitespace and the +field body. The field body may contain multiple body elements, +indented relative to the field marker. The first line after the field +name marker determines the indentation of the field body. For +example:: :Date: 2001-08-16 :Version: 1 -- cgit v1.2.1 From e2f7e14c49a9716f32856d8e47d93ada223f5802 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 21 Nov 2005 19:57:52 +0000 Subject: added history entries for recent additions of language mapping files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4093 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index dbe1920ac..db79ed639 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -50,6 +50,12 @@ Changes Since 0.3.9 ``document.anonymous_refs``, and ``document.anonymous_targets``. - Added a "container" element. +* 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: @@ -85,6 +91,12 @@ Changes Since 0.3.9 standard data files for the "include" directive. Initial contents: character entity substitution definition sets. +* docutils/parsers/rst/languages/ja.py: Added to project: Japanese + mappings by Hisashi Morita. + +* 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 -- cgit v1.2.1 From 1d2f8f5719300e12ba5d974e6bcb84e65e760021 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 21 Nov 2005 20:19:09 +0000 Subject: added history entries for recent additions and changes to Emacs support; added history entry for fix of centered images git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4094 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/HISTORY.txt b/HISTORY.txt index db79ed639..ebfc41407 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -22,6 +22,9 @@ Changes Since 0.3.9 * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. +* docs/user/emacs.txt: Added to project; a document about Emacs + support for reStructuredText and Docutils. + * docutils/__init__.py: - Added ``__version_details__`` attribute to describe code source @@ -167,6 +170,7 @@ Changes Since 0.3.9 simple field lists. - Made cloaking of email addresses with ``--cloak-email-addresses`` less obtrusive. + - Fixed support for centered images. * docutils/writers/latex2e.py: @@ -225,6 +229,13 @@ Changes Since 0.3.9 * 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 to docutils/writers/support/ or its subdirectories. -- cgit v1.2.1 From e5ba1950c904e32f886b52106e876f5c7de33a7c Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 21 Nov 2005 21:35:32 +0000 Subject: added to-do list entry for multiple stylesheets; re-added to-do list entry for separating PEP-specific stuff in pep.css git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4095 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 05d12007b..3fd9b55c6 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1658,6 +1658,9 @@ Unimplemented Transforms HTML Writer =========== +* Add support for _`multiple stylesheets`. See + <http://thread.gmane.org/gmane.text.docutils.cvs/4336>. + * Add more support for <link> elements, especially for navigation bars. @@ -1677,6 +1680,15 @@ HTML Writer identifying them as such. Text in Docutils language module. +PEP/HTML Writer +=============== + +* Remove the generic style information (duplicated from html4css1.css) + from pep.css to avoid redundancy. + + We need support for `multiple stylesheets`_ before, though. + + LaTeX writer ============ -- cgit v1.2.1 From 80230d4c0a272847d5181dcc78b1161be8f1e494 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 25 Nov 2005 05:01:36 +0000 Subject: added idea for config directories; clarified disable-ToC setting rationale git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4099 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 3fd9b55c6..36c450868 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -474,6 +474,13 @@ General * Add support for _`plugins`. +* _`Config directories`: Currently, ~/.docutils, ./docutils.conf/, & + /etc/docutils.conf are read as configuration files. Proposal: make + ~/.docutils/ into a configuration *directory*, along with + /etc/docutils/ and ./docutils.conf/. Within these directories, + check for config.txt files. We can also have subdirectories here, + for plugins, S5 themes, components (readers/writers/parsers) etc. + * Add support for document decorations other than headers & footers? For example, top/bottom/side navigation bars for web pages. Generic decorations? @@ -487,7 +494,14 @@ General rst2html.py. * Add a "disable table of contents" setting? The S5 writer could set - it as a default. + it as a default. Rationale: + + The ``contents`` (table of contents) directive must not be used + [in S5/HTML documents]. It changes the CSS class of headings + and they won't show up correctly in the screen presentation. + + -- `Easy Slide Shows With reStructuredText & S5 + <../user/slide-shows.html>`_ Documentation -- cgit v1.2.1 From e44c7e7c66a2ff0339be0b4e7480f2eeaa994414 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 25 Nov 2005 05:02:29 +0000 Subject: fixed variable names git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4100 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- tools/editors/emacs/rst.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/editors/emacs/rst.el b/tools/editors/emacs/rst.el index 5bb8f18bf..cd4277837 100644 --- a/tools/editors/emacs/rst.el +++ b/tools/editors/emacs/rst.el @@ -250,8 +250,8 @@ ;; like this: ;; ;; (add-hook 'text-mode-hook 'rst-set-paragraph-separation) -(defvar rst-extra-paragraph-separate - "\\|[ \t]*\\([-+*]\\|[0-9]+\\.\\) " +(defvar rst-extra-paragraph-start + "\\|[ \t]*\\([-+*] \\|[0-9]+\\. \\)" "Extra parapraph-separate patterns to add for text-mode.") ;; FIXME: What about the missing >? ;; The author uses a hardcoded for paragraph-separate: "\f\\|>*[ \t]*$" @@ -261,7 +261,7 @@ ;; FIXME: the variable should be made automatically buffer local rather than ;; using a function here, this function is unnecessary. (make-local-variable 'paragraph-start) ; prevent it growing every time - (setq paragraph-start (concat paragraph-start rst-extra-paragraph-separate))) + (setq paragraph-start (concat paragraph-start rst-extra-paragraph-start))) ;; FIXME: What about paragraph-separate? paragraph-start and paragraph-separate ;; are different. The author hardcodes the value to -- cgit v1.2.1 From b5d3261cc76590df360d65281f8cf7d6370eb4a8 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Fri, 25 Nov 2005 21:46:28 +0000 Subject: added bug about block quote attributions; fixed typo in todo.txt git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4105 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 31 +++++++++++++++++++++++++++++++ docs/dev/todo.txt | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/BUGS.txt b/BUGS.txt index 35b8ab51f..c0d46aae8 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -111,6 +111,37 @@ Known Bugs Also see the `SourceForge Bug Tracker`_. +* The reST parser does not recognize _`block quote attributions` that + have an indented second line, but only if there is any text after + the block quote:: + + $ rst2pseudoxml.py + Block quote. + + -- This is + the attribution. + + Normal text. + <document source="<stdin>"> + <block_quote> + <paragraph> + Block quote. + <definition_list> + <definition_list_item> + <term> + -- This is + <definition> + <paragraph> + the attribution. + <paragraph> + Normal text. + + According to `the spec`__, it should work: "If the attribution + consists of multiple lines, the left edges of the second and + subsequent lines must align." + + __ docs/ref/rst/restructuredtext.html#block-quotes + * _`List items with an empty first line` don't work as expected:: 1. diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 36c450868..e9561c488 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -501,7 +501,7 @@ General and they won't show up correctly in the screen presentation. -- `Easy Slide Shows With reStructuredText & S5 - <../user/slide-shows.html>`_ + <../user/slide-shows.html>`_ Documentation -- cgit v1.2.1 From 312ae3b66e2a73eb282566124c5a964e6954159b Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Mon, 28 Nov 2005 00:33:23 +0000 Subject: added examples & elaboration for custom "directive" directive; whitespace & minor tweaks git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4106 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index e9561c488..468ef32d1 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -475,12 +475,15 @@ General * Add support for _`plugins`. * _`Config directories`: Currently, ~/.docutils, ./docutils.conf/, & - /etc/docutils.conf are read as configuration files. Proposal: make - ~/.docutils/ into a configuration *directory*, along with + /etc/docutils.conf are read as configuration files. Proposal: allow + ~/.docutils to be a a configuration *directory*, along with /etc/docutils/ and ./docutils.conf/. Within these directories, check for config.txt files. We can also have subdirectories here, for plugins, S5 themes, components (readers/writers/parsers) etc. + Docutils will continue to support configuration files for backwards + compatibility. + * Add support for document decorations other than headers & footers? For example, top/bottom/side navigation bars for web pages. Generic decorations? @@ -740,7 +743,7 @@ __ rst/alternatives.html#or-not-to-do quote 2 - ---Attrib 2 + ---Attrib 2 * Change the specification so that more punctuation is allowed before/after inline markup start/end string @@ -1059,7 +1062,7 @@ when used in a document. * Allow for field lists in list tables. See <http://thread.gmane.org/gmane.text.docutils.devel/3392>. - + * .. _unify tables: Unify table implementations and unify options of table directives @@ -1196,7 +1199,33 @@ when used in a document. - _`misc.gather`: Gather (move, or copy) all instances of a specific element. A generalization of the "endnotes" & "citations" ideas. - - Add a "directive" directive, equivalent to "role"? + - Add a custom "directive" directive, equivalent to "role"? For + example:: + + .. directive:: incr + + .. class:: incremental + + .. incr:: + + "``.. incr::``" above is equivalent to "``.. class:: incremental``". + + Another example:: + + .. directive:: printed-links + + .. topic:: Links + :class: print-block + + .. target-notes:: + :class: print-inline + + This acts like macros. The directive contents will have to be + evaluated when referenced, not when defined. + + * Call the directive "macro"? + * What to do with directive arguments & options when the + macro/directive is referenced? - .. _conditional directives: -- cgit v1.2.1 From 579928eeb2451d0681415f274e6349d855fd35f6 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 30 Nov 2005 00:06:38 +0000 Subject: removed unnecessary stylesheet_path settings git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4118 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/tests/dangerous.py | 1 - test/functional/tests/field_name_limit.py | 1 - test/functional/tests/pep_html.py | 2 -- test/functional/tests/standalone_rst_html4css1.py | 3 +-- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/test/functional/tests/dangerous.py b/test/functional/tests/dangerous.py index b2faca07a..620a927ba 100644 --- a/test/functional/tests/dangerous.py +++ b/test/functional/tests/dangerous.py @@ -10,4 +10,3 @@ writer_name = "html" # Settings settings_overrides['file_insertion_enabled'] = 0 settings_overrides['raw_enabled'] = 0 -settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" diff --git a/test/functional/tests/field_name_limit.py b/test/functional/tests/field_name_limit.py index 27c5c296e..db79d4c67 100644 --- a/test/functional/tests/field_name_limit.py +++ b/test/functional/tests/field_name_limit.py @@ -10,4 +10,3 @@ writer_name = "html" # Settings settings_overrides['field_name_limit'] = 0 # no limit settings_overrides['docinfo_xform'] = 0 -settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" diff --git a/test/functional/tests/pep_html.py b/test/functional/tests/pep_html.py index 5a292b207..00e127ba7 100644 --- a/test/functional/tests/pep_html.py +++ b/test/functional/tests/pep_html.py @@ -8,8 +8,6 @@ parser_name = "rst" writer_name = "pep_html" # Settings -settings_overrides['stylesheet_path'] = ( - "../docutils/writers/support/pep_html/pep.css") settings_overrides['python_home'] = "http://www.python.org" settings_overrides['pep_home'] = "http://www.python.org/peps" settings_overrides['no_random'] = 1 diff --git a/test/functional/tests/standalone_rst_html4css1.py b/test/functional/tests/standalone_rst_html4css1.py index 874deada5..c34298eab 100644 --- a/test/functional/tests/standalone_rst_html4css1.py +++ b/test/functional/tests/standalone_rst_html4css1.py @@ -7,5 +7,4 @@ test_destination = "standalone_rst_html4css1.html" # Keyword parameters passed to publish_file. writer_name = "html4css1" -# Settings. -settings_overrides['stylesheet_path'] = "../docutils/writers/support/html4css1.css" +# Settings: settings_overrides['setting'] = value -- cgit v1.2.1 From ac71c958c50062334eab3f20045afe1a247e2d99 Mon Sep 17 00:00:00 2001 From: wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Wed, 30 Nov 2005 23:52:13 +0000 Subject: updated expected functional test files git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4119 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/expected/pep_html.html | 2 +- test/functional/expected/standalone_rst_html4css1.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index 8eb626e62..c6d403a23 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -5,7 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" /> <title> - +
    diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index 81bc6dc3a..c4539909a 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index 277b2e6ca..444fa5d3c 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -10,7 +10,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! PEP 100 -- Test PEP - +
    list table with integral header
    - +
    -- cgit v1.2.1 From c6b28c3a2265fe50a0db10d79706a2872dbb63fb Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 1 Dec 2005 00:56:35 +0000 Subject: removed "qa" directive idea from docs/dev/todo.txt; added it to docs/dev/rst/alternatives.txt ("not implemented"); added FAQ entry about marking up FAQs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4120 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- FAQ.txt | 57 ++++++++++++++++++++++++++++++++++++++----- docs/dev/rst/alternatives.txt | 44 ++++++++++++++++++++++++++++++++- docs/dev/todo.txt | 44 ++++++--------------------------- 3 files changed, 102 insertions(+), 43 deletions(-) diff --git a/FAQ.txt b/FAQ.txt index 9126a5d2a..f543d6eea 100644 --- a/FAQ.txt +++ b/FAQ.txt @@ -9,12 +9,6 @@ :Web site: http://docutils.sourceforge.net/ :Copyright: This document has been placed in the public domain. -.. Please note that until there's a Q&A-specific construct available, - this FAQ will use section titles for questions. Therefore - questions must fit on one line. The title may be a summary of the - question, with the full question in the section body. - - .. contents:: .. sectnum:: @@ -700,6 +694,57 @@ automatically building websites, or parts of websites. http://webware.sourceforge.net/Papers/Templates/ +How can I mark up a FAQ or other list of questions & answers? +------------------------------------------------------------- + +There is no specific syntax for FAQs and Q&A lists. Here are two +options: + +1. For a FAQ (Frequently Asked Questions, usually with answers), a + convenient way to mark up the questions is as section titles, with + the answer(s) as section content. This document is marked up in + this way. + + The advantages of using section titles for questions are: sections + can be numbered automatically, and a table of contents can be + generated automatically. One limitation of this format is that + questions must fit on one line (section titles may not wrap, in the + source text). For very long questions, the title may be a summary + of the question, with the full question in the section body. + +2. Field lists work well as Q&A lists:: + + :Q: What kind of questions can we + put here? + + :A: Any kind we like! + + In order to separate questions, lists can be used: + + 1. :Q: What kind of question can we + put here? + :A: Any kind we like! + + 2. :Q: How many answers can a question have? + :A: It can have one, + :A: or more. + :A3: Answers can be numbered like this. + :A: 1. Or like this. + 2. We're flexible! + + If you don't want to number or otherwise mark questions, you can + use an empty comment between individual field lists to separate + them:: + + :Q: First question? + :A: Answer. + + .. + + :Q: Second question? + :A: Answer. + + HTML Writer =========== diff --git a/docs/dev/rst/alternatives.txt b/docs/dev/rst/alternatives.txt index d6e0957e7..12874c5fb 100644 --- a/docs/dev/rst/alternatives.txt +++ b/docs/dev/rst/alternatives.txt @@ -2095,6 +2095,49 @@ the "auto-symbol footnote" concept, which has been added. Citations and citation references have also been added. +Syntax for Questions & Answers +============================== + +Implement as a generic two-column marked list? As a standalone +(non-directive) construct? (Is the markup ambiguous?) Add support to +parts.contents? + +New elements would be required. Perhaps:: + + + + + + + +Originally I thought of implementing a Q&A list with special syntax:: + + Q: What am I? + + A: You are a question-and-answer + list. + + Q: What are you? + + A: I am the omniscient "we". + +Where each "Q" and "A" could also be numbered (e.g., "Q1"). However, +a simple enumerated or bulleted list will do just fine for syntax. A +directive could treat the list specially; e.g. the first paragraph +could be treated as a question, the remainder as the answer (multiple +answers could be represented by nested lists). Without special +syntax, this directive becomes low priority. + +As described in the FAQ__, no special syntax or directive is needed +for this application. + +__ http://docutils.sf.net/FAQ.html + #how-can-i-mark-up-a-faq-or-other-list-of-questions-answers + + -------- Tabled -------- @@ -3076,7 +3119,6 @@ idea, and there is no "tool tip" in formats other than HTML. Add a "term" role for unfamiliar or specialized terminology? Probably not; there is no real use case, and emphasis is enough for most cases. - .. Local Variables: diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 468ef32d1..993b54813 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1284,42 +1284,6 @@ when used in a document. delim off .EN - - _`body.qa` (directive a.k.a. "faq", "questions"): Questions & - Answers. Implement as a generic two-column marked list? As a - standalone (non-directive) construct? (Is the markup ambiguous?) - Add support to parts.contents. - - New elements would be required. Perhaps:: - - - - - - - - Originally I thought of implementing a Q&A list with special - syntax:: - - Q: What am I? - - A: You are a question-and-answer - list. - - Q: What are you? - - A: I am the omniscient "we". - - Where each "Q" and "A" could also be numbered (e.g., "Q1"). - However, a simple enumerated or bulleted list will do just fine - for syntax. A directive could treat the list specially; e.g. the - first paragraph could be treated as a question, the remainder as - the answer (multiple answers could be represented by nested - lists). Without special syntax, this directive becomes low - priority. - - _`body.example`: Examples; suggested by Simon Hefti. Semantics as per Docbook's "example"; admonition-style, numbered, reference, with a caption/title. @@ -1704,6 +1668,14 @@ HTML Writer * Add support for _`multiple stylesheets`. See . +* Idea for field-list rendering: hanging indent:: + + Field name (bold): First paragraph of field body begins + with the field name inline. + + If the first item of a field body is not a paragraph, + it would begin on the following line. + * Add more support for elements, especially for navigation bars. -- cgit v1.2.1 From 620f3f7758d2d4723b0024a33026c3a1020fc560 Mon Sep 17 00:00:00 2001 From: goodger Date: Thu, 1 Dec 2005 03:02:02 +0000 Subject: revert revision 4119 git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4121 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/functional/expected/dangerous.html | 2 +- test/functional/expected/field_name_limit.html | 2 +- test/functional/expected/pep_html.html | 2 +- test/functional/expected/standalone_rst_html4css1.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/expected/dangerous.html b/test/functional/expected/dangerous.html index c6d403a23..8eb626e62 100644 --- a/test/functional/expected/dangerous.html +++ b/test/functional/expected/dangerous.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/expected/field_name_limit.html b/test/functional/expected/field_name_limit.html index c4539909a..81bc6dc3a 100644 --- a/test/functional/expected/field_name_limit.html +++ b/test/functional/expected/field_name_limit.html @@ -5,7 +5,7 @@ - +
    diff --git a/test/functional/expected/pep_html.html b/test/functional/expected/pep_html.html index 444fa5d3c..277b2e6ca 100644 --- a/test/functional/expected/pep_html.html +++ b/test/functional/expected/pep_html.html @@ -10,7 +10,7 @@ to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE! PEP 100 -- Test PEP - +
    - +
    -- cgit v1.2.1 From 61fff66ccbdf0463f131340e2349e7042eb568a6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Dec 2005 02:11:03 +0000 Subject: set sys.path to pick up the right Docutils git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4131 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/DocutilsTestSupport.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/DocutilsTestSupport.py b/test/DocutilsTestSupport.py index 6947c4478..5ad3673d4 100644 --- a/test/DocutilsTestSupport.py +++ b/test/DocutilsTestSupport.py @@ -43,6 +43,10 @@ __docformat__ = 'reStructuredText' import sys import os + +testroot = os.path.abspath(os.path.dirname(__file__) or os.curdir) +sys.path.insert(1, os.path.normpath(os.path.join(testroot, '..'))) + import unittest import docutils_difflib import inspect @@ -75,9 +79,6 @@ except: StringList.__repr__ = StringList.__str__ -testroot = os.path.abspath(os.path.dirname(__file__) or os.curdir) - - class DevNull: """Output sink.""" -- cgit v1.2.1 From 7e720ee65bc79a0430adb825f3deae4c93424959 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 3 Dec 2005 02:13:12 +0000 Subject: corrected order of imports git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4132 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- test/alltests.py | 1 + test/test_dependencies.py | 2 +- test/test_functional.py | 2 +- test/test_io.py | 1 + test/test_language.py | 11 ++++++----- test/test_nodes.py | 1 + test/test_publisher.py | 4 +--- test/test_settings.py | 1 + test/test_transforms/test___init__.py | 1 + test/test_transforms/test_expose_internals.py | 2 +- test/test_transforms/test_transitions.py | 2 +- test/test_transforms/test_writer_aux.py | 2 +- 12 files changed, 17 insertions(+), 13 deletions(-) diff --git a/test/alltests.py b/test/alltests.py index c6a44e003..edf1ac7ad 100755 --- a/test/alltests.py +++ b/test/alltests.py @@ -22,6 +22,7 @@ start = time.time() import sys import os from types import UnicodeType +import DocutilsTestSupport # must be imported before docutils import docutils diff --git a/test/test_dependencies.py b/test/test_dependencies.py index c9f00518d..46e8ff846 100755 --- a/test/test_dependencies.py +++ b/test/test_dependencies.py @@ -13,9 +13,9 @@ Test module for the --record-dependencies option. import os.path import unittest import sys +import DocutilsTestSupport # must be imported before docutils import docutils.core import docutils.utils -import DocutilsTestSupport class RecordDependenciesTests(unittest.TestCase): diff --git a/test/test_functional.py b/test/test_functional.py index e52d41422..1cebc2462 100755 --- a/test/test_functional.py +++ b/test/test_functional.py @@ -17,9 +17,9 @@ import os import os.path import unittest import difflib +import DocutilsTestSupport # must be imported before docutils import docutils import docutils.core -import DocutilsTestSupport datadir = 'functional' diff --git a/test/test_io.py b/test/test_io.py index e65b05c6c..b82911e44 100755 --- a/test/test_io.py +++ b/test/test_io.py @@ -11,6 +11,7 @@ Test module for io.py. """ import unittest +import DocutilsTestSupport # must be imported before docutils from docutils import io diff --git a/test/test_language.py b/test/test_language.py index 79509b46a..0571275e7 100755 --- a/test/test_language.py +++ b/test/test_language.py @@ -17,20 +17,21 @@ import sys import os import re from types import UnicodeType +import DocutilsTestSupport # must be imported before docutils import docutils.languages import docutils.parsers.rst.languages from docutils.parsers.rst import states, directives, roles -from DocutilsTestSupport import CustomTestSuite, CustomTestCase + reference_language = 'en' -class LanguageTestSuite(CustomTestSuite): +class LanguageTestSuite(DocutilsTestSupport.CustomTestSuite): language_module_pattern = re.compile('^([a-z]{2,3}(_[a-z]{2,8})*)\.py$') def __init__(self, languages=None): - CustomTestSuite.__init__(self) + DocutilsTestSupport.CustomTestSuite.__init__(self) if languages: self.languages = languages else: @@ -56,7 +57,7 @@ class LanguageTestSuite(CustomTestSuite): id=language+'.py', language=language) -class LanguageTestCase(CustomTestCase): +class LanguageTestCase(DocutilsTestSupport.CustomTestCase): test_methods = ['test_labels', 'test_bibliographic_fields', 'test_directives', 'test_roles'] @@ -66,7 +67,7 @@ class LanguageTestCase(CustomTestCase): self.ref = docutils.languages.get_language(reference_language) self.language = kwargs['language'] del kwargs['language'] # only wanted here - CustomTestCase.__init__(self, *args, **kwargs) + DocutilsTestSupport.CustomTestCase.__init__(self, *args, **kwargs) def _xor(self, ref_dict, l_dict): """ diff --git a/test/test_nodes.py b/test/test_nodes.py index 4471b3a15..5467c5490 100755 --- a/test/test_nodes.py +++ b/test/test_nodes.py @@ -12,6 +12,7 @@ Test module for nodes.py. import unittest from types import ClassType +import DocutilsTestSupport # must be imported before docutils from DocutilsTestSupport import nodes, utils debug = 0 diff --git a/test/test_publisher.py b/test/test_publisher.py index 545822bc6..708c3ef87 100755 --- a/test/test_publisher.py +++ b/test/test_publisher.py @@ -12,12 +12,10 @@ Test the `Publisher` facade and the ``publish_*`` convenience functions. import pickle from types import StringType, DictType - +import DocutilsTestSupport # must be imported before docutils import docutils from docutils import core, nodes, io -import DocutilsTestSupport - test_document = """\ Test Document diff --git a/test/test_settings.py b/test/test_settings.py index 4226af580..157cb71e1 100755 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -17,6 +17,7 @@ import pprint import warnings import unittest from types import StringType +import DocutilsTestSupport # must be imported before docutils from docutils import frontend, utils from docutils.writers import html4css1, pep_html from docutils.parsers import rst diff --git a/test/test_transforms/test___init__.py b/test/test_transforms/test___init__.py index a126d8854..30e60afd3 100755 --- a/test/test_transforms/test___init__.py +++ b/test/test_transforms/test___init__.py @@ -10,6 +10,7 @@ Test module for transforms/__init__.py. """ +from __init__ import DocutilsTestSupport # must be imported before docutils from docutils import transforms, utils import unittest diff --git a/test/test_transforms/test_expose_internals.py b/test/test_transforms/test_expose_internals.py index db19d2a0a..69193246a 100755 --- a/test/test_transforms/test_expose_internals.py +++ b/test/test_transforms/test_expose_internals.py @@ -11,8 +11,8 @@ Test module for universal.ExposeInternals transform. """ +from __init__ import DocutilsTestSupport # must be imported before docutils from docutils.transforms.universal import ExposeInternals -from __init__ import DocutilsTestSupport from docutils.parsers.rst import Parser def suite(): diff --git a/test/test_transforms/test_transitions.py b/test/test_transforms/test_transitions.py index e450ddff7..098c8bba3 100755 --- a/test/test_transforms/test_transitions.py +++ b/test/test_transforms/test_transitions.py @@ -10,8 +10,8 @@ Test module for misc.Transitions transform. """ +from __init__ import DocutilsTestSupport # must be imported before docutils from docutils.transforms.misc import Transitions -from __init__ import DocutilsTestSupport from docutils.parsers.rst import Parser def suite(): diff --git a/test/test_transforms/test_writer_aux.py b/test/test_transforms/test_writer_aux.py index 34b723241..5ec040a69 100755 --- a/test/test_transforms/test_writer_aux.py +++ b/test/test_transforms/test_writer_aux.py @@ -10,8 +10,8 @@ Test module for writer_aux transforms. """ +from __init__ import DocutilsTestSupport # must be imported before docutils from docutils.transforms import writer_aux -from __init__ import DocutilsTestSupport from docutils.parsers.rst import Parser def suite(): -- cgit v1.2.1 From 507cddee06eea200d202f38761c960815a814517 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 5 Dec 2005 17:41:58 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4142 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 993b54813..364b783db 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -1223,7 +1223,7 @@ when used in a document. This acts like macros. The directive contents will have to be evaluated when referenced, not when defined. - * Call the directive "macro"? + * Needs a better name? "Macro", "substitution"? * What to do with directive arguments & options when the macro/directive is referenced? -- cgit v1.2.1 From b5b4f9aa40074887bcb68e1d9f455e52b6b3d2fe Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 5 Dec 2005 20:08:24 +0000 Subject: ordered alphabetically git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4143 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index ebfc41407..4c5320579 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -22,9 +22,34 @@ Changes Since 0.3.9 * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. +* 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/ref/rst/substitutions.txt: "reStructuredText Standard + Substitution Definition Sets", added to project. + * docutils/__init__.py: - Added ``__version_details__`` attribute to describe code source @@ -189,31 +214,6 @@ Changes Since 0.3.9 * docutils/writers/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. -* 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/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/ref/rst/substitutions.txt: "reStructuredText Standard - Substitution Definition Sets", added to project. - * test/coverage.sh: Added to project; test coverage script. * test/DocutilsTestSupport.py: -- cgit v1.2.1 From ac2a06229e13e5d0c624ae2f5794628a24ee9c56 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 5 Dec 2005 20:26:30 +0000 Subject: removed outdated history entries git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4144 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 4c5320579..80810317d 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -182,11 +182,8 @@ Changes Since 0.3.9 - Added support for image width and height units. - Made ``xmlcharrefreplace`` the default output encoding error handler. - - A warning is now issued if neither ``--stylesheet`` nor - ``--stylesheet-path`` is specified. - Made ``--embed-stylesheet`` the default rather than ``--link-stylesheet``. - - Added writer-specific transform to check the stylesheet setting. - 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.) -- cgit v1.2.1 From dbf820e37f2340da82ab631cd0b7869cebdfc560 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 5 Dec 2005 23:25:24 +0000 Subject: moved docs behind docutils git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4145 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 80810317d..55c6861c0 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -22,34 +22,6 @@ Changes Since 0.3.9 * setup.py: Added installation of data files in ``docutils/parsers/rst/include/``. -* 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/ref/rst/substitutions.txt: "reStructuredText Standard - Substitution Definition Sets", added to project. - * docutils/__init__.py: - Added ``__version_details__`` attribute to describe code source @@ -211,6 +183,34 @@ Changes Since 0.3.9 * docutils/writers/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. +* 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/ref/rst/substitutions.txt: "reStructuredText Standard + Substitution Definition Sets", added to project. + * test/coverage.sh: Added to project; test coverage script. * test/DocutilsTestSupport.py: -- cgit v1.2.1 From a04370ee3ed5d062e87180e5cbdf1cebb133045e Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 6 Dec 2005 01:05:17 +0000 Subject: Added trailing whitespace stripping to ``string2lines()`` git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4146 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/statemachine.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index dfd49a777..2a2f38ba6 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -1433,7 +1433,8 @@ class StateCorrection(Exception): def string2lines(astring, tab_width=8, convert_whitespace=0, whitespace=re.compile('[\v\f]')): """ - Return a list of one-line strings with tabs expanded and no newlines. + Return a list of one-line strings with tabs expanded, no newlines, and + trailing whitespace stripped. Each tab is expanded with between 1 and `tab_width` spaces, so that the next character's index becomes a multiple of `tab_width` (8 by default). @@ -1446,7 +1447,7 @@ def string2lines(astring, tab_width=8, convert_whitespace=0, """ if convert_whitespace: astring = whitespace.sub(' ', astring) - return [s.expandtabs(tab_width) for s in astring.splitlines()] + return [s.expandtabs(tab_width).rstrip() for s in astring.splitlines()] def _exception_data(): """ -- cgit v1.2.1 From 2ee75a675d5c74d75b587b2d28de459436ac25e6 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 6 Dec 2005 01:06:33 +0000 Subject: Fixed bugs: list items with blank first lines; block quote attributions with indented second lines. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4147 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/states.py | 15 +++-- test/test_parsers/test_rst/test_block_quotes.py | 4 ++ .../test_parsers/test_rst/test_enumerated_lists.py | 66 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index 3a9c49094..b149c1888 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -1114,6 +1114,7 @@ class Body(RSTState): Return a 3-tuple: (block quote lines, attribution lines, attribution offset). """ + #import pdb ; pdb.set_trace() blank = None nonblank_seen = None indent = 0 @@ -1130,8 +1131,10 @@ class Body(RSTState): indent = (len(indented[blank + 2]) - len(indented[blank + 2].lstrip())) for j in range(blank + 3, len(indented)): - if indent != (len(indented[j]) - - len(indented[j].lstrip())): # bad shape + if ( indented[j] # may be blank last line + and indent != (len(indented[j]) + - len(indented[j].lstrip()))): + # bad shape blank = None break if blank: @@ -1169,8 +1172,12 @@ class Body(RSTState): return [], next_state, [] def list_item(self, indent): - indented, line_offset, blank_finish = \ - self.state_machine.get_known_indented(indent) + if self.state_machine.line[indent:]: + indented, line_offset, blank_finish = ( + self.state_machine.get_known_indented(indent)) + else: + indented, indent, line_offset, blank_finish = ( + self.state_machine.get_first_known_indented(indent)) listitem = nodes.list_item('\n'.join(indented)) if indented: self.nested_parse(indented, input_offset=line_offset, diff --git a/test/test_parsers/test_rst/test_block_quotes.py b/test/test_parsers/test_rst/test_block_quotes.py index b94fa8588..dd7561723 100755 --- a/test/test_parsers/test_rst/test_block_quotes.py +++ b/test/test_parsers/test_rst/test_block_quotes.py @@ -191,6 +191,8 @@ Paragraph. -- Attribution line one and line two + +Paragraph. """, """\ @@ -210,6 +212,8 @@ Paragraph. Attribution line one and line two + + Paragraph. """], ["""\ Paragraph. diff --git a/test/test_parsers/test_rst/test_enumerated_lists.py b/test/test_parsers/test_rst/test_enumerated_lists.py index b8ab093e5..0375b33e9 100755 --- a/test/test_parsers/test_rst/test_enumerated_lists.py +++ b/test/test_parsers/test_rst/test_enumerated_lists.py @@ -834,6 +834,72 @@ x z. x """], +["""\ +3-space indent, with a trailing space: + +1. \n\ + foo + +3-space indent, no trailing space: + +1. + foo + +2-space indent: + +1. + foo + +1-space indent: + +1. + foo + +0-space indent, not a list item: + +1. +foo + +No item content: + +1. +""", +"""\ + + + 3-space indent, with a trailing space: + + + + foo + + 3-space indent, no trailing space: + + + + foo + + 2-space indent: + + + + foo + + 1-space indent: + + + + foo + + 0-space indent, not a list item: + + 1. + foo + + No item content: + + +"""], ] -- cgit v1.2.1 From f4f7c04762a2ca3c6ef26cfa0be404c3da1ba956 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 6 Dec 2005 01:07:16 +0000 Subject: in ``Publisher.publish()``, expanded the generic top-level exception catching git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4148 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docutils/core.py b/docutils/core.py index 043c8ebfc..a9acfafb5 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -193,20 +193,21 @@ class Publisher: already set), run `self.reader` and then `self.writer`. Return `self.writer`'s output. """ - if self.settings is None: - self.process_command_line( - argv, usage, description, settings_spec, config_section, - **(settings_overrides or {})) - self.set_io() exit = None try: + if self.settings is None: + self.process_command_line( + argv, usage, description, settings_spec, config_section, + **(settings_overrides or {})) + self.set_io() self.document = self.reader.read(self.source, self.parser, self.settings) self.apply_transforms() output = self.writer.write(self.document, self.destination) self.writer.assemble_parts() except Exception, error: - if self.settings.traceback: # propagate exceptions? + if self.settings and self.settings.traceback: + # propagate exceptions? self.debugging_dumps() raise self.report_Exception(error) -- cgit v1.2.1 From 39cb158f9ab3dd8f91011d855359bfd2aaaed341 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 6 Dec 2005 01:07:49 +0000 Subject: updated git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4149 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- BUGS.txt | 85 ------------------------------------------------------------- HISTORY.txt | 11 +++++--- 2 files changed, 8 insertions(+), 88 deletions(-) diff --git a/BUGS.txt b/BUGS.txt index c0d46aae8..f0ee7f202 100644 --- a/BUGS.txt +++ b/BUGS.txt @@ -111,91 +111,6 @@ Known Bugs Also see the `SourceForge Bug Tracker`_. -* The reST parser does not recognize _`block quote attributions` that - have an indented second line, but only if there is any text after - the block quote:: - - $ rst2pseudoxml.py - Block quote. - - -- This is - the attribution. - - Normal text. - - - - Block quote. - - - - -- This is - - - the attribution. - - Normal text. - - According to `the spec`__, it should work: "If the attribution - consists of multiple lines, the left edges of the second and - subsequent lines must align." - - __ docs/ref/rst/restructuredtext.html#block-quotes - -* _`List items with an empty first line` don't work as expected:: - - 1. - foo - - places "foo" inside a block quote, whereas :: - - 1. - foo - - (which should normally be invalid) causes the "foo" paragraph to - wind up inside the list item. - - The behavior also depends on whether there is a space after the list - marker:: - - 1. - foo - - works as expected. With multiple spaces after the marker, the list - item contents must be indented with mutiple spaces. - - This is bad. Invisible white space at the end of a line shouldn't - impact the parsing results. - -* .. _non-existent working directory: - - Running Docutils in a no-longer existent working directory causes a - crash:: - - $ rst2pseudoxml.py - Traceback (most recent call last): - File "/home/felix/bin/rst2pseudoxml.py", line 25, in ? - publish_cmdline(description=description) - File "/home/felix/.python/lib/docutils/core.py", line 329, in publish_cmdline - config_section=config_section, enable_exit_status=enable_exit_status) - File "/home/felix/.python/lib/docutils/core.py", line 197, in publish - self.process_command_line( - File "/home/felix/.python/lib/docutils/core.py", line 155, in process_command_line - self.settings = option_parser.parse_args(argv) - File "/usr/lib/python2.4/optparse.py", line 1280, in parse_args - return self.check_values(values, args) - File "/home/felix/.python/lib/docutils/frontend.py", line 577, in check_values - os.getcwd()) - OSError: [Errno 2] No such file or directory - - Reproduce by creating a directory, cd'ing into it, rd'ing the - directory in a separate shell and running "rst2pseudoxml.py" in the - original shell. - - To fix this, we'd need to fix all occurences of os.getcwd(). Maybe - add a docutils.utils.getcwd() function which returns an empty string - on OSError? - * The "stylesheet" setting (a URL, to be used verbatim) should be allowed to be combined with "embed_stylesheet". The stylesheet data should be read in using urllib. There was an assumption that a diff --git a/HISTORY.txt b/HISTORY.txt index 55c6861c0..f7c1551b2 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -19,9 +19,6 @@ Changes Since 0.3.9 - Updated the project policies for trunk/branch development & version numbering. -* setup.py: Added installation of data files in - ``docutils/parsers/rst/include/``. - * docutils/__init__.py: - Added ``__version_details__`` attribute to describe code source @@ -50,6 +47,10 @@ Changes Since 0.3.9 ``document.anonymous_refs``, and ``document.anonymous_targets``. - Added a "container" element. +* docutils/statemachine.py: + + - Added trailing whitespace stripping to ``string2lines()``. + * docutils/languages/ja.py: Added to project: Japanese mappings by Hisashi Morita. @@ -71,6 +72,8 @@ Changes Since 0.3.9 - 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. * docutils/parsers/rst/directives/body.py: @@ -252,6 +255,8 @@ Release 0.3.9 (2005-05-26) - Enabled ``--dump-*`` options when ``--traceback`` specified, allowing for easier debugging. + - In ``Publisher.publish()``, expanded the generic top-level + exception catching. * docutils/examples.py: -- cgit v1.2.1 From 261175e07bc7221ba941ebb592781b5a8fbd7e6d Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Dec 2005 14:30:56 +0000 Subject: don't catch SystemExit exceptions git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4150 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/core.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docutils/core.py b/docutils/core.py index a9acfafb5..a0da54033 100644 --- a/docutils/core.py +++ b/docutils/core.py @@ -194,6 +194,7 @@ class Publisher: `self.writer`'s output. """ exit = None + exit_status = 0 try: if self.settings is None: self.process_command_line( @@ -205,6 +206,8 @@ class Publisher: self.apply_transforms() output = self.writer.write(self.document, self.destination) self.writer.assemble_parts() + except SystemExit: + exit = 1 except Exception, error: if self.settings and self.settings.traceback: # propagate exceptions? @@ -212,13 +215,14 @@ class Publisher: raise self.report_Exception(error) exit = 1 + exit_status = 1 self.debugging_dumps() if (enable_exit_status and self.document and (self.document.reporter.max_level >= self.settings.exit_status_level)): sys.exit(self.document.reporter.max_level + 10) elif exit: - sys.exit(1) + sys.exit(exit_status) return output def debugging_dumps(self): -- cgit v1.2.1 From 2c7be05e9e776313b36c539c205a63295ace5107 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Dec 2005 23:45:52 +0000 Subject: minor fix git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4151 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docs/dev/todo.txt | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/docs/dev/todo.txt b/docs/dev/todo.txt index 364b783db..06ce321f1 100644 --- a/docs/dev/todo.txt +++ b/docs/dev/todo.txt @@ -50,7 +50,12 @@ the short term) to include: * [DONE in rev. 3962] Incorporate new branch policy into the docs. ("Development strategy" thread on Docutils-develop) -* Fix East-Asian `double-width characters`_ issue. [DavidG] +* [DONE in rev. 4152] Added East-Asian double-width character support. + +* Merge the S5 branch. + +* Convert ``docutils/writers/support/*`` to individual writer + packages. Anything else? @@ -764,22 +769,8 @@ __ rst/alternatives.html#or-not-to-do * Add test for ":figwidth: image" option of "figure" directive. (Test code needs to check if PIL is available on the system.) -* The parser doesn't know anything about _`double-width characters` - such as Chinese hanza & Japanese kanji/kana. Also, it's dependent - on whitespace and punctuation as markup delimiters, which may not be - applicable in these languages. - - Especially the table parsers suffer from this problem. - - We need to use the ``unicodedata.east_asian_width`` function, - introduced in Python 2.4. - - From `Unicode Standard Annex #11: East Asian Width - `_: - - In a broad sense, wide characters include W, F, and A (when in - EA context), while narrow characters include N, Na, H, and A - (when not in EA context). +* Add support for CJK double-width whitespace & punctuation + characters? * Add motivation sections for constructs in spec. @@ -1701,7 +1692,7 @@ PEP/HTML Writer * Remove the generic style information (duplicated from html4css1.css) from pep.css to avoid redundancy. - We need support for `multiple stylesheets`_ before, though. + We need support for `multiple stylesheets`_ first, though. LaTeX writer -- cgit v1.2.1 From e571eb6f3616063e8cc1096b3451aa6f3e659858 Mon Sep 17 00:00:00 2001 From: goodger Date: Wed, 7 Dec 2005 23:46:30 +0000 Subject: added East Asian double-width character support; thanks to Frank Bennett for inspiration on ``docutils.utils.east_asian_column_width()`` git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4152 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- HISTORY.txt | 12 + THANKS.txt | 1 + docutils/parsers/rst/states.py | 14 +- docutils/parsers/rst/tableparser.py | 5 + docutils/statemachine.py | 31 +- docutils/utils.py | 26 ++ test/test_parsers/test_rst/test_east_asian_text.py | 324 +++++++++++++++++++++ 7 files changed, 407 insertions(+), 6 deletions(-) create mode 100755 test/test_parsers/test_rst/test_east_asian_text.py diff --git a/HISTORY.txt b/HISTORY.txt index f7c1551b2..822a098aa 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -50,6 +50,13 @@ Changes Since 0.3.9 * 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. @@ -74,6 +81,11 @@ Changes Since 0.3.9 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: diff --git a/THANKS.txt b/THANKS.txt index 5917a3b03..2c0218922 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -21,6 +21,7 @@ donations, tasty treats, and related projects: * Heiko Baumann * Anthony Baxter * Eric Bellot +* Frank Bennett * Ian Bicking * Marek Blaha * Martin Blais diff --git a/docutils/parsers/rst/states.py b/docutils/parsers/rst/states.py index b149c1888..66c4393b8 100644 --- a/docutils/parsers/rst/states.py +++ b/docutils/parsers/rst/states.py @@ -114,7 +114,7 @@ from docutils import ApplicationError, DataError from docutils.statemachine import StateMachineWS, StateWS from docutils.nodes import fully_normalize_name as normalize_name from docutils.nodes import whitespace_normalize_name -from docutils.utils import escape2null, unescape +from docutils.utils import escape2null, unescape, column_width from docutils.parsers.rst import directives, languages, tableparser, roles from docutils.parsers.rst.languages import en as _fallback_language_module @@ -995,6 +995,9 @@ class Body(RSTState): Generic classifier of the first line of a block. """ + double_width_pad_char = tableparser.TableParser.double_width_pad_char + """Padding character for East Asian double-width text.""" + enum = Struct() """Enumerated list parsing information.""" @@ -1592,6 +1595,8 @@ class Body(RSTState): source=source, line=lineno)) blank_finish = 0 block.disconnect() + # for East Asian chars: + block.pad_double_width(self.double_width_pad_char) width = len(block[0].strip()) for i in range(len(block)): block[i] = block[i].strip() @@ -1656,9 +1661,12 @@ class Body(RSTState): return [], messages, not extra self.state_machine.next_line(end - start) block = lines[start:end+1] + # for East Asian chars: + block.pad_double_width(self.double_width_pad_char) return block, [], end == limit or not lines[end+1].strip() def malformed_table(self, block, detail=''): + block.replace(self.double_width_pad_char, '') data = '\n'.join(block) message = 'Malformed table.' lineno = self.state_machine.abs_line_number() - len(block) + 1 @@ -2586,7 +2594,7 @@ class Text(RSTState): underline = match.string.rstrip() source = title + '\n' + underline messages = [] - if len(title) > len(underline): + if column_width(title) > len(underline): if len(underline) < 4: if self.state_machine.match_titles: msg = self.reporter.info( @@ -2825,7 +2833,7 @@ class Line(SpecializedText): return [], 'Body', [] title = title.rstrip() messages = [] - if len(title) > len(overline): + if column_width(title) > len(overline): blocktext = overline + '\n' + title + '\n' + underline if len(overline.rstrip()) < 4: self.short_overline(context, blocktext, lineno, 2) diff --git a/docutils/parsers/rst/tableparser.py b/docutils/parsers/rst/tableparser.py index 8529a65b0..1d5dc9dfd 100644 --- a/docutils/parsers/rst/tableparser.py +++ b/docutils/parsers/rst/tableparser.py @@ -39,6 +39,9 @@ class TableParser: head_body_separator_pat = None """Matches the row separator between head rows and body rows.""" + double_width_pad_char = '\x00' + """Padding character for East Asian double-width text.""" + def parse(self, block): """ Analyze the text `block` and return a table data structure. @@ -169,6 +172,7 @@ class GridTableParser(TableParser): cellblock = self.block.get_2D_block(top + 1, left + 1, bottom, right) cellblock.disconnect() # lines in cell can't sync with parent + cellblock.replace(self.double_width_pad_char, '') self.cells.append((top, left, bottom, right, cellblock)) corners.extend([(top, right), (bottom, left)]) corners.sort() @@ -469,6 +473,7 @@ class SimpleTableParser(TableParser): start, end = columns[i] cellblock = lines.get_2D_block(0, start, len(lines), end) cellblock.disconnect() # lines in cell can't sync with parent + cellblock.replace(self.double_width_pad_char, '') row[i][3] = cellblock self.table.append(row) diff --git a/docutils/statemachine.py b/docutils/statemachine.py index 2a2f38ba6..b14b308f7 100644 --- a/docutils/statemachine.py +++ b/docutils/statemachine.py @@ -110,7 +110,8 @@ __docformat__ = 'restructuredtext' import sys import re -from types import SliceType as _SliceType +import types +import unicodedata class StateMachine: @@ -1116,7 +1117,7 @@ class ViewList: # indexing a list with a slice object; they just work). def __getitem__(self, i): - if isinstance(i, _SliceType): + if isinstance(i, types.SliceType): assert i.step in (None, 1), 'cannot handle slice with stride' return self.__class__(self.data[i.start:i.stop], items=self.items[i.start:i.stop], @@ -1125,7 +1126,7 @@ class ViewList: return self.data[i] def __setitem__(self, i, item): - if isinstance(i, _SliceType): + if isinstance(i, types.SliceType): assert i.step in (None, 1), 'cannot handle slice with stride' if not isinstance(item, ViewList): raise TypeError('assigning non-ViewList to ViewList slice') @@ -1400,6 +1401,30 @@ class StringList(ViewList): block.data = [line[indent:] for line in block.data] return block + def pad_double_width(self, pad_char): + """ + Pad all double-width characters in self by appending `pad_char` to each. + For East Asian language support. + """ + if hasattr(unicodedata, 'east_asian_width'): + east_asian_width = unicodedata.east_asian_width + else: + return # new in Python 2.4 + for i in range(len(self.data)): + line = self.data[i] + if isinstance(line, types.UnicodeType): + new = [] + for char in line: + new.append(char) + if east_asian_width(char) in 'WF': # 'W'ide & 'F'ull-width + new.append(pad_char) + self.data[i] = ''.join(new) + + def replace(self, old, new): + """Replace all occurrences of substring `old` with `new`.""" + for i in range(len(self.data)): + self.data[i] = self.data[i].replace(old, new) + class StateMachineError(Exception): pass class UnknownStateError(StateMachineError): pass diff --git a/docutils/utils.py b/docutils/utils.py index 100f8671d..24c4986f0 100644 --- a/docutils/utils.py +++ b/docutils/utils.py @@ -13,7 +13,9 @@ __docformat__ = 'reStructuredText' import sys import os import os.path +import types import warnings +import unicodedata from types import StringType, UnicodeType from docutils import ApplicationError, DataError from docutils import frontend, nodes @@ -489,6 +491,30 @@ def unescape(text, restore_backslashes=0): text = ''.join(text.split(sep)) return text +east_asian_widths = {'W': 2, # Wide + 'F': 2, # Full-width (wide) + 'Na': 1, # Narrow + 'H': 1, # Half-width (narrow) + 'N': 1, # Neutral (not East Asian, treated as narrow) + 'A': 1} # Ambiguous (s/b wide in East Asian context, + # narrow otherwise, but that doesn't work) +"""Mapping of result codes from `unicodedata.east_asian_width()` to character +column widths.""" + +def east_asian_column_width(text): + if isinstance(text, types.UnicodeType): + total = 0 + for c in text: + total += east_asian_widths[unicodedata.east_asian_width(c)] + return total + else: + return len(text) + +if hasattr(unicodedata, 'east_asian_width'): + column_width = east_asian_column_width +else: + column_width = len + class DependencyList: diff --git a/test/test_parsers/test_rst/test_east_asian_text.py b/test/test_parsers/test_rst/test_east_asian_text.py new file mode 100755 index 000000000..1ac27743e --- /dev/null +++ b/test/test_parsers/test_rst/test_east_asian_text.py @@ -0,0 +1,324 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Tests for East Asian text with double-width characters. +""" + +from __init__ import DocutilsTestSupport + +import unicodedata +try: + east_asian_width = unicodedata.east_asian_width +except AttributeError: + east_asian_width = None + +def suite(): + s = DocutilsTestSupport.ParserTestSuite() + s.generateTests(totest) + return s + +totest = {} + +if not east_asian_width: + print ('test_east_asian_text.py tests skipped; ' + 'Python 2.4 or higher required.') +else: + totest['double-width'] = [ +[u"""\ +タイトル1 +========= + +タイトル2 +======== +""", +u"""\ + +
    + + タイトル1 + <section ids="id2" names="タイトル2"> + <title> + タイトル2 + <system_message level="2" line="5" source="test data" type="WARNING"> + <paragraph> + Title underline too short. + <literal_block xml:space="preserve"> + タイトル2 + ======== +"""], +[ur""" ++-----------------------+ +| * ヒョウ:ダイ1ギョウ | +| * ダイ2ギョウ | ++-----------------------+ +| \* ダイ1ギョウ | +| * ダイ2ギョウ | ++-----------------------+ +""", +u"""\ +<document source="test data"> + <table> + <tgroup cols="1"> + <colspec colwidth="23"> + <tbody> + <row> + <entry> + <bullet_list bullet="*"> + <list_item> + <paragraph> + ヒョウ:ダイ1ギョウ + <list_item> + <paragraph> + ダイ2ギョウ + <row> + <entry> + <paragraph> + * ダイ1ギョウ + * ダイ2ギョウ +"""], +[u"""\ +Complex spanning pattern (no edge knows all rows/cols): + ++--------+---------------------+ +| 北西・ | 北・北東セル | +| 西セル +--------------+------+ +| | 真ん中のセル | 東・ | ++--------+--------------+ 南東 | +| 南西・南セル | セル | ++-----------------------+------+ +""", +u"""\ +<document source="test data"> + <paragraph> + Complex spanning pattern (no edge knows all rows/cols): + <table> + <tgroup cols="3"> + <colspec colwidth="8"> + <colspec colwidth="14"> + <colspec colwidth="6"> + <tbody> + <row> + <entry morerows="1"> + <paragraph> + 北西・ + 西セル + <entry morecols="1"> + <paragraph> + 北・北東セル + <row> + <entry> + <paragraph> + 真ん中のセル + <entry morerows="1"> + <paragraph> + 東・ + 南東 + セル + <row> + <entry morecols="1"> + <paragraph> + 南西・南セル +"""], +[u"""\ +========= ========= +ダイ1ラン ダイ2ラン +========= ========= + +======== ========= +ダイ1ラン ダイ2ラン +======== ========= +""", +u"""\ +<document source="test data"> + <table> + <tgroup cols="2"> + <colspec colwidth="9"> + <colspec colwidth="9"> + <tbody> + <row> + <entry> + <paragraph> + ダイ1ラン + <entry> + <paragraph> + ダイ2ラン + <system_message level="3" line="5" source="test data" type="ERROR"> + <paragraph> + Malformed table. + Text in column margin at line offset 1. + <literal_block xml:space="preserve"> + ======== ========= + ダイ1ラン ダイ2ラン + ======== ========= +"""], +[u"""\ +Some ambiguous-width characters: + += =================================== +© copyright sign +® registered sign +« left pointing guillemet +» right pointing guillemet +– en-dash +— em-dash +‘ single turned comma quotation mark +’ single comma quotation mark +‚ low single comma quotation mark +“ double turned comma quotation mark +” double comma quotation mark +„ low double comma quotation mark +† dagger +‡ double dagger +… ellipsis +™ trade mark sign +⇔ left-right double arrow += =================================== +""", +u"""\ +<document source="test data"> + <paragraph> + Some ambiguous-width characters: + <table> + <tgroup cols="2"> + <colspec colwidth="1"> + <colspec colwidth="35"> + <tbody> + <row> + <entry> + <paragraph> + \xa9 + <entry> + <paragraph> + copyright sign + <row> + <entry> + <paragraph> + \xae + <entry> + <paragraph> + registered sign + <row> + <entry> + <paragraph> + \xab + <entry> + <paragraph> + left pointing guillemet + <row> + <entry> + <paragraph> + \xbb + <entry> + <paragraph> + right pointing guillemet + <row> + <entry> + <paragraph> + \\u2013 + <entry> + <paragraph> + en-dash + <row> + <entry> + <paragraph> + \\u2014 + <entry> + <paragraph> + em-dash + <row> + <entry> + <paragraph> + \\u2018 + <entry> + <paragraph> + single turned comma quotation mark + <row> + <entry> + <paragraph> + \\u2019 + <entry> + <paragraph> + single comma quotation mark + <row> + <entry> + <paragraph> + \\u201a + <entry> + <paragraph> + low single comma quotation mark + <row> + <entry> + <paragraph> + \\u201c + <entry> + <paragraph> + double turned comma quotation mark + <row> + <entry> + <paragraph> + \\u201d + <entry> + <paragraph> + double comma quotation mark + <row> + <entry> + <paragraph> + \\u201e + <entry> + <paragraph> + low double comma quotation mark + <row> + <entry> + <paragraph> + \\u2020 + <entry> + <paragraph> + dagger + <row> + <entry> + <paragraph> + \\u2021 + <entry> + <paragraph> + double dagger + <row> + <entry> + <paragraph> + \\u2026 + <entry> + <paragraph> + ellipsis + <row> + <entry> + <paragraph> + \\u2122 + <entry> + <paragraph> + trade mark sign + <row> + <entry> + <paragraph> + \\u21d4 + <entry> + <paragraph> + left-right double arrow +"""], +] +''' +[u"""\ +""", +u"""\ +"""], +''' + + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') -- cgit v1.2.1 From 118dd3d2aa36cf563590197e28830c1a905f9cd8 Mon Sep 17 00:00:00 2001 From: goodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> Date: Thu, 8 Dec 2005 04:43:13 +0000 Subject: merged branches/s5 changes r4011:4155 into trunk/docutils git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@4156 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- COPYING.txt | 6 + HISTORY.txt | 39 +- MANIFEST.in | 2 +- THANKS.txt | 1 + docs/dev/testing.txt | 19 +- docs/index.txt | 5 +- docs/ref/rst/definitions.txt | 180 ++++ docs/ref/rst/directives.txt | 8 +- docs/ref/rst/substitutions.txt | 162 ---- docs/user/config.txt | 68 +- docs/user/images/big-black.png | Bin 0 -> 19823 bytes docs/user/images/big-white.png | Bin 0 -> 25697 bytes docs/user/images/default.png | Bin 0 -> 59358 bytes docs/user/images/happy_monkey.png | Bin 0 -> 5202 bytes docs/user/images/medium-black.png | Bin 0 -> 24021 bytes docs/user/images/medium-white.png | Bin 0 -> 33756 bytes docs/user/images/rsp-all.png | Bin 0 -> 32565 bytes docs/user/images/rsp-breaks.png | Bin 0 -> 17754 bytes docs/user/images/rsp-covers.png | Bin 0 -> 19080 bytes docs/user/images/rsp-cuts.png | Bin 0 -> 20751 bytes docs/user/images/rsp-empty.png | Bin 0 -> 4900 bytes docs/user/images/rsp-objects.png | Bin 0 -> 21291 bytes docs/user/images/rsp.svg | 636 +++++++++++++ docs/user/images/s5-files.png | Bin 0 -> 25404 bytes docs/user/images/s5-files.svg | 639 +++++++++++++ docs/user/images/small-black.png | Bin 0 -> 41144 bytes docs/user/images/small-white.png | Bin 0 -> 41120 bytes docs/user/slide-shows.txt | 984 +++++++++++++++++++++ docs/user/tools.txt | 142 ++- docutils/frontend.py | 8 +- docutils/parsers/rst/directives/references.py | 4 + docutils/parsers/rst/include/s5defs.txt | 49 + docutils/transforms/references.py | 15 +- docutils/writers/__init__.py | 3 +- docutils/writers/html4css1.py | 53 +- docutils/writers/s5_html.py | 314 +++++++ docutils/writers/support/s5_html/README.txt | 6 + .../writers/support/s5_html/big-black/__base__ | 2 + .../s5_html/big-black/big_inverse/framing.css | 25 + .../writers/support/s5_html/big-black/framing.css | 25 + .../writers/support/s5_html/big-black/pretty.css | 111 +++ .../writers/support/s5_html/big-white/framing.css | 24 + .../writers/support/s5_html/big-white/pretty.css | 109 +++ docutils/writers/support/s5_html/default/blank.gif | Bin 0 -> 49 bytes .../writers/support/s5_html/default/framing.css | 25 + .../writers/support/s5_html/default/iepngfix.htc | 42 + docutils/writers/support/s5_html/default/opera.css | 8 + .../writers/support/s5_html/default/outline.css | 21 + .../writers/support/s5_html/default/pretty.css | 122 +++ docutils/writers/support/s5_html/default/print.css | 33 + .../writers/support/s5_html/default/s5-core.css | 11 + .../writers/support/s5_html/default/slides.css | 10 + docutils/writers/support/s5_html/default/slides.js | 559 ++++++++++++ .../writers/support/s5_html/medium-black/__base__ | 2 + .../support/s5_html/medium-black/pretty.css | 117 +++ .../support/s5_html/medium-white/framing.css | 24 + .../support/s5_html/medium-white/pretty.css | 115 +++ .../writers/support/s5_html/small-black/__base__ | 2 + .../writers/support/s5_html/small-black/pretty.css | 118 +++ .../support/s5_html/small-white/framing.css | 24 + .../writers/support/s5_html/small-white/pretty.css | 116 +++ setup.py | 6 +- .../expected/standalone_rst_html4css1.html | 2 +- .../expected/standalone_rst_s5_html_1.html | 148 ++++ .../expected/standalone_rst_s5_html_2.html | 144 +++ test/functional/expected/ui/default/blank.gif | Bin 0 -> 49 bytes test/functional/expected/ui/default/framing.css | 25 + test/functional/expected/ui/default/iepngfix.htc | 42 + test/functional/expected/ui/default/opera.css | 8 + test/functional/expected/ui/default/outline.css | 21 + test/functional/expected/ui/default/pretty.css | 122 +++ test/functional/expected/ui/default/print.css | 33 + test/functional/expected/ui/default/s5-core.css | 11 + test/functional/expected/ui/default/slides.css | 10 + test/functional/expected/ui/default/slides.js | 559 ++++++++++++ test/functional/expected/ui/small-black/blank.gif | Bin 0 -> 49 bytes .../functional/expected/ui/small-black/framing.css | 24 + .../expected/ui/small-black/iepngfix.htc | 42 + test/functional/expected/ui/small-black/opera.css | 8 + .../functional/expected/ui/small-black/outline.css | 21 + test/functional/expected/ui/small-black/pretty.css | 118 +++ test/functional/expected/ui/small-black/print.css | 33 + .../functional/expected/ui/small-black/s5-core.css | 11 + test/functional/expected/ui/small-black/slides.css | 10 + test/functional/expected/ui/small-black/slides.js | 559 ++++++++++++ test/functional/input/standalone_rst_s5_html.txt | 126 +++ test/functional/tests/standalone_rst_s5_html_1.py | 44 + test/functional/tests/standalone_rst_s5_html_2.py | 7 + test/test_functional.py | 50 +- .../test_rst/test_directives/test_target_notes.py | 64 ++ test/test_transforms/test_target_notes.py | 84 ++ tools/rst2s5.py | 26 + 92 files changed, 7104 insertions(+), 242 deletions(-) create mode 100644 docs/ref/rst/definitions.txt delete mode 100644 docs/ref/rst/substitutions.txt create mode 100644 docs/user/images/big-black.png create mode 100644 docs/user/images/big-white.png create mode 100644 docs/user/images/default.png create mode 100644 docs/user/images/happy_monkey.png create mode 100644 docs/user/images/medium-black.png create mode 100644 docs/user/images/medium-white.png create mode 100644 docs/user/images/rsp-all.png create mode 100644 docs/user/images/rsp-breaks.png create mode 100644 docs/user/images/rsp-covers.png create mode 100644 docs/user/images/rsp-cuts.png create mode 100644 docs/user/images/rsp-empty.png create mode 100644 docs/user/images/rsp-objects.png create mode 100644 docs/user/images/rsp.svg create mode 100644 docs/user/images/s5-files.png create mode 100644 docs/user/images/s5-files.svg create mode 100644 docs/user/images/small-black.png create mode 100644 docs/user/images/small-white.png create mode 100644 docs/user/slide-shows.txt create mode 100644 docutils/parsers/rst/include/s5defs.txt create mode 100644 docutils/writers/s5_html.py create mode 100644 docutils/writers/support/s5_html/README.txt create mode 100644 docutils/writers/support/s5_html/big-black/__base__ create mode 100644 docutils/writers/support/s5_html/big-black/big_inverse/framing.css create mode 100644 docutils/writers/support/s5_html/big-black/framing.css create mode 100644 docutils/writers/support/s5_html/big-black/pretty.css create mode 100644 docutils/writers/support/s5_html/big-white/framing.css create mode 100644 docutils/writers/support/s5_html/big-white/pretty.css create mode 100644 docutils/writers/support/s5_html/default/blank.gif create mode 100644 docutils/writers/support/s5_html/default/framing.css create mode 100644 docutils/writers/support/s5_html/default/iepngfix.htc create mode 100644 docutils/writers/support/s5_html/default/opera.css create mode 100644 docutils/writers/support/s5_html/default/outline.css create mode 100644 docutils/writers/support/s5_html/default/pretty.css create mode 100644 docutils/writers/support/s5_html/default/print.css create mode 100644 docutils/writers/support/s5_html/default/s5-core.css create mode 100644 docutils/writers/support/s5_html/default/slides.css create mode 100644 docutils/writers/support/s5_html/default/slides.js create mode 100644 docutils/writers/support/s5_html/medium-black/__base__ create mode 100644 docutils/writers/support/s5_html/medium-black/pretty.css create mode 100644 docutils/writers/support/s5_html/medium-white/framing.css create mode 100644 docutils/writers/support/s5_html/medium-white/pretty.css create mode 100644 docutils/writers/support/s5_html/small-black/__base__ create mode 100644 docutils/writers/support/s5_html/small-black/pretty.css create mode 100644 docutils/writers/support/s5_html/small-white/framing.css create mode 100644 docutils/writers/support/s5_html/small-white/pretty.css create mode 100644 test/functional/expected/standalone_rst_s5_html_1.html create mode 100644 test/functional/expected/standalone_rst_s5_html_2.html create mode 100644 test/functional/expected/ui/default/blank.gif create mode 100644 test/functional/expected/ui/default/framing.css create mode 100644 test/functional/expected/ui/default/iepngfix.htc create mode 100644 test/functional/expected/ui/default/opera.css create mode 100644 test/functional/expected/ui/default/outline.css create mode 100644 test/functional/expected/ui/default/pretty.css create mode 100644 test/functional/expected/ui/default/print.css create mode 100644 test/functional/expected/ui/default/s5-core.css create mode 100644 test/functional/expected/ui/default/slides.css create mode 100644 test/functional/expected/ui/default/slides.js create mode 100644 test/functional/expected/ui/small-black/blank.gif create mode 100644 test/functional/expected/ui/small-black/framing.css create mode 100644 test/functional/expected/ui/small-black/iepngfix.htc create mode 100644 test/functional/expected/ui/small-black/opera.css create mode 100644 test/functional/expected/ui/small-black/outline.css create mode 100644 test/functional/expected/ui/small-black/pretty.css create mode 100644 test/functional/expected/ui/small-black/print.css create mode 100644 test/functional/expected/ui/small-black/s5-core.css create mode 100644 test/functional/expected/ui/small-black/slides.css create mode 100644 test/functional/expected/ui/small-black/slides.js create mode 100644 test/functional/input/standalone_rst_s5_html.txt create mode 100755 test/functional/tests/standalone_rst_s5_html_1.py create mode 100755 test/functional/tests/standalone_rst_s5_html_2.py create mode 100755 test/test_parsers/test_rst/test_directives/test_target_notes.py create mode 100755 test/test_transforms/test_target_notes.py create mode 100755 tools/rst2s5.py diff --git a/COPYING.txt b/COPYING.txt index c90da5189..6411688bc 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -65,6 +65,12 @@ Exceptions The exceptions to the `Public Domain Dedication`_ above are: +* docutils/writers/support/s5_html/default/iepngfix.htc: + + IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull + <http://www.twinhelix.com>. Free usage permitted as long as + this notice remains intact. + * extras/optparse.py, copyright by Gregory P. Ward, released under a BSD-style license (which can be found in the module's source code). diff --git a/HISTORY.txt b/HISTORY.txt index 822a098aa..ba3d38eec 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -102,9 +102,15 @@ Changes Since 0.3.9 - 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. + 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 Hisashi Morita. @@ -137,6 +143,7 @@ Changes Since 0.3.9 - Added references.DanglingReferences transform, extracted from universal.FinalChecks. - Fixed bug with doubly-indirect substitutions. + - Added footnote_reference classes attribute to "TargetNotes". * docutils/transforms/universal.py: @@ -180,20 +187,23 @@ Changes Since 0.3.9 - 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.py: - Underscores in citekeys are no longer escaped. +* docutils/writers/s5_html.py: Added to project; writer for S5-format + slide shows. + * docutils/writers/support/: Directory added to project. Modules and data files that support writers have been moved here. - * The stylesheets are now installed along with the code, the code - now knows where to find them, and the default is now to use - (actually, to embed) the built-in stylesheets. 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". + The stylesheets are now installed along with the code, the code + knows where to find them, and the default is to use (actually, to + embed) the built-in stylesheets. 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/support/newlatex2e/unicode_map.py: Added to project; mapping of Unicode characters to LaTeX equivalents. @@ -223,8 +233,11 @@ Changes Since 0.3.9 * docs/user/mailing-lists.txt: Added to project; information about Docutils-related mailing lists and how to access them. -* docs/ref/rst/substitutions.txt: "reStructuredText Standard - Substitution Definition Sets", added to project. +* 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. @@ -232,6 +245,14 @@ Changes Since 0.3.9 - 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 diff --git a/MANIFEST.in b/MANIFEST.in index 5b627650c..9b9c4968d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,4 +6,4 @@ recursive-include extras * recursive-include licenses * recursive-include test * recursive-include tools * -recursive-exclude * .cvsignore *.pyc *~ +recursive-exclude * .cvsignore *.pyc *~ .DS_Store diff --git a/THANKS.txt b/THANKS.txt index 2c0218922..d5ead0f83 100644 --- a/THANKS.txt +++ b/THANKS.txt @@ -86,6 +86,7 @@ donations, tasty treats, and related projects: * Daniel Larsson * Marc-Andre Lemburg * Julien Letessier +* Chris Liechti * Wolfgang Lipp * Edward Loper * Dallas Mahrt diff --git a/docs/dev/testing.txt b/docs/dev/testing.txt index 6963f6541..82e9ed31c 100644 --- a/docs/dev/testing.txt +++ b/docs/dev/testing.txt @@ -193,12 +193,21 @@ file name (relative to ``functional/output/`` and arbitrarily. However, the file names in ``functional/output/`` *must* match the file names in ``functional/expected/``. -All other variables are passed as keyword arguments to -``docutils.core.publish_file``, so you can set reader, parser, -writer and anything else you want to configure. +If defined, ``_test_more`` must be a function with the following +signature:: -Note that ``settings_overrides`` is already initialized as a -dictionary *before* the execution of the config file. + def _test_more(expected_dir, output_dir, test_case, parameters): + +This function is called from the test case to perform tests beyond the +simple comparison of expected and actual output files. + +``test_source`` and ``test_destination`` are removed from the +namespace, as are all variables whose names begin with an underscore +("_"). The remaining names are passed as keyword arguments to +``docutils.core.publish_file``, so you can set reader, parser, writer +and anything else you want to configure. Note that +``settings_overrides`` is already initialized as a dictionary *before* +the execution of the config file. Creating New Tests diff --git a/docs/index.txt b/docs/index.txt index 69cceb717..e25d66e07 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -79,6 +79,7 @@ top level of the Docutils project directory. Docutils-general: * `Docutils Front-End Tools <user/tools.html>`__ +* `Easy Slide Shows With reStructuredText & S5 <user/slide-shows.html>`__ * `Docutils Configuration Files <user/config.html>`__ * `Docutils LaTeX Writer <user/latex.html>`__ * `Docutils Mailing Lists <user/mailing-lists.html>`__ @@ -128,8 +129,8 @@ reStructuredText_: * `reStructuredText Markup Specification <ref/rst/restructuredtext.html>`__ * `reStructuredText Directives <ref/rst/directives.html>`__ * `reStructuredText Interpreted Text Roles <ref/rst/roles.html>`__ -* `reStructuredText Standard Substitution Definition Sets - <ref/rst/substitutions.html>`_ +* `reStructuredText Standard Definition Files + <ref/rst/definitions.html>`_ Prehistoric: diff --git a/docs/ref/rst/definitions.txt b/docs/ref/rst/definitions.txt new file mode 100644 index 000000000..78a2bf8da --- /dev/null +++ b/docs/ref/rst/definitions.txt @@ -0,0 +1,180 @@ +============================================ + reStructuredText Standard Definition Files +============================================ +:Author: David Goodger +:Contact: goodger@python.org +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This document has been placed in the public domain. + +.. contents:: + + +This document describes standard definition files, such as sets of +substitution definitions and interpreted text roles, that can be +included in reStructuredText documents. The `"include" directive`__ +has a special syntax for these standard definition files, angle +brackets around the file name:: + + .. include:: <filename.txt> + +__ directives.html#include + +The individual data files are stored with the Docutils source code in +the "docutils" package, in the ``docutils/parsers/rst/include`` +directory. + + +Substitution Definitions +======================== + +Many of the standard definition files contain sets of `substitution +definitions`__, which can be used in documents via `substitution +references`__. For example, the copyright symbol is defined in +``isonum.txt`` as "copy":: + + .. include:: <isonum.txt> + + Copyright |copy| 2003 by John Q. Public, all rights reserved. + +__ restructuredtext.html#substitution-definitions +__ restructuredtext.html#substitution-references + +Individual substitution definitions can also be copied from definition +files and pasted into documents. This has two advantages: it removes +dependencies, and it saves processing of unused definitions. However, +multiple substitution definitions add clutter to the document. + +Substitution references require separation from the surrounding text +with whitespace or punctuation. To use a substitution without +intervening whitespace, you can use the disappearing-whitespace escape +sequence, backslash-space:: + + .. include:: isonum.txt + + Copyright |copy| 2003, BogusMegaCorp\ |trade|. + +Custom substitution definitions may use the `"unicode" directive`__. +Whitespace is ignored and removed, effectively sqeezing together the +text:: + + .. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN + .. |BogusMegaCorp (TM)| unicode:: BogusMegaCorp U+2122 + .. with trademark sign + + Copyright |copy| 2003, |BogusMegaCorp (TM)|. + +__ directives.html#unicode + +In addition, the "ltrim", "rtrim", and "trim" options may be used with +the "unicode" directive to automatically trim spaces from the left, +right, or both sides (respectively) of substitution references:: + + .. |---| unicode:: U+02014 .. em dash + :trim: + + +Character Entity Sets +--------------------- + +The following files contain substitution definitions corresponding to +XML character entity sets, from the following standards: ISO 8879 & +ISO 9573-13 (combined), MathML, and XHTML1. They were generated by +the ``tools/dev/unicode2rstsubs.py`` program from the input file +unicode.xml__, which is maintained as part of the MathML 2 +Recommentation XML source. + +__ http://www.w3.org/2003/entities/xml/ + +=================== ================================================= +Entity Set File Description +=================== ================================================= +isoamsa.txt_ Added Mathematical Symbols: Arrows +isoamsb.txt_ Added Mathematical Symbols: Binary Operators +isoamsc.txt_ Added Mathematical Symbols: Delimiters +isoamsn.txt_ Added Mathematical Symbols: Negated Relations +isoamso.txt_ Added Mathematical Symbols: Ordinary +isoamsr.txt_ Added Mathematical Symbols: Relations +isobox.txt_ Box and Line Drawing +isocyr1.txt_ Russian Cyrillic +isocyr2.txt_ Non-Russian Cyrillic +isodia.txt_ Diacritical Marks +isogrk1.txt_ Greek Letters +isogrk2.txt_ Monotoniko Greek +isogrk3.txt_ Greek Symbols +isogrk4.txt_ [1]_ Alternative Greek Symbols +isolat1.txt_ Added Latin 1 +isolat2.txt_ Added Latin 2 +isomfrk.txt_ [1]_ Mathematical Fraktur +isomopf.txt_ [1]_ Mathematical Openface (Double-struck) +isomscr.txt_ [1]_ Mathematical Script +isonum.txt_ Numeric and Special Graphic +isopub.txt_ Publishing +isotech.txt_ General Technical +mmlalias.txt_ MathML aliases for entities from other sets +mmlextra.txt_ [1]_ Extra names added by MathML +xhtml1-lat1.txt_ XHTML Latin 1 +xhtml1-special.txt_ XHTML Special Characters +xhtml1-symbol.txt_ XHTML Mathematical, Greek and Symbolic Characters +=================== ================================================= + +.. [1] There are ``*-wide.txt`` variants for each of these character + entity set files, containing characters outside of the Unicode + basic multilingual plane or BMP (wide-Unicode; code points greater + than U+FFFF). Most pre-built Python distributions are "narrow" and + do not support wide-Unicode characters. Python *can* be built with + wide-Unicode support though; consult the Python build instructions + for details. + +For example, the copyright symbol is defined as the XML character +entity ``©``. The equivalent reStructuredText substitution +reference (defined in both ``isonum.txt`` and ``xhtml1-lat1.txt``) is +``|copy|``. + +.. _isoamsa.txt: ../../../docutils/parsers/rst/include/isoamsa.txt +.. _isoamsb.txt: ../../../docutils/parsers/rst/include/isoamsb.txt +.. _isoamsc.txt: ../../../docutils/parsers/rst/include/isoamsc.txt +.. _isoamsn.txt: ../../../docutils/parsers/rst/include/isoamsn.txt +.. _isoamso.txt: ../../../docutils/parsers/rst/include/isoamso.txt +.. _isoamsr.txt: ../../../docutils/parsers/rst/include/isoamsr.txt +.. _isobox.txt: ../../../docutils/parsers/rst/include/isobox.txt +.. _isocyr1.txt: ../../../docutils/parsers/rst/include/isocyr1.txt +.. _isocyr2.txt: ../../../docutils/parsers/rst/include/isocyr2.txt +.. _isodia.txt: ../../../docutils/parsers/rst/include/isodia.txt +.. _isogrk1.txt: ../../../docutils/parsers/rst/include/isogrk1.txt +.. _isogrk2.txt: ../../../docutils/parsers/rst/include/isogrk2.txt +.. _isogrk3.txt: ../../../docutils/parsers/rst/include/isogrk3.txt +.. _isogrk4.txt: ../../../docutils/parsers/rst/include/isogrk4.txt +.. _isolat1.txt: ../../../docutils/parsers/rst/include/isolat1.txt +.. _isolat2.txt: ../../../docutils/parsers/rst/include/isolat2.txt +.. _isomfrk.txt: ../../../docutils/parsers/rst/include/isomfrk.txt +.. _isomopf.txt: ../../../docutils/parsers/rst/include/isomopf.txt +.. _isomscr.txt: ../../../docutils/parsers/rst/include/isomscr.txt +.. _isonum.txt: ../../../docutils/parsers/rst/include/isonum.txt +.. _isopub.txt: ../../../docutils/parsers/rst/include/isopub.txt +.. _isotech.txt: ../../../docutils/parsers/rst/include/isotech.txt +.. _mmlalias.txt: ../../../docutils/parsers/rst/include/mmlalias.txt +.. _mmlextra.txt: ../../../docutils/parsers/rst/include/mmlextra.txt +.. _xhtml1-lat1.txt: ../../../docutils/parsers/rst/include/xhtml1-lat1.txt +.. _xhtml1-special.txt: ../../../docutils/parsers/rst/include/xhtml1-special.txt +.. _xhtml1-symbol.txt: ../../../docutils/parsers/rst/include/xhtml1-symbol.txt + + +S5/HTML Definitions +=================== + +The "s5defs.txt_" standard definition file contains interpreted text +roles (classes) and other definitions for documents destined to become +`S5/HTML slide shows`_. + +.. _s5defs.txt: ../../../docutils/parsers/rst/include/s5defs.txt +.. _S5/HTML slide shows: ../../user/slide-shows.html + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/ref/rst/directives.txt b/docs/ref/rst/directives.txt index 58fa324cf..12959e86d 100644 --- a/docs/ref/rst/directives.txt +++ b/docs/ref/rst/directives.txt @@ -1065,7 +1065,7 @@ Target Footnotes :Directive Type: "target-notes" :Doctree Elements: pending, footnote, footnote_reference :Directive Arguments: None. -:Directive Options: None. +:Directive Options: Possible. :Directive Content: None. The "target-notes" directive creates a footnote for each external @@ -1074,6 +1074,12 @@ reference. For every explicit target (of the form, ``.. _target name: URL``) in the text, a footnote will be generated containing the visible URL as content. +The following option is recognized: + +``class`` : text + Set a "class" attribute value on all footnote_reference elements. + See the class_ directive below. + Footnotes ========= diff --git a/docs/ref/rst/substitutions.txt b/docs/ref/rst/substitutions.txt deleted file mode 100644 index 5ea9562f2..000000000 --- a/docs/ref/rst/substitutions.txt +++ /dev/null @@ -1,162 +0,0 @@ -======================================================== - reStructuredText Standard Substitution Definition Sets -======================================================== -:Author: David Goodger -:Contact: goodger@python.org -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This document has been placed in the public domain. - -.. contents:: - - -The data files described below contain sets of reStructuredText -`substitution definitions`__. They can be included in documents using -the `"include" directive's`__ special syntax for standard data files, -angle brackets around the file name:: - - .. include:: <filename.txt> - -__ restructuredtext.html#substitution-definitions -__ directives.html#include - -The definitions can then be used in documents using `substitution -references`__. For example, the copyright symbol is defined in -``isonum.txt`` as "copy":: - - .. include:: <isonum.txt> - - Copyright |copy| 2003 by John Q. Public, all rights reserved. - -__ restructuredtext.html#substitution-references - -Individual definitions can also be copied from these data files and -pasted into documents. This has two advantages: it removes -dependencies, and it saves processing of unused definitions. However, -multiple substitution definitions add clutter to the document. - -Substitution references require separation from the surrounding text -with whitespace or punctuation. To use a substitution without -intervening whitespace, you can use the disappearing-whitespace escape -sequence, backslash-space:: - - .. include:: isonum.txt - - Copyright |copy| 2003, BogusMegaCorp\ |trade|. - -Custom definitions may use the `"unicode" directive`__. Whitespace is -ignored and removed, effectively sqeezing together the text:: - - .. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN - .. |BogusMegaCorp (TM)| unicode:: BogusMegaCorp U+2122 - .. with trademark sign - - Copyright |copy| 2003, |BogusMegaCorp (TM)|. - -__ directives.html#unicode - -In addition, the "ltrim", "rtrim", and "trim" options may be used with -the "unicode" directive to automatically trim spaces from the left, -right, or both sides (respectively) of substitution references:: - - .. |---| unicode:: U+02014 .. em dash - :trim: - -The individual data files are stored with the Docutils source code in -the "docutils" package, in the ``docutils/parsers/rst/include`` -directory. - - -Character Entity Sets -===================== - -The following files contain substitution definitions corresponding to -XML character entity sets, from the following standards: ISO 8879 & -ISO 9573-13 (combined), MathML, and XHTML1. They were generated by -the ``tools/dev/unicode2rstsubs.py`` program from the input file -unicode.xml__, which is maintained as part of the MathML 2 -Recommentation XML source. - -__ http://www.w3.org/2003/entities/xml/ - -=================== ================================================= -Entity Set File Description -=================== ================================================= -isoamsa.txt_ Added Mathematical Symbols: Arrows -isoamsb.txt_ Added Mathematical Symbols: Binary Operators -isoamsc.txt_ Added Mathematical Symbols: Delimiters -isoamsn.txt_ Added Mathematical Symbols: Negated Relations -isoamso.txt_ Added Mathematical Symbols: Ordinary -isoamsr.txt_ Added Mathematical Symbols: Relations -isobox.txt_ Box and Line Drawing -isocyr1.txt_ Russian Cyrillic -isocyr2.txt_ Non-Russian Cyrillic -isodia.txt_ Diacritical Marks -isogrk1.txt_ Greek Letters -isogrk2.txt_ Monotoniko Greek -isogrk3.txt_ Greek Symbols -isogrk4.txt_ [1]_ Alternative Greek Symbols -isolat1.txt_ Added Latin 1 -isolat2.txt_ Added Latin 2 -isomfrk.txt_ [1]_ Mathematical Fraktur -isomopf.txt_ [1]_ Mathematical Openface (Double-struck) -isomscr.txt_ [1]_ Mathematical Script -isonum.txt_ Numeric and Special Graphic -isopub.txt_ Publishing -isotech.txt_ General Technical -mmlalias.txt_ MathML aliases for entities from other sets -mmlextra.txt_ [1]_ Extra names added by MathML -xhtml1-lat1.txt_ XHTML Latin 1 -xhtml1-special.txt_ XHTML Special Characters -xhtml1-symbol.txt_ XHTML Mathematical, Greek and Symbolic Characters -=================== ================================================= - -.. [1] There are ``*-wide.txt`` variants for each of these character - entity set files, containing characters outside of the Unicode - basic multilingual plane or BMP (wide-Unicode; code points greater - than U+FFFF). Most pre-built Python distributions are "narrow" and - do not support wide-Unicode characters. Python *can* be built with - wide-Unicode support though; consult the Python build instructions - for details. - -For example, the copyright symbol is defined as the XML character -entity ``©``. The equivalent reStructuredText substitution -reference (defined in both ``isonum.txt`` and ``xhtml1-lat1.txt``) is -``|copy|``. - -.. _isoamsa.txt: ../../../docutils/parsers/rst/include/isoamsa.txt -.. _isoamsb.txt: ../../../docutils/parsers/rst/include/isoamsb.txt -.. _isoamsc.txt: ../../../docutils/parsers/rst/include/isoamsc.txt -.. _isoamsn.txt: ../../../docutils/parsers/rst/include/isoamsn.txt -.. _isoamso.txt: ../../../docutils/parsers/rst/include/isoamso.txt -.. _isoamsr.txt: ../../../docutils/parsers/rst/include/isoamsr.txt -.. _isobox.txt: ../../../docutils/parsers/rst/include/isobox.txt -.. _isocyr1.txt: ../../../docutils/parsers/rst/include/isocyr1.txt -.. _isocyr2.txt: ../../../docutils/parsers/rst/include/isocyr2.txt -.. _isodia.txt: ../../../docutils/parsers/rst/include/isodia.txt -.. _isogrk1.txt: ../../../docutils/parsers/rst/include/isogrk1.txt -.. _isogrk2.txt: ../../../docutils/parsers/rst/include/isogrk2.txt -.. _isogrk3.txt: ../../../docutils/parsers/rst/include/isogrk3.txt -.. _isogrk4.txt: ../../../docutils/parsers/rst/include/isogrk4.txt -.. _isolat1.txt: ../../../docutils/parsers/rst/include/isolat1.txt -.. _isolat2.txt: ../../../docutils/parsers/rst/include/isolat2.txt -.. _isomfrk.txt: ../../../docutils/parsers/rst/include/isomfrk.txt -.. _isomopf.txt: ../../../docutils/parsers/rst/include/isomopf.txt -.. _isomscr.txt: ../../../docutils/parsers/rst/include/isomscr.txt -.. _isonum.txt: ../../../docutils/parsers/rst/include/isonum.txt -.. _isopub.txt: ../../../docutils/parsers/rst/include/isopub.txt -.. _isotech.txt: ../../../docutils/parsers/rst/include/isotech.txt -.. _mmlalias.txt: ../../../docutils/parsers/rst/include/mmlalias.txt -.. _mmlextra.txt: ../../../docutils/parsers/rst/include/mmlextra.txt -.. _xhtml1-lat1.txt: ../../../docutils/parsers/rst/include/xhtml1-lat1.txt -.. _xhtml1-special.txt: ../../../docutils/parsers/rst/include/xhtml1-special.txt -.. _xhtml1-symbol.txt: ../../../docutils/parsers/rst/include/xhtml1-symbol.txt - - -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: diff --git a/docs/user/config.txt b/docs/user/config.txt index 2f6fa40c8..cbd874972 100644 --- a/docs/user/config.txt +++ b/docs/user/config.txt @@ -345,7 +345,8 @@ _`sectnum_xform` Enable or disable the section numbering transform (docutils.transforms.parts.SectNum). - Default: enabled (1). Options: ``--no-section-numbering``. + Default: enabled (1). Options: ``--section-numbering``, + ``--no-section-numbering``. _`source_link` Include a "View document source" link in the document footer. URL @@ -584,16 +585,18 @@ _`cloak_email_addresses` _`compact_lists` Remove extra vertical whitespace between items of bullet lists and enumerated lists, when list items are "simple" (i.e., all items - each contain one paragraph and/or one "simple" sublist only). + each contain one paragraph and/or one "simple" sublist only). The + behaviour can be specified directly via "class" attributes (values + "compact" and "open") in the document. Default: enabled (1). Options: ``--compact-lists, --no-compact-lists``. _`compact_field_lists` - Remove extra vertical whitespace between items of field lists that are "simple" (i.e., all field bodies each contain at most one - paragraph). + paragraph). The behaviour can be specified directly via "class" + attributes (values "compact" and "open") in the document. Default: enabled (1). Options: ``--compact-field-lists, --no-compact-field-lists``. @@ -643,9 +646,9 @@ _`option_limit` .. _stylesheet [html4css1 writer]: stylesheet - CSS stylesheet URL, used verbatim. Overrides stylesheet_path - [#override]_. Pass an empty string to deactivate stylesheet - inclusion. + CSS stylesheet URL, used verbatim. Overrides the + "stylesheet_path" setting [#override]_. Pass an empty string to + deactivate stylesheet inclusion. Default: None. Options: ``--stylesheet``. @@ -656,10 +659,9 @@ stylesheet .. _stylesheet_path [html4css1 writer]: stylesheet_path - Path to CSS stylesheet [#pwd]_. Overrides "stylesheet" URL - setting (``--stylesheet``) [#override]_. Path is adjusted - relative to the output HTML file. Also defined for the `LaTeX - Writer`__. + Path to CSS stylesheet [#pwd]_. Overrides the "stylesheet" URL + setting [#override]_. Path is adjusted relative to the output + HTML file. Also defined for the `LaTeX Writer`__. Default: "html4css1.css" in the docutils/writers/support directory (installed automatically; for the exact machine-specific path, use @@ -720,6 +722,50 @@ _`python_home` Default: parent directory (".."). Options: ``--python-home``. +[s5_html writer] +................. + +The S5/HTML Writer derives from the standard HTML Writer, and shares +all settings defined in the `[html4css1 writer]`_ section. The +"[html4css1 writer]" section of configuration files is processed +before the "[s5_html writer]" section. + +The S5/HTML Writer's default for the ``compact_lists`` setting differs +from that of the standard HTML Writer: the default here is to disable +compact lists. + +_`current_slide` + + Enable or disable the current slide indicator ("1/15"). + + Default: disabled (None). Options: ``--current-slide``, + ``--no-current-slide``. + +_`overwrite_theme_files` + Allow or prevent the overwriting of existing theme files in the + ``ui/<theme>`` directory. This has no effect if "theme_url_" is + used. + + Default: keep existing theme files (None). Options: + ``--keep-theme-files``, ``--overwrite-theme-files``. + +_`theme` + Name of an installed S5 theme, to be copied into a ``ui/<theme>`` + subdirectory, beside the destination file (output HTML). Note + that existing theme files will not be overwritten; the existing + theme directory you must be deleted manually. Overrides the + "theme_url_" setting [#override]_. + + Default: "default". Option: ``--theme``. + +_`theme-url` + The URL of an S5 theme directory. The destination file (output + HTML) will link to this theme; nothing will be copied. Overrides + the "theme_" setting [#override]_. + + Default: None. Option: ``--theme-url``. + + [latex2e writer] ```````````````` diff --git a/docs/user/images/big-black.png b/docs/user/images/big-black.png new file mode 100644 index 000000000..869a0cf9f Binary files /dev/null and b/docs/user/images/big-black.png differ diff --git a/docs/user/images/big-white.png b/docs/user/images/big-white.png new file mode 100644 index 000000000..1ce6d7d7d Binary files /dev/null and b/docs/user/images/big-white.png differ diff --git a/docs/user/images/default.png b/docs/user/images/default.png new file mode 100644 index 000000000..509eeddad Binary files /dev/null and b/docs/user/images/default.png differ diff --git a/docs/user/images/happy_monkey.png b/docs/user/images/happy_monkey.png new file mode 100644 index 000000000..2164c06dd Binary files /dev/null and b/docs/user/images/happy_monkey.png differ diff --git a/docs/user/images/medium-black.png b/docs/user/images/medium-black.png new file mode 100644 index 000000000..f851e679e Binary files /dev/null and b/docs/user/images/medium-black.png differ diff --git a/docs/user/images/medium-white.png b/docs/user/images/medium-white.png new file mode 100644 index 000000000..e5a465a56 Binary files /dev/null and b/docs/user/images/medium-white.png differ diff --git a/docs/user/images/rsp-all.png b/docs/user/images/rsp-all.png new file mode 100644 index 000000000..3e5f5ede3 Binary files /dev/null and b/docs/user/images/rsp-all.png differ diff --git a/docs/user/images/rsp-breaks.png b/docs/user/images/rsp-breaks.png new file mode 100644 index 000000000..f2a31b098 Binary files /dev/null and b/docs/user/images/rsp-breaks.png differ diff --git a/docs/user/images/rsp-covers.png b/docs/user/images/rsp-covers.png new file mode 100644 index 000000000..597c2c2a8 Binary files /dev/null and b/docs/user/images/rsp-covers.png differ diff --git a/docs/user/images/rsp-cuts.png b/docs/user/images/rsp-cuts.png new file mode 100644 index 000000000..aa46b3876 Binary files /dev/null and b/docs/user/images/rsp-cuts.png differ diff --git a/docs/user/images/rsp-empty.png b/docs/user/images/rsp-empty.png new file mode 100644 index 000000000..f6b93c38b Binary files /dev/null and b/docs/user/images/rsp-empty.png differ diff --git a/docs/user/images/rsp-objects.png b/docs/user/images/rsp-objects.png new file mode 100644 index 000000000..43ce276f1 Binary files /dev/null and b/docs/user/images/rsp-objects.png differ diff --git a/docs/user/images/rsp.svg b/docs/user/images/rsp.svg new file mode 100644 index 000000000..03445d3bc --- /dev/null +++ b/docs/user/images/rsp.svg @@ -0,0 +1,636 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="1224.0000pt" + height="792.00000pt" + id="svg16130" + sodipodi:version="0.32" + inkscape:version="0.42" + sodipodi:docbase="/Users/david/projects/docutils/s5-branch/docs/user/images" + sodipodi:docname="rsp.svg" + inkscape:export-filename="/Users/david/projects/docutils/s5-branch/docs/user/images/rsp-empty.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000"> + <defs + id="defs16132"> + <radialGradient + cx="64.960804" + cy="86.732626" + fx="64.394720" + fy="89.843742" + id="radialGradient1157" + r="4.6795605" + xlink:href="#linearGradient1125" + gradientTransform="scale(1.232968,0.811051)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1147" + x1="30.807715" + x2="9.1659926" + xlink:href="#linearGradient1129" + y1="134.41771" + y2="128.61883" + gradientTransform="scale(2.035443,0.491293)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1146" + x1="23.109005" + x2="23.655650" + xlink:href="#linearGradient1129" + y1="86.372661" + y2="75.530011" + gradientTransform="scale(1.564854,0.639037)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1150" + x1="7.1055503" + x2="37.417715" + xlink:href="#linearGradient1152" + y1="148.97907" + y2="149.31015" + gradientTransform="scale(1.328405,0.752782)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1152"> + <stop + id="stop1153" + offset="0.00000000" + style="stop-color:#ffffff;stop-opacity:0.00000000;" /> + <stop + id="stop1155" + offset="0.44302326" + style="stop-color:#ffffff;stop-opacity:0.46274510;" /> + <stop + id="stop1154" + offset="1.0000000" + style="stop-color:#ffffff;stop-opacity:0.00000000;" /> + </linearGradient> + <linearGradient + id="linearGradient1151" + x1="29.180973" + x2="12.077421" + xlink:href="#linearGradient1152" + y1="176.88234" + y2="176.49016" + gradientTransform="scale(1.503932,0.664924)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1135" + x1="5.6004575" + x2="57.337623" + xlink:href="#linearGradient1136" + y1="125.70108" + y2="125.70108" + gradientTransform="scale(1.240748,0.805966)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1129"> + <stop + id="stop1130" + offset="0.00000000" + style="stop-color:#ffffff;stop-opacity:0.00000000;" /> + <stop + id="stop1131" + offset="1.0000000" + style="stop-color:#ffffff;stop-opacity:0.64583331;" /> + </linearGradient> + <linearGradient + id="linearGradient1128" + x1="76.620649" + x2="89.927438" + xlink:href="#linearGradient1129" + y1="79.202017" + y2="132.51965" + gradientTransform="scale(1.342210,0.745040)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1133" + x1="95.959445" + x2="95.959445" + xlink:href="#linearGradient1125" + y1="96.280971" + y2="6.0312801" + gradientTransform="scale(1.356086,0.737416)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1136"> + <stop + id="stop1137" + offset="0.00000000" + style="stop-color:#000000;stop-opacity:1.0000000;" /> + <stop + id="stop1138" + offset="1.0000000" + style="stop-color:#454545;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient1145" + x1="26.716417" + x2="57.535761" + xlink:href="#linearGradient1136" + y1="72.512797" + y2="104.12337" + gradientTransform="scale(1.435519,0.696612)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1125"> + <stop + id="stop1126" + offset="0.00000000" + style="stop-color:#979797;stop-opacity:1.0000000;" /> + <stop + id="stop1163" + offset="0.35050300" + style="stop-color:#fafafa;stop-opacity:1.0000000;" /> + <stop + id="stop1164" + offset="0.36050299" + style="stop-color:#9f9f9f;stop-opacity:1.0000000;" /> + <stop + id="stop1127" + offset="1.0000000" + style="stop-color:#ffffff;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient1134" + x1="66.560545" + x2="26.091148" + xlink:href="#linearGradient1125" + y1="135.98955" + y2="85.436682" + gradientTransform="scale(1.892867,0.528299)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient1243"> + <stop + id="stop1244" + offset="0.00000000" + style="stop-color:#000000;stop-opacity:0.19791667;" /> + <stop + id="stop1245" + offset="1.0000000" + style="stop-color:#000000;stop-opacity:0.00000000;" /> + </linearGradient> + <linearGradient + id="linearGradient1149" + x1="508.22840" + x2="505.28565" + xlink:href="#linearGradient1243" + y1="556.37391" + y2="107.87502" + gradientTransform="scale(1.347706,0.742001)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient1243" + id="linearGradient16217" + gradientUnits="userSpaceOnUse" + gradientTransform="scale(1.347706,0.742001)" + x1="508.22840" + y1="556.37391" + x2="505.28565" + y2="107.87502" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient1243" + id="linearGradient16219" + gradientUnits="userSpaceOnUse" + gradientTransform="scale(1.347706,0.742001)" + x1="508.22840" + y1="556.37391" + x2="505.28565" + y2="107.87502" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient1243" + id="linearGradient16221" + gradientUnits="userSpaceOnUse" + gradientTransform="scale(1.347706,0.742001)" + x1="508.22840" + y1="556.37391" + x2="505.28565" + y2="107.87502" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient1243" + id="linearGradient16223" + gradientUnits="userSpaceOnUse" + gradientTransform="scale(1.347706,0.742001)" + x1="508.22840" + y1="556.37391" + x2="505.28565" + y2="107.87502" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.52132701" + inkscape:cx="650.00000" + inkscape:cy="497.00000" + inkscape:document-units="px" + inkscape:current-layer="layer7" + showgrid="true" + inkscape:grid-bbox="false" + inkscape:grid-points="false" + gridspacingx="5.0000000px" + gridspacingy="5.0000000px" + gridtolerance="2.5000000px" + inkscape:window-width="920" + inkscape:window-height="603" + inkscape:window-x="20" + inkscape:window-y="73" /> + <metadata + id="metadata16135"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="base" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <g + id="g17404" + transform="translate(100.0000,-75.00000)" + style="stroke:none;stroke-opacity:1.0000000"> + <rect + ry="38.000000" + rx="38.000000" + style="fill:#ffffff;fill-opacity:0.14999999;stroke:none;stroke-opacity:1.0000000" + id="rrect19" + width="1100.0000" + height="844.00000" + x="0.0000000" + y="146.00000" /> + <rect + ry="36.000000" + rx="36.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect18" + width="1096.0000" + height="840.00000" + x="2.0000000" + y="148.00000" /> + <rect + ry="34.000000" + rx="34.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect17" + width="1092.0000" + height="836.00000" + x="4.0000000" + y="150.00000" /> + <rect + ry="32.000000" + rx="32.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect16" + width="1088.0000" + height="832.00000" + x="6.0000000" + y="152.00000" /> + <rect + ry="30.000000" + rx="30.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect15" + width="1084.0000" + height="828.00000" + x="8.0000000" + y="154.00000" /> + <rect + ry="28.000000" + rx="28.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect14" + width="1080.0000" + height="824.00000" + x="10.000000" + y="156.00000" /> + <rect + ry="26.000000" + rx="26.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect13" + width="1076.0000" + height="820.00000" + x="12.000000" + y="158.00000" /> + <rect + ry="24.000000" + rx="24.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect12" + width="1072.0000" + height="816.00000" + x="14.000000" + y="160.00000" /> + <rect + ry="22.000000" + rx="22.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect11" + width="1068.0000" + height="812.00000" + x="16.000000" + y="162.00000" /> + <rect + ry="20.000000" + rx="20.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect10" + width="1064.0000" + height="808.00000" + x="18.000000" + y="164.00000" /> + <rect + ry="18.000000" + rx="18.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect9" + width="1060.0000" + height="804.00000" + x="20.000000" + y="166.00000" /> + <rect + ry="16.000000" + rx="16.000000" + style="fill:#ffffff;fill-opacity:0.099999972;stroke:none;stroke-opacity:1.0000000" + id="rrect8" + width="1056.0000" + height="800.00000" + x="22.000000" + y="168.00000" /> + <rect + ry="14.000000" + rx="14.000000" + style="fill:#ffffff;fill-opacity:0.11999995;stroke:none;stroke-opacity:1.0000000" + id="rrect7" + width="1052.0000" + height="796.00000" + x="24.000000" + y="170.00000" /> + <rect + ry="12.000000" + rx="12.000000" + style="fill:#ffffff;fill-opacity:0.14000000;stroke:none;stroke-opacity:1.0000000" + id="rrect6" + width="1048.0000" + height="792.00000" + x="26.000000" + y="172.00000" /> + <rect + ry="10.000000" + rx="10.000000" + style="fill:#ffffff;fill-opacity:0.15999998;stroke:none;stroke-opacity:1.0000000" + id="rrect5" + width="1044.0000" + height="788.00000" + x="28.000000" + y="174.00000" /> + <rect + ry="8.0000000" + rx="8.0000000" + style="fill:#ffffff;fill-opacity:0.17999996;stroke:none;stroke-opacity:1.0000000" + id="rrect4" + width="1040.0000" + height="784.00000" + x="30.000000" + y="176.00000" /> + <rect + ry="6.0000000" + rx="6.0000000" + style="fill:#ffffff;fill-opacity:0.20000000;stroke:none;stroke-opacity:1.0000000" + id="rrect3" + width="1036.0000" + height="780.00000" + x="32.000000" + y="178.00000" /> + <rect + ry="4.0000000" + rx="4.0000000" + style="fill:#ffffff;fill-opacity:0.21999998;stroke:none;stroke-opacity:1.0000000" + id="rrect2" + width="1032.0000" + height="776.00000" + x="34.000000" + y="180.00000" /> + <rect + ry="2.0000000" + rx="2.0000000" + style="fill:#ffffff;fill-opacity:0.49999997;stroke:none;stroke-opacity:1.0000000" + id="rrect1" + width="1028.0000" + height="772.00000" + x="36.000000" + y="182.00000" /> + <rect + style="fill:#ffffff;fill-opacity:1.0000000;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="rect7529" + width="1024.0000" + height="768.00000" + x="38.000000" + y="184.00000" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer6" + inkscape:label="cuts" + style="display:inline"> + <g + style="display:inline" + id="g17268" + transform="matrix(3.955288,0.000000,0.000000,3.955288,-1133.851,-788.5280)"> + <g + transform="matrix(-1.028194e-2,1.033891e-2,-1.033891e-2,-1.028194e-2,587.3686,366.0048)" + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" + id="g17126"> + <path + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" + sodipodi:nodetypes="ccccc" + id="path17128" + d="M 7602.2995,10592.638 L 6351.2995,11841.638 L 7603.2995,9842.6385 L 8851.2995,11843.638 L 7602.2995,10592.638 z " /> + </g> + <path + id="text17130" + d="M 346.56856,325.28003 C 346.01656,325.52003 345.34456,325.66403 344.48056,325.66403 C 342.70456,325.66403 341.26456,324.51203 341.26456,322.35203 C 341.24056,320.43204 342.48856,319.06403 344.40856,319.06403 C 345.36856,319.06403 346.01656,319.23203 346.44856,319.42403 L 347.02456,316.71203 C 346.25656,316.42403 345.20056,316.25603 344.24056,316.25603 C 339.87256,316.25603 337.52056,319.06404 337.52056,322.49603 C 337.52056,326.19203 339.94456,328.52003 343.73656,328.52003 C 345.12856,328.52003 346.35256,328.28003 347.00056,327.96803 L 346.56856,325.28003 M 360.08468,316.52003 L 356.43668,316.52003 L 356.43668,323.50403 C 356.43668,323.81603 356.38868,324.08003 356.29268,324.29603 C 356.07668,324.87203 355.47668,325.56803 354.46868,325.56803 C 353.17269,325.56803 352.62068,324.53603 352.62068,322.83203 L 352.62068,316.52003 L 348.97268,316.52003 L 348.97268,323.40803 C 348.97268,327.03203 350.70069,328.52003 353.10068,328.52003 C 355.21268,328.52003 356.31669,327.32003 356.77268,326.60003 L 356.84468,326.60003 L 357.01268,328.25603 L 360.18068,328.25603 C 360.13268,327.27204 360.08468,326.02403 360.08468,324.48803 L 360.08468,316.52003 M 363.54031,314.31203 L 363.54031,316.52003 L 361.98031,316.52003 L 361.98031,319.20803 L 363.54031,319.20803 L 363.54031,324.03203 C 363.54031,325.68803 363.87631,326.81603 364.54831,327.51203 C 365.14831,328.11203 366.13231,328.52003 367.30831,328.52003 C 368.31631,328.52003 369.20431,328.37603 369.66031,328.20803 L 369.63631,325.44803 C 369.30031,325.52003 369.06031,325.54403 368.55631,325.54403 C 367.47631,325.54403 367.11631,324.89603 367.11631,323.48003 L 367.11631,319.20803 L 369.73231,319.20803 L 369.73231,316.52003 L 367.11631,316.52003 L 367.11631,313.32803 L 363.54031,314.31203 M 371.17681,327.68003 C 372.06481,328.16003 373.43281,328.52003 374.96881,328.52003 C 378.32881,328.52003 380.03281,326.91203 380.03281,324.70403 C 380.00881,323.00004 379.09681,321.84803 376.86481,321.10403 C 375.42481,320.60003 374.96881,320.31203 374.96881,319.73603 C 374.96881,319.16003 375.47281,318.80003 376.36081,318.80003 C 377.34481,318.80003 378.37681,319.18403 378.90481,319.44803 L 379.52881,316.95203 C 378.80881,316.59203 377.60881,316.25603 376.24081,316.25603 C 373.33681,316.25603 371.46481,317.91204 371.46481,320.12003 C 371.44081,321.48803 372.37681,322.83203 374.82481,323.62403 C 376.16881,324.08003 376.52881,324.36803 376.52881,324.99203 C 376.52881,325.59203 376.07281,325.95203 374.96881,325.95203 C 373.88881,325.95203 372.49681,325.49603 371.82481,325.08803 L 371.17681,327.68003" + style="font-size:24.000000px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#007f00;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Myriad" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="scissors" + style="display:inline"> + <g + style="display:inline" + transform="matrix(-0.261242,0.531875,-0.531875,-0.261243,609.4123,269.4384)" + id="g834"> + <path + transform="matrix(-0.974540,0.224211,0.224211,0.974540,434.7533,-39.90828)" + style="font-size:12.000000px;fill:#dadadb;fill-rule:evenodd;stroke:#000000;stroke-width:10.000006;stroke-linejoin:round;stroke-dasharray:none" + id="path693" + d="M 130.58000,19.228100 C 131.42800,19.228100 283.20600,268.51700 283.20600,268.51700 C 283.20600,268.51700 237.41800,294.80300 238.26600,294.80300 C 239.11400,294.80300 112.77400,100.62900 130.58000,19.228100 z " /> + <path + style="font-size:12.000000px;fill:#1f1f61;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:10.000000;stroke-linejoin:bevel;stroke-dasharray:none" + id="path596" + d="M 267.36640,300.28500 C 267.36640,300.28500 221.96450,419.33820 230.36720,437.01870 C 230.00410,447.80450 196.57070,496.47240 174.95750,496.94460 C 156.32120,498.11630 95.023300,483.45520 104.85110,423.19450 C 116.53670,361.19710 166.80670,382.68650 186.68190,380.35660 C 206.55780,378.02600 240.34010,301.17560 216.89540,284.78780 C 243.06010,291.66780 266.70660,302.06270 267.36640,300.28500 z M 178.01080,388.46270 C 110.22310,370.58330 97.043850,476.92290 157.42350,483.15570 C 225.11850,486.03500 224.54920,396.02940 178.01080,388.46270 z " /> + <path + transform="matrix(0.984591,0.174877,-0.174877,0.984591,41.27270,-35.37063)" + style="font-size:12.000000px;fill:#dadadb;fill-rule:evenodd;stroke:#000000;stroke-width:9.9999933;stroke-linejoin:bevel;stroke-dasharray:none" + id="path674" + d="M 130.58000,19.228100 C 131.42800,19.228100 283.20600,268.51700 283.20600,268.51700 C 283.20600,268.51700 237.41800,294.80300 238.26600,294.80300 C 239.11400,294.80300 112.77400,100.62900 130.58000,19.228100 z " /> + <path + transform="translate(161.5948,57.16911)" + style="font-size:12.000000px;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6.2500000;stroke-dasharray:none" + sodipodi:nodetypes="ccc" + id="path710" + d="M 81.400500,200.68300 C 66.137900,201.53100 63.594200,225.27300 81.400500,226.12100 C 98.359000,225.27300 98.359200,200.68300 81.400500,200.68300 z " /> + <path + transform="translate(161.5948,57.16911)" + style="font-size:12.000000px;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6.2500000;stroke-dasharray:none" + id="path711" + d="M 69.529600,209.16300 C 71.225500,209.16300 86.488100,224.42500 86.488100,224.42500" /> + <path + transform="translate(161.5948,57.16911)" + style="font-size:12.000000px;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6.2500000;stroke-dasharray:none" + sodipodi:nodetypes="cc" + id="path712" + d="M 76.313000,203.22700 C 77.160900,203.22700 92.423500,218.49000 92.423500,218.49000" /> + <path + style="font-size:12.000000px;fill:#e6ffff;fill-opacity:0.75000000;fill-rule:evenodd;stroke-width:1.0000000pt" + sodipodi:nodetypes="cccc" + id="path717" + d="M 311.59912,21.282200 C 312.44712,21.282200 250.54912,207.82500 250.54912,207.82500 C 250.54912,207.82500 257.17737,220.62188 259.72037,219.77388 C 262.26437,218.92588 318.38312,30.609400 311.59912,21.282200 z " /> + <path + transform="translate(-3.750000,3.750000)" + style="font-size:12.000000px;fill-opacity:0.31851897;fill-rule:evenodd;stroke-width:1.0000000pt" + sodipodi:nodetypes="ccccc" + id="path718" + d="M 236.85900,262.03100 L 240.39000,257.08300 L 256.63200,272.60800 L 252.68100,276.70800 L 236.85900,262.03100 z " /> + <path + style="font-size:12.000000px;fill:#1f1f61;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:10.000000;stroke-linejoin:bevel;stroke-dasharray:none" + id="path590" + d="M 319.25070,379.53570 C 386.05280,358.26700 404.56760,463.80860 344.57810,473.07250 C 277.11370,479.35530 273.15220,389.43500 319.25070,379.53570 z M 225.57020,295.96700 C 225.57020,295.96700 276.90680,412.58430 269.40450,430.66530 C 270.31010,441.41910 306.15060,488.34270 327.76030,487.72650 C 346.43190,487.95870 406.91430,470.23100 394.06590,410.54120 C 379.27480,349.21050 330.15000,373.20280 310.18270,371.87620 C 290.21460,370.54890 252.60710,295.49620 275.19730,277.94910 C 249.41200,286.13730 226.31860,297.70920 225.57020,295.96700 z " /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="breaks" + style="display:inline"> + <g + style="display:inline" + id="g17263" + transform="matrix(3.955288,0.000000,0.000000,3.955288,-654.3060,-855.6644)"> + <g + transform="matrix(0.000000,1.458120e-2,1.458120e-2,0.000000,167.9907,189.6206)" + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" + id="g2604"> + <path + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" + sodipodi:nodetypes="ccccc" + id="path2606" + d="M 7601.0000,11063.000 L 6350.0000,12312.000 L 7602.0000,10313.000 L 8850.0000,12314.000 L 7601.0000,11063.000 z " /> + </g> + <path + id="text17114" + d="M 299.55643,273.07213 C 299.55643,274.39213 299.50843,275.80813 299.46043,276.57613 L 302.55643,276.57613 L 302.70043,274.94413 L 302.74843,274.94413 C 303.56443,276.33613 304.90843,276.84013 306.27643,276.84013 C 308.96443,276.84013 311.62843,274.72813 311.62843,270.50413 C 311.65243,266.90413 309.61243,264.57613 306.80443,264.57613 C 305.17243,264.57613 303.94843,265.22413 303.25243,266.23213 L 303.20443,266.23213 L 303.20443,259.53613 L 299.55643,259.53613 L 299.55643,273.07213 M 303.20443,269.85613 C 303.20443,269.61613 303.22843,269.40013 303.27643,269.18413 C 303.51643,268.12813 304.42843,267.38413 305.41243,267.38413 C 307.11643,267.38413 307.93243,268.82413 307.93243,270.64813 C 307.93243,272.76013 306.97243,273.96013 305.41243,273.96013 C 304.35643,273.96013 303.51643,273.19213 303.27643,272.23213 C 303.22843,272.04013 303.20443,271.82413 303.20443,271.58413 L 303.20443,269.85613 M 313.90018,276.57613 L 317.54818,276.57613 L 317.54818,270.64813 C 317.54818,270.33613 317.57218,270.07213 317.62018,269.83213 C 317.86018,268.68013 318.77218,267.98413 320.11618,267.98413 C 320.52418,267.98413 320.81218,268.03213 321.12418,268.08013 L 321.12418,264.64813 C 320.86018,264.60013 320.69218,264.57613 320.35618,264.57613 C 319.20418,264.57613 317.78818,265.29613 317.18818,267.02413 L 317.09218,267.02413 L 316.94818,264.84013 L 313.82818,264.84013 C 313.90018,265.84813 313.92418,266.97613 313.92418,268.70413 L 313.90018,276.57613 M 333.40881,271.87213 C 333.45681,271.58413 333.52881,271.03213 333.52881,270.40813 C 333.52881,267.50413 332.08880,264.55213 328.29681,264.55213 C 324.24081,264.55213 322.36881,267.84013 322.36881,270.81613 C 322.36881,274.51213 324.64881,276.81613 328.63281,276.81613 C 330.21681,276.81613 331.68081,276.57613 332.88081,276.07213 L 332.40081,273.60013 C 331.41681,273.93613 330.40881,274.10413 329.16081,274.10413 C 327.45681,274.10413 325.96881,273.38413 325.84881,271.84813 L 333.40881,271.87213 M 325.82481,269.35213 C 325.92081,268.39213 326.54481,266.97613 328.10481,266.97613 C 329.76081,266.97613 330.14481,268.48813 330.14481,269.35213 L 325.82481,269.35213 M 345.46506,269.64013 C 345.46506,266.88013 344.24105,264.57613 340.32906,264.57613 C 338.19306,264.57613 336.58506,265.17613 335.76906,265.63213 L 336.44106,267.96013 C 337.20906,267.50413 338.48106,267.09613 339.68106,267.09613 C 341.48106,267.09613 341.81706,267.98413 341.81706,268.60813 L 341.81706,268.75213 C 337.66506,268.75213 334.92906,270.19213 334.92906,273.24013 C 334.92906,275.11213 336.34506,276.84013 338.72106,276.84013 C 340.11306,276.84013 341.31306,276.33613 342.08106,275.40013 L 342.15306,275.40013 L 342.36906,276.57613 L 345.65706,276.57613 C 345.51306,275.92813 345.46506,274.84813 345.46506,273.74413 L 345.46506,269.64013 M 341.93706,272.30413 C 341.93706,272.52013 341.91306,272.73613 341.86506,272.92813 C 341.62506,273.67213 340.85706,274.27213 339.96906,274.27213 C 339.15306,274.27213 338.52906,273.81613 338.52906,272.88013 C 338.52906,271.48813 340.01706,271.03213 341.93706,271.03213 L 341.93706,272.30413 M 352.00131,259.53613 L 348.35331,259.53613 L 348.35331,276.57613 L 352.00131,276.57613 L 352.00131,272.92813 L 352.91331,271.75213 L 355.76931,276.57613 L 360.25731,276.57613 L 355.45731,269.59213 L 359.65731,264.84013 L 355.26531,264.84013 L 352.88931,268.39213 C 352.60131,268.82413 352.31331,269.30413 352.04931,269.80813 L 352.00131,269.80813 L 352.00131,259.53613 M 360.71256,276.00013 C 361.60056,276.48013 362.96856,276.84013 364.50456,276.84013 C 367.86455,276.84013 369.56856,275.23213 369.56856,273.02413 C 369.54456,271.32013 368.63256,270.16813 366.40056,269.42413 C 364.96056,268.92013 364.50456,268.63213 364.50456,268.05613 C 364.50456,267.48013 365.00856,267.12013 365.89656,267.12013 C 366.88056,267.12013 367.91256,267.50413 368.44056,267.76813 L 369.06456,265.27213 C 368.34456,264.91213 367.14456,264.57613 365.77656,264.57613 C 362.87256,264.57613 361.00056,266.23213 361.00056,268.44013 C 360.97656,269.80813 361.91256,271.15213 364.36056,271.94413 C 365.70456,272.40013 366.06456,272.68813 366.06456,273.31213 C 366.06456,273.91213 365.60856,274.27213 364.50456,274.27213 C 363.42456,274.27213 362.03256,273.81613 361.36056,273.40813 L 360.71256,276.00013" + style="font-size:24.000000px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#007f00;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Myriad" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="rock" + style="display:inline"> + <g + style="display:inline" + transform="matrix(0.708388,0.000000,0.000000,0.708388,768.4189,171.0555)" + id="g2067"> + <path + sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + id="path10" + d="M 149.15160,130.25073 L 138.01458,125.99417 L 132.85423,131.15452 L 127.69388,137.17493 L 120.81341,144.91545 L 113.07289,154.37609 L 105.33236,163.83673 L 97.591837,173.29738 L 89.851312,183.61808 L 82.970845,194.79883 L 76.090379,205.11953 L 70.069971,215.44023 L 64.909621,224.04082 L 61.469388,232.64140 L 58.889213,240.38192 L 58.889213,246.40233 L 60.609329,250.70262 L 66.629738,257.58309 L 73.510204,263.60350 L 82.110787,269.62391 L 90.711370,275.64431 L 100.17201,280.80466 L 108.77259,285.96501 L 117.37318,291.98542 L 124.25364,296.28571 L 129.41399,300.58601 L 132.85423,304.02624 L 135.43440,306.60641 L 138.01458,308.32653 L 140.59475,310.04665 L 144.03499,311.76676 L 150.05539,314.34694 L 156.93586,316.92711 L 165.53644,319.50729 L 195.63848,318.64723 L 201.65889,318.64723 L 208.53936,318.64723 L 216.27988,319.50729 L 224.02041,320.36735 L 230.90087,321.22741 L 236.06122,323.80758 L 241.22157,325.52770 L 248.10204,325.52770 L 254.98251,325.52770 L 261.86297,324.66764 L 268.74344,322.94752 L 275.62391,321.22741 L 281.64431,318.64723 L 286.80466,316.92711 L 291.10496,314.34694 L 295.40525,310.90671 L 298.84548,306.60641 L 303.14577,302.30612 L 306.58601,298.00583 L 310.02624,293.70554 L 312.60641,291.12536 L 315.18659,290.26531 L 318.62682,290.26531 L 322.92711,289.40525 L 328.94752,287.68513 L 334.96793,285.10496 L 340.98834,283.38484 L 346.14869,280.80466 L 349.58892,279.08455 L 351.30904,277.36443 L 356.78718,268.76385 L 364.48397,254.32361 L 363.12536,245.36152 L 359.04956,237.80175 L 362.48980,236.94169 L 365.93003,234.36152 L 368.51020,230.92128 L 371.09038,225.76093 L 373.67055,221.46064 L 375.39067,218.02041 L 376.25073,215.44023 L 377.11079,214.58017 L 365.93003,182.75802 L 364.20991,181.03790 L 361.62974,176.73761 L 357.32945,171.57726 L 352.16910,164.69679 L 347.00875,158.67638 L 342.70845,153.51603 L 333.79008,153.06414 L 329.62682,149.89505 L 322.92711,148.35569 L 320.03207,145.27697 L 315.64140,143.64723 L 312.97085,142.01749 L 308.94169,139.52769 L 304.14285,137.62682 L 299.34403,135.63557 L 295.22449,130.56560 L 290.24490,127.71429 L 286.80466,123.41399 L 284.22449,119.97376 L 282.50437,117.39359 L 281.64431,116.53353 L 239.50146,101.91254 L 238.64140,101.91254 L 236.06122,101.05248 L 231.76093,100.19242 L 227.46064,99.332362 L 222.30029,98.472303 L 218.00000,98.472303 L 213.69971,98.472303 L 211.11953,98.472303 L 181.51020,124.82216 L 149.15160,130.25073 z " + style="fill:#b5abab;fill-opacity:1.0000000" /> + <path + sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + id="path1333" + d="M 272.27930,110.03646 L 278.00000,110.00000 L 281.00000,109.00000 L 285.00000,109.00000 L 288.00000,109.00000 L 290.00000,113.00000 L 293.00000,116.00000 L 295.00000,119.00000 L 298.00000,123.00000 L 300.00000,126.00000 L 302.00000,130.00000 L 303.00000,134.00000 L 303.00000,138.00000 L 302.00000,139.00000 L 302.00000,139.00000 L 301.00000,140.00000 L 301.00000,140.00000 L 297.00000,137.00000 L 293.00000,135.00000 L 290.00000,132.00000 L 287.00000,129.00000 L 284.00000,128.00000 L 280.00000,127.00000 L 277.00000,126.00000 L 273.00000,126.00000 L 270.00000,125.00000 L 266.00000,125.00000 L 262.00000,125.00000 L 259.00000,125.00000 L 254.00000,122.00000 L 249.00000,119.00000 L 245.00000,116.00000 L 240.00000,112.00000 L 235.00000,110.00000 L 230.00000,108.00000 L 225.00000,109.00000 L 219.00000,111.00000 L 214.00000,113.00000 L 209.00000,116.00000 L 204.00000,119.00000 L 199.00000,122.00000 L 194.00000,125.00000 L 190.00000,129.00000 L 186.00000,134.00000 L 183.00000,139.00000 L 177.00000,141.00000 L 171.00000,143.00000 L 164.00000,143.00000 L 157.00000,143.00000 L 150.00000,144.00000 L 143.00000,145.00000 L 137.00000,147.00000 L 131.00000,151.00000 L 129.00000,153.00000 L 127.00000,155.00000 L 125.00000,158.00000 L 124.00000,161.00000 L 117.00000,167.00000 L 111.00000,174.00000 L 106.00000,181.00000 L 101.00000,188.00000 L 96.000000,195.00000 L 92.000000,203.00000 L 87.000000,211.00000 L 81.000000,218.00000 L 78.000000,225.00000 L 74.000000,231.00000 L 70.000000,238.00000 L 69.000000,246.00000 L 74.000000,250.00000 L 79.000000,254.00000 L 83.000000,259.00000 L 88.000000,263.00000 L 93.000000,267.00000 L 97.000000,272.00000 L 102.00000,276.00000 L 107.00000,280.00000 L 111.00000,284.00000 L 116.00000,287.00000 L 121.00000,291.00000 L 126.00000,294.00000 L 132.00000,296.00000 L 138.00000,299.00000 L 144.00000,301.00000 L 150.00000,302.00000 L 155.00000,302.00000 L 159.00000,302.00000 L 164.00000,302.00000 L 168.00000,302.00000 L 172.00000,302.00000 L 176.00000,301.00000 L 180.00000,300.00000 L 184.00000,297.00000 L 188.00000,296.00000 L 191.00000,296.00000 L 193.00000,297.00000 L 196.00000,300.00000 L 198.00000,302.00000 L 201.00000,304.00000 L 204.00000,306.00000 L 207.00000,306.00000 L 211.00000,308.00000 L 214.00000,309.00000 L 218.00000,310.00000 L 222.00000,311.00000 L 226.00000,312.00000 L 230.00000,312.00000 L 233.00000,313.00000 L 237.00000,314.00000 L 240.00000,314.00000 L 244.00000,314.00000 L 246.00000,314.00000 L 249.00000,313.00000 L 252.00000,312.00000 L 255.00000,311.00000 L 258.00000,311.00000 L 261.00000,311.00000 L 267.00000,308.00000 L 273.00000,305.00000 L 279.00000,301.00000 L 285.00000,296.00000 L 290.00000,291.00000 L 296.00000,287.00000 L 302.00000,282.00000 L 308.00000,278.00000 L 312.00000,277.00000 L 316.00000,276.00000 L 321.00000,276.00000 L 325.00000,275.00000 L 329.00000,275.00000 L 334.00000,275.00000 L 338.00000,274.00000 L 343.00000,274.00000 L 344.00000,272.00000 L 346.00000,270.00000 L 349.00000,268.00000 L 351.00000,265.00000 L 354.00000,263.00000 L 356.00000,259.00000 L 357.00000,256.00000 L 359.00000,253.00000 L 357.00000,248.00000 L 355.00000,244.00000 L 353.00000,239.00000 L 352.00000,234.00000 L 355.00000,231.00000 L 359.00000,228.00000 L 363.00000,226.00000 L 366.00000,222.00000 L 363.00000,217.00000 L 359.00000,212.00000 L 355.00000,206.00000 L 354.00000,200.00000 L 356.00000,192.00000 L 358.00000,183.00000 L 358.00000,175.00000 L 354.00000,167.00000 L 352.00000,165.00000 L 349.00000,163.00000 L 347.00000,161.00000 L 344.00000,160.00000 L 341.00000,159.00000 L 338.00000,158.00000 L 335.00000,158.00000 L 332.00000,158.00000 L 330.00000,156.00000 L 328.00000,154.00000 L 327.00000,153.00000 L 327.00000,150.00000 L 329.00000,149.00000 L 335.00000,150.00000 L 342.00000,151.00000 L 349.00000,152.00000 L 355.00000,154.00000 L 361.00000,156.00000 L 367.00000,160.00000 L 371.00000,164.00000 L 374.00000,171.00000 L 374.00000,178.00000 L 373.00000,186.00000 L 372.00000,193.00000 L 375.00000,200.00000 L 379.00000,204.00000 L 382.00000,208.00000 L 386.00000,212.00000 L 388.00000,216.00000 L 389.00000,216.00000 L 389.00000,217.00000 L 389.00000,218.00000 L 389.00000,219.00000 L 389.00000,219.00000 L 391.00000,219.00000 L 391.00000,224.00000 L 390.00000,227.00000 L 388.00000,230.00000 L 385.00000,233.00000 L 382.00000,235.00000 L 378.00000,238.00000 L 375.00000,240.00000 L 373.00000,243.00000 L 372.00000,249.00000 L 372.00000,254.00000 L 370.00000,259.00000 L 367.00000,264.00000 L 365.00000,269.00000 L 362.00000,274.00000 L 358.00000,279.00000 L 353.00000,283.00000 L 348.00000,286.00000 L 343.00000,289.00000 L 338.00000,292.00000 L 332.00000,293.00000 L 328.00000,293.00000 L 325.00000,294.00000 L 321.00000,296.00000 L 319.00000,298.00000 L 317.00000,302.00000 L 315.00000,305.00000 L 313.00000,308.00000 L 311.00000,312.00000 L 308.00000,315.00000 L 306.00000,318.00000 L 302.00000,321.00000 L 299.00000,322.00000 L 295.00000,324.00000 L 291.00000,325.00000 L 288.00000,327.00000 L 284.00000,329.00000 L 276.00000,330.00000 L 267.00000,332.00000 L 259.00000,333.00000 L 250.00000,333.00000 L 242.00000,333.00000 L 233.00000,333.00000 L 225.00000,332.00000 L 217.00000,329.00000 L 212.00000,328.00000 L 207.00000,327.00000 L 202.00000,325.00000 L 197.00000,324.00000 L 192.00000,323.00000 L 187.00000,323.00000 L 182.00000,324.00000 L 178.00000,326.00000 L 168.00000,325.00000 L 158.00000,322.00000 L 149.00000,317.00000 L 140.00000,312.00000 L 131.00000,306.00000 L 123.00000,301.00000 L 115.00000,295.00000 L 108.00000,291.00000 L 105.00000,289.00000 L 102.00000,286.00000 L 98.000000,284.00000 L 94.000000,283.00000 L 90.000000,281.00000 L 86.000000,279.00000 L 83.000000,277.00000 L 79.000000,275.00000 L 75.000000,272.00000 L 71.000000,269.00000 L 66.000000,266.00000 L 62.000000,263.00000 L 58.000000,260.00000 L 54.000000,256.00000 L 51.000000,251.00000 L 49.000000,247.00000 L 51.000000,238.00000 L 54.000000,229.00000 L 58.000000,221.00000 L 63.000000,213.00000 L 85.000000,179.00000 L 89.000000,173.00000 L 94.000000,167.00000 L 99.000000,162.00000 L 104.00000,156.00000 L 108.00000,151.00000 L 113.00000,146.00000 L 117.00000,141.00000 L 121.00000,135.00000 L 125.00000,132.00000 L 128.00000,129.00000 L 132.00000,126.00000 L 135.00000,123.00000 L 139.00000,121.00000 L 143.00000,119.00000 L 148.00000,118.00000 L 152.00000,117.00000 L 157.00000,117.00000 L 162.00000,117.00000 L 167.00000,117.00000 L 172.00000,117.00000 L 176.00000,117.00000 L 181.00000,115.00000 L 185.00000,113.00000 L 189.00000,110.00000 L 192.00000,107.00000 L 196.00000,105.00000 L 200.00000,102.00000 L 203.00000,99.000000 L 207.00000,96.000000 L 210.00000,94.000000 L 214.00000,92.000000 L 219.00000,91.000000 L 221.00000,89.000000 L 223.00000,88.000000 L 227.00000,89.000000 L 230.00000,89.000000 L 234.00000,89.000000 L 237.00000,91.000000 L 241.00000,92.000000 L 244.00000,95.000000 L 247.00000,97.000000 L 250.00000,100.00000 L 253.00000,103.00000 L 257.03646,105.51823 L 262.08918,108.23892" + style="fill:#000000" /> + <path + sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + style="fill:#645858;fill-opacity:1.0000000" + d="M 289.76968,176.61808 L 294.76968,177.61808 L 298.76968,178.61808 L 303.76968,179.61808 L 308.76968,180.61808 L 312.76968,182.61808 L 316.76968,184.61808 L 320.76968,186.61808 L 322.88387,187.07485 L 323.76968,189.55120 L 325.24603,192.02754 L 322.76968,193.61808 L 320.88387,193.01571 L 319.76968,193.61808 L 316.76968,193.61808 L 313.58860,194.38970 L 311.00000,195.69680 L 307.54519,197.77551 L 303.00583,200.85423 L 298.46647,201.08455 L 293.92711,197.23616 L 287.84840,196.69680 L 283.30904,197.46648 L 279.53936,196.46648 L 275.76968,193.69680 L 269.32070,193.78135 L 264.55102,194.01167 L 259.78134,194.70263 L 256.55102,193.85423 L 252.62974,193.46648 L 245.24198,195.69680 L 240.70262,196.38776 L 235.62391,196.84840 L 230.31487,199.61808 L 225.77551,203.69680 L 218.92711,207.23616 L 213.16327,211.85423 L 206.31487,213.16327 L 201.23615,211.93295 L 193.84840,210.70263 L 187.99806,205.86607 L 181.57290,203.02154 L 174.66149,202.84239 L 166.45481,204.08455 L 159.37609,206.62391 L 151.06495,208.38970 L 147.76968,206.79916 L 144.29333,204.91335 L 142.58860,202.02754 L 141.58860,199.14173 L 142.47441,196.07485 L 146.76968,196.61808 L 151.76968,194.61808 L 156.76968,191.61808 L 161.76968,189.61808 L 165.76968,187.61808 L 170.76968,185.61808 L 175.76968,182.61808 L 180.76968,180.61808 L 183.76968,180.61808 L 187.76968,179.61808 L 190.76968,180.61808 L 193.76968,181.61808 L 196.76968,182.61808 L 198.76968,183.61808 L 201.76968,185.61808 L 204.76968,188.61808 L 208.76968,187.61808 L 212.76968,184.61808 L 215.76968,180.61808 L 217.76968,176.61808 L 221.76968,174.61808 L 225.76968,172.61808 L 229.76968,169.61808 L 233.76968,167.61808 L 237.76968,165.61808 L 242.76968,163.61808 L 246.76968,161.61808 L 250.76968,159.61808 L 256.76968,160.61808 L 261.76968,162.61808 L 265.76968,165.61808 L 269.76968,169.61808 L 274.76968,173.61808 L 278.76968,175.61808 L 283.76968,177.61808 L 289.76968,176.61808 z " + id="path2065" /> + <path + id="path16" + d="M 289.00000,172.00000 L 294.00000,173.00000 L 298.00000,174.00000 L 303.00000,175.00000 L 308.00000,176.00000 L 312.00000,178.00000 L 316.00000,180.00000 L 320.00000,182.00000 L 323.00000,186.00000 L 323.00000,187.00000 L 323.00000,188.00000 L 322.00000,189.00000 L 321.00000,190.00000 L 319.00000,189.00000 L 316.00000,189.00000 L 314.00000,188.00000 L 311.00000,188.00000 L 308.00000,188.00000 L 305.00000,188.00000 L 303.00000,188.00000 L 300.00000,188.00000 L 296.00000,187.00000 L 293.00000,187.00000 L 290.00000,188.00000 L 287.00000,188.00000 L 284.00000,189.00000 L 281.00000,189.00000 L 278.00000,188.00000 L 275.00000,186.00000 L 272.00000,184.00000 L 268.00000,181.00000 L 264.00000,178.00000 L 260.00000,176.00000 L 256.00000,174.00000 L 252.00000,173.00000 L 247.00000,173.00000 L 243.00000,174.00000 L 239.00000,177.00000 L 235.00000,180.00000 L 232.00000,183.00000 L 229.00000,186.00000 L 228.00000,185.00000 L 226.00000,188.00000 L 223.00000,191.00000 L 221.00000,193.00000 L 218.00000,195.00000 L 215.00000,196.00000 L 212.00000,198.00000 L 210.00000,200.00000 L 207.00000,202.00000 L 204.00000,201.00000 L 202.00000,200.00000 L 199.00000,200.00000 L 197.00000,198.00000 L 194.00000,197.00000 L 192.00000,195.00000 L 190.00000,193.00000 L 189.00000,191.00000 L 185.00000,190.00000 L 182.00000,190.00000 L 178.00000,191.00000 L 174.00000,192.00000 L 150.00000,202.00000 L 147.00000,201.00000 L 145.00000,200.00000 L 143.00000,198.00000 L 142.00000,196.00000 L 142.00000,195.00000 L 146.00000,192.00000 L 151.00000,190.00000 L 156.00000,187.00000 L 161.00000,185.00000 L 165.00000,183.00000 L 170.00000,181.00000 L 175.00000,178.00000 L 180.00000,176.00000 L 183.00000,176.00000 L 187.00000,175.00000 L 190.00000,176.00000 L 193.00000,177.00000 L 196.00000,178.00000 L 198.00000,179.00000 L 201.00000,181.00000 L 204.00000,184.00000 L 208.00000,183.00000 L 212.00000,180.00000 L 215.00000,176.00000 L 217.00000,172.00000 L 221.00000,170.00000 L 225.00000,168.00000 L 229.00000,165.00000 L 233.00000,163.00000 L 237.00000,161.00000 L 242.00000,159.00000 L 246.00000,157.00000 L 250.00000,155.00000 L 256.00000,156.00000 L 261.00000,158.00000 L 265.00000,161.00000 L 269.00000,165.00000 L 274.00000,169.00000 L 278.00000,171.00000 L 283.00000,173.00000 L 289.00000,172.00000 z " + style="fill:#000000" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer8" + inkscape:label="covers" + style="display:inline"> + <g + id="g17273" + transform="matrix(3.955288,0.000000,0.000000,3.955288,155.1671,-915.1278)"> + <g + id="g17118" + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" + transform="matrix(1.274278e-2,7.087528e-3,-7.087528e-3,1.274278e-2,147.7444,148.5166)"> + <path + d="M 7601.0000,11063.000 L 6350.0000,12312.000 L 7602.0000,10313.000 L 8850.0000,12314.000 L 7601.0000,11063.000 z " + id="path17120" + sodipodi:nodetypes="ccccc" + style="fill:#00ff00;fill-opacity:1.0000000;stroke:#000000;stroke-width:47.034168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" /> + </g> + <path + id="text17122" + d="M 187.95573,356.23294 C 187.40374,356.47294 186.73173,356.61694 185.86773,356.61694 C 184.09174,356.61694 182.65173,355.46494 182.65173,353.30494 C 182.62773,351.38494 183.87574,350.01694 185.79573,350.01694 C 186.75573,350.01694 187.40374,350.18494 187.83573,350.37694 L 188.41173,347.66494 C 187.64374,347.37694 186.58773,347.20894 185.62773,347.20894 C 181.25974,347.20894 178.90773,350.01694 178.90773,353.44894 C 178.90773,357.14493 181.33174,359.47294 185.12373,359.47294 C 186.51573,359.47294 187.73974,359.23294 188.38773,358.92094 L 187.95573,356.23294 M 195.83186,359.47294 C 198.95186,359.47294 201.99986,357.50493 201.99986,353.23294 C 201.99986,349.68094 199.59986,347.20894 196.02386,347.20894 C 192.23186,347.20894 189.73586,349.63294 189.73586,353.42494 C 189.73586,357.21693 192.37586,359.47294 195.80786,359.47294 L 195.83186,359.47294 M 195.85586,356.85694 C 194.31986,356.85694 193.47986,355.34494 193.47986,353.35294 C 193.47986,351.60094 194.15186,349.82494 195.87986,349.82494 C 197.53586,349.82494 198.20786,351.60094 198.20786,353.32894 C 198.20786,355.44094 197.31986,356.85694 195.87986,356.85694 L 195.85586,356.85694 M 202.98798,347.47294 L 207.25998,359.20894 L 210.90798,359.20894 L 215.27598,347.47294 L 211.43598,347.47294 L 209.92398,352.92094 C 209.65999,353.92894 209.46798,354.81694 209.27598,355.77694 L 209.20398,355.77694 C 209.01199,354.84094 208.81998,353.90494 208.53198,352.92094 L 206.94798,347.47294 L 202.98798,347.47294 M 227.30711,354.50494 C 227.35511,354.21694 227.42711,353.66494 227.42711,353.04094 C 227.42711,350.13694 225.98711,347.18494 222.19511,347.18494 C 218.13911,347.18494 216.26711,350.47294 216.26711,353.44894 C 216.26711,357.14493 218.54711,359.44894 222.53111,359.44894 C 224.11511,359.44894 225.57911,359.20894 226.77911,358.70494 L 226.29911,356.23294 C 225.31511,356.56894 224.30711,356.73694 223.05911,356.73694 C 221.35511,356.73694 219.86711,356.01694 219.74711,354.48094 L 227.30711,354.50494 M 219.72311,351.98494 C 219.81911,351.02494 220.44311,349.60894 222.00311,349.60894 C 223.65911,349.60894 224.04311,351.12094 224.04311,351.98494 L 219.72311,351.98494 M 229.59536,359.20894 L 233.24336,359.20894 L 233.24336,353.28094 C 233.24336,352.96894 233.26736,352.70494 233.31536,352.46494 C 233.55536,351.31294 234.46736,350.61694 235.81136,350.61694 C 236.21936,350.61694 236.50736,350.66494 236.81936,350.71294 L 236.81936,347.28094 C 236.55536,347.23294 236.38736,347.20894 236.05136,347.20894 C 234.89936,347.20894 233.48336,347.92894 232.88336,349.65694 L 232.78736,349.65694 L 232.64336,347.47294 L 229.52336,347.47294 C 229.59536,348.48094 229.61936,349.60894 229.61936,351.33694 L 229.59536,359.20894 M 238.06398,358.63294 C 238.95198,359.11294 240.31999,359.47294 241.85598,359.47294 C 245.21598,359.47294 246.91998,357.86494 246.91998,355.65694 C 246.89598,353.95294 245.98398,352.80094 243.75198,352.05694 C 242.31199,351.55294 241.85598,351.26494 241.85598,350.68894 C 241.85598,350.11294 242.35999,349.75294 243.24798,349.75294 C 244.23198,349.75294 245.26399,350.13694 245.79198,350.40094 L 246.41598,347.90494 C 245.69599,347.54494 244.49598,347.20894 243.12798,347.20894 C 240.22399,347.20894 238.35198,348.86494 238.35198,351.07294 C 238.32798,352.44094 239.26399,353.78494 241.71198,354.57694 C 243.05598,355.03294 243.41598,355.32094 243.41598,355.94494 C 243.41598,356.54494 242.95998,356.90494 241.85598,356.90494 C 240.77599,356.90494 239.38398,356.44894 238.71198,356.04094 L 238.06398,358.63294" + style="font-size:24.000000px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#007f00;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Myriad" /> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer7" + inkscape:label="paper" + style="display:inline"> + <g + style="display:inline" + id="g17136" + transform="matrix(3.955288,0.000000,0.000000,3.955288,-708.3488,-857.6103)"> + <path + sodipodi:nodetypes="cccccccc" + d="M 390.34708,372.49332 L 332.34539,427.86139 L 272.20460,392.33038 L 341.37790,339.74173 L 378.06120,351.10999 C 379.20468,351.78631 380.06344,352.64698 380.62363,353.61296 L 390.84522,371.30530 C 391.02046,371.60027 390.83244,372.00903 390.34708,372.49332 z " + style="fill:#ffff19;fill-opacity:1.0000000;stroke:#000000;stroke-width:1.6000000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path12105" /> + <path + id="path12107" + style="fill:#bebe12;fill-opacity:1.0000000;stroke:#000000;stroke-width:1.6000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 390.84798,371.31968 C 390.67230,371.01421 390.16897,370.87309 389.44281,370.86931 L 380.40026,370.92353 L 380.40026,370.92353 L 381.40039,356.76032 C 381.45531,355.66353 381.19370,354.58394 380.62363,353.61296 L 390.84798,371.31968 z " + sodipodi:nodetypes="ccccccc" /> + </g> + </g> +</svg> diff --git a/docs/user/images/s5-files.png b/docs/user/images/s5-files.png new file mode 100644 index 000000000..53cbbf250 Binary files /dev/null and b/docs/user/images/s5-files.png differ diff --git a/docs/user/images/s5-files.svg b/docs/user/images/s5-files.svg new file mode 100644 index 000000000..a3e644a22 --- /dev/null +++ b/docs/user/images/s5-files.svg @@ -0,0 +1,639 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="595.27559pt" + height="841.88976pt" + id="svg5904" + sodipodi:version="0.32" + inkscape:version="0.42" + sodipodi:docbase="/Users/david/projects/docutils/s5-branch/docs/user/images" + sodipodi:docname="s5-files.svg" + inkscape:export-filename="/Users/david/projects/docutils/s5-branch/docs/user/images/s5-files.png" + inkscape:export-xdpi="100.00000" + inkscape:export-ydpi="100.00000"> + <defs + id="defs5906"> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mstart" + style="overflow:visible"> + <path + sodipodi:nodetypes="ccccc" + id="path10526" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + sodipodi:nodetypes="ccccc" + id="path10529" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="Arrow2Mend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow2Mend" + style="overflow:visible;"> + <path + sodipodi:nodetypes="cccc" + id="path10518" + style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " + transform="scale(0.6) rotate(180) translate(-5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow2Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow2Mstart" + style="overflow:visible"> + <path + sodipodi:nodetypes="cccc" + id="path10509" + style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " + transform="scale(0.6) translate(-5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow2Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow2Lend" + style="overflow:visible;"> + <path + sodipodi:nodetypes="cccc" + id="path10521" + style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " + transform="scale(1.1) rotate(180) translate(-5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow2Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow2Lstart" + style="overflow:visible"> + <path + sodipodi:nodetypes="cccc" + id="path10512" + style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " + transform="scale(1.1) translate(-5,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.0050485" + inkscape:cx="359.99999" + inkscape:cy="345.00000" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1161" + inkscape:window-height="810" + inkscape:window-x="51" + inkscape:window-y="22" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:grid-points="true" + gridspacingx="5.0000000px" + gridspacingy="5.0000000px" + gridtolerance="2.0000000px" /> + <metadata + id="metadata5909"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <g + id="g15792"> + <g + transform="translate(-5.000000,-55.00000)" + id="g13828" + style="stroke:#000000;stroke-opacity:1.0000000;stroke-linejoin:round;stroke-linecap:round"> + <g + id="g13761" + style="stroke:#000000;stroke-opacity:1.0000000;stroke-linejoin:round;stroke-linecap:round"> + <path + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" + d="M 451.84175,542.36220 L 490.47866,542.36220" + id="path13719" /> + <path + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" + d="M 515.00000,597.36220 L 491.83836,597.36220" + id="path13721" /> + <path + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" + d="M 515.00000,487.36218 L 491.83836,487.36218" + id="path13723" /> + <path + id="path13725" + d="M 491.83836,487.36218 L 491.83836,597.36220 L 491.83836,707.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13757" + d="M 515.00000,707.36218 L 491.83836,707.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + </g> + <g + id="g13695" + style="stroke:#000000;stroke-opacity:1.0000000;stroke-linejoin:round;stroke-linecap:round"> + <path + id="path10755" + d="M 451.84175,982.36220 L 490.47866,982.36220" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13691" + d="M 515.00000,1037.3622 L 491.83836,1037.3622" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13689" + d="M 515.00000,927.36218 L 491.83836,927.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13687" + d="M 491.83836,1037.3622 L 491.83836,927.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + </g> + <g + id="g13174" + style="stroke:#000000;stroke-opacity:1.0000000;stroke-linejoin:round;stroke-linecap:round"> + <path + id="path9672" + d="M 205.00000,762.36217 L 275.47323,762.36217" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13150" + d="M 325.12023,762.36218 L 276.91055,762.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13148" + d="M 325.12023,872.36218 L 276.91055,872.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13146" + d="M 325.12023,982.36218 L 276.91055,982.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13156" + d="M 325.12023,542.36218 L 276.91055,542.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13154" + d="M 276.91055,982.36218 L 276.91055,542.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:none;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + <path + id="path13144" + d="M 325.12023,652.36218 L 276.91055,652.36218" + style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" /> + </g> + </g> + <g + transform="translate(-5.000000,-55.00000)" + id="g13805" + style="stroke:#000000;stroke-opacity:1.0000000"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13533" + transform="translate(-160.0000,215.0000)"> + <g + id="g13262" + transform="translate(522.7639,-102.4046)" + style="stroke:#000000;stroke-opacity:1.0000000"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path13264" /> + <path + sodipodi:nodetypes="ccccccc" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + id="path13266" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9098" + y="266.27817" + x="748.73212" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="266.27817" + x="748.73212" + id="tspan9100" + sodipodi:role="line">s5-core</tspan><tspan + id="tspan9102" + y="290.27818" + x="748.73212" + sodipodi:role="line">.css</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13541" + transform="translate(-160.0000,215.0000)"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + transform="translate(522.7639,7.595400)" + id="g13276"> + <path + id="path13278" + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + sodipodi:nodetypes="ccccccccc" /> + <path + id="path13280" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9104" + y="377.05817" + x="749.49524" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="377.05817" + x="749.49524" + id="tspan9106" + sodipodi:role="line">framing</tspan><tspan + id="tspan9108" + y="401.05818" + x="749.49524" + sodipodi:role="line">.css</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13549" + transform="translate(-160.0000,215.0000)"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + transform="translate(522.7639,117.5954)" + id="g13290"> + <path + id="path13292" + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + sodipodi:nodetypes="ccccccccc" /> + <path + id="path13294" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + transform="scale(1.075185,0.930073)" + sodipodi:linespacing="100.00000%" + id="text9110" + y="522.89044" + x="696.86365" + style="font-size:25.804459px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="522.89044" + x="696.86365" + id="tspan9112" + sodipodi:role="line">pretty</tspan><tspan + id="tspan9114" + y="548.69490" + x="696.86365" + sodipodi:role="line">.css</tspan></text> + </g> + </g> + <g + transform="translate(-5.000000,-55.00000)" + id="g13701" + style="stroke:#000000;stroke-opacity:1.0000000"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13617" + transform="translate(-150.0000,240.0000)"> + <g + id="g13322" + transform="translate(512.7639,312.5954)" + style="stroke:#000000;stroke-opacity:1.0000000"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path13324" /> + <path + sodipodi:nodetypes="ccccccc" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + id="path13326" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9122" + y="682.05817" + x="740.27032" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="682.05817" + x="740.27033" + id="tspan9124" + sodipodi:role="line">iepngfix</tspan><tspan + id="tspan9126" + y="706.05818" + x="740.27032" + sodipodi:role="line">.htc</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13609" + transform="translate(-150.0000,240.0000)"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + transform="translate(512.7639,422.5954)" + id="g13336"> + <path + id="path13338" + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + sodipodi:nodetypes="ccccccccc" /> + <path + id="path13340" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9116" + y="790.57019" + x="739.14758" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="790.57019" + x="739.14758" + id="tspan9118" + sodipodi:role="line">blank</tspan><tspan + id="tspan9120" + y="814.57020" + x="739.14758" + sodipodi:role="line">.gif</tspan></text> + </g> + </g> + <g + transform="translate(-5.000000,-55.00000)" + id="g13768" + style="stroke:#000000;stroke-opacity:1.0000000"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g12998" + transform="translate(140.0000,160.0000)"> + <g + id="g12960" + transform="translate(32.76392,117.5954)" + style="stroke:#000000;stroke-opacity:1.0000000"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path12962" /> + <path + sodipodi:nodetypes="ccccccc" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + id="path12964" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9080" + y="486.96219" + x="259.42813" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="486.96219" + x="259.42813" + id="tspan9082" + sodipodi:role="line">outline</tspan><tspan + id="tspan9084" + y="510.96220" + x="259.42813" + sodipodi:role="line">.css</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13006" + transform="translate(140.0000,160.0000)"> + <g + id="g12972" + transform="translate(32.76392,227.5954)" + style="stroke:#000000;stroke-opacity:1.0000000"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path12974" /> + <path + sodipodi:nodetypes="ccccccc" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + id="path12976" /> + </g> + <text + xml:space="preserve" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + x="259.34225" + y="596.96216" + id="text9284" + sodipodi:linespacing="100.00000%"><tspan + sodipodi:role="line" + id="tspan9290" + x="259.34226" + y="596.96216">print</tspan><tspan + sodipodi:role="line" + id="tspan9292" + x="259.34225" + y="620.96217">.css</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13014" + transform="translate(140.0000,160.0000)"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + transform="translate(32.76392,337.5954)" + id="g12978"> + <path + id="path12980" + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + sodipodi:nodetypes="ccccccccc" /> + <path + id="path12982" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + xml:space="preserve" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + x="259.56012" + y="706.32617" + id="text12043" + sodipodi:linespacing="100.00000%"><tspan + sodipodi:role="line" + id="tspan12045" + x="259.56012" + y="706.32617">opera</tspan><tspan + sodipodi:role="line" + x="259.56012" + y="730.32618" + id="tspan12047">.css</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13022" + transform="translate(140.0000,160.0000)"> + <g + id="g12984" + transform="translate(32.76392,447.5954)" + style="stroke:#000000;stroke-opacity:1.0000000"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path12986" /> + <path + sodipodi:nodetypes="ccccccc" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + id="path12988" /> + </g> + <text + sodipodi:linespacing="100.00000%" + id="text9092" + y="816.30219" + x="259.32312" + style="font-size:24.000011px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="816.30219" + x="259.32312" + id="tspan9094" + sodipodi:role="line">slides</tspan><tspan + id="tspan9096" + y="840.30220" + x="259.32312" + sodipodi:role="line">.js</tspan></text> + </g> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g12990" + transform="translate(140.0000,160.0000)"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + transform="translate(32.76392,7.595403)" + id="g12886"> + <path + id="path2125" + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + d="M 286.53987,344.38881 L 259.95853,330.91154 C 258.50529,330.17714 256.87802,329.76853 255.16608,329.76765 L 167.23608,329.76678 L 167.23608,329.76678 L 167.23608,419.76678 L 287.23608,419.76678 L 287.22985,346.10313 C 287.20953,345.21142 286.98750,344.61022 286.53987,344.38881 z " + sodipodi:nodetypes="ccccccccc" /> + <path + id="path2168" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 286.55635,344.40356 C 286.09815,344.17032 285.49622,344.35102 284.82132,344.84280 L 276.51509,351.08392 L 276.51509,351.08392 L 263.72436,334.02075 C 262.71303,332.71478 261.42576,331.64498 259.95853,330.91154 L 286.55635,344.40356 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + transform="scale(1.003177,0.996833)" + sodipodi:linespacing="100.00000%" + id="text9074" + y="378.15045" + x="258.4964" + style="font-size:24.117754px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + xml:space="preserve"><tspan + y="378.15045" + x="258.49640" + id="tspan9076" + sodipodi:role="line">slides</tspan><tspan + id="tspan9078" + y="402.26821" + x="258.49640" + sodipodi:role="line">.css</tspan></text> + </g> + </g> + <g + id="g14176"> + <g + style="stroke:#000000;stroke-opacity:1.0000000" + id="g13130" + transform="translate(0.000000,-54.99999)"> + <path + sodipodi:nodetypes="ccccccccc" + d="M 209.99815,696.86669 L 210.00000,852.36217 L 75.000000,852.36217 L 75.000000,672.36217 L 75.000000,672.36217 L 161.90250,672.36347 C 164.47041,672.36479 166.91132,672.97771 169.09117,674.07931 L 208.96319,694.29521 C 209.63463,694.62733 209.96767,695.52913 209.99815,696.86669 z " + style="fill:#ffffff;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" + id="path12105" /> + <path + id="path12107" + style="fill:#a6a6a6;fill-opacity:1.0000000;stroke:#000000;stroke-width:3.7500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;display:inline" + d="M 208.98791,694.31734 C 208.30060,693.96748 207.39771,694.23853 206.38536,694.97620 L 193.92602,704.33788 L 193.92602,704.33788 L 174.73992,678.74312 C 173.22293,676.78417 171.29202,675.17947 169.09117,674.07931 L 208.98791,694.31734 z " + sodipodi:nodetypes="ccccccc" /> + </g> + <text + xml:space="preserve" + style="font-size:36.814487px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100.00000%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;font-family:Myriad" + x="146.13911" + y="695.62231" + id="text9058" + sodipodi:linespacing="100.00000%" + transform="scale(0.997872,1.002133)"><tspan + sodipodi:role="line" + x="146.13911" + y="695.62231" + id="tspan9128"><tspan + id="tspan14172" + style="font-size:36.814487px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:99.999976%;writing-mode:lr-tb;text-anchor:middle;stroke:#000000;stroke-width:0.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000;font-family:Myriad" />*.html</tspan><tspan + sodipodi:role="line" + x="146.13912" + y="732.43680" + id="tspan14174">output</tspan></text> + </g> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="2" + style="display:inline" /> +</svg> diff --git a/docs/user/images/small-black.png b/docs/user/images/small-black.png new file mode 100644 index 000000000..f8d80d387 Binary files /dev/null and b/docs/user/images/small-black.png differ diff --git a/docs/user/images/small-white.png b/docs/user/images/small-white.png new file mode 100644 index 000000000..65f96895d Binary files /dev/null and b/docs/user/images/small-white.png differ diff --git a/docs/user/slide-shows.txt b/docs/user/slide-shows.txt new file mode 100644 index 000000000..1fdd8398b --- /dev/null +++ b/docs/user/slide-shows.txt @@ -0,0 +1,984 @@ +.. include:: <s5defs.txt> + +============================================= + Easy Slide Shows With reStructuredText & S5 +============================================= + +:Authors: David Goodger & Chris Liechti +:Date: $Date$ + +.. This document has been placed in the public domain. + +.. class:: handout + + This document serves both as a user manual and as a usage example + of the s5_html.py writer and the rst2s5.py front end. + +.. contents:: + :class: handout + +How to create quick, good-looking presentation slide shows with +Docutils_/reStructuredText_ and S5_. + +.. class:: small + +* Use the arrow keys to navigate. + +* Click the "|mode|" button to switch between presentation & + handout/outline modes. + +.. container:: handout + + In presentation mode, mouse over to the lower right-hand corner to + display the controls. + + The first slide of a presentation consists of all visible text up + to the first section title. The document title is also added to + the footer of all slides. + + The "footer" directive is used to specify part of the slide footer + text. It is currently limited to one short line (one paragraph). + + There is no support for the "header" directive in the themes + included with Docutils. + +.. _Docutils: http://docutils.sourceforge.net/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _S5: http://meyerweb.com/eric/tools/s5/ +.. |bullet| unicode:: U+02022 +.. |mode| unicode:: U+00D8 .. capital o with stroke +.. footer:: Location |bullet| Date + + +Introduction +============ + +.. class:: handout + + ``rst2s5.py`` is a Docutils_ front end that outputs HTML for use + with S5_, a "Simple Standards-based Slide Show System" by Eric + Meyer. + +.. topic:: Installation + :class: handout + + Prerequisites: Python and the Docutils_ package have to be + installed. See the `Docutils README`__ file for installation + instructions. + + __ http://docutils.sourceforge.net/README.html + +* reStructuredText + + .. class:: handout + + Uses normal reStructuredText as input. + +* One section per slide + + .. class:: handout + + Each first-level section is converted into a single slide. + +* (X)HTML output + + .. class:: handout + + Presentations can be viewed using any modern graphical web browser. + The browser must support CSS, JavaScript, and XHTML. S5 even works + with IE! + +* Themes + + .. class:: handout + + A variety of themes are available. See `Example Themes`_, below. + +* ``rst2s5.py`` + + .. class:: handout + + The front-end tool to generate S5 slide shows. + +.. topic:: Keyboard Controls + :class: handout + + The following apply in any supporting browser besides Opera, which + uses the default Opera Show controls instead. + + .. list-table:: + :header-rows: 1 + + * - Action + - Key(s) + * - Go to the next slide + - * [Space bar] + * [Return] + * [Enter] + * [Right arrow] + * [Down arrow] + * [Page down] + * Click the left mouse button outside of the control area, + Flash object, or movie + * - Go to the previous slide + - * [Left arrow] + * [Up arrow] + * [Page up] + * - Go to the title (first) slide + - [Home] + * - Go to the last slide + - [End] + * - Jump directly to a slide + - Type the slide number, then hit [Return] or [Enter] + * - Skip forward *n* slides + - Type the number of slides to skip, then hit any "go to next" + key (except [Return] or [Enter]) + * - Skip backward *n* slides + - Type the number of slides to skip, then hit any "go to + previous" key + * - Switch between slideshow and outline view + - * [T] + * Click the |mode| button + * - Show/hide slide controls + - * [C] + * Move the mouse pointer over the control area + + Further details of the S5 user interface can be found at `Eric + Meyer's S5 page`__. + + __ S5_ + + +Features (1) +============ + +.. container:: handout + + The S5/HTML Writer supports all the standard Docutils HTML + features. + +S5-specific features: + +.. class:: incremental + +* The document title is duplicated on each slide in the S5 footer. + +* The ``footer`` directive may be used to define additional text in + the S5 footer. + + .. container:: handout + + But it is limited to one line of text. + + This is useful for information such as the date of the + presentation and/or the location. The field in the footer is + left blank if no ``footer`` directive is used. + + Example:: + + .. footer:: Location - Date + +* Incremental display. + + .. class:: handout + + An "incremental" class can be assigned to lists and other elements + to get one-item-at-a-time behavior (like this list). + + +Features (2): Handouts +====================== + +``<element class="handout">`` + +.. container:: handout + + The contents of any element with a "class" attribute value of + "handout" are hidden in the slide presentation, and are only + visible when the presentation is printed, or viewed in outline + mode. "Handout"-class elements can appear anywhere in the text, as + often as needed. + + This means that the slides and extra handout material can be + combined in one document. The handout can be printed directly from + the browser, and it will contain more than just silly framed + slides. This can be used to provide more detailed information, or + for speaker's notes. + +.. class:: incremental + +* Use the "class" directive:: + + .. class:: handout + + .. container:: handout + + The ``.. class:: handout`` directive can be used to tag + individual paragraphs and other elements. The "class" directive + applies to the first element immediately following:: + + .. class:: handout + + This paragraph will get a ``class="handout"`` attribute. + + This paragraph will not be affected. + + It also applies to multiple elements in the directive content:: + + .. class:: handout + + These paragraphs are the content of the "class" directive. + And as such... + + Both paragraphs will *individually* receive + ``class="handout"`` attributes. + +* Use the "container" directive:: + + .. container:: handout + + .. container:: handout + + Arbitrary handout blocks can be created using the ``container`` + directive. The content is treated as one. + +* Add a "class" option to certain directives:: + + .. topic:: Extra Material For Handouts + :class: handout + +.. container:: handout + + The following directives support "class" options: + + * all admonition directives ("admonition", "note", "hint", etc.) + * "image" & "figure" + * "topic" + * "sidebar" + * "line-block" + * "parsed-literal" + * "rubric" + * "compound" + * "table", "csv-table", & "list-table" + * "target-notes" (more about that below) + * "role" (pre-defined; more below) + + Handout contents are also visible on the screen if the S5 view mode + is toggled from "slide show" to "outline" mode. + + +Caveats +======= + +.. class:: incremental + +1. Some Docutils features are not supported by some themes. + + .. container:: handout + + For example, header rendering is not supported by the themes + supplied with Docutils. + + The "header" directive is used to set header text. S5 + automatically inserts section/slide titles into the "header" + area of a slide. If both Docutils headers and S5 headers (slide + titles) exist simultaneously, they interfere with each other. + +2. Care must be taken with the "contents" directive. + + .. container:: handout + + The ``--no-toc-backlinks`` option is the default for the S5/HTML + writer (``toc_backlinks=0`` setting). Other values for this + setting will change the CSS class of headings such that they + won't show up correctly in the slide show. + + Use the ``:class: handout`` option on the "contents" directive + to limit the table of contents to the handout/outline mode + only:: + + .. contents:: + :class: handout + + +.. class:: incremental + +3. Subsections ... +------------------ + +... may be used, sparingly. + +.. container:: handout + + Only first-level sections become slides. Not many levels of + subsections can fit on a slide. + + Subsections (of any level) work normally in handouts though. Add + "``.. class:: handout``" before a subsection (or sub-subsection, or + ...), and the entire subsection will only appear in the handout. + + +Generating a Slide Show (1) +=========================== + +.. class:: incremental + +1. Open a console (terminal, command shell) and go to the folder + containing your file, ``presentation.txt``. + +2. Run the command:: + + rst2s5.py presentation.txt \ + presentation.html + +3. Specify an S5 theme with the ``--theme`` option. + + .. class:: handout + + Docutils will copy the S5 theme files into a ``ui/<theme>`` folder + beside the output HTML file. A slide show can also link to an + existing theme using the ``--theme-url`` option. + + +Generating a Slide Show (2) +=========================== + +.. class:: incremental + +4. Include a copy of any linked stylesheet. + + .. class:: handout + + The default Docutils stylesheet, ``html4css1.css``, will normally + be embedded in the output HTML. If you choose to link to a + stylesheet instead of embedding, you must include a copy (suggested + location: in the ``ui/`` directory). + +5. Open ``presentation.html`` in a web browser. + +6. Expand the browser window to full-screen mode, and speak. + + .. class:: handout + + The `Web Developer`__ extension for Firefox is very useful. With + it, you can resize your browser window to the exact dimensions of + the projector you'll be using, so you can test beforehand. There + are many other useful features as well. + + __ http://chrispederick.com/work/webdeveloper/ + +7. Profit! + + +Examples (1) +============ + +.. sidebar:: Hint + + Admonitions, tables, sidebars, and other elements can be used in + on-screen presentations in handouts. Images too! + + .. image:: images/happy_monkey.png + :alt: sample image + +===== ===== ====== + A B A or B +===== ===== ====== +False False False +True False True +False True True +True True True +===== ===== ====== + + +Examples (2): Incremental Text +============================== + +.. class:: incremental + + Paragraphs can be displayed one at a time... + + .. container:: + + ... or a bunch at a time. + + This second paragraph is displayed together with the previous + one by grouping them with the "container" directive. + +| `We can also display` `one` `word` `at` `a` `time,` +| `or a phrase` `at a time,` +| `or even` `o`\ `n`\ `e` `l`\ `e`\ `t`\ `t`\ `e`\ `r` `at a time!` +| +| `(But the markup ain't pretty.)` + + +Examples (3): Incr. Graphics +============================ + +Let's play... Rock, Scissors, Paper + +.. container:: animation + + .. image:: images/rsp-empty.png + + .. class:: incremental + + .. image:: images/rsp-objects.png + .. image:: images/rsp-cuts.png + .. image:: images/rsp-covers.png + .. image:: images/rsp-breaks.png + .. image:: images/rsp-all.png + + +Themes +====== + +.. class:: incremental + +* Several themes are available, and they're easy to adapt. + + .. container:: handout + + Themes from the `S5 tutorial`__ can be used. These themes are in + the public domain and may be redistributed freely. + + __ http://meyerweb.com/eric/tools/s5/s5blank.zip + + Sites with other S5 themes: + + * http://meyerweb.com/eric/tools/s5/themes/ + * http://mozilla.wikicities.com/wiki/Firefox_S5:Designs + * http://lachy.id.au/dev/mozilla/firefox/s5/ + + S5 is becoming more popular every day. Do a web search for "S5 + theme" and you're bound to find plenty of choices. + +* "``--theme``" option. + + .. container:: handout + + The theme can be specified with the "``--theme``" command-line + option. + + Example:: + + rst2s5 --theme big-black presentation.txt presentation.html + + The default theme is "default". + +* "``theme``" setting. + + .. class:: handout + + You can set the theme with the "``theme``" configuration file + setting. + +* Copied to ``./ui/<theme>/``. + + .. class:: handout + + Themes are copied into a ``ui/<theme>`` folder inside the folder + containing the presentation. + +* Link with "``--theme-url``" option. + + .. class:: handout + + Link to a theme on the same or another web site, using the + "``--theme-url``" option or "``theme_url``" configuration file + setting. + + +Example Themes +============== + +.. class:: handout + + The default theme, "default", is a simplified version of S5's + default theme. It accommodates up to 13 lines of text. + +.. class:: center + + "default" + + .. image:: images/default.png + :align: center + + +Example Themes: Small Text +========================== + +.. class:: handout + + The "small-white" and "small-black" themes are simplifications of + the default theme (**small** black text on a **white** background, + and **small** black text on a **white** background, respectively). + They each accommodate up to 15 lines of text. + +.. list-table:: + :class: borderless + + * - "small-white" + + .. image:: images/small-white.png + + - "small-black" + + .. image:: images/small-black.png + + +Example Themes: Large Text +========================== + +.. class:: handout + + The "big-white" and "big-black" themes feature very large, bold + text, with no footers. Only five short lines of large text fits + per slide. + +.. list-table:: + :class: borderless + + * - "big-white" + + .. image:: images/big-white.png + + - "big-black" + + .. image:: images/big-black.png + + +Example Themes: Medium Text +=========================== + +.. class:: handout + + The "medium-white" and "medium-black" themes feature medium-sized + text. Up to 8 lines of text are accommodated. + +.. list-table:: + :class: borderless + + * - "medium-white" + + .. image:: images/medium-white.png + + - "medium-black" + + .. image:: images/medium-black.png + + +S5 Theme Files +============== + +An S5 theme consists of a directory containing several files -- +stylesheets, JavaScript, and graphics: + +.. image:: images/s5-files.png + :align: center + +.. container:: handout + + The generated HTML contains the entire slide show text. It also + contains links to the following files: + + * slides.css simply contains import links to: + + - s5-core.css: Default styles critical to the proper functioning + of the slide show; don't touch this! + + - framing.css: Sets the basic layout of slide components (header, + footer, controls, etc. This file is the often edited. + + - pretty.css: Presentation styles that give the slide show a + unique look and feel. This is the file that you're most likely + to edit for a custom theme. You can make a whole new theme + just by editing this file, and not touching the others. + + * outline.css: Styles for outline mode. + + * print.css: Styles for printing; hides most layout elements, and + may display others. + + * opera.css: Styles necessary for the proper functioning of S5 in + Opera Show. + + * slides.js: the JavaScript that drives the dynamic side of the + slide show (actions and navigation controls). It automatically + IDs the slides when the document loads, builds the navigation + menu, handles the hiding and showing of slides, and so on. The + code also manages the fallback to Opera Show if you're using + the Opera web browser. + + Two files are included to support PNG transparency (alpha + channels) in Internet Explorer: + + - iepngfix.htc + - blank.gif + + +Making a Custom Theme +===================== + +.. class:: incremental + +1. Run "``rst2s5.py --theme <base-theme> <doc>.txt <doc>.html``". + + .. class:: handout + + This initializes the ``ui`` directory with the base theme files. + +2. Copy ``ui/<base-theme>`` to ``ui/<new-theme>``. + +3. Edit the styles. + + .. class:: handout + + Start with ``pretty.css``; edit ``framing.css`` if you need to make + layout changes. + +4. Run "``rst2s5.py --theme <new-theme> <doc>.txt <doc>.html``". + + .. class:: handout + + Open your ``<doc>.html`` in a browser to test the new theme. + +5. Rinse & repeat. + + .. class:: handout + + Repeat from step 3 until you're satisfied. + +.. TODO: What to do next: + + * add a ``__base__`` file + * create a personal reusable theme (plugin) + * submit the new theme to Docutils + + ``docutils/writers/support/s5_html/<theme>`` + +.. container:: handout + + Resources: + + * W3C's `Learning CSS <http://www.w3.org/Style/CSS/learning>`__ + + * `Creating An S5 Theme <http://home.cogeco.ca/~ve3ll/s5themes.htm>`__ + + * A short tutorial on how to create themes (in German): + `Eigenes Theme erstellen <http://yatil.de/s5/dokumentation/9/>`__ + + +Classes: Incremental (1) +======================== + +.. class:: handout + + Several "class" attribute values have built-in support in the + themes supplied with Docutils. + +.. class:: incremental + + As described earlier, + + * ``.. class:: incremental`` + + * ``.. container:: incremental`` + + * :: + + .. sidebar:: title + :class: incremental + + +Classes: Incremental (2) +======================== + +The "incremental" interpreted text role is also supported: + +.. class:: incremental + + :: + + :incremental:`This will appear first,` `and + this will appear second.`:incremental: + + Requires "``.. include:: <s5defs.txt>``". + +.. container:: handout + + As you can see, this markup is not very convenient. + +.. class:: incremental + + | But ``s5defs.txt`` includes this useful definition: + | "``.. default-role:: incremental``". So: + + :: + + `This` `is` `all` `we` `need` + +`This` `is` `all` `we` `need` `to mark up incremental text.` + + +Classes: Incremental (3) +======================== + +.. class:: handout + + The "animation" class is provided to support incremental graphics. + This is how the example earlier was done: + +:: + + .. container:: animation + + .. image:: images/rsp-empty.png + + .. class:: incremental + + .. image:: images/rsp-objects.png + .. image:: images/rsp-cuts.png + .. image:: images/rsp-covers.png + .. image:: images/rsp-breaks.png + .. image:: images/rsp-all.png + +.. admonition:: Caveat + :class: handout + + The animation effects are caused by placing successive images at + the same location, laying each image over the last. For best + results, all images should be the same size, and the positions of + image elements should be consistent. Use image transparency (alpha + channels) to get overlay effects. + + Absolute positioning is used, which means that the images take up + no space in the flow. If you want text to follow the images, you + have to specify the image sizes. Otherwise, the images and any + following text will overlap. + + +Classes: Text Size +================== + +.. class:: incremental + + * :tiny:`tiny` (class & role name: "tiny", e.g. "``:tiny:`text```") + * :small:`small` ("small") + * normal (unstyled) + * :big:`big` ("big") + * :huge:`huge` ("huge") + + Requires "``.. include:: <s5defs.txt>``". + + +Classes: Alignment +================== + +.. class:: incremental + + .. class:: left + + Left (class name: "left") + + .. class:: center + + Center ("center" & "centre") + + .. class:: right + + Right ("right") + +.. class:: handout + + These classes apply to block-level elements only. They cannot be + used for inline text (i.e., they're not interpreted text roles). + +.. class:: incremental + + Example:: + + .. class:: center + + Text to be centered. + + +Classes: Text Colours +===================== + +:black:`black` [black], :gray:`gray`, :silver:`silver`, :white:`white` +[white], :maroon:`maroon`, :red:`red`, :magenta:`magenta`, +:fuchsia:`fuchsia`, :pink:`pink`, :orange:`orange`, :yellow:`yellow`, +:lime:`lime`, :green:`green`, :olive:`olive`, :teal:`teal`, +:cyan:`cyan`, :aqua:`aqua`, :blue:`blue`, :navy:`navy`, +:purple:`purple` + +The class names and role names are the same as the colour names. For +example, "``:orange:`text```" produces ":orange:`text`". + +.. class:: incremental + +Requires "``.. include:: <s5defs.txt>``". + + +Classes: Borderless Tables +========================== + +.. class:: handout + + Here's an ordinary, unstyled table: + +.. class:: incremental + + ========= ======= + Sometimes borders + --------- ------- + are useful. + ========= ======= + + And after applying "``.. class:: borderless``": + + .. class:: borderless + + ======= ========== ======= + But sometimes, borders + ------- ---------- ------- + are **not** wanted. + ======= ========== ======= + + +Classes: Print-Only +=================== + +.. class:: handout + + Two classes are provided that only display their contents in + hardcopy. The "print-block" class applies to block-level elements + (like paragraphs, lists, and topics). The "print-inline" class + applies to text within paragraphs. + +.. class:: incremental + + | "print-block" for block elements + | "print-inline" for inline text + + Example: the "target-notes" directive:: + + .. topic:: Links + :class: print-block + + .. target-notes:: + :class: print-inline + +.. container:: handout + + One good example, used in this document, is the "target-notes" + directive. For each external target (hyperlink) in the text, this + directive generates a footnote containing the visible URL as + content. Footnote references are placed after each hyperlink + reference. + + The "topic" directive is given a "class" attribute with value + "print-block"; the entire topic will only be displayed when + printed. The "target-notes" assigns a "class" attribute with value + "print-inline" to each of the footnote references it inserts + throughout the text; they will only show up when printed. + +.. class:: incremental + + Other uses may require "``.. include:: <s5defs.txt>``". + + +Chained Presentations +===================== + +.. class:: handout + + Presentation slide shows can be chained together. This is useful + for including all or part of one presentation in another, and for + changing themes. Slide numbers are not carried over, unless you + fake a continuous multi-themed presentation: + + 1. Generate slide show HTML files with two different names from + different themes but from the same source text. + + 2. Include a link to the **next** slide, in the **second** theme's + file. + + 3. To return to the first theme, include a link to the **next** + slide, in the **first** theme. + +From one theme, `to another...`__ + +__ slide-shows-alt.html#chained-presentations-2 + + +Chained Presentations (2) +========================= + +... and `back again...`__ + +__ slide-shows.html#chained-presentations-3 + + +Chained Presentations (3) +========================= + +... back to the first theme. + +.. container:: handout + + Now we're back where we started from, back in the first theme, but + two slides further on. + + In this way, any number of themes can be chained together. + +`Or you could cheat.` + +.. container:: handout + + Just prepare the browser in advance, with all the slide show files + set up at the right slide in separate tabs in your browser, in the + right order. Closing one tab will reveal the next. + + +To Do +===== + +.. class:: incremental + + * Multi-display support: + + - speaker's notes on the laptop screen + - slides on the projector + - two views stay in sync + - presentation controlled from either display + + * Add timeout to incremental style. + + .. class:: handout + + I.e., incremental-specific style should go away (revert to + normal) after a certain interval. + + These will require some serious JavaScript-fu! + + +That's All, Folks! +================== + +.. class:: huge + + Further information: + http://docutils.sf.net + + Docutils users' mailing list: + docutils-users@lists.sf.net + + `Any questions?` + + +.. topic:: Links + :class: print-block + + .. target-notes:: :class: print-inline diff --git a/docs/user/tools.txt b/docs/user/tools.txt index 48105e1ba..6f39b5021 100644 --- a/docs/user/tools.txt +++ b/docs/user/tools.txt @@ -3,7 +3,7 @@ ========================== :Author: David Goodger -:Contact: goodger@users.sourceforge.net +:Contact: goodger@python.org :Revision: $Revision$ :Date: $Date$ :Copyright: This document has been placed in the public domain. @@ -11,8 +11,9 @@ .. contents:: -Introduction -============ +-------------- + Introduction +-------------- Once the Docutils package is unpacked, you will discover a "``tools``" directory containing several front ends for common Docutils @@ -40,7 +41,7 @@ input (stdin) is used for the source as well. Getting Help ------------- +============ First, try the "``--help``" option each front-end tool has. @@ -51,8 +52,12 @@ list. .. _Docutils-users: mailing-lists.html#docutils-users -The Tools -========= +----------- + The Tools +----------- + +HTML-Generating Tools +===================== buildhtml.py ------------ @@ -154,6 +159,116 @@ For example, to process a PEP into HTML:: rstpep2html.py pep-0287.txt pep-0287.html +rst2s5.py +--------- + +:Reader: Standalone +:Parser: reStructuredText +:Writer: S5/HTML + +The ``rst2s5.py`` front end reads standalone reStructuredText source +files and produces (X)HTML output compatible with S5_, the "Simple +Standards-based Slide Show System" by Eric Meyer. A theme is required +for proper rendering; several are distributed with Docutils and others +are available; see Themes_ below. + +For example, to process a reStructuredText file "``slides.txt``" into +S5/HTML:: + + rst2s5.py slides.txt slides.html + +Now open the "``slides.html``" file in your favorite browser, switch +to full-screen mode, and enjoy the results. + +.. _S5: http://meyerweb.com/eric/tools/s5/ + + +Themes +`````` + +Each S5 theme consists of a directory containing several files: +stylesheets, JavaScript, and graphics. These are copied into a +``ui/<theme>`` directory beside the generated HTML. A theme is chosen +using the "``--theme``" option (for themes that come with Docutils) or +the "``--theme-url``" option (for themes anywhere). For example, the +"medium-black" theme can be specified as follows:: + + rst2s5.py --theme medium-black slides.txt slides.html + +The theme will be copied to the ``ui/medium-black`` directory. + +Several themes are included with Docutils: + +``default`` + This is a simplified version of S5's default theme. + + :Main content: black serif text on a white background + :Text capacity: about 13 lines + :Headers: light blue, bold sans-serif text on a dark blue + background; titles are limited to one line + :Footers: small, gray, bold sans-serif text on a dark blue + background + +``small-white`` + (Small text on a white background.) + + :Main content: black serif text on a white background + :Text capacity: about 15 lines + :Headers: black, bold sans-serif text on a white background; + titles wrap + :Footers: small, dark gray, bold sans-serif text on a white + background + +``small-black`` + :Main content: white serif text on a black background + :Text capacity: about 15 lines + :Headers: white, bold sans-serif text on a black background; + titles wrap + :Footers: small, light gray, bold sans-serif text on a black + background + +``medium-white`` + :Main content: black serif text on a white background + :Text capacity: about 9 lines + :Headers: black, bold sans-serif text on a white background; + titles wrap + :Footers: small, dark gray, bold sans-serif text on a white + background + +``medium-black`` + :Main content: white serif text on a black background + :Text capacity: about 9 lines + :Headers: white, bold sans-serif text on a black background; + titles wrap + :Footers: small, light gray, bold sans-serif text on a black + background + +``big-white`` + :Main content: black, bold sans-serif text on a white background + :Text capacity: about 5 lines + :Headers: black, bold sans-serif text on a white background; + titles wrap + :Footers: not displayed + +``big-black`` + :Main content: white, bold sans-serif text on a black background + :Text capacity: about 5 lines + :Headers: white, bold sans-serif text on a black background; + titles wrap + :Footers: not displayed + +If a theme directory contains a file named ``__base__``, the name of +the theme's base theme will be read from it. Files are accumulated +from the named theme, any base themes, and the "default" theme (which +is the implicit base of all themes). + +For details, please see `Easy Slide Shows With reStructuredText & +S5 <slide-shows.html>`_. + + +LaTeX-Generating Tools +====================== + rst2latex.py ------------ @@ -181,6 +296,9 @@ Some limitations and difference apply: - Not all constructs are possible, see `Generating LaTeX with Docutils`_. +XML-Generating Tools +==================== + rst2xml.py ---------- @@ -193,6 +311,9 @@ This can be transformed with standard XML tools such as XSLT processors into arbitrary final forms. +Testing/Debugging Tools +======================= + rst2pseudoxml.py ---------------- @@ -228,11 +349,12 @@ document. Various forms output are possible: -Customization -============= +--------------- + Customization +--------------- Command-Line Options --------------------- +==================== Each front-end tool supports command-line options for one-off customization. For persistent customization, use `configuration @@ -248,7 +370,7 @@ corresponding configuration file entry names are listed in the .. _configuration file: Configuration Files -------------------- +=================== Configuration files are used for persistent customization; they can be set once and take effect every time you use a front-end tool. diff --git a/docutils/frontend.py b/docutils/frontend.py index 93506bce5..43750c30c 100644 --- a/docutils/frontend.py +++ b/docutils/frontend.py @@ -338,10 +338,14 @@ class OptionParser(optparse.OptionParser, docutils.SettingsSpec): ('Disable backlinks from footnotes and citations.', ['--no-footnote-backlinks'], {'dest': 'footnote_backlinks', 'action': 'store_false'}), - ('Disable Docutils section numbering', + ('Enable Docutils section numbering (default: enabled).', + ['--section-numbering'], + {'action': 'store_true', 'dest': 'sectnum_xform', + 'default': 1, 'validator': validate_boolean}), + ('Disable Docutils section numbering (default: enabled).', ['--no-section-numbering'], {'action': 'store_false', 'dest': 'sectnum_xform', - 'default': 1, 'validator': validate_boolean}), + 'validator': validate_boolean}), ('Set verbosity threshold; report system messages at or higher than ' '<level> (by name or number: "info" or "1", warning/2, error/3, ' 'severe/4; also, "none" or "5"). Default is 2 (warning).', diff --git a/docutils/parsers/rst/directives/references.py b/docutils/parsers/rst/directives/references.py index 92966140f..0406182b6 100644 --- a/docutils/parsers/rst/directives/references.py +++ b/docutils/parsers/rst/directives/references.py @@ -12,12 +12,16 @@ __docformat__ = 'reStructuredText' from docutils import nodes from docutils.transforms import references +from docutils.parsers.rst import directives def target_notes(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Target footnote generation.""" pending = nodes.pending(references.TargetNotes) + pending.details.update(options) state_machine.document.note_pending(pending) nodelist = [pending] return nodelist + +target_notes.options = {'class': directives.class_option} diff --git a/docutils/parsers/rst/include/s5defs.txt b/docutils/parsers/rst/include/s5defs.txt new file mode 100644 index 000000000..d5d3047ce --- /dev/null +++ b/docutils/parsers/rst/include/s5defs.txt @@ -0,0 +1,49 @@ +.. Definitions of interpreted text roles (classes) for S5/HTML data. +.. This data file has been placed in the public domain. + +.. Colours + ======= + +.. role:: black +.. role:: gray +.. role:: silver +.. role:: white + +.. role:: maroon +.. role:: red +.. role:: magenta +.. role:: fuchsia +.. role:: pink +.. role:: orange +.. role:: yellow +.. role:: lime +.. role:: green +.. role:: olive +.. role:: teal +.. role:: cyan +.. role:: aqua +.. role:: blue +.. role:: navy +.. role:: purple + + +.. Text Sizes + ========== + +.. role:: huge +.. role:: big +.. role:: small +.. role:: tiny + + +.. Print-Only + ========== + +.. role:: print-inline + + +.. Incremental Display + =================== + +.. role:: incremental +.. default-role:: incremental diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py index bcf33dfe5..c3de8e3f1 100644 --- a/docutils/transforms/references.py +++ b/docutils/transforms/references.py @@ -713,6 +713,12 @@ class TargetNotes(Transform): """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 = [] @@ -736,7 +742,8 @@ class TargetNotes(Transform): if not ref.get('anonymous'): continue if ref.hasattr('refuri'): - footnote = self.make_target_footnote(ref['refuri'], [ref], notes) + footnote = self.make_target_footnote(ref['refuri'], [ref], + notes) if not notes.has_key(ref['refuri']): notes[ref['refuri']] = footnote nodelist.append(footnote) @@ -765,12 +772,16 @@ class TargetNotes(Transform): 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): - reflist.insert(0, nodes.Text(' ')) + 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 diff --git a/docutils/writers/__init__.py b/docutils/writers/__init__.py index c020fbf62..fb4cbee0b 100644 --- a/docutils/writers/__init__.py +++ b/docutils/writers/__init__.py @@ -125,7 +125,8 @@ _writer_aliases = { 'pprint': 'pseudoxml', 'pformat': 'pseudoxml', 'pdf': 'rlpdf', - 'xml': 'docutils_xml',} + 'xml': 'docutils_xml', + 's5': 's5_html'} def get_writer_class(writer_name): """Return the Writer class from the `writer_name` module.""" diff --git a/docutils/writers/html4css1.py b/docutils/writers/html4css1.py index a53bda2ca..065d90584 100644 --- a/docutils/writers/html4css1.py +++ b/docutils/writers/html4css1.py @@ -99,19 +99,23 @@ class Writer(writers.Writer): ('Remove extra vertical whitespace between items of bullet lists ' 'and enumerated lists, when list items are "simple" (i.e., all ' 'items each contain one paragraph and/or one "simple" sublist ' - 'only). Default: enabled.', + 'only). Default: enabled. Can be specified directly via "class" ' + 'attributes (values "compact" and "open") in the document.', ['--compact-lists'], {'default': 1, 'action': 'store_true', 'validator': frontend.validate_boolean}), - ('Disable compact simple bullet and enumerated lists.', + ('Disable compact simple bullet and enumerated lists (except where ' + 'specified directly via "class" attributes; see --compact-lists).', ['--no-compact-lists'], {'dest': 'compact_lists', 'action': 'store_false'}), ('Remove extra vertical whitespace between items of simple field ' - 'lists. Default: enabled.', + 'lists. Default: enabled. Can be specified directly via "class" ' + 'attributes (values "compact" and "open") in the document.', ['--compact-field-lists'], {'default': 1, 'action': 'store_true', 'validator': frontend.validate_boolean}), - ('Disable compact simple field lists.', + ('Disable compact simple field lists (except where specified ' + 'directly via "class" attributes; see --compact-field-lists).', ['--no-compact-field-lists'], {'dest': 'compact_field_lists', 'action': 'store_false'}), ('Omit the XML declaration. Use with caution.', @@ -508,10 +512,12 @@ class HTMLTranslator(nodes.NodeVisitor): old_compact_simple = self.compact_simple self.context.append((self.compact_simple, self.compact_p)) self.compact_p = None - self.compact_simple = (self.settings.compact_lists and - (self.compact_simple - or self.topic_classes == ['contents'] - or self.check_simple_list(node))) + self.compact_simple = ('compact' in node['classes'] + or (self.settings.compact_lists + and 'open' not in node['classes'] + and (self.compact_simple + or self.topic_classes == ['contents'] + or self.check_simple_list(node)))) if self.compact_simple and not old_compact_simple: atts['class'] = 'simple' self.body.append(self.starttag(node, 'ul', **atts)) @@ -763,10 +769,12 @@ class HTMLTranslator(nodes.NodeVisitor): old_compact_simple = self.compact_simple self.context.append((self.compact_simple, self.compact_p)) self.compact_p = None - self.compact_simple = (self.settings.compact_lists and - (self.compact_simple - or self.topic_classes == ['contents'] - or self.check_simple_list(node))) + self.compact_simple = ('compact' in node['classes'] + or (self.settings.compact_lists + and 'open' not in node['classes'] + and (self.compact_simple + or self.topic_classes == ['contents'] + or self.check_simple_list(node)))) if self.compact_simple and not old_compact_simple: atts['class'] = (atts.get('class', '') + ' simple').strip() self.body.append(self.starttag(node, 'ol', **atts)) @@ -805,7 +813,10 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_field_list(self, node): self.context.append((self.compact_field_list, self.compact_p)) self.compact_p = None - if self.settings.compact_field_lists: + if 'compact' in node['classes']: + self.compact_field_list = 1 + elif (self.settings.compact_field_lists + and 'open' not in node['classes']): self.compact_field_list = 1 for field in node: field_body = field[-1] @@ -1440,7 +1451,7 @@ class HTMLTranslator(nodes.NodeVisitor): def depart_tip(self, node): self.depart_admonition() - def visit_title(self, node): + def visit_title(self, node, move_ids=1): """Only 6 section levels are supported by HTML.""" check_id = 0 close_tag = '</p>\n' @@ -1475,14 +1486,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append( self.starttag(node, 'h%s' % h_level, '', **atts)) atts = {} - # !!! next 2 lines to be removed in Docutils 0.5: - if node.parent['ids']: - atts['ids'] = node.parent['ids'] + # !!! conditional to be removed in Docutils 0.5: + if move_ids: + if node.parent['ids']: + atts['ids'] = node.parent['ids'] if node.hasattr('refid'): atts['class'] = 'toc-backref' atts['href'] = '#' + node['refid'] - self.body.append(self.starttag({}, 'a', '', **atts)) - self.context.append('</a></h%s>\n' % (h_level)) + if atts: + self.body.append(self.starttag({}, 'a', '', **atts)) + self.context.append('</a></h%s>\n' % (h_level)) + else: + self.context.append('</h%s>\n' % (h_level)) # !!! conditional to be removed in Docutils 0.5: if check_id: if node.parent['ids']: diff --git a/docutils/writers/s5_html.py b/docutils/writers/s5_html.py new file mode 100644 index 000000000..853787544 --- /dev/null +++ b/docutils/writers/s5_html.py @@ -0,0 +1,314 @@ +# Author: Chris Liechti +# Contact: cliechti@gmx.net +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +S5/HTML Slideshow Writer. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os +import docutils +from docutils import frontend, nodes, utils, writers +from docutils.writers import html4css1 +from docutils.parsers.rst import directives + +support_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(writers.support_path, 's5_html')) + +def find_theme(name): + # Where else to look for a theme? + # Check working dir? Destination dir? Config dir? Plugins dir? + path = os.path.join(support_path, name) + if not os.path.isdir(path): + raise docutils.ApplicationError('Theme directory not found: %r' % name) + return path + + +class Writer(html4css1.Writer): + + settings_spec = html4css1.Writer.settings_spec + ( + 'S5 Slideshow Specific Options', + 'For the S5/HTML writer, the --no-toc-backlinks option ' + '(defined in General Docutils Options above) is the default, ' + 'and should not be changed.', + (('Specify an installed S5 theme by name. Overrides --theme-url. ' + 'The default theme name is "default". The theme files will be ' + 'copied into a "ui/<theme>" directory, in the same directory as the ' + 'destination file (output HTML). Note that existing theme files ' + 'will not be overwritten (unless --overwrite-theme-files is used).', + ['--theme'], + {'default': 'default', 'metavar': '<name>', + 'overrides': 'theme_url'}), + ('Specify an S5 theme URL. The destination file (output HTML) will ' + 'link to this theme; nothing will be copied. Overrides --theme.', + ['--theme-url'], + {'metavar': '<URL>', 'overrides': 'theme'}), + ('Allow existing theme files in the ``ui/<theme>`` directory to be ' + 'overwritten. The default is not to overwrite theme files.', + ['--overwrite-theme-files'], + {'action': 'store_true'}), + ('Keep existing theme files in the ``ui/<theme>`` directory; do not ' + 'overwrite any. This is the default.', + ['--keep-theme-files'], + {'dest': 'overwrite_theme_files', 'action': 'store_false'}), + ('Enable the current slide indicator ("1 / 15"). ' + 'The default is to disable it.', + ['--current-slide'], + {'action': 'store_true'}), + ('Disable the current slide indicator. This is the default.', + ['--no-current-slide'], + {'dest': 'current_slide', 'action': 'store_false'}),)) + + settings_default_overrides = {'toc_backlinks': 0} + + config_section = 's5_html writer' + config_section_dependencies = ('writers', 'html4css1 writer') + + def __init__(self): + html4css1.Writer.__init__(self) + self.translator_class = S5HTMLTranslator + + +class S5HTMLTranslator(html4css1.HTMLTranslator): + + doctype = ( + '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n') + + s5_stylesheet_template = """\ +<!-- configuration parameters --> +<meta name="defaultView" content="slideshow" /> +<meta name="controlVis" content="hidden" /> +<!-- style sheet links --> +<link rel="stylesheet" href="%(path)s/slides.css" + type="text/css" media="projection" id="slideProj" /> +<link rel="stylesheet" href="%(path)s/outline.css" + type="text/css" media="screen" id="outlineStyle" /> +<link rel="stylesheet" href="%(path)s/print.css" + type="text/css" media="print" id="slidePrint" /> +<link rel="stylesheet" href="%(path)s/opera.css" + type="text/css" media="projection" id="operaFix" /> +<script src="%(path)s/slides.js" type="text/javascript"></script>\n""" + + disable_current_slide = """ +<style type="text/css"> +#currentSlide {display: none;} +</style>\n""" + + layout_template = """\ +<div class="layout"> +<div id="controls"></div> +<div id="currentSlide"></div> +<div id="header"> +%(header)s +</div> +<div id="footer"> +%(title)s%(footer)s +</div> +</div>\n""" +# <div class="topleft"></div> +# <div class="topright"></div> +# <div class="bottomleft"></div> +# <div class="bottomright"></div> + + default_theme = 'default' + """Name of the default theme.""" + + base_theme_file = '__base__' + """Name of the file containing the name of the base theme.""" + + direct_theme_files = ( + 'slides.css', 'outline.css', 'print.css', 'opera.css', 'slides.js') + """Names of theme files directly linked to in the output HTML""" + + indirect_theme_files = ( + 's5-core.css', 'framing.css', 'pretty.css', 'blank.gif', 'iepngfix.htc') + """Names of files used indirectly; imported or used by files in + `direct_theme_files`.""" + + required_theme_files = indirect_theme_files + direct_theme_files + """Names of mandatory theme files.""" + + def __init__(self, *args): + html4css1.HTMLTranslator.__init__(self, *args) + #insert S5-specific stylesheet and script stuff: + self.theme_file_path = None + self.setup_theme() + self.stylesheet.append(self.s5_stylesheet_template + % {'path': self.theme_file_path}) + if not self.document.settings.current_slide: + self.stylesheet.append(self.disable_current_slide) + self.add_meta('<meta name="version" content="S5 1.1" />\n') + self.s5_footer = [] + self.s5_header = [] + self.section_count = 0 + self.theme_files_copied = None + + def setup_theme(self): + if self.document.settings.theme: + self.copy_theme() + elif self.document.settings.theme_url: + self.theme_file_path = self.document.settings.theme_url + else: + raise docutils.ApplicationError( + 'No theme specified for S5/HTML writer.') + + def copy_theme(self): + """ + Locate & copy theme files. + + A theme may be explicitly based on another theme via a '__base__' + file. The default base theme is 'default'. Files are accumulated + from the specified theme, any base themes, and 'default'. + """ + settings = self.document.settings + path = find_theme(settings.theme) + theme_paths = [path] + self.theme_files_copied = {} + copied = {} + # This is a link (URL) in HTML, so we use "/", not os.sep: + self.theme_file_path = '%s/%s' % ('ui', settings.theme) + if settings._destination: + dest = os.path.join( + os.path.dirname(settings._destination), 'ui', settings.theme) + if not os.path.isdir(dest): + os.makedirs(dest) + else: + # no destination, so we can't copy the theme + return + default = 0 + while path: + for f in os.listdir(path): # copy all files from each theme + if f == self.base_theme_file: + continue # ... except the "__base__" file + if ( self.copy_file(f, path, dest) + and f in self.required_theme_files): + copied[f] = 1 + if default: + break # "default" theme has no base theme + # Find the "__base__" file in theme directory: + base_theme_file = os.path.join(path, self.base_theme_file) + # If it exists, read it and record the theme path: + if os.path.isfile(base_theme_file): + lines = open(base_theme_file).readlines() + for line in lines: + line = line.strip() + if line and not line.startswith('#'): + path = find_theme(line) + if path in theme_paths: # check for duplicates (cycles) + path = None # if found, use default base + else: + theme_paths.append(path) + break + else: # no theme name found + path = None # use default base + else: # no base theme file found + path = None # use default base + if not path: + path = find_theme(self.default_theme) + theme_paths.append(path) + default = 1 + if len(copied) != len(self.required_theme_files): + # Some all required files weren't found & couldn't be copied. + required = list(self.required_theme_files) + for f in copied.keys(): + required.remove(f) + raise docutils.ApplicationError( + 'Theme files not found: %s' + % ', '.join(['%r' % f for f in required])) + + def copy_file(self, name, source_dir, dest_dir): + """ + Copy file `name` from `source_dir` to `dest_dir`. + Return 1 if the file exists in either `source_dir` or `dest_dir`. + """ + source = os.path.join(source_dir, name) + dest = os.path.join(dest_dir, name) + if self.theme_files_copied.has_key(dest): + return 1 + else: + self.theme_files_copied[dest] = 1 + if os.path.isfile(source): + settings = self.document.settings + if os.path.exists(dest) and not settings.overwrite_theme_files: + settings.record_dependencies.add(dest) + else: + src_file = open(source, 'rb') + src_data = src_file.read() + src_file.close() + dest_file = open(dest, 'wb') + dest_file.write(src_data.replace( + 'ui/default', dest_dir[dest_dir.rfind('ui/'):])) + dest_file.close() + settings.record_dependencies.add(source) + return 1 + if os.path.isfile(dest): + return 1 + + def depart_document(self, node): + header = ''.join(self.s5_header) + footer = ''.join(self.s5_footer) + title = ''.join(self.html_title).replace('<h1 class="title">', '<h1>') + layout = self.layout_template % {'header': header, + 'title': title, + 'footer': footer} + self.fragment.extend(self.body) + self.body_prefix.extend(layout) + self.body_prefix.append('<div class="presentation">\n') + self.body_prefix.append( + self.starttag({'classes': ['slide'], 'ids': ['slide0']}, 'div')) + self.body_suffix.insert(0, '</div>\n') + # skip content-type meta tag with interpolated charset value: + self.html_head.extend(self.head[1:]) + self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + + self.docinfo + self.body + + self.body_suffix[:-1]) + + def depart_footer(self, node): + start = self.context.pop() + self.s5_footer.append('<h2>') + self.s5_footer.extend(self.body[start:]) + self.s5_footer.append('</h2>') + del self.body[start:] + + def depart_header(self, node): + start = self.context.pop() + header = ['<div id="header">\n'] + header.extend(self.body[start:]) + header.append('\n</div>\n') + del self.body[start:] + self.s5_header.extend(header) + + def visit_section(self, node): + if not self.section_count: + self.body.append('\n</div>\n') + self.section_count += 1 + self.section_level += 1 + if self.section_level > 1: + # dummy for matching div's + self.body.append(self.starttag(node, 'div', CLASS='section')) + else: + self.body.append(self.starttag(node, 'div', CLASS='slide')) + + def visit_subtitle(self, node): + if isinstance(node.parent, nodes.section): + level = self.section_level + self.initial_header_level - 1 + if level == 1: + level = 2 + tag = 'h%s' % level + self.body.append(self.starttag(node, tag, '')) + self.context.append('</%s>\n' % tag) + else: + html4css1.HTMLTranslator.visit_subtitle(self, node) + + def visit_title(self, node, move_ids=0): + html4css1.HTMLTranslator.visit_title(self, node, move_ids=move_ids) diff --git a/docutils/writers/support/s5_html/README.txt b/docutils/writers/support/s5_html/README.txt new file mode 100644 index 000000000..2e01b51ee --- /dev/null +++ b/docutils/writers/support/s5_html/README.txt @@ -0,0 +1,6 @@ +Except where otherwise noted (default/iepngfix.htc), all files in this +directory have been released into the Public Domain. + +These files are based on files from S5 1.1, released into the Public +Domain by Eric Meyer. For further details, please see +http://www.meyerweb.com/eric/tools/s5/credits.html. diff --git a/docutils/writers/support/s5_html/big-black/__base__ b/docutils/writers/support/s5_html/big-black/__base__ new file mode 100644 index 000000000..f08be9ad5 --- /dev/null +++ b/docutils/writers/support/s5_html/big-black/__base__ @@ -0,0 +1,2 @@ +# base theme of this theme: +big-white diff --git a/docutils/writers/support/s5_html/big-black/big_inverse/framing.css b/docutils/writers/support/s5_html/big-black/big_inverse/framing.css new file mode 100644 index 000000000..5a31113fb --- /dev/null +++ b/docutils/writers/support/s5_html/big-black/big_inverse/framing.css @@ -0,0 +1,25 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; z-index: 1;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.1em 4% 4%; z-index: 2;} +/* list-style: none;} */ +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/big-black/framing.css b/docutils/writers/support/s5_html/big-black/framing.css new file mode 100644 index 000000000..5a31113fb --- /dev/null +++ b/docutils/writers/support/s5_html/big-black/framing.css @@ -0,0 +1,25 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; z-index: 1;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.1em 4% 4%; z-index: 2;} +/* list-style: none;} */ +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/big-black/pretty.css b/docutils/writers/support/s5_html/big-black/pretty.css new file mode 100644 index 000000000..91a85dec2 --- /dev/null +++ b/docutils/writers/support/s5_html/big-black/pretty.css @@ -0,0 +1,111 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: black; color: white;} +:link, :visited {text-decoration: none; color: cyan;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #CCC;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;} +.slide h2 {font-size: 110%;} +.slide h3 {font-size: 105%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: black; color: #CCC;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #AAA; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0; + font-size: 150%; white-space: normal; background: transparent;} +#slide0 h2 {font: 110%; font-style: italic; color: gray;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #FCC;} + +.incremental, .incremental *, .incremental *:after { + color: black; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: lime;} + +.print-block, .print-inline {display: none;} + +.huge {font-size: 150%;} +.big {font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +div.sidebar {background-color: black;} + +pre.literal-block, pre.doctest-block {background-color: black;} + +tt.docutils {background-color: black;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/big-white/framing.css b/docutils/writers/support/s5_html/big-white/framing.css new file mode 100644 index 000000000..cd343432b --- /dev/null +++ b/docutils/writers/support/s5_html/big-white/framing.css @@ -0,0 +1,24 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.25em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/big-white/pretty.css b/docutils/writers/support/s5_html/big-white/pretty.css new file mode 100644 index 000000000..8ecb1dd65 --- /dev/null +++ b/docutils/writers/support/s5_html/big-white/pretty.css @@ -0,0 +1,109 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;} +.slide h2 {font-size: 110%;} +.slide h3 {font-size: 105%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #005; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #444; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0; + font-size: 150%; white-space: normal; background: transparent;} +#slide0 h2 {font: 110%; font-style: italic; color: gray;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after { + color: white; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-size: 150%;} +.big {font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/default/blank.gif b/docutils/writers/support/s5_html/default/blank.gif new file mode 100644 index 000000000..75b945d25 Binary files /dev/null and b/docutils/writers/support/s5_html/default/blank.gif differ diff --git a/docutils/writers/support/s5_html/default/framing.css b/docutils/writers/support/s5_html/default/framing.css new file mode 100644 index 000000000..c4727f303 --- /dev/null +++ b/docutils/writers/support/s5_html/default/framing.css @@ -0,0 +1,25 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {position: fixed; top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/default/iepngfix.htc b/docutils/writers/support/s5_html/default/iepngfix.htc new file mode 100644 index 000000000..9f3d628b5 --- /dev/null +++ b/docutils/writers/support/s5_html/default/iepngfix.htc @@ -0,0 +1,42 @@ +<public:component> +<public:attach event="onpropertychange" onevent="doFix()" /> + +<script> + +// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com +// Free usage permitted as long as this notice remains intact. + +// This must be a path to a blank image. That's all the configuration you need here. +var blankImg = 'ui/default/blank.gif'; + +var f = 'DXImageTransform.Microsoft.AlphaImageLoader'; + +function filt(s, m) { + if (filters[f]) { + filters[f].enabled = s ? true : false; + if (s) with (filters[f]) { src = s; sizingMethod = m } + } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")'; +} + +function doFix() { + if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) || + (event && !/(background|src)/.test(event.propertyName))) return; + + if (tagName == 'IMG') { + if ((/\.png$/i).test(src)) { + filt(src, 'image'); // was 'scale' + src = blankImg; + } else if (src.indexOf(blankImg) < 0) filt(); + } else if (style.backgroundImage) { + if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) { + var s = RegExp.$1; + style.backgroundImage = ''; + filt(s, 'crop'); + } else filt(); + } +} + +doFix(); + +</script> +</public:component> \ No newline at end of file diff --git a/docutils/writers/support/s5_html/default/opera.css b/docutils/writers/support/s5_html/default/opera.css new file mode 100644 index 000000000..c9d1148be --- /dev/null +++ b/docutils/writers/support/s5_html/default/opera.css @@ -0,0 +1,8 @@ +/* This file has been placed in the public domain. */ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff --git a/docutils/writers/support/s5_html/default/outline.css b/docutils/writers/support/s5_html/default/outline.css new file mode 100644 index 000000000..cb3588d5a --- /dev/null +++ b/docutils/writers/support/s5_html/default/outline.css @@ -0,0 +1,21 @@ +/* This file has been placed in the public domain. */ +/* Don't change this unless you want the layout stuff to show up in the + outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0.75em; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block, .print-inline {display: none;} diff --git a/docutils/writers/support/s5_html/default/pretty.css b/docutils/writers/support/s5_html/default/pretty.css new file mode 100644 index 000000000..f83ca2bf5 --- /dev/null +++ b/docutils/writers/support/s5_html/default/pretty.css @@ -0,0 +1,122 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +/* Replace the background style above with the style below (and again for + div#header) for a graphic: */ +/* background: white url(bodybg.gif) -16px 0 no-repeat; */ +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#header, div#footer {background: #005; color: #AAB; font-family: sans-serif;} +/* background: #005 url(bodybg.gif) -16px 0 no-repeat; */ +div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {position: absolute; top: 0.45em; z-index: 1; + margin: 0; padding-left: 0.7em; white-space: nowrap; + font: bold 150% sans-serif; color: #DDE; background: #005;} +.slide h2 {font: bold 120%/1em sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #449; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 1.5em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; color: #000; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after {visibility: visible; + color: white; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/default/print.css b/docutils/writers/support/s5_html/default/print.css new file mode 100644 index 000000000..76e6352ee --- /dev/null +++ b/docutils/writers/support/s5_html/default/print.css @@ -0,0 +1,33 @@ +/* This file has been placed in the public domain. */ +/* The following rule is necessary to have all slides appear in print! + DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} +.extra {background: transparent !important;} +div.extra, pre.extra, .example {font-size: 10pt; color: #333;} +ul.extra a {font-weight: bold;} +p.example {display: none;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; + font-style: italic;} +#footer h2, #controls {display: none;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block {display: block !important;} +.print-inline {display: inline !important;} + +/* The following rule keeps the layout stuff out of print. + Remove at your own risk! */ +.layout, .layout * {display: none !important;} diff --git a/docutils/writers/support/s5_html/default/s5-core.css b/docutils/writers/support/s5_html/default/s5-core.css new file mode 100644 index 000000000..6965f5e8f --- /dev/null +++ b/docutils/writers/support/s5_html/default/s5-core.css @@ -0,0 +1,11 @@ +/* This file has been placed in the public domain. */ +/* Do not edit or override these styles! + The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff --git a/docutils/writers/support/s5_html/default/slides.css b/docutils/writers/support/s5_html/default/slides.css new file mode 100644 index 000000000..82bdc0ee0 --- /dev/null +++ b/docutils/writers/support/s5_html/default/slides.css @@ -0,0 +1,10 @@ +/* This file has been placed in the public domain. */ + +/* required to make the slide show run at all */ +@import url(s5-core.css); + +/* sets basic placement and size of slide components */ +@import url(framing.css); + +/* styles that make the slides look good */ +@import url(pretty.css); diff --git a/docutils/writers/support/s5_html/default/slides.js b/docutils/writers/support/s5_html/default/slides.js new file mode 100644 index 000000000..f0f81bbf8 --- /dev/null +++ b/docutils/writers/support/s5_html/default/slides.js @@ -0,0 +1,559 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// Modified for Docutils (http://docutils.sf.net) by David Goodger +// $Revision$ +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for +// information about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var slideIDs = new Array(); +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + if (obj.getAttribute('id')) { + slideIDs[n] = obj.getAttribute('id'); + } + else { + obj.setAttribute('id',did); + slideIDs[n] = did; + } + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + var footer_nodes; + var vis = 'visible'; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + footer_nodes = document.getElementById('footer').childNodes; + } else { + cs = document.currentSlide; + footer = document.footer.childNodes; + } + cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>'; + if (snum == 0) { + vis = 'hidden'; + } + cs.style.visibility = vis; + for (var i = 0; i < footer_nodes.length; i++) { + if (footer_nodes[i].nodeType == 1) { + footer_nodes[i].style.visibility = vis; + } + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = slideIDs[snum]; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = slideIDs[snum]; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById(slideIDs[0]); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = document.getElementById(hash); + if (target) { + for (var i = 0; i < slideIDs.length; i++) { + if (target.id == slideIDs[i]) return i; + } + } + return null; +} + +function slideJump() { + if (window.location.hash == null || window.location.hash == '') { + currentSlide(); + return; + } + if (window.location.hash == null) return; + var dest = null; + dest = findSlide(window.location.hash.slice(1)); + if (dest == null) { + dest = 0; + } + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#.+'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i<anchors.length; i++) { + var anchor = anchors[i]; + if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) { + anchor.target = '_blank'; + addClass(anchor,'external'); + } + } +} + +function createControls() { + var controlsDiv = document.getElementById("controls"); + if (!controlsDiv) return; + var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"'; + var hideDiv, hideList = ''; + if (controlVis == 'hidden') { + hideDiv = hider; + } else { + hideList = hider; + } + controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' + + '<div id="navLinks">' + + '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' + + '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' + + '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' + + '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' + + '<\/div><\/form>'; + if (controlVis == 'hidden') { + var hidden = document.getElementById('navLinks'); + } else { + var hidden = document.getElementById('jumplist'); + } + addClass(hidden,'hideme'); +} + +function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers + if (!s5mode) return false; + var vScale = 22; // both yield 32 (after rounding) at 1024x768 + var hScale = 32; // perhaps should auto-calculate based on theme's declared value? + if (window.innerHeight) { + var vSize = window.innerHeight; + var hSize = window.innerWidth; + } else if (document.documentElement.clientHeight) { + var vSize = document.documentElement.clientHeight; + var hSize = document.documentElement.clientWidth; + } else if (document.body.clientHeight) { + var vSize = document.body.clientHeight; + var hSize = document.body.clientWidth; + } else { + var vSize = 700; // assuming 1024x768, minus chrome and such + var hSize = 1024; // these do not account for kiosk mode or Opera Show + } + var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale)); + fontSize(newSize + 'px'); + if (isGe) { // hack to counter incremental reflow bugs + var obj = document.getElementsByTagName('body')[0]; + obj.style.display = 'none'; + obj.style.display = 'block'; + } +} + +function fontSize(value) { + if (!(s5ss = document.getElementById('s5ss'))) { + if (!isIE) { + document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style')); + s5ss.setAttribute('media','screen, projection'); + s5ss.setAttribute('id','s5ss'); + } else { + document.createStyleSheet(); + document.s5ss = document.styleSheets[document.styleSheets.length - 1]; + } + } + if (!isIE) { + while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild); + s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}')); + } else { + document.s5ss.addRule('body','font-size: ' + value + ' !important;'); + } +} + +function notOperaFix() { + slideCSS = document.getElementById('slideProj').href; + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + slides.setAttribute('media','screen'); + outline.disabled = true; + if (isGe) { + slides.setAttribute('href','null'); // Gecko fix + slides.setAttribute('href',slideCSS); // Gecko fix + } + if (isIE && document.styleSheets && document.styleSheets[0]) { + document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)'); + } +} + +function getIncrementals(obj) { + var incrementals = new Array(); + if (!obj) + return incrementals; + var children = obj.childNodes; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (hasClass(child, 'incremental')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'incremental'); + for (var j = 0; j < child.childNodes.length; j++) { + if (child.childNodes[j].nodeType == 1) { + addClass(child.childNodes[j], 'incremental'); + } + } + } else { + incrementals[incrementals.length] = child; + removeClass(child,'incremental'); + } + } + if (hasClass(child, 'show-first')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'show-first'); + if (child.childNodes[isGe].nodeType == 1) { + removeClass(child.childNodes[isGe], 'incremental'); + } + } else { + incrementals[incrementals.length] = child; + } + } + incrementals = incrementals.concat(getIncrementals(child)); + } + return incrementals; +} + +function createIncrementals() { + var incrementals = new Array(); + for (var i = 0; i < smax; i++) { + incrementals[i] = getIncrementals(document.getElementById(slideIDs[i])); + } + return incrementals; +} + +function defaultCheck() { + var allMetas = document.getElementsByTagName('meta'); + for (var i = 0; i< allMetas.length; i++) { + if (allMetas[i].name == 'defaultView') { + defaultView = allMetas[i].content; + } + if (allMetas[i].name == 'controlVis') { + controlVis = allMetas[i].content; + } + } +} + +// Key trap fix, new function body for trap() +function trap(e) { + if (!e) { + e = event; + e.which = e.keyCode; + } + try { + modifierKey = e.ctrlKey || e.altKey || e.metaKey; + } + catch(e) { + modifierKey = false; + } + return modifierKey || e.which == 0; +} + +function startup() { + defaultCheck(); + if (!isOp) createControls(); + slideLabel(); + fixLinks(); + externalLinks(); + fontScale(); + if (!isOp) { + notOperaFix(); + incrementals = createIncrementals(); + slideJump(); + if (defaultView == 'outline') { + toggle(); + } + document.onkeyup = keys; + document.onkeypress = trap; + document.onclick = clicker; + } +} + +window.onload = startup; +window.onresize = function(){setTimeout('fontScale()', 50);} diff --git a/docutils/writers/support/s5_html/medium-black/__base__ b/docutils/writers/support/s5_html/medium-black/__base__ new file mode 100644 index 000000000..401b621bd --- /dev/null +++ b/docutils/writers/support/s5_html/medium-black/__base__ @@ -0,0 +1,2 @@ +# base theme of this theme: +medium-white diff --git a/docutils/writers/support/s5_html/medium-black/pretty.css b/docutils/writers/support/s5_html/medium-black/pretty.css new file mode 100644 index 000000000..6bc13353a --- /dev/null +++ b/docutils/writers/support/s5_html/medium-black/pretty.css @@ -0,0 +1,117 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: black; color: white;} +:link, :visited {text-decoration: none; color: cyan;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #CCC;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#footer {font-family: sans-serif; color: #AAA; + font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.75em;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;} +.slide h2 {font: bold 125% sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 110% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: black; color: #CCC;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #AAA; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 1em; top: 0; + font: bold 150% sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 125% sans-serif; color: gray;} +#slide0 h3 {margin-top: 1.5em; font: bold 110% sans-serif;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #FCC;} + +.incremental, .incremental *, .incremental *:after { + color: black; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: lime;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +div.sidebar {background-color: black;} + +pre.literal-block, pre.doctest-block {background-color: black;} + +tt.docutils {background-color: black;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/medium-white/framing.css b/docutils/writers/support/s5_html/medium-white/framing.css new file mode 100644 index 000000000..6c4e3abf2 --- /dev/null +++ b/docutils/writers/support/s5_html/medium-white/framing.css @@ -0,0 +1,24 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 0.75em 4% 0 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/medium-white/pretty.css b/docutils/writers/support/s5_html/medium-white/pretty.css new file mode 100644 index 000000000..fe70a39f7 --- /dev/null +++ b/docutils/writers/support/s5_html/medium-white/pretty.css @@ -0,0 +1,115 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #222;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#footer {font-family: sans-serif; color: #444; + font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.75em;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;} +.slide h2 {font: bold 125% sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 110% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #222;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #444; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 1em; top: 0; + font: bold 150% sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 125% sans-serif; color: gray;} +#slide0 h3 {margin-top: 1.5em; font: bold 110% sans-serif;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after { + color: white; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/small-black/__base__ b/docutils/writers/support/s5_html/small-black/__base__ new file mode 100644 index 000000000..67f4db2bf --- /dev/null +++ b/docutils/writers/support/s5_html/small-black/__base__ @@ -0,0 +1,2 @@ +# base theme of this theme: +small-white diff --git a/docutils/writers/support/s5_html/small-black/pretty.css b/docutils/writers/support/s5_html/small-black/pretty.css new file mode 100644 index 000000000..991bb9fdb --- /dev/null +++ b/docutils/writers/support/s5_html/small-black/pretty.css @@ -0,0 +1,118 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: black; color: white;} +:link, :visited {text-decoration: none; color: cyan;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #CCC;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#footer {font-family: sans-serif; color: #AAA; + font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;} +.slide h2 {font: bold 120% sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: black; color: #CCC;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #AAA; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 0em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #FCC;} + +.incremental, .incremental *, .incremental *:after { + color: black; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: lime;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +div.sidebar {background-color: black;} + +pre.literal-block, pre.doctest-block {background-color: black;} + +tt.docutils {background-color: black;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/support/s5_html/small-white/framing.css b/docutils/writers/support/s5_html/small-white/framing.css new file mode 100644 index 000000000..70287dd06 --- /dev/null +++ b/docutils/writers/support/s5_html/small-white/framing.css @@ -0,0 +1,24 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 1em 4% 0 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/support/s5_html/small-white/pretty.css b/docutils/writers/support/s5_html/small-white/pretty.css new file mode 100644 index 000000000..243763ffc --- /dev/null +++ b/docutils/writers/support/s5_html/small-white/pretty.css @@ -0,0 +1,116 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #222;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#footer {font-family: sans-serif; color: #444; + font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;} +.slide h2 {font: bold 120% sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #222;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #444; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 0em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after { + color: white; visibility: visible; border: 0; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/setup.py b/setup.py index 24caa593c..157158c4f 100755 --- a/setup.py +++ b/setup.py @@ -71,8 +71,12 @@ what-you-see-is-what-you-get plaintext markup syntax.""", # wrap at col 60 ['docutils/writers/support/newlatex2e/base.tex']), ('docutils/writers/support/pep_html', ['docutils/writers/support/pep_html/pep.css', - 'docutils/writers/support/pep_html/template.txt']),], + 'docutils/writers/support/pep_html/template.txt']), + ('docutils/writers/support/s5_html', + (['docutils/writers/support/s5_html/README.txt'] + + glob.glob('docutils/writers/support/s5_html/*/*')))], 'scripts' : ['tools/rst2html.py', + 'tools/rst2s5.py', 'tools/rst2latex.py', 'tools/rst2newlatex.py', 'tools/rst2xml.py', diff --git a/test/functional/expected/standalone_rst_html4css1.html b/test/functional/expected/standalone_rst_html4css1.html index dd19f2710..6f2fbb49c 100644 --- a/test/functional/expected/standalone_rst_html4css1.html +++ b/test/functional/expected/standalone_rst_html4css1.html @@ -970,7 +970,7 @@ section, "Docutils System Messages":</p> <!-- section should be added by Docutils automatically --> </div> <div class="system-messages section"> -<h1><a>Docutils System Messages</a></h1> +<h1>Docutils System Messages</h1> <div class="system-message" id="id23"> <p class="system-message-title">System Message: <a name="id23">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 100); <em><a href="#id24">backlink</a></em></p> Undefined substitution referenced: "problematic".</div> diff --git a/test/functional/expected/standalone_rst_s5_html_1.html b/test/functional/expected/standalone_rst_s5_html_1.html new file mode 100644 index 000000000..bbface42e --- /dev/null +++ b/test/functional/expected/standalone_rst_s5_html_1.html @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" /> +<meta name="version" content="S5 1.1" /> +<title>Slide Shows + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +
    +
    +

    Slide Shows

    +
    +++ + + + + + +
    Author:David Goodger
    Date:2005-11-28
    + + + + + + + +

    This is a test. This is only a test. If this were a real slide +show, there would be a projector handy.

    +

    Let's test the S5/HTML writer!

    +
      +
    • Use the arrow keys to navigate.
    • +
    • Click the "Ø" button to switch between presentation & +handout/outline modes.
    • +
    +
    +In presentation mode, mouse over to the lower right-hand corner to +display the controls.
    + +
    +
    +

    Introduction

    +
      +
    • reStructuredText

      Uses normal reStructuredText as input.

      +
    • +
    • One section per slide

      Each first-level section is converted into a single slide.

      +
    • +
    • (X)HTML output

      Presentations can be viewed using any modern graphical web browser. +The browser must support CSS, JavaScript, and XHTML. S5 even works +with IE!

      +
    • +
    • Themes

      A variety of themes are available.

      +
    • +
    • rst2s5.py

      The front-end tool to generate S5 slide shows.

      +
    • +
    +
    +
    +

    Features (1)

    +

    A flush-left paragraph

    +

    A centered paragraph

    +

    A flush-right paragraph

    +

    Some colours: black [black], gray, silver, +white [white], maroon, red, +magenta, fuchsia, pink, +orange, yellow, lime, green, +olive, teal, cyan, aqua, +blue, navy, purple

    +
    +
    +

    Features (2)

    +

    Some incremental text.

    +
      +
    • tiny (class & role name: "tiny", e.g. ":tiny:`text`")

      +
    • +
    • small ("small")

      +
    • +
    • normal (unstyled)

      +
    • +
    • big ("big")

      +
    • +
    • huge ("huge")

      +
    • +
    +
    +
    +

    Checklist

    +
      +
    • The document title should be duplicated on each slide in the footer +(except for the first slide, slide0, where the entire footer is +disabled).
    • +
    • The footer also contains a second line, "Location • Date"
    • +
    • There's no table of contents on the first slide (the directive is +disabled).
    • +
    • Handout material is not displayed in presentation mode.
    • +
    • The theme directories should be created, and the theme files copied +over.
    • +
    +
    +
    + + diff --git a/test/functional/expected/standalone_rst_s5_html_2.html b/test/functional/expected/standalone_rst_s5_html_2.html new file mode 100644 index 000000000..31d5e8750 --- /dev/null +++ b/test/functional/expected/standalone_rst_s5_html_2.html @@ -0,0 +1,144 @@ + + + + + + + +Slide Shows + + + + + + + + + + + + + + +
    +
    +
    + + +
    +
    +
    +

    Slide Shows

    + +++ + + + + + +
    Author:David Goodger
    Date:2005-11-28
    + + + + + + + +

    This is a test. This is only a test. If this were a real slide +show, there would be a projector handy.

    +

    Let's test the S5/HTML writer!

    +
      +
    • Use the arrow keys to navigate.
    • +
    • Click the "Ø" button to switch between presentation & +handout/outline modes.
    • +
    +
    +In presentation mode, mouse over to the lower right-hand corner to +display the controls.
    + +
    +
    +

    Introduction

    +
      +
    • reStructuredText

      Uses normal reStructuredText as input.

      +
    • +
    • One section per slide

      Each first-level section is converted into a single slide.

      +
    • +
    • (X)HTML output

      Presentations can be viewed using any modern graphical web browser. +The browser must support CSS, JavaScript, and XHTML. S5 even works +with IE!

      +
    • +
    • Themes

      A variety of themes are available.

      +
    • +
    • rst2s5.py

      The front-end tool to generate S5 slide shows.

      +
    • +
    +
    +
    +

    Features (1)

    +

    A flush-left paragraph

    +

    A centered paragraph

    +

    A flush-right paragraph

    +

    Some colours: black [black], gray, silver, +white [white], maroon, red, +magenta, fuchsia, pink, +orange, yellow, lime, green, +olive, teal, cyan, aqua, +blue, navy, purple

    +
    +
    +

    Features (2)

    +

    Some incremental text.

    +
      +
    • tiny (class & role name: "tiny", e.g. ":tiny:`text`")

      +
    • +
    • small ("small")

      +
    • +
    • normal (unstyled)

      +
    • +
    • big ("big")

      +
    • +
    • huge ("huge")

      +
    • +
    +
    +
    +

    Checklist

    +
      +
    • The document title should be duplicated on each slide in the footer +(except for the first slide, slide0, where the entire footer is +disabled).
    • +
    • The footer also contains a second line, "Location • Date"
    • +
    • There's no table of contents on the first slide (the directive is +disabled).
    • +
    • Handout material is not displayed in presentation mode.
    • +
    • The theme directories should be created, and the theme files copied +over.
    • +
    +
    +
    + + diff --git a/test/functional/expected/ui/default/blank.gif b/test/functional/expected/ui/default/blank.gif new file mode 100644 index 000000000..75b945d25 Binary files /dev/null and b/test/functional/expected/ui/default/blank.gif differ diff --git a/test/functional/expected/ui/default/framing.css b/test/functional/expected/ui/default/framing.css new file mode 100644 index 000000000..c4727f303 --- /dev/null +++ b/test/functional/expected/ui/default/framing.css @@ -0,0 +1,25 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {position: fixed; top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/test/functional/expected/ui/default/iepngfix.htc b/test/functional/expected/ui/default/iepngfix.htc new file mode 100644 index 000000000..9f3d628b5 --- /dev/null +++ b/test/functional/expected/ui/default/iepngfix.htc @@ -0,0 +1,42 @@ + + + + + \ No newline at end of file diff --git a/test/functional/expected/ui/default/opera.css b/test/functional/expected/ui/default/opera.css new file mode 100644 index 000000000..c9d1148be --- /dev/null +++ b/test/functional/expected/ui/default/opera.css @@ -0,0 +1,8 @@ +/* This file has been placed in the public domain. */ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff --git a/test/functional/expected/ui/default/outline.css b/test/functional/expected/ui/default/outline.css new file mode 100644 index 000000000..cb3588d5a --- /dev/null +++ b/test/functional/expected/ui/default/outline.css @@ -0,0 +1,21 @@ +/* This file has been placed in the public domain. */ +/* Don't change this unless you want the layout stuff to show up in the + outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0.75em; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block, .print-inline {display: none;} diff --git a/test/functional/expected/ui/default/pretty.css b/test/functional/expected/ui/default/pretty.css new file mode 100644 index 000000000..f83ca2bf5 --- /dev/null +++ b/test/functional/expected/ui/default/pretty.css @@ -0,0 +1,122 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +/* Replace the background style above with the style below (and again for + div#header) for a graphic: */ +/* background: white url(bodybg.gif) -16px 0 no-repeat; */ +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#header, div#footer {background: #005; color: #AAB; font-family: sans-serif;} +/* background: #005 url(bodybg.gif) -16px 0 no-repeat; */ +div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {position: absolute; top: 0.45em; z-index: 1; + margin: 0; padding-left: 0.7em; white-space: nowrap; + font: bold 150% sans-serif; color: #DDE; background: #005;} +.slide h2 {font: bold 120%/1em sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #449; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 1.5em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; color: #000; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after {visibility: visible; + color: white; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/test/functional/expected/ui/default/print.css b/test/functional/expected/ui/default/print.css new file mode 100644 index 000000000..76e6352ee --- /dev/null +++ b/test/functional/expected/ui/default/print.css @@ -0,0 +1,33 @@ +/* This file has been placed in the public domain. */ +/* The following rule is necessary to have all slides appear in print! + DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} +.extra {background: transparent !important;} +div.extra, pre.extra, .example {font-size: 10pt; color: #333;} +ul.extra a {font-weight: bold;} +p.example {display: none;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; + font-style: italic;} +#footer h2, #controls {display: none;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block {display: block !important;} +.print-inline {display: inline !important;} + +/* The following rule keeps the layout stuff out of print. + Remove at your own risk! */ +.layout, .layout * {display: none !important;} diff --git a/test/functional/expected/ui/default/s5-core.css b/test/functional/expected/ui/default/s5-core.css new file mode 100644 index 000000000..6965f5e8f --- /dev/null +++ b/test/functional/expected/ui/default/s5-core.css @@ -0,0 +1,11 @@ +/* This file has been placed in the public domain. */ +/* Do not edit or override these styles! + The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff --git a/test/functional/expected/ui/default/slides.css b/test/functional/expected/ui/default/slides.css new file mode 100644 index 000000000..82bdc0ee0 --- /dev/null +++ b/test/functional/expected/ui/default/slides.css @@ -0,0 +1,10 @@ +/* This file has been placed in the public domain. */ + +/* required to make the slide show run at all */ +@import url(s5-core.css); + +/* sets basic placement and size of slide components */ +@import url(framing.css); + +/* styles that make the slides look good */ +@import url(pretty.css); diff --git a/test/functional/expected/ui/default/slides.js b/test/functional/expected/ui/default/slides.js new file mode 100644 index 000000000..cc4ddfa1e --- /dev/null +++ b/test/functional/expected/ui/default/slides.js @@ -0,0 +1,559 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// Modified for Docutils (http://docutils.sf.net) by David Goodger +// $Revision: 4117 $ +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for +// information about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var slideIDs = new Array(); +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + if (obj.getAttribute('id')) { + slideIDs[n] = obj.getAttribute('id'); + } + else { + obj.setAttribute('id',did); + slideIDs[n] = did; + } + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + var footer_nodes; + var vis = 'visible'; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + footer_nodes = document.getElementById('footer').childNodes; + } else { + cs = document.currentSlide; + footer = document.footer.childNodes; + } + cs.innerHTML = '' + snum + '<\/span> ' + + '\/<\/span> ' + + '' + (smax-1) + '<\/span>'; + if (snum == 0) { + vis = 'hidden'; + } + cs.style.visibility = vis; + for (var i = 0; i < footer_nodes.length; i++) { + if (footer_nodes[i].nodeType == 1) { + footer_nodes[i].style.visibility = vis; + } + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = slideIDs[snum]; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = slideIDs[snum]; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById(slideIDs[0]); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = document.getElementById(hash); + if (target) { + for (var i = 0; i < slideIDs.length; i++) { + if (target.id == slideIDs[i]) return i; + } + } + return null; +} + +function slideJump() { + if (window.location.hash == null || window.location.hash == '') { + currentSlide(); + return; + } + if (window.location.hash == null) return; + var dest = null; + dest = findSlide(window.location.hash.slice(1)); + if (dest == null) { + dest = 0; + } + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#.+'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i' + + '\n') - - def visit_container(self, node): - self.body.append(self.starttag(node, 'div', CLASS='container')) - - def depart_container(self, node): - self.body.append('
    \n') - - def visit_contact(self, node): - self.visit_docinfo_item(node, 'contact', meta=None) - - def depart_contact(self, node): - self.depart_docinfo_item() - - def visit_copyright(self, node): - self.visit_docinfo_item(node, 'copyright') - - def depart_copyright(self, node): - self.depart_docinfo_item() - - def visit_danger(self, node): - self.visit_admonition(node, 'danger') - - def depart_danger(self, node): - self.depart_admonition() - - def visit_date(self, node): - self.visit_docinfo_item(node, 'date') - - def depart_date(self, node): - self.depart_docinfo_item() - - def visit_decoration(self, node): - pass - - def depart_decoration(self, node): - pass - - def visit_definition(self, node): - self.body.append('\n') - self.body.append(self.starttag(node, 'dd', '')) - self.set_first_last(node) - - def depart_definition(self, node): - self.body.append('\n') - - def visit_definition_list(self, node): - self.body.append(self.starttag(node, 'dl', CLASS='docutils')) - - def depart_definition_list(self, node): - self.body.append('\n') - - def visit_definition_list_item(self, node): - pass - - def depart_definition_list_item(self, node): - pass - - def visit_description(self, node): - self.body.append(self.starttag(node, 'td', '')) - self.set_first_last(node) - - def depart_description(self, node): - self.body.append('') - - def visit_docinfo(self, node): - self.context.append(len(self.body)) - self.body.append(self.starttag(node, 'table', - CLASS='docinfo', - frame="void", rules="none")) - self.body.append('\n' - '\n' - '\n') - self.in_docinfo = 1 - - def depart_docinfo(self, node): - self.body.append('\n\n') - self.in_docinfo = None - start = self.context.pop() - self.docinfo = self.body[start:] - self.body = [] - - def visit_docinfo_item(self, node, name, meta=1): - if meta: - meta_tag = '\n' \ - % (name, self.attval(node.astext())) - self.add_meta(meta_tag) - self.body.append(self.starttag(node, 'tr', '')) - self.body.append('%s:\n' - % self.language.labels[name]) - if len(node): - if isinstance(node[0], nodes.Element): - node[0]['classes'].append('first') - if isinstance(node[-1], nodes.Element): - node[-1]['classes'].append('last') - - def depart_docinfo_item(self): - self.body.append('\n') - - def visit_doctest_block(self, node): - self.body.append(self.starttag(node, 'pre', CLASS='doctest-block')) - - def depart_doctest_block(self, node): - self.body.append('\n\n') - - def visit_document(self, node): - self.head.append('%s\n' - % self.encode(node.get('title', ''))) - - def depart_document(self, node): - self.fragment.extend(self.body) - self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) - self.body_suffix.insert(0, '
    \n') - # skip content-type meta tag with interpolated charset value: - self.html_head.extend(self.head[1:]) - self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo - + self.docinfo + self.body - + self.body_suffix[:-1]) - - def visit_emphasis(self, node): - self.body.append('') - - def depart_emphasis(self, node): - self.body.append('') - - def visit_entry(self, node): - atts = {'class': []} - if isinstance(node.parent.parent, nodes.thead): - atts['class'].append('head') - if node.parent.parent.parent.stubs[node.parent.column]: - # "stubs" list is an attribute of the tgroup element - atts['class'].append('stub') - if atts['class']: - tagname = 'th' - atts['class'] = ' '.join(atts['class']) - else: - tagname = 'td' - del atts['class'] - node.parent.column += 1 - if node.has_key('morerows'): - atts['rowspan'] = node['morerows'] + 1 - if node.has_key('morecols'): - atts['colspan'] = node['morecols'] + 1 - node.parent.column += node['morecols'] - self.body.append(self.starttag(node, tagname, '', **atts)) - self.context.append('\n' % tagname.lower()) - if len(node) == 0: # empty cell - self.body.append(' ') - self.set_first_last(node) - - def depart_entry(self, node): - self.body.append(self.context.pop()) - - def visit_enumerated_list(self, node): - """ - The 'start' attribute does not conform to HTML 4.01's strict.dtd, but - CSS1 doesn't help. CSS2 isn't widely enough supported yet to be - usable. - """ - atts = {} - if node.has_key('start'): - atts['start'] = node['start'] - if node.has_key('enumtype'): - atts['class'] = node['enumtype'] - # @@@ To do: prefix, suffix. How? Change prefix/suffix to a - # single "format" attribute? Use CSS2? - old_compact_simple = self.compact_simple - self.context.append((self.compact_simple, self.compact_p)) - self.compact_p = None - self.compact_simple = ('compact' in node['classes'] - or (self.settings.compact_lists - and 'open' not in node['classes'] - and (self.compact_simple - or self.topic_classes == ['contents'] - or self.check_simple_list(node)))) - if self.compact_simple and not old_compact_simple: - atts['class'] = (atts.get('class', '') + ' simple').strip() - self.body.append(self.starttag(node, 'ol', **atts)) - - def depart_enumerated_list(self, node): - self.compact_simple, self.compact_p = self.context.pop() - self.body.append('\n') - - def visit_error(self, node): - self.visit_admonition(node, 'error') - - def depart_error(self, node): - self.depart_admonition() - - def visit_field(self, node): - self.body.append(self.starttag(node, 'tr', '', CLASS='field')) - - def depart_field(self, node): - self.body.append('\n') - - def visit_field_body(self, node): - self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) - self.set_class_on_child(node, 'first', 0) - field = node.parent - if (self.compact_field_list or - isinstance(field.parent, nodes.docinfo) or - field.parent.index(field) == len(field.parent) - 1): - # If we are in a compact list, the docinfo, or if this is - # the last field of the field list, do not add vertical - # space after last element. - self.set_class_on_child(node, 'last', -1) - - def depart_field_body(self, node): - self.body.append('\n') - - def visit_field_list(self, node): - self.context.append((self.compact_field_list, self.compact_p)) - self.compact_p = None - if 'compact' in node['classes']: - self.compact_field_list = 1 - elif (self.settings.compact_field_lists - and 'open' not in node['classes']): - self.compact_field_list = 1 - for field in node: - field_body = field[-1] - assert isinstance(field_body, nodes.field_body) - children = [n for n in field_body - if not isinstance(n, nodes.Invisible)] - if not (len(children) == 0 or - len(children) == 1 and - isinstance(children[0], nodes.paragraph)): - self.compact_field_list = 0 - break - self.body.append(self.starttag(node, 'table', frame='void', - rules='none', - CLASS='docutils field-list')) - self.body.append('\n' - '\n' - '\n') - - def depart_field_list(self, node): - self.body.append('\n\n') - self.compact_field_list, self.compact_p = self.context.pop() - - def visit_field_name(self, node): - atts = {} - if self.in_docinfo: - atts['class'] = 'docinfo-name' - else: - atts['class'] = 'field-name' - if ( self.settings.field_name_limit - and len(node.astext()) > self.settings.field_name_limit): - atts['colspan'] = 2 - self.context.append('\n ') - else: - self.context.append('') - self.body.append(self.starttag(node, 'th', '', **atts)) - - def depart_field_name(self, node): - self.body.append(':') - self.body.append(self.context.pop()) - - def visit_figure(self, node): - atts = {'class': 'figure'} - if node.get('width'): - atts['style'] = 'width: %spx' % node['width'] - if node.get('align'): - atts['align'] = node['align'] - self.body.append(self.starttag(node, 'div', **atts)) - - def depart_figure(self, node): - self.body.append('
    \n') - - def visit_footer(self, node): - self.context.append(len(self.body)) - - def depart_footer(self, node): - start = self.context.pop() - footer = [self.starttag(node, 'div', CLASS='footer'), - '\n'] - footer.extend(self.body[start:]) - footer.append('\n
    \n') - self.footer.extend(footer) - self.body_suffix[:0] = footer - del self.body[start:] - - def visit_footnote(self, node): - self.body.append(self.starttag(node, 'table', - CLASS='docutils footnote', - frame="void", rules="none")) - self.body.append('\n' - '\n' - '') - self.footnote_backrefs(node) - - def footnote_backrefs(self, node): - backlinks = [] - backrefs = node['backrefs'] - if self.settings.footnote_backlinks and backrefs: - if len(backrefs) == 1: - self.context.append('') - self.context.append( - '' - % (backrefs[0], node['ids'][0])) - else: - i = 1 - for backref in backrefs: - backlinks.append('%s' - % (backref, i)) - i += 1 - self.context.append('(%s) ' % ', '.join(backlinks)) - self.context.append('' % node['ids'][0]) - else: - self.context.append('') - self.context.append('' % node['ids'][0]) - # If the node does not only consist of a label. - if len(node) > 1: - # If there are preceding backlinks, we do not set class - # 'first', because we need to retain the top-margin. - if not backlinks: - node[1]['classes'].append('first') - node[-1]['classes'].append('last') - - def depart_footnote(self, node): - self.body.append('\n' - '\n\n') - - def visit_footnote_reference(self, node): - href = '#' + node['refid'] - format = self.settings.footnote_references - if format == 'brackets': - suffix = '[' - self.context.append(']') - else: - assert format == 'superscript' - suffix = '' - self.context.append('') - self.body.append(self.starttag(node, 'a', suffix, - CLASS='footnote-reference', href=href)) - - def depart_footnote_reference(self, node): - self.body.append(self.context.pop() + '') - - def visit_generated(self, node): - pass - - def depart_generated(self, node): - pass - - def visit_header(self, node): - self.context.append(len(self.body)) - - def depart_header(self, node): - start = self.context.pop() - header = [self.starttag(node, 'div', CLASS='header')] - header.extend(self.body[start:]) - header.append('\n
    \n
    \n') - self.body_prefix.extend(header) - self.header.extend(header) - del self.body[start:] - - def visit_hint(self, node): - self.visit_admonition(node, 'hint') - - def depart_hint(self, node): - self.depart_admonition() - - def visit_image(self, node): - atts = {} - atts['src'] = node['uri'] - if node.has_key('width'): - atts['width'] = node['width'] - if node.has_key('height'): - atts['height'] = node['height'] - if node.has_key('scale'): - if Image and not (node.has_key('width') - and node.has_key('height')): - try: - im = Image.open(str(atts['src'])) - except (IOError, # Source image can't be found or opened - UnicodeError): # PIL doesn't like Unicode paths. - pass - else: - if not atts.has_key('width'): - atts['width'] = str(im.size[0]) - if not atts.has_key('height'): - atts['height'] = str(im.size[1]) - del im - for att_name in 'width', 'height': - if atts.has_key(att_name): - match = re.match(r'([0-9.]+)(\S*)$', atts[att_name]) - assert match - atts[att_name] = '%s%s' % ( - float(match.group(1)) * (float(node['scale']) / 100), - match.group(2)) - style = [] - for att_name in 'width', 'height': - if atts.has_key(att_name): - if re.match(r'^[0-9.]+$', atts[att_name]): - # Interpret unitless values as pixels. - atts[att_name] += 'px' - style.append('%s: %s;' % (att_name, atts[att_name])) - del atts[att_name] - if style: - atts['style'] = ' '.join(style) - atts['alt'] = node.get('alt', atts['src']) - if (isinstance(node.parent, nodes.TextElement) or - (isinstance(node.parent, nodes.reference) and - not isinstance(node.parent.parent, nodes.TextElement))): - # Inline context or surrounded by .... - suffix = '' - else: - suffix = '\n' - if node.has_key('align'): - if node['align'] == 'center': - # "align" attribute is set in surrounding "div" element. - self.body.append('
    ') - self.context.append('
    \n') - suffix = '' - else: - # "align" attribute is set in "img" element. - atts['align'] = node['align'] - self.context.append('') - atts['class'] = 'align-%s' % node['align'] - else: - self.context.append('') - self.body.append(self.emptytag(node, 'img', suffix, **atts)) - - def depart_image(self, node): - self.body.append(self.context.pop()) - - def visit_important(self, node): - self.visit_admonition(node, 'important') - - def depart_important(self, node): - self.depart_admonition() - - def visit_inline(self, node): - self.body.append(self.starttag(node, 'span', '')) - - def depart_inline(self, node): - self.body.append('
    ') - - def visit_label(self, node): - self.body.append(self.starttag(node, 'td', '%s[' % self.context.pop(), - CLASS='label')) - - def depart_label(self, node): - self.body.append(']%s' % self.context.pop()) - - def visit_legend(self, node): - self.body.append(self.starttag(node, 'div', CLASS='legend')) - - def depart_legend(self, node): - self.body.append('
    \n') - - def visit_line(self, node): - self.body.append(self.starttag(node, 'div', suffix='', CLASS='line')) - if not len(node): - self.body.append('
    ') - - def depart_line(self, node): - self.body.append('
    \n') - - def visit_line_block(self, node): - self.body.append(self.starttag(node, 'div', CLASS='line-block')) - - def depart_line_block(self, node): - self.body.append('
    \n') - - def visit_list_item(self, node): - self.body.append(self.starttag(node, 'li', '')) - if len(node): - node[0]['classes'].append('first') - - def depart_list_item(self, node): - self.body.append('\n') - - def visit_literal(self, node): - """Process text to prevent tokens from wrapping.""" - self.body.append( - self.starttag(node, 'tt', '', CLASS='docutils literal')) - text = node.astext() - for token in self.words_and_spaces.findall(text): - if token.strip(): - # Protect text like "--an-option" from bad line wrapping: - self.body.append('%s' - % self.encode(token)) - elif token in ('\n', ' '): - # Allow breaks at whitespace: - self.body.append(token) - else: - # Protect runs of multiple spaces; the last space can wrap: - self.body.append(' ' * (len(token) - 1) + ' ') - self.body.append('
    ') - # Content already processed: - raise nodes.SkipNode - - def visit_literal_block(self, node): - self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) - - def depart_literal_block(self, node): - self.body.append('\n\n') - - def visit_meta(self, node): - meta = self.emptytag(node, 'meta', **node.non_default_attributes()) - self.add_meta(meta) - - def depart_meta(self, node): - pass - - def add_meta(self, tag): - self.meta.append(tag) - self.head.append(tag) - - def visit_note(self, node): - self.visit_admonition(node, 'note') - - def depart_note(self, node): - self.depart_admonition() - - def visit_option(self, node): - if self.context[-1]: - self.body.append(', ') - self.body.append(self.starttag(node, 'span', '', CLASS='option')) - - def depart_option(self, node): - self.body.append('') - self.context[-1] += 1 - - def visit_option_argument(self, node): - self.body.append(node.get('delimiter', ' ')) - self.body.append(self.starttag(node, 'var', '')) - - def depart_option_argument(self, node): - self.body.append('') - - def visit_option_group(self, node): - atts = {} - if ( self.settings.option_limit - and len(node.astext()) > self.settings.option_limit): - atts['colspan'] = 2 - self.context.append('\n ') - else: - self.context.append('') - self.body.append( - self.starttag(node, 'td', CLASS='option-group', **atts)) - self.body.append('') - self.context.append(0) # count number of options - - def depart_option_group(self, node): - self.context.pop() - self.body.append('\n') - self.body.append(self.context.pop()) - - def visit_option_list(self, node): - self.body.append( - self.starttag(node, 'table', CLASS='docutils option-list', - frame="void", rules="none")) - self.body.append('\n' - '\n' - '\n') - - def depart_option_list(self, node): - self.body.append('\n\n') - - def visit_option_list_item(self, node): - self.body.append(self.starttag(node, 'tr', '')) - - def depart_option_list_item(self, node): - self.body.append('\n') - - def visit_option_string(self, node): - pass - - def depart_option_string(self, node): - pass - - def visit_organization(self, node): - self.visit_docinfo_item(node, 'organization') - - def depart_organization(self, node): - self.depart_docinfo_item() - - def should_be_compact_paragraph(self, node): - """ - Determine if the

    tags around paragraph ``node`` can be omitted. - """ - if (isinstance(node.parent, nodes.document) or - isinstance(node.parent, nodes.compound)): - # Never compact paragraphs in document or compound. - return 0 - for key, value in node.attlist(): - if (node.is_not_default(key) and - not (key == 'classes' and value in - ([], ['first'], ['last'], ['first', 'last']))): - # Attribute which needs to survive. - return 0 - if (self.compact_simple or - self.compact_field_list or - self.compact_p and (len(node.parent) == 1 or - len(node.parent) == 2 and - isinstance(node.parent[0], nodes.label))): - return 1 - return 0 - - def visit_paragraph(self, node): - if self.should_be_compact_paragraph(node): - self.context.append('') - else: - self.body.append(self.starttag(node, 'p', '')) - self.context.append('

    \n') - - def depart_paragraph(self, node): - self.body.append(self.context.pop()) - - def visit_problematic(self, node): - if node.hasattr('refid'): - self.body.append('' % (node['refid'], - node['ids'][0])) - self.context.append('') - else: - self.context.append('') - self.body.append(self.starttag(node, 'span', '', CLASS='problematic')) - - def depart_problematic(self, node): - self.body.append('') - self.body.append(self.context.pop()) - - def visit_raw(self, node): - if 'html' in node.get('format', '').split(): - t = isinstance(node.parent, nodes.TextElement) and 'span' or 'div' - if node['classes']: - self.body.append(self.starttag(node, t, suffix='')) - self.body.append(node.astext()) - if node['classes']: - self.body.append('' % t) - # Keep non-HTML raw text out of output: - raise nodes.SkipNode - - def visit_reference(self, node): - if node.has_key('refuri'): - href = node['refuri'] - if ( self.settings.cloak_email_addresses - and href.startswith('mailto:')): - href = self.cloak_mailto(href) - self.in_mailto = 1 - else: - assert node.has_key('refid'), \ - 'References must have "refuri" or "refid" attribute.' - href = '#' + node['refid'] - atts = {'href': href, 'class': 'reference'} - if not isinstance(node.parent, nodes.TextElement): - assert len(node) == 1 and isinstance(node[0], nodes.image) - atts['class'] += ' image-reference' - self.body.append(self.starttag(node, 'a', '', **atts)) - - def depart_reference(self, node): - self.body.append('') - if not isinstance(node.parent, nodes.TextElement): - self.body.append('\n') - self.in_mailto = 0 - - def visit_revision(self, node): - self.visit_docinfo_item(node, 'revision', meta=None) - - def depart_revision(self, node): - self.depart_docinfo_item() - - def visit_row(self, node): - self.body.append(self.starttag(node, 'tr', '')) - node.column = 0 - - def depart_row(self, node): - self.body.append('\n') - - def visit_rubric(self, node): - self.body.append(self.starttag(node, 'p', '', CLASS='rubric')) - - def depart_rubric(self, node): - self.body.append('

    \n') - - def visit_section(self, node): - self.section_level += 1 - self.body.append( - self.start_tag_with_title(node, 'div', CLASS='section')) - - def depart_section(self, node): - self.section_level -= 1 - self.body.append('
    \n') - - def visit_sidebar(self, node): - self.body.append( - self.start_tag_with_title(node, 'div', CLASS='sidebar')) - self.set_first_last(node) - self.in_sidebar = 1 - - def depart_sidebar(self, node): - self.body.append('
    \n') - self.in_sidebar = None - - def visit_status(self, node): - self.visit_docinfo_item(node, 'status', meta=None) - - def depart_status(self, node): - self.depart_docinfo_item() - - def visit_strong(self, node): - self.body.append('') - - def depart_strong(self, node): - self.body.append('') - - def visit_subscript(self, node): - self.body.append(self.starttag(node, 'sub', '')) - - def depart_subscript(self, node): - self.body.append('') - - def visit_substitution_definition(self, node): - """Internal only.""" - raise nodes.SkipNode - - def visit_substitution_reference(self, node): - self.unimplemented_visit(node) - - def visit_subtitle(self, node): - if isinstance(node.parent, nodes.sidebar): - self.body.append(self.starttag(node, 'p', '', - CLASS='sidebar-subtitle')) - self.context.append('

    \n') - elif isinstance(node.parent, nodes.document): - self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) - self.context.append('\n') - self.in_document_title = len(self.body) - elif isinstance(node.parent, nodes.section): - tag = 'h%s' % (self.section_level + self.initial_header_level - 1) - self.body.append( - self.starttag(node, tag, '', CLASS='section-subtitle') + - self.starttag({}, 'span', '', CLASS='section-subtitle')) - self.context.append('\n' % tag) - - def depart_subtitle(self, node): - self.body.append(self.context.pop()) - if self.in_document_title: - self.subtitle = self.body[self.in_document_title:-1] - self.in_document_title = 0 - self.body_pre_docinfo.extend(self.body) - self.html_subtitle.extend(self.body) - del self.body[:] - - def visit_superscript(self, node): - self.body.append(self.starttag(node, 'sup', '')) - - def depart_superscript(self, node): - self.body.append('') - - def visit_system_message(self, node): - self.body.append(self.starttag(node, 'div', CLASS='system-message')) - self.body.append('

    ') - attr = {} - backref_text = '' - if node['ids']: - attr['name'] = node['ids'][0] - if len(node['backrefs']): - backrefs = node['backrefs'] - if len(backrefs) == 1: - backref_text = ('; backlink' - % backrefs[0]) - else: - i = 1 - backlinks = [] - for backref in backrefs: - backlinks.append('%s' % (backref, i)) - i += 1 - backref_text = ('; backlinks: %s' - % ', '.join(backlinks)) - if node.hasattr('line'): - line = ', line %s' % node['line'] - else: - line = '' - if attr: - a_start = self.starttag({}, 'a', '', **attr) - a_end = '' - else: - a_start = a_end = '' - self.body.append('System Message: %s%s/%s%s ' - '(%s%s)%s

    \n' - % (a_start, node['type'], node['level'], a_end, - self.encode(node['source']), line, backref_text)) - - def depart_system_message(self, node): - self.body.append('
    \n') - - def visit_table(self, node): - self.body.append( - self.starttag(node, 'table', CLASS='docutils', border="1")) - - def depart_table(self, node): - self.body.append('\n') - - def visit_target(self, node): - if not (node.has_key('refuri') or node.has_key('refid') - or node.has_key('refname')): - self.body.append(self.starttag(node, 'span', '', CLASS='target')) - self.context.append('') - else: - self.context.append('') - - def depart_target(self, node): - self.body.append(self.context.pop()) - - def visit_tbody(self, node): - self.write_colspecs() - self.body.append(self.context.pop()) # '\n' or '' - self.body.append(self.starttag(node, 'tbody', valign='top')) - - def depart_tbody(self, node): - self.body.append('\n') - - def visit_term(self, node): - self.body.append(self.starttag(node, 'dt', '')) - - def depart_term(self, node): - """ - Leave the end tag to `self.visit_definition()`, in case there's a - classifier. - """ - pass - - def visit_tgroup(self, node): - # Mozilla needs : - self.body.append(self.starttag(node, 'colgroup')) - # Appended by thead or tbody: - self.context.append('\n') - node.stubs = [] - - def depart_tgroup(self, node): - pass - - def visit_thead(self, node): - self.write_colspecs() - self.body.append(self.context.pop()) # '\n' - # There may or may not be a ; this is for to use: - self.context.append('') - self.body.append(self.starttag(node, 'thead', valign='bottom')) - - def depart_thead(self, node): - self.body.append('\n') - - def visit_tip(self, node): - self.visit_admonition(node, 'tip') - - def depart_tip(self, node): - self.depart_admonition() - - def visit_title(self, node, move_ids=1): - """Only 6 section levels are supported by HTML.""" - check_id = 0 - close_tag = '

    \n' - if isinstance(node.parent, nodes.topic): - self.body.append( - self.starttag(node, 'p', '', CLASS='topic-title first')) - check_id = 1 - elif isinstance(node.parent, nodes.sidebar): - self.body.append( - self.starttag(node, 'p', '', CLASS='sidebar-title')) - check_id = 1 - elif isinstance(node.parent, nodes.Admonition): - self.body.append( - self.starttag(node, 'p', '', CLASS='admonition-title')) - check_id = 1 - elif isinstance(node.parent, nodes.table): - self.body.append( - self.starttag(node, 'caption', '')) - check_id = 1 - close_tag = '\n' - elif isinstance(node.parent, nodes.document): - self.body.append(self.starttag(node, 'h1', '', CLASS='title')) - self.context.append('\n') - self.in_document_title = len(self.body) - else: - assert isinstance(node.parent, nodes.section) - h_level = self.section_level + self.initial_header_level - 1 - atts = {} - if (len(node.parent) >= 2 and - isinstance(node.parent[1], nodes.subtitle)): - atts['CLASS'] = 'with-subtitle' - self.body.append( - self.starttag(node, 'h%s' % h_level, '', **atts)) - atts = {} - # !!! conditional to be removed in Docutils 0.5: - if move_ids: - if node.parent['ids']: - atts['ids'] = node.parent['ids'] - if node.hasattr('refid'): - atts['class'] = 'toc-backref' - atts['href'] = '#' + node['refid'] - if atts: - self.body.append(self.starttag({}, 'a', '', **atts)) - self.context.append('\n' % (h_level)) - else: - self.context.append('\n' % (h_level)) - # !!! conditional to be removed in Docutils 0.5: - if check_id: - if node.parent['ids']: - atts={'ids': node.parent['ids']} - self.body.append( - self.starttag({}, 'a', '', **atts)) - self.context.append('' + close_tag) - else: - self.context.append(close_tag) - - def depart_title(self, node): - self.body.append(self.context.pop()) - if self.in_document_title: - self.title = self.body[self.in_document_title:-1] - self.in_document_title = 0 - self.body_pre_docinfo.extend(self.body) - self.html_title.extend(self.body) - del self.body[:] - - def visit_title_reference(self, node): - self.body.append(self.starttag(node, 'cite', '')) - - def depart_title_reference(self, node): - self.body.append('') - - def visit_topic(self, node): - self.body.append(self.start_tag_with_title(node, 'div', CLASS='topic')) - self.topic_classes = node['classes'] - - def depart_topic(self, node): - self.body.append('
    \n') - self.topic_classes = [] - - def visit_transition(self, node): - self.body.append(self.emptytag(node, 'hr', CLASS='docutils')) - - def depart_transition(self, node): - pass - - def visit_version(self, node): - self.visit_docinfo_item(node, 'version', meta=None) - - def depart_version(self, node): - self.depart_docinfo_item() - - def visit_warning(self, node): - self.visit_admonition(node, 'warning') - - def depart_warning(self, node): - self.depart_admonition() - - def unimplemented_visit(self, node): - raise NotImplementedError('visiting unimplemented node type: %s' - % node.__class__.__name__) - - -class SimpleListChecker(nodes.GenericNodeVisitor): - - """ - Raise `nodes.NodeFound` if non-simple list item is encountered. - - Here "simple" means a list item containing nothing other than a single - paragraph, a simple list, or a paragraph followed by a simple list. - """ - - def default_visit(self, node): - raise nodes.NodeFound - - def visit_bullet_list(self, node): - pass - - def visit_enumerated_list(self, node): - pass - - def visit_list_item(self, node): - children = [] - for child in node.children: - if not isinstance(child, nodes.Invisible): - children.append(child) - if (children and isinstance(children[0], nodes.paragraph) - and (isinstance(children[-1], nodes.bullet_list) - or isinstance(children[-1], nodes.enumerated_list))): - children.pop() - if len(children) <= 1: - return - else: - raise nodes.NodeFound - - def visit_paragraph(self, node): - raise nodes.SkipNode - - def invisible_visit(self, node): - """Invisible nodes should be ignored.""" - raise nodes.SkipNode - - visit_comment = invisible_visit - visit_substitution_definition = invisible_visit - visit_target = invisible_visit - visit_pending = invisible_visit diff --git a/docutils/writers/html4css1/__init__.py b/docutils/writers/html4css1/__init__.py new file mode 100644 index 000000000..9543e9016 --- /dev/null +++ b/docutils/writers/html4css1/__init__.py @@ -0,0 +1,1599 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Simple HyperText Markup Language document tree Writer. + +The output conforms to the XHTML version 1.0 Transitional DTD +(*almost* strict). The output contains a minimum of formatting +information. The cascading style sheet "html4css1.css" is required +for proper viewing with a modern graphical browser. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os +import os.path +import time +import re +from types import ListType +try: + import Image # check for the Python Imaging Library +except ImportError: + Image = None +import docutils +from docutils import frontend, nodes, utils, writers, languages + + +class Writer(writers.Writer): + + supported = ('html', 'html4css1', 'xhtml') + """Formats this writer supports.""" + + default_stylesheet = 'html4css1.css' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(os.path.dirname(__file__), default_stylesheet)) + + settings_spec = ( + 'HTML-Specific Options', + None, + (('Specify a stylesheet URL, used verbatim. Overrides ' + '--stylesheet-path.', + ['--stylesheet'], + {'metavar': '', 'overrides': 'stylesheet_path'}), + ('Specify a stylesheet file, relative to the current working ' + 'directory. The path is adjusted relative to the output HTML ' + 'file. Overrides --stylesheet. Default: "%s"' + % default_stylesheet_path, + ['--stylesheet-path'], + {'metavar': '', 'overrides': 'stylesheet', + 'default': default_stylesheet_path}), + ('Embed the stylesheet in the output HTML file. The stylesheet ' + 'file must be accessible during processing (--stylesheet-path is ' + 'recommended). This is the default.', + ['--embed-stylesheet'], + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Link to the stylesheet in the output HTML file. Default: ' + 'embed the stylesheet, do not link to it.', + ['--link-stylesheet'], + {'dest': 'embed_stylesheet', 'action': 'store_false', + 'validator': frontend.validate_boolean}), + ('Specify the initial header level. Default is 1 for "

    ". ' + 'Does not affect document title & subtitle (see --no-doc-title).', + ['--initial-header-level'], + {'choices': '1 2 3 4 5 6'.split(), 'default': '1', + 'metavar': ''}), + ('Specify the maximum width (in characters) for one-column field ' + 'names. Longer field names will span an entire row of the table ' + 'used to render the field list. Default is 14 characters. ' + 'Use 0 for "no limit".', + ['--field-name-limit'], + {'default': 14, 'metavar': '', + 'validator': frontend.validate_nonnegative_int}), + ('Specify the maximum width (in characters) for options in option ' + 'lists. Longer options will span an entire row of the table used ' + 'to render the option list. Default is 14 characters. ' + 'Use 0 for "no limit".', + ['--option-limit'], + {'default': 14, 'metavar': '', + 'validator': frontend.validate_nonnegative_int}), + ('Format for footnote references: one of "superscript" or ' + '"brackets". Default is "brackets".', + ['--footnote-references'], + {'choices': ['superscript', 'brackets'], 'default': 'brackets', + 'metavar': '', + 'overrides': 'trim_footnote_reference_space'}), + ('Format for block quote attributions: one of "dash" (em-dash ' + 'prefix), "parentheses"/"parens", or "none". Default is "dash".', + ['--attribution'], + {'choices': ['dash', 'parentheses', 'parens', 'none'], + 'default': 'dash', 'metavar': ''}), + ('Remove extra vertical whitespace between items of bullet lists ' + 'and enumerated lists, when list items are "simple" (i.e., all ' + 'items each contain one paragraph and/or one "simple" sublist ' + 'only). Default: enabled. Can be specified directly via "class" ' + 'attributes (values "compact" and "open") in the document.', + ['--compact-lists'], + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compact simple bullet and enumerated lists (except where ' + 'specified directly via "class" attributes; see --compact-lists).', + ['--no-compact-lists'], + {'dest': 'compact_lists', 'action': 'store_false'}), + ('Remove extra vertical whitespace between items of simple field ' + 'lists. Default: enabled. Can be specified directly via "class" ' + 'attributes (values "compact" and "open") in the document.', + ['--compact-field-lists'], + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compact simple field lists (except where specified ' + 'directly via "class" attributes; see --compact-field-lists).', + ['--no-compact-field-lists'], + {'dest': 'compact_field_lists', 'action': 'store_false'}), + ('Omit the XML declaration. Use with caution.', + ['--no-xml-declaration'], + {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', + 'validator': frontend.validate_boolean}), + ('Obfuscate email addresses to confuse harvesters while still ' + 'keeping email links usable with standards-compliant browsers.', + ['--cloak-email-addresses'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + + settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} + + relative_path_settings = ('stylesheet_path',) + + config_section = 'html4css1 writer' + config_section_dependencies = ('writers',) + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = HTMLTranslator + + def translate(self): + self.visitor = visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix', + 'body_pre_docinfo', 'docinfo', 'body', 'fragment', + 'body_suffix'): + setattr(self, attr, getattr(visitor, attr)) + + def assemble_parts(self): + writers.Writer.assemble_parts(self) + for part in ('title', 'subtitle', 'docinfo', 'body', 'header', + 'footer', 'meta', 'stylesheet', 'fragment', + 'html_prolog', 'html_head', 'html_title', 'html_subtitle', + 'html_body'): + self.parts[part] = ''.join(getattr(self.visitor, part)) + + +class HTMLTranslator(nodes.NodeVisitor): + + """ + This HTML writer has been optimized to produce visually compact + lists (less vertical whitespace). HTML's mixed content models + allow list items to contain "
  • body elements

  • " or + "
  • just text
  • " or even "
  • text

    and body + elements

    combined
  • ", each with different effects. It would + be best to stick with strict body elements in list items, but they + affect vertical spacing in browsers (although they really + shouldn't). + + Here is an outline of the optimization: + + - Check for and omit

    tags in "simple" lists: list items + contain either a single paragraph, a nested simple list, or a + paragraph followed by a nested simple list. This means that + this list can be compact: + + - Item 1. + - Item 2. + + But this list cannot be compact: + + - Item 1. + + This second paragraph forces space between list items. + + - Item 2. + + - In non-list contexts, omit

    tags on a paragraph if that + paragraph is the only child of its parent (footnotes & citations + are allowed a label first). + + - Regardless of the above, in definitions, table cells, field bodies, + option descriptions, and list items, mark the first child with + 'class="first"' and the last child with 'class="last"'. The stylesheet + sets the margins (top & bottom respectively) to 0 for these elements. + + The ``no_compact_lists`` setting (``--no-compact-lists`` command-line + option) disables list whitespace optimization. + """ + + xml_declaration = '\n' + doctype = ('\n') + head_prefix_template = ('\n\n') + content_type = ('\n') + generator = ('\n') + stylesheet_link = '\n' + embedded_stylesheet = '\n' + named_tags = ['a', 'applet', 'form', 'frame', 'iframe', 'img', 'map'] + words_and_spaces = re.compile(r'\S+| +|\n') + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = settings = document.settings + lcode = settings.language_code + self.language = languages.get_language(lcode) + self.meta = [self.content_type % settings.output_encoding, + self.generator % docutils.__version__] + self.head_prefix = [] + self.html_prolog = [] + if settings.xml_declaration: + self.head_prefix.append(self.xml_declaration + % settings.output_encoding) + # encoding not interpolated: + self.html_prolog.append(self.xml_declaration) + self.head_prefix.extend([self.doctype, + self.head_prefix_template % (lcode, lcode)]) + self.html_prolog.append(self.doctype) + self.head = self.meta[:] + stylesheet = utils.get_stylesheet_reference(settings) + self.stylesheet = [] + if stylesheet: + if settings.embed_stylesheet: + stylesheet = utils.get_stylesheet_reference( + settings, os.path.join(os.getcwd(), 'dummy')) + settings.record_dependencies.add(stylesheet) + stylesheet_text = open(stylesheet).read() + self.stylesheet = [self.embedded_stylesheet % stylesheet_text] + else: + self.stylesheet = [self.stylesheet_link + % self.encode(stylesheet)] + self.body_prefix = ['\n\n'] + # document title, subtitle display + self.body_pre_docinfo = [] + # author, date, etc. + self.docinfo = [] + self.body = [] + self.fragment = [] + self.body_suffix = ['\n\n'] + self.section_level = 0 + self.initial_header_level = int(settings.initial_header_level) + # A heterogenous stack used in conjunction with the tree traversal. + # Make sure that the pops correspond to the pushes: + self.context = [] + self.topic_classes = [] + self.colspecs = [] + self.compact_p = 1 + self.compact_simple = None + self.compact_field_list = None + self.in_docinfo = None + self.in_sidebar = None + self.title = [] + self.subtitle = [] + self.header = [] + self.footer = [] + self.html_head = [self.content_type] # charset not interpolated + self.html_title = [] + self.html_subtitle = [] + self.html_body = [] + self.in_document_title = 0 + self.in_mailto = 0 + self.author_in_authors = None + + def astext(self): + return ''.join(self.head_prefix + self.head + + self.stylesheet + self.body_prefix + + self.body_pre_docinfo + self.docinfo + + self.body + self.body_suffix) + + def encode(self, text): + """Encode special characters in `text` & return.""" + # @@@ A codec to do these and all other HTML entities would be nice. + text = text.replace("&", "&") + text = text.replace("<", "<") + text = text.replace('"', """) + text = text.replace(">", ">") + text = text.replace("@", "@") # may thwart some address harvesters + # Replace the non-breaking space character with the HTML entity: + text = text.replace(u'\u00a0', " ") + return text + + def cloak_mailto(self, uri): + """Try to hide a mailto: URL from harvesters.""" + # Encode "@" using a URL octet reference (see RFC 1738). + # Further cloaking with HTML entities will be done in the + # `attval` function. + return uri.replace('@', '%40') + + def cloak_email(self, addr): + """Try to hide the link text of a email link from harversters.""" + # Surround at-signs and periods with tags. ("@" has + # already been encoded to "@" by the `encode` method.) + addr = addr.replace('@', '@') + addr = addr.replace('.', '.') + return addr + + def attval(self, text, + whitespace=re.compile('[\n\r\t\v\f]')): + """Cleanse, HTML encode, and return attribute value text.""" + encoded = self.encode(whitespace.sub(' ', text)) + if self.in_mailto and self.settings.cloak_email_addresses: + # Cloak at-signs ("%40") and periods with HTML entities. + encoded = encoded.replace('%40', '%40') + encoded = encoded.replace('.', '.') + return encoded + + def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): + """ + Construct and return a start tag given a node (id & class attributes + are extracted), tag name, and optional attributes. + """ + tagname = tagname.lower() + prefix = [] + atts = {} + ids = [] + for (name, value) in attributes.items(): + atts[name.lower()] = value + classes = node.get('classes', []) + if atts.has_key('class'): + classes.append(atts['class']) + if classes: + atts['class'] = ' '.join(classes) + assert not atts.has_key('id') + ids.extend(node.get('ids', [])) + if atts.has_key('ids'): + ids.extend(atts['ids']) + del atts['ids'] + if ids: + atts['id'] = ids[0] + for id in ids[1:]: + # Add empty "span" elements for additional IDs. Note + # that we cannot use empty "a" elements because there + # may be targets inside of references, but nested "a" + # elements aren't allowed in XHTML (even if they do + # not all have a "href" attribute). + if empty: + # Empty tag. Insert target right in front of element. + prefix.append('' % id) + else: + # Non-empty tag. Place the auxiliary tag + # *inside* the element, as the first child. + suffix += '' % id + # !!! next 2 lines to be removed in Docutils 0.5: + if atts.has_key('id') and tagname in self.named_tags: + atts['name'] = atts['id'] # for compatibility with old browsers + attlist = atts.items() + attlist.sort() + parts = [tagname] + for name, value in attlist: + # value=None was used for boolean attributes without + # value, but this isn't supported by XHTML. + assert value is not None + if isinstance(value, ListType): + values = [unicode(v) for v in value] + parts.append('%s="%s"' % (name.lower(), + self.attval(' '.join(values)))) + else: + try: + uval = unicode(value) + except TypeError: # for Python 2.1 compatibility: + uval = unicode(str(value)) + parts.append('%s="%s"' % (name.lower(), self.attval(uval))) + if empty: + infix = ' /' + else: + infix = '' + return ''.join(prefix) + '<%s%s>' % (' '.join(parts), infix) + suffix + + def emptytag(self, node, tagname, suffix='\n', **attributes): + """Construct and return an XML-compatible empty tag.""" + return self.starttag(node, tagname, suffix, empty=1, **attributes) + + # !!! to be removed in Docutils 0.5 (change calls to use "starttag"): + def start_tag_with_title(self, node, tagname, **atts): + """ID and NAME attributes will be handled in the title.""" + node = {'classes': node.get('classes', [])} + return self.starttag(node, tagname, **atts) + + def set_class_on_child(self, node, class_, index=0): + """ + Set class `class_` on the visible child no. index of `node`. + Do nothing if node has fewer children than `index`. + """ + children = [n for n in node if not isinstance(n, nodes.Invisible)] + try: + child = children[index] + except IndexError: + return + child['classes'].append(class_) + + def set_first_last(self, node): + self.set_class_on_child(node, 'first', 0) + self.set_class_on_child(node, 'last', -1) + + def visit_Text(self, node): + text = node.astext() + encoded = self.encode(text) + if self.in_mailto and self.settings.cloak_email_addresses: + encoded = self.cloak_email(encoded) + self.body.append(encoded) + + def depart_Text(self, node): + pass + + def visit_abbreviation(self, node): + # @@@ implementation incomplete ("title" attribute) + self.body.append(self.starttag(node, 'abbr', '')) + + def depart_abbreviation(self, node): + self.body.append('') + + def visit_acronym(self, node): + # @@@ implementation incomplete ("title" attribute) + self.body.append(self.starttag(node, 'acronym', '')) + + def depart_acronym(self, node): + self.body.append('') + + def visit_address(self, node): + self.visit_docinfo_item(node, 'address', meta=None) + self.body.append(self.starttag(node, 'pre', CLASS='address')) + + def depart_address(self, node): + self.body.append('\n\n') + self.depart_docinfo_item() + + def visit_admonition(self, node, name=''): + self.body.append(self.start_tag_with_title( + node, 'div', CLASS=(name or 'admonition'))) + if name: + node.insert(0, nodes.title(name, self.language.labels[name])) + self.set_first_last(node) + + def depart_admonition(self, node=None): + self.body.append('

    \n') + + def visit_attention(self, node): + self.visit_admonition(node, 'attention') + + def depart_attention(self, node): + self.depart_admonition() + + attribution_formats = {'dash': ('—', ''), + 'parentheses': ('(', ')'), + 'parens': ('(', ')'), + 'none': ('', '')} + + def visit_attribution(self, node): + prefix, suffix = self.attribution_formats[self.settings.attribution] + self.context.append(suffix) + self.body.append( + self.starttag(node, 'p', prefix, CLASS='attribution')) + + def depart_attribution(self, node): + self.body.append(self.context.pop() + '

    \n') + + def visit_author(self, node): + if isinstance(node.parent, nodes.authors): + if self.author_in_authors: + self.body.append('\n
    ') + else: + self.visit_docinfo_item(node, 'author') + + def depart_author(self, node): + if isinstance(node.parent, nodes.authors): + self.author_in_authors += 1 + else: + self.depart_docinfo_item() + + def visit_authors(self, node): + self.visit_docinfo_item(node, 'authors') + self.author_in_authors = 0 + + def depart_authors(self, node): + self.depart_docinfo_item() + self.author_in_authors = None + + def visit_block_quote(self, node): + self.body.append(self.starttag(node, 'blockquote')) + + def depart_block_quote(self, node): + self.body.append('\n') + + def check_simple_list(self, node): + """Check for a simple list that can be rendered compactly.""" + visitor = SimpleListChecker(self.document) + try: + node.walk(visitor) + except nodes.NodeFound: + return None + else: + return 1 + + def visit_bullet_list(self, node): + atts = {} + old_compact_simple = self.compact_simple + self.context.append((self.compact_simple, self.compact_p)) + self.compact_p = None + self.compact_simple = ('compact' in node['classes'] + or (self.settings.compact_lists + and 'open' not in node['classes'] + and (self.compact_simple + or self.topic_classes == ['contents'] + or self.check_simple_list(node)))) + if self.compact_simple and not old_compact_simple: + atts['class'] = 'simple' + self.body.append(self.starttag(node, 'ul', **atts)) + + def depart_bullet_list(self, node): + self.compact_simple, self.compact_p = self.context.pop() + self.body.append('\n') + + def visit_caption(self, node): + self.body.append(self.starttag(node, 'p', '', CLASS='caption')) + + def depart_caption(self, node): + self.body.append('

    \n') + + def visit_caution(self, node): + self.visit_admonition(node, 'caution') + + def depart_caution(self, node): + self.depart_admonition() + + def visit_citation(self, node): + self.body.append(self.starttag(node, 'table', + CLASS='docutils citation', + frame="void", rules="none")) + self.body.append('\n' + '\n' + '') + self.footnote_backrefs(node) + + def depart_citation(self, node): + self.body.append('\n' + '\n\n') + + def visit_citation_reference(self, node): + href = '#' + node['refid'] + self.body.append(self.starttag( + node, 'a', '[', CLASS='citation-reference', href=href)) + + def depart_citation_reference(self, node): + self.body.append(']') + + def visit_classifier(self, node): + self.body.append(' : ') + self.body.append(self.starttag(node, 'span', '', CLASS='classifier')) + + def depart_classifier(self, node): + self.body.append('') + + def visit_colspec(self, node): + self.colspecs.append(node) + # "stubs" list is an attribute of the tgroup element: + node.parent.stubs.append(node.attributes.get('stub')) + + def depart_colspec(self, node): + pass + + def write_colspecs(self): + width = 0 + for node in self.colspecs: + width += node['colwidth'] + for node in self.colspecs: + colwidth = int(node['colwidth'] * 100.0 / width + 0.5) + self.body.append(self.emptytag(node, 'col', + width='%i%%' % colwidth)) + self.colspecs = [] + + def visit_comment(self, node, + sub=re.compile('-(?=-)').sub): + """Escape double-dashes in comment text.""" + self.body.append('\n' % sub('- ', node.astext())) + # Content already processed: + raise nodes.SkipNode + + def visit_compound(self, node): + self.body.append(self.starttag(node, 'div', CLASS='compound')) + if len(node) > 1: + node[0]['classes'].append('compound-first') + node[-1]['classes'].append('compound-last') + for child in node[1:-1]: + child['classes'].append('compound-middle') + + def depart_compound(self, node): + self.body.append('\n') + + def visit_container(self, node): + self.body.append(self.starttag(node, 'div', CLASS='container')) + + def depart_container(self, node): + self.body.append('\n') + + def visit_contact(self, node): + self.visit_docinfo_item(node, 'contact', meta=None) + + def depart_contact(self, node): + self.depart_docinfo_item() + + def visit_copyright(self, node): + self.visit_docinfo_item(node, 'copyright') + + def depart_copyright(self, node): + self.depart_docinfo_item() + + def visit_danger(self, node): + self.visit_admonition(node, 'danger') + + def depart_danger(self, node): + self.depart_admonition() + + def visit_date(self, node): + self.visit_docinfo_item(node, 'date') + + def depart_date(self, node): + self.depart_docinfo_item() + + def visit_decoration(self, node): + pass + + def depart_decoration(self, node): + pass + + def visit_definition(self, node): + self.body.append('\n') + self.body.append(self.starttag(node, 'dd', '')) + self.set_first_last(node) + + def depart_definition(self, node): + self.body.append('\n') + + def visit_definition_list(self, node): + self.body.append(self.starttag(node, 'dl', CLASS='docutils')) + + def depart_definition_list(self, node): + self.body.append('\n') + + def visit_definition_list_item(self, node): + pass + + def depart_definition_list_item(self, node): + pass + + def visit_description(self, node): + self.body.append(self.starttag(node, 'td', '')) + self.set_first_last(node) + + def depart_description(self, node): + self.body.append('') + + def visit_docinfo(self, node): + self.context.append(len(self.body)) + self.body.append(self.starttag(node, 'table', + CLASS='docinfo', + frame="void", rules="none")) + self.body.append('\n' + '\n' + '\n') + self.in_docinfo = 1 + + def depart_docinfo(self, node): + self.body.append('\n\n') + self.in_docinfo = None + start = self.context.pop() + self.docinfo = self.body[start:] + self.body = [] + + def visit_docinfo_item(self, node, name, meta=1): + if meta: + meta_tag = '\n' \ + % (name, self.attval(node.astext())) + self.add_meta(meta_tag) + self.body.append(self.starttag(node, 'tr', '')) + self.body.append('%s:\n' + % self.language.labels[name]) + if len(node): + if isinstance(node[0], nodes.Element): + node[0]['classes'].append('first') + if isinstance(node[-1], nodes.Element): + node[-1]['classes'].append('last') + + def depart_docinfo_item(self): + self.body.append('\n') + + def visit_doctest_block(self, node): + self.body.append(self.starttag(node, 'pre', CLASS='doctest-block')) + + def depart_doctest_block(self, node): + self.body.append('\n\n') + + def visit_document(self, node): + self.head.append('%s\n' + % self.encode(node.get('title', ''))) + + def depart_document(self, node): + self.fragment.extend(self.body) + self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) + self.body_suffix.insert(0, '\n') + # skip content-type meta tag with interpolated charset value: + self.html_head.extend(self.head[1:]) + self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + + self.docinfo + self.body + + self.body_suffix[:-1]) + + def visit_emphasis(self, node): + self.body.append('') + + def depart_emphasis(self, node): + self.body.append('') + + def visit_entry(self, node): + atts = {'class': []} + if isinstance(node.parent.parent, nodes.thead): + atts['class'].append('head') + if node.parent.parent.parent.stubs[node.parent.column]: + # "stubs" list is an attribute of the tgroup element + atts['class'].append('stub') + if atts['class']: + tagname = 'th' + atts['class'] = ' '.join(atts['class']) + else: + tagname = 'td' + del atts['class'] + node.parent.column += 1 + if node.has_key('morerows'): + atts['rowspan'] = node['morerows'] + 1 + if node.has_key('morecols'): + atts['colspan'] = node['morecols'] + 1 + node.parent.column += node['morecols'] + self.body.append(self.starttag(node, tagname, '', **atts)) + self.context.append('\n' % tagname.lower()) + if len(node) == 0: # empty cell + self.body.append(' ') + self.set_first_last(node) + + def depart_entry(self, node): + self.body.append(self.context.pop()) + + def visit_enumerated_list(self, node): + """ + The 'start' attribute does not conform to HTML 4.01's strict.dtd, but + CSS1 doesn't help. CSS2 isn't widely enough supported yet to be + usable. + """ + atts = {} + if node.has_key('start'): + atts['start'] = node['start'] + if node.has_key('enumtype'): + atts['class'] = node['enumtype'] + # @@@ To do: prefix, suffix. How? Change prefix/suffix to a + # single "format" attribute? Use CSS2? + old_compact_simple = self.compact_simple + self.context.append((self.compact_simple, self.compact_p)) + self.compact_p = None + self.compact_simple = ('compact' in node['classes'] + or (self.settings.compact_lists + and 'open' not in node['classes'] + and (self.compact_simple + or self.topic_classes == ['contents'] + or self.check_simple_list(node)))) + if self.compact_simple and not old_compact_simple: + atts['class'] = (atts.get('class', '') + ' simple').strip() + self.body.append(self.starttag(node, 'ol', **atts)) + + def depart_enumerated_list(self, node): + self.compact_simple, self.compact_p = self.context.pop() + self.body.append('\n') + + def visit_error(self, node): + self.visit_admonition(node, 'error') + + def depart_error(self, node): + self.depart_admonition() + + def visit_field(self, node): + self.body.append(self.starttag(node, 'tr', '', CLASS='field')) + + def depart_field(self, node): + self.body.append('\n') + + def visit_field_body(self, node): + self.body.append(self.starttag(node, 'td', '', CLASS='field-body')) + self.set_class_on_child(node, 'first', 0) + field = node.parent + if (self.compact_field_list or + isinstance(field.parent, nodes.docinfo) or + field.parent.index(field) == len(field.parent) - 1): + # If we are in a compact list, the docinfo, or if this is + # the last field of the field list, do not add vertical + # space after last element. + self.set_class_on_child(node, 'last', -1) + + def depart_field_body(self, node): + self.body.append('\n') + + def visit_field_list(self, node): + self.context.append((self.compact_field_list, self.compact_p)) + self.compact_p = None + if 'compact' in node['classes']: + self.compact_field_list = 1 + elif (self.settings.compact_field_lists + and 'open' not in node['classes']): + self.compact_field_list = 1 + for field in node: + field_body = field[-1] + assert isinstance(field_body, nodes.field_body) + children = [n for n in field_body + if not isinstance(n, nodes.Invisible)] + if not (len(children) == 0 or + len(children) == 1 and + isinstance(children[0], nodes.paragraph)): + self.compact_field_list = 0 + break + self.body.append(self.starttag(node, 'table', frame='void', + rules='none', + CLASS='docutils field-list')) + self.body.append('\n' + '\n' + '\n') + + def depart_field_list(self, node): + self.body.append('\n\n') + self.compact_field_list, self.compact_p = self.context.pop() + + def visit_field_name(self, node): + atts = {} + if self.in_docinfo: + atts['class'] = 'docinfo-name' + else: + atts['class'] = 'field-name' + if ( self.settings.field_name_limit + and len(node.astext()) > self.settings.field_name_limit): + atts['colspan'] = 2 + self.context.append('\n ') + else: + self.context.append('') + self.body.append(self.starttag(node, 'th', '', **atts)) + + def depart_field_name(self, node): + self.body.append(':') + self.body.append(self.context.pop()) + + def visit_figure(self, node): + atts = {'class': 'figure'} + if node.get('width'): + atts['style'] = 'width: %spx' % node['width'] + if node.get('align'): + atts['align'] = node['align'] + self.body.append(self.starttag(node, 'div', **atts)) + + def depart_figure(self, node): + self.body.append('\n') + + def visit_footer(self, node): + self.context.append(len(self.body)) + + def depart_footer(self, node): + start = self.context.pop() + footer = [self.starttag(node, 'div', CLASS='footer'), + '\n'] + footer.extend(self.body[start:]) + footer.append('\n\n') + self.footer.extend(footer) + self.body_suffix[:0] = footer + del self.body[start:] + + def visit_footnote(self, node): + self.body.append(self.starttag(node, 'table', + CLASS='docutils footnote', + frame="void", rules="none")) + self.body.append('\n' + '\n' + '') + self.footnote_backrefs(node) + + def footnote_backrefs(self, node): + backlinks = [] + backrefs = node['backrefs'] + if self.settings.footnote_backlinks and backrefs: + if len(backrefs) == 1: + self.context.append('') + self.context.append( + '' + % (backrefs[0], node['ids'][0])) + else: + i = 1 + for backref in backrefs: + backlinks.append('%s' + % (backref, i)) + i += 1 + self.context.append('(%s) ' % ', '.join(backlinks)) + self.context.append('' % node['ids'][0]) + else: + self.context.append('') + self.context.append('' % node['ids'][0]) + # If the node does not only consist of a label. + if len(node) > 1: + # If there are preceding backlinks, we do not set class + # 'first', because we need to retain the top-margin. + if not backlinks: + node[1]['classes'].append('first') + node[-1]['classes'].append('last') + + def depart_footnote(self, node): + self.body.append('\n' + '\n\n') + + def visit_footnote_reference(self, node): + href = '#' + node['refid'] + format = self.settings.footnote_references + if format == 'brackets': + suffix = '[' + self.context.append(']') + else: + assert format == 'superscript' + suffix = '' + self.context.append('') + self.body.append(self.starttag(node, 'a', suffix, + CLASS='footnote-reference', href=href)) + + def depart_footnote_reference(self, node): + self.body.append(self.context.pop() + '') + + def visit_generated(self, node): + pass + + def depart_generated(self, node): + pass + + def visit_header(self, node): + self.context.append(len(self.body)) + + def depart_header(self, node): + start = self.context.pop() + header = [self.starttag(node, 'div', CLASS='header')] + header.extend(self.body[start:]) + header.append('\n
    \n\n') + self.body_prefix.extend(header) + self.header.extend(header) + del self.body[start:] + + def visit_hint(self, node): + self.visit_admonition(node, 'hint') + + def depart_hint(self, node): + self.depart_admonition() + + def visit_image(self, node): + atts = {} + atts['src'] = node['uri'] + if node.has_key('width'): + atts['width'] = node['width'] + if node.has_key('height'): + atts['height'] = node['height'] + if node.has_key('scale'): + if Image and not (node.has_key('width') + and node.has_key('height')): + try: + im = Image.open(str(atts['src'])) + except (IOError, # Source image can't be found or opened + UnicodeError): # PIL doesn't like Unicode paths. + pass + else: + if not atts.has_key('width'): + atts['width'] = str(im.size[0]) + if not atts.has_key('height'): + atts['height'] = str(im.size[1]) + del im + for att_name in 'width', 'height': + if atts.has_key(att_name): + match = re.match(r'([0-9.]+)(\S*)$', atts[att_name]) + assert match + atts[att_name] = '%s%s' % ( + float(match.group(1)) * (float(node['scale']) / 100), + match.group(2)) + style = [] + for att_name in 'width', 'height': + if atts.has_key(att_name): + if re.match(r'^[0-9.]+$', atts[att_name]): + # Interpret unitless values as pixels. + atts[att_name] += 'px' + style.append('%s: %s;' % (att_name, atts[att_name])) + del atts[att_name] + if style: + atts['style'] = ' '.join(style) + atts['alt'] = node.get('alt', atts['src']) + if (isinstance(node.parent, nodes.TextElement) or + (isinstance(node.parent, nodes.reference) and + not isinstance(node.parent.parent, nodes.TextElement))): + # Inline context or surrounded by .... + suffix = '' + else: + suffix = '\n' + if node.has_key('align'): + if node['align'] == 'center': + # "align" attribute is set in surrounding "div" element. + self.body.append('
    ') + self.context.append('
    \n') + suffix = '' + else: + # "align" attribute is set in "img" element. + atts['align'] = node['align'] + self.context.append('') + atts['class'] = 'align-%s' % node['align'] + else: + self.context.append('') + self.body.append(self.emptytag(node, 'img', suffix, **atts)) + + def depart_image(self, node): + self.body.append(self.context.pop()) + + def visit_important(self, node): + self.visit_admonition(node, 'important') + + def depart_important(self, node): + self.depart_admonition() + + def visit_inline(self, node): + self.body.append(self.starttag(node, 'span', '')) + + def depart_inline(self, node): + self.body.append('') + + def visit_label(self, node): + self.body.append(self.starttag(node, 'td', '%s[' % self.context.pop(), + CLASS='label')) + + def depart_label(self, node): + self.body.append(']%s' % self.context.pop()) + + def visit_legend(self, node): + self.body.append(self.starttag(node, 'div', CLASS='legend')) + + def depart_legend(self, node): + self.body.append('\n') + + def visit_line(self, node): + self.body.append(self.starttag(node, 'div', suffix='', CLASS='line')) + if not len(node): + self.body.append('
    ') + + def depart_line(self, node): + self.body.append('\n') + + def visit_line_block(self, node): + self.body.append(self.starttag(node, 'div', CLASS='line-block')) + + def depart_line_block(self, node): + self.body.append('\n') + + def visit_list_item(self, node): + self.body.append(self.starttag(node, 'li', '')) + if len(node): + node[0]['classes'].append('first') + + def depart_list_item(self, node): + self.body.append('\n') + + def visit_literal(self, node): + """Process text to prevent tokens from wrapping.""" + self.body.append( + self.starttag(node, 'tt', '', CLASS='docutils literal')) + text = node.astext() + for token in self.words_and_spaces.findall(text): + if token.strip(): + # Protect text like "--an-option" from bad line wrapping: + self.body.append('%s' + % self.encode(token)) + elif token in ('\n', ' '): + # Allow breaks at whitespace: + self.body.append(token) + else: + # Protect runs of multiple spaces; the last space can wrap: + self.body.append(' ' * (len(token) - 1) + ' ') + self.body.append('
    ') + # Content already processed: + raise nodes.SkipNode + + def visit_literal_block(self, node): + self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) + + def depart_literal_block(self, node): + self.body.append('\n\n') + + def visit_meta(self, node): + meta = self.emptytag(node, 'meta', **node.non_default_attributes()) + self.add_meta(meta) + + def depart_meta(self, node): + pass + + def add_meta(self, tag): + self.meta.append(tag) + self.head.append(tag) + + def visit_note(self, node): + self.visit_admonition(node, 'note') + + def depart_note(self, node): + self.depart_admonition() + + def visit_option(self, node): + if self.context[-1]: + self.body.append(', ') + self.body.append(self.starttag(node, 'span', '', CLASS='option')) + + def depart_option(self, node): + self.body.append('') + self.context[-1] += 1 + + def visit_option_argument(self, node): + self.body.append(node.get('delimiter', ' ')) + self.body.append(self.starttag(node, 'var', '')) + + def depart_option_argument(self, node): + self.body.append('') + + def visit_option_group(self, node): + atts = {} + if ( self.settings.option_limit + and len(node.astext()) > self.settings.option_limit): + atts['colspan'] = 2 + self.context.append('\n ') + else: + self.context.append('') + self.body.append( + self.starttag(node, 'td', CLASS='option-group', **atts)) + self.body.append('') + self.context.append(0) # count number of options + + def depart_option_group(self, node): + self.context.pop() + self.body.append('\n') + self.body.append(self.context.pop()) + + def visit_option_list(self, node): + self.body.append( + self.starttag(node, 'table', CLASS='docutils option-list', + frame="void", rules="none")) + self.body.append('\n' + '\n' + '\n') + + def depart_option_list(self, node): + self.body.append('\n\n') + + def visit_option_list_item(self, node): + self.body.append(self.starttag(node, 'tr', '')) + + def depart_option_list_item(self, node): + self.body.append('\n') + + def visit_option_string(self, node): + pass + + def depart_option_string(self, node): + pass + + def visit_organization(self, node): + self.visit_docinfo_item(node, 'organization') + + def depart_organization(self, node): + self.depart_docinfo_item() + + def should_be_compact_paragraph(self, node): + """ + Determine if the

    tags around paragraph ``node`` can be omitted. + """ + if (isinstance(node.parent, nodes.document) or + isinstance(node.parent, nodes.compound)): + # Never compact paragraphs in document or compound. + return 0 + for key, value in node.attlist(): + if (node.is_not_default(key) and + not (key == 'classes' and value in + ([], ['first'], ['last'], ['first', 'last']))): + # Attribute which needs to survive. + return 0 + if (self.compact_simple or + self.compact_field_list or + self.compact_p and (len(node.parent) == 1 or + len(node.parent) == 2 and + isinstance(node.parent[0], nodes.label))): + return 1 + return 0 + + def visit_paragraph(self, node): + if self.should_be_compact_paragraph(node): + self.context.append('') + else: + self.body.append(self.starttag(node, 'p', '')) + self.context.append('

    \n') + + def depart_paragraph(self, node): + self.body.append(self.context.pop()) + + def visit_problematic(self, node): + if node.hasattr('refid'): + self.body.append('' % (node['refid'], + node['ids'][0])) + self.context.append('') + else: + self.context.append('') + self.body.append(self.starttag(node, 'span', '', CLASS='problematic')) + + def depart_problematic(self, node): + self.body.append('') + self.body.append(self.context.pop()) + + def visit_raw(self, node): + if 'html' in node.get('format', '').split(): + t = isinstance(node.parent, nodes.TextElement) and 'span' or 'div' + if node['classes']: + self.body.append(self.starttag(node, t, suffix='')) + self.body.append(node.astext()) + if node['classes']: + self.body.append('' % t) + # Keep non-HTML raw text out of output: + raise nodes.SkipNode + + def visit_reference(self, node): + if node.has_key('refuri'): + href = node['refuri'] + if ( self.settings.cloak_email_addresses + and href.startswith('mailto:')): + href = self.cloak_mailto(href) + self.in_mailto = 1 + else: + assert node.has_key('refid'), \ + 'References must have "refuri" or "refid" attribute.' + href = '#' + node['refid'] + atts = {'href': href, 'class': 'reference'} + if not isinstance(node.parent, nodes.TextElement): + assert len(node) == 1 and isinstance(node[0], nodes.image) + atts['class'] += ' image-reference' + self.body.append(self.starttag(node, 'a', '', **atts)) + + def depart_reference(self, node): + self.body.append('') + if not isinstance(node.parent, nodes.TextElement): + self.body.append('\n') + self.in_mailto = 0 + + def visit_revision(self, node): + self.visit_docinfo_item(node, 'revision', meta=None) + + def depart_revision(self, node): + self.depart_docinfo_item() + + def visit_row(self, node): + self.body.append(self.starttag(node, 'tr', '')) + node.column = 0 + + def depart_row(self, node): + self.body.append('\n') + + def visit_rubric(self, node): + self.body.append(self.starttag(node, 'p', '', CLASS='rubric')) + + def depart_rubric(self, node): + self.body.append('

    \n') + + def visit_section(self, node): + self.section_level += 1 + self.body.append( + self.start_tag_with_title(node, 'div', CLASS='section')) + + def depart_section(self, node): + self.section_level -= 1 + self.body.append('\n') + + def visit_sidebar(self, node): + self.body.append( + self.start_tag_with_title(node, 'div', CLASS='sidebar')) + self.set_first_last(node) + self.in_sidebar = 1 + + def depart_sidebar(self, node): + self.body.append('\n') + self.in_sidebar = None + + def visit_status(self, node): + self.visit_docinfo_item(node, 'status', meta=None) + + def depart_status(self, node): + self.depart_docinfo_item() + + def visit_strong(self, node): + self.body.append('') + + def depart_strong(self, node): + self.body.append('') + + def visit_subscript(self, node): + self.body.append(self.starttag(node, 'sub', '')) + + def depart_subscript(self, node): + self.body.append('') + + def visit_substitution_definition(self, node): + """Internal only.""" + raise nodes.SkipNode + + def visit_substitution_reference(self, node): + self.unimplemented_visit(node) + + def visit_subtitle(self, node): + if isinstance(node.parent, nodes.sidebar): + self.body.append(self.starttag(node, 'p', '', + CLASS='sidebar-subtitle')) + self.context.append('

    \n') + elif isinstance(node.parent, nodes.document): + self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) + self.context.append('\n') + self.in_document_title = len(self.body) + elif isinstance(node.parent, nodes.section): + tag = 'h%s' % (self.section_level + self.initial_header_level - 1) + self.body.append( + self.starttag(node, tag, '', CLASS='section-subtitle') + + self.starttag({}, 'span', '', CLASS='section-subtitle')) + self.context.append('\n' % tag) + + def depart_subtitle(self, node): + self.body.append(self.context.pop()) + if self.in_document_title: + self.subtitle = self.body[self.in_document_title:-1] + self.in_document_title = 0 + self.body_pre_docinfo.extend(self.body) + self.html_subtitle.extend(self.body) + del self.body[:] + + def visit_superscript(self, node): + self.body.append(self.starttag(node, 'sup', '')) + + def depart_superscript(self, node): + self.body.append('') + + def visit_system_message(self, node): + self.body.append(self.starttag(node, 'div', CLASS='system-message')) + self.body.append('

    ') + attr = {} + backref_text = '' + if node['ids']: + attr['name'] = node['ids'][0] + if len(node['backrefs']): + backrefs = node['backrefs'] + if len(backrefs) == 1: + backref_text = ('; backlink' + % backrefs[0]) + else: + i = 1 + backlinks = [] + for backref in backrefs: + backlinks.append('%s' % (backref, i)) + i += 1 + backref_text = ('; backlinks: %s' + % ', '.join(backlinks)) + if node.hasattr('line'): + line = ', line %s' % node['line'] + else: + line = '' + if attr: + a_start = self.starttag({}, 'a', '', **attr) + a_end = '' + else: + a_start = a_end = '' + self.body.append('System Message: %s%s/%s%s ' + '(%s%s)%s

    \n' + % (a_start, node['type'], node['level'], a_end, + self.encode(node['source']), line, backref_text)) + + def depart_system_message(self, node): + self.body.append('\n') + + def visit_table(self, node): + self.body.append( + self.starttag(node, 'table', CLASS='docutils', border="1")) + + def depart_table(self, node): + self.body.append('\n') + + def visit_target(self, node): + if not (node.has_key('refuri') or node.has_key('refid') + or node.has_key('refname')): + self.body.append(self.starttag(node, 'span', '', CLASS='target')) + self.context.append('') + else: + self.context.append('') + + def depart_target(self, node): + self.body.append(self.context.pop()) + + def visit_tbody(self, node): + self.write_colspecs() + self.body.append(self.context.pop()) # '\n' or '' + self.body.append(self.starttag(node, 'tbody', valign='top')) + + def depart_tbody(self, node): + self.body.append('\n') + + def visit_term(self, node): + self.body.append(self.starttag(node, 'dt', '')) + + def depart_term(self, node): + """ + Leave the end tag to `self.visit_definition()`, in case there's a + classifier. + """ + pass + + def visit_tgroup(self, node): + # Mozilla needs : + self.body.append(self.starttag(node, 'colgroup')) + # Appended by thead or tbody: + self.context.append('\n') + node.stubs = [] + + def depart_tgroup(self, node): + pass + + def visit_thead(self, node): + self.write_colspecs() + self.body.append(self.context.pop()) # '\n' + # There may or may not be a ; this is for to use: + self.context.append('') + self.body.append(self.starttag(node, 'thead', valign='bottom')) + + def depart_thead(self, node): + self.body.append('\n') + + def visit_tip(self, node): + self.visit_admonition(node, 'tip') + + def depart_tip(self, node): + self.depart_admonition() + + def visit_title(self, node, move_ids=1): + """Only 6 section levels are supported by HTML.""" + check_id = 0 + close_tag = '

    \n' + if isinstance(node.parent, nodes.topic): + self.body.append( + self.starttag(node, 'p', '', CLASS='topic-title first')) + check_id = 1 + elif isinstance(node.parent, nodes.sidebar): + self.body.append( + self.starttag(node, 'p', '', CLASS='sidebar-title')) + check_id = 1 + elif isinstance(node.parent, nodes.Admonition): + self.body.append( + self.starttag(node, 'p', '', CLASS='admonition-title')) + check_id = 1 + elif isinstance(node.parent, nodes.table): + self.body.append( + self.starttag(node, 'caption', '')) + check_id = 1 + close_tag = '\n' + elif isinstance(node.parent, nodes.document): + self.body.append(self.starttag(node, 'h1', '', CLASS='title')) + self.context.append('\n') + self.in_document_title = len(self.body) + else: + assert isinstance(node.parent, nodes.section) + h_level = self.section_level + self.initial_header_level - 1 + atts = {} + if (len(node.parent) >= 2 and + isinstance(node.parent[1], nodes.subtitle)): + atts['CLASS'] = 'with-subtitle' + self.body.append( + self.starttag(node, 'h%s' % h_level, '', **atts)) + atts = {} + # !!! conditional to be removed in Docutils 0.5: + if move_ids: + if node.parent['ids']: + atts['ids'] = node.parent['ids'] + if node.hasattr('refid'): + atts['class'] = 'toc-backref' + atts['href'] = '#' + node['refid'] + if atts: + self.body.append(self.starttag({}, 'a', '', **atts)) + self.context.append('\n' % (h_level)) + else: + self.context.append('\n' % (h_level)) + # !!! conditional to be removed in Docutils 0.5: + if check_id: + if node.parent['ids']: + atts={'ids': node.parent['ids']} + self.body.append( + self.starttag({}, 'a', '', **atts)) + self.context.append('' + close_tag) + else: + self.context.append(close_tag) + + def depart_title(self, node): + self.body.append(self.context.pop()) + if self.in_document_title: + self.title = self.body[self.in_document_title:-1] + self.in_document_title = 0 + self.body_pre_docinfo.extend(self.body) + self.html_title.extend(self.body) + del self.body[:] + + def visit_title_reference(self, node): + self.body.append(self.starttag(node, 'cite', '')) + + def depart_title_reference(self, node): + self.body.append('') + + def visit_topic(self, node): + self.body.append(self.start_tag_with_title(node, 'div', CLASS='topic')) + self.topic_classes = node['classes'] + + def depart_topic(self, node): + self.body.append('\n') + self.topic_classes = [] + + def visit_transition(self, node): + self.body.append(self.emptytag(node, 'hr', CLASS='docutils')) + + def depart_transition(self, node): + pass + + def visit_version(self, node): + self.visit_docinfo_item(node, 'version', meta=None) + + def depart_version(self, node): + self.depart_docinfo_item() + + def visit_warning(self, node): + self.visit_admonition(node, 'warning') + + def depart_warning(self, node): + self.depart_admonition() + + def unimplemented_visit(self, node): + raise NotImplementedError('visiting unimplemented node type: %s' + % node.__class__.__name__) + + +class SimpleListChecker(nodes.GenericNodeVisitor): + + """ + Raise `nodes.NodeFound` if non-simple list item is encountered. + + Here "simple" means a list item containing nothing other than a single + paragraph, a simple list, or a paragraph followed by a simple list. + """ + + def default_visit(self, node): + raise nodes.NodeFound + + def visit_bullet_list(self, node): + pass + + def visit_enumerated_list(self, node): + pass + + def visit_list_item(self, node): + children = [] + for child in node.children: + if not isinstance(child, nodes.Invisible): + children.append(child) + if (children and isinstance(children[0], nodes.paragraph) + and (isinstance(children[-1], nodes.bullet_list) + or isinstance(children[-1], nodes.enumerated_list))): + children.pop() + if len(children) <= 1: + return + else: + raise nodes.NodeFound + + def visit_paragraph(self, node): + raise nodes.SkipNode + + def invisible_visit(self, node): + """Invisible nodes should be ignored.""" + raise nodes.SkipNode + + visit_comment = invisible_visit + visit_substitution_definition = invisible_visit + visit_target = invisible_visit + visit_pending = invisible_visit diff --git a/docutils/writers/html4css1/html4css1.css b/docutils/writers/html4css1/html4css1.css new file mode 100644 index 000000000..d477c8053 --- /dev/null +++ b/docutils/writers/html4css1/html4css1.css @@ -0,0 +1,275 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. +*/ + +/* "! important" is used here to override other ``margin-top`` and + ``margin-bottom`` styles that are later in the stylesheet or + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ +.first { + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +dl.docutils dd { + margin-bottom: 0.5em } + +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em ; + margin-right: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +img.align-left { + clear: left } + +img.align-right { + clear: right } + +img.borderless { + border: 0 } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid 1px gray; + margin-left: 1px } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid 1px black; + margin-left: 1px } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } diff --git a/docutils/writers/latex2e.py b/docutils/writers/latex2e.py deleted file mode 100644 index 695160dd4..000000000 --- a/docutils/writers/latex2e.py +++ /dev/null @@ -1,2050 +0,0 @@ -""" -:Author: Engelbert Gruber -:Contact: grubert@users.sourceforge.net -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -LaTeX2e document tree Writer. -""" - -__docformat__ = 'reStructuredText' - -# code contributions from several people included, thanks to all. -# some named: David Abrahams, Julien Letessier, Lele Gaifax, and others. -# -# convention deactivate code by two # e.g. ##. - -import sys -import time -import re -import string -from types import ListType -from docutils import frontend, nodes, languages, writers, utils - - -class Writer(writers.Writer): - - supported = ('latex','latex2e') - """Formats this writer supports.""" - - settings_spec = ( - 'LaTeX-Specific Options', - 'The LaTeX "--output-encoding" default is "latin-1:strict".', - (('Specify documentclass. Default is "article".', - ['--documentclass'], - {'default': 'article', }), - ('Specify document options. Multiple options can be given, ' - 'separated by commas. Default is "10pt,a4paper".', - ['--documentoptions'], - {'default': '10pt,a4paper', }), - ('Use LaTeX footnotes. LaTeX supports only numbered footnotes (does it?). ' - 'Default: no, uses figures.', - ['--use-latex-footnotes'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Format for footnote references: one of "superscript" or ' - '"brackets". Default is "superscript".', - ['--footnote-references'], - {'choices': ['superscript', 'brackets'], 'default': 'superscript', - 'metavar': '', - 'overrides': 'trim_footnote_reference_space'}), - ('Use LaTeX citations. ' - 'Default: no, uses figures which might get mixed with images.', - ['--use-latex-citations'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Format for block quote attributions: one of "dash" (em-dash ' - 'prefix), "parentheses"/"parens", or "none". Default is "dash".', - ['--attribution'], - {'choices': ['dash', 'parentheses', 'parens', 'none'], - 'default': 'dash', 'metavar': ''}), - ('Specify a stylesheet file. The file will be "input" by latex in ' - 'the document header. Default is no stylesheet (""). ' - 'Overrides --stylesheet-path.', - ['--stylesheet'], - {'default': '', 'metavar': '', - 'overrides': 'stylesheet_path'}), - ('Specify a stylesheet file, relative to the current working ' - 'directory. Overrides --stylesheet.', - ['--stylesheet-path'], - {'metavar': '', 'overrides': 'stylesheet'}), - ('Table of contents by docutils (default) or latex. Latex (writer) ' - 'supports only one ToC per document, but docutils does not write ' - 'pagenumbers.', - ['--use-latex-toc'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Let LaTeX print author and date, do not show it in docutils ' - 'document info.', - ['--use-latex-docinfo'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Color of any hyperlinks embedded in text ' - '(default: "blue", "0" to disable).', - ['--hyperlink-color'], {'default': 'blue'}), - ('Enable compound enumerators for nested enumerated lists ' - '(e.g. "1.2.a.ii"). Default: disabled.', - ['--compound-enumerators'], - {'default': None, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Disable compound enumerators for nested enumerated lists. This is ' - 'the default.', - ['--no-compound-enumerators'], - {'action': 'store_false', 'dest': 'compound_enumerators'}), - ('Enable section ("." subsection ...) prefixes for compound ' - 'enumerators. This has no effect without --compound-enumerators. ' - 'Default: disabled.', - ['--section-prefix-for-enumerators'], - {'default': None, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Disable section prefixes for compound enumerators. ' - 'This is the default.', - ['--no-section-prefix-for-enumerators'], - {'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}), - ('Set the separator between section number and enumerator ' - 'for compound enumerated lists. Default is "-".', - ['--section-enumerator-separator'], - {'default': '-', 'metavar': ''}), - ('When possibile, use verbatim for literal-blocks. ' - 'Default is to always use the mbox environment.', - ['--use-verbatim-when-possible'], - {'default': 0, 'action': 'store_true', - 'validator': frontend.validate_boolean}), - ('Table style. "standard" with horizontal and vertical lines, ' - '"booktabs" (LaTeX booktabs style) only horizontal lines ' - 'above and below the table and below the header or "nolines". ' - 'Default: "standard"', - ['--table-style'], - {'choices': ['standard', 'booktabs','nolines'], 'default': 'standard', - 'metavar': ''}), - ('LaTeX graphicx package option. ' - 'Possible values are "dvips", "pdftex". "auto" includes LaTeX code ' - 'to use "pdftex" if processing with pdf(la)tex and dvips otherwise. ' - 'Default is no option.', - ['--graphicx-option'], - {'default': ''}), - ('LaTeX font encoding. ' - 'Possible values are "T1", "OT1", "" or some other fontenc option. ' - 'The font encoding influences available symbols, e.g. "<<" as one ' - 'character. Default is "" which leads to package "ae" (a T1 ' - 'emulation using CM fonts).', - ['--font-encoding'], - {'default': ''}), - ),) - - settings_defaults = {'output_encoding': 'latin-1'} - - relative_path_settings = ('stylesheet_path',) - - config_section = 'latex2e writer' - config_section_dependencies = ('writers',) - - output = None - """Final translated form of `document`.""" - - def __init__(self): - writers.Writer.__init__(self) - self.translator_class = LaTeXTranslator - - def translate(self): - visitor = self.translator_class(self.document) - self.document.walkabout(visitor) - self.output = visitor.astext() - self.head_prefix = visitor.head_prefix - self.head = visitor.head - self.body_prefix = visitor.body_prefix - self.body = visitor.body - self.body_suffix = visitor.body_suffix - -""" -Notes on LaTeX --------------- - -* latex does not support multiple tocs in one document. - (might be no limitation except for docutils documentation) - -* width - - * linewidth - width of a line in the local environment - * textwidth - the width of text on the page - - Maybe always use linewidth ? - - *Bug* inside a minipage a (e.g. Sidebar) the linewidth is - not changed, needs fix in docutils so that tables - are not too wide. - - So we add locallinewidth set it initially and - on entering sidebar and reset on exit. -""" - -class Babel: - """Language specifics for LaTeX.""" - # country code by a.schlock. - # partly manually converted from iso and babel stuff, dialects and some - _ISO639_TO_BABEL = { - 'no': 'norsk', #XXX added by hand ( forget about nynorsk?) - 'gd': 'scottish', #XXX added by hand - 'hu': 'magyar', #XXX added by hand - 'pt': 'portuguese',#XXX added by hand - 'sl': 'slovenian', - 'af': 'afrikaans', - 'bg': 'bulgarian', - 'br': 'breton', - 'ca': 'catalan', - 'cs': 'czech', - 'cy': 'welsh', - 'da': 'danish', - 'fr': 'french', - # french, francais, canadien, acadian - 'de': 'ngerman', #XXX rather than german - # ngerman, naustrian, german, germanb, austrian - 'el': 'greek', - 'en': 'english', - # english, USenglish, american, UKenglish, british, canadian - 'eo': 'esperanto', - 'es': 'spanish', - 'et': 'estonian', - 'eu': 'basque', - 'fi': 'finnish', - 'ga': 'irish', - 'gl': 'galician', - 'he': 'hebrew', - 'hr': 'croatian', - 'hu': 'hungarian', - 'is': 'icelandic', - 'it': 'italian', - 'la': 'latin', - 'nl': 'dutch', - 'pl': 'polish', - 'pt': 'portuguese', - 'ro': 'romanian', - 'ru': 'russian', - 'sk': 'slovak', - 'sr': 'serbian', - 'sv': 'swedish', - 'tr': 'turkish', - 'uk': 'ukrainian' - } - - def __init__(self,lang): - self.language = lang - # pdflatex does not produce double quotes for ngerman in tt. - self.double_quote_replacment = None - if re.search('^de',self.language): - #self.quotes = ("\"`", "\"'") - self.quotes = ('{\\glqq}', '{\\grqq}') - self.double_quote_replacment = "{\\dq}" - else: - self.quotes = ("``", "''") - self.quote_index = 0 - - def next_quote(self): - q = self.quotes[self.quote_index] - self.quote_index = (self.quote_index+1)%2 - return q - - def quote_quotes(self,text): - t = None - for part in text.split('"'): - if t == None: - t = part - else: - t += self.next_quote() + part - return t - - def double_quotes_in_tt (self,text): - if not self.double_quote_replacment: - return text - return text.replace('"', self.double_quote_replacment) - - def get_language(self): - if self._ISO639_TO_BABEL.has_key(self.language): - return self._ISO639_TO_BABEL[self.language] - else: - # support dialects. - l = self.language.split("_")[0] - if self._ISO639_TO_BABEL.has_key(l): - return self._ISO639_TO_BABEL[l] - return None - - -latex_headings = { - 'optionlist_environment' : [ - '\\newcommand{\\optionlistlabel}[1]{\\bf #1 \\hfill}\n' - '\\newenvironment{optionlist}[1]\n' - '{\\begin{list}{}\n' - ' {\\setlength{\\labelwidth}{#1}\n' - ' \\setlength{\\rightmargin}{1cm}\n' - ' \\setlength{\\leftmargin}{\\rightmargin}\n' - ' \\addtolength{\\leftmargin}{\\labelwidth}\n' - ' \\addtolength{\\leftmargin}{\\labelsep}\n' - ' \\renewcommand{\\makelabel}{\\optionlistlabel}}\n' - '}{\\end{list}}\n', - ], - 'lineblock_environment' : [ - '\\newlength{\\lineblockindentation}\n' - '\\setlength{\\lineblockindentation}{2.5em}\n' - '\\newenvironment{lineblock}[1]\n' - '{\\begin{list}{}\n' - ' {\\setlength{\\partopsep}{\\parskip}\n' - ' \\addtolength{\\partopsep}{\\baselineskip}\n' - ' \\topsep0pt\\itemsep0.15\\baselineskip\\parsep0pt\n' - ' \\leftmargin#1}\n' - ' \\raggedright}\n' - '{\\end{list}}\n' - ], - 'footnote_floats' : [ - '% begin: floats for footnotes tweaking.\n', - '\\setlength{\\floatsep}{0.5em}\n', - '\\setlength{\\textfloatsep}{\\fill}\n', - '\\addtolength{\\textfloatsep}{3em}\n', - '\\renewcommand{\\textfraction}{0.5}\n', - '\\renewcommand{\\topfraction}{0.5}\n', - '\\renewcommand{\\bottomfraction}{0.5}\n', - '\\setcounter{totalnumber}{50}\n', - '\\setcounter{topnumber}{50}\n', - '\\setcounter{bottomnumber}{50}\n', - '% end floats for footnotes\n', - ], - 'some_commands' : [ - '% some commands, that could be overwritten in the style file.\n' - '\\newcommand{\\rubric}[1]' - '{\\subsection*{~\\hfill {\\it #1} \\hfill ~}}\n' - '\\newcommand{\\titlereference}[1]{\\textsl{#1}}\n' - '% end of "some commands"\n', - ] - } - -class DocumentClass: - """Details of a LaTeX document class.""" - - # BUG: LaTeX has no deeper sections (actually paragrah is no - # section either). - # BUG: No support for unknown document classes. Make 'article' - # default? - _class_sections = { - 'book': ( 'chapter', 'section', 'subsection', 'subsubsection' ), - 'scrbook': ( 'chapter', 'section', 'subsection', 'subsubsection' ), - 'report': ( 'chapter', 'section', 'subsection', 'subsubsection' ), - 'scrreprt': ( 'chapter', 'section', 'subsection', 'subsubsection' ), - 'article': ( 'section', 'subsection', 'subsubsection' ), - 'scrartcl': ( 'section', 'subsection', 'subsubsection' ), - } - _deepest_section = 'subsubsection' - - def __init__(self, document_class): - self.document_class = document_class - - def section(self, level): - """ Return the section name at the given level for the specific - document class. - - Level is 1,2,3..., as level 0 is the title.""" - - sections = self._class_sections[self.document_class] - if level <= len(sections): - return sections[level-1] - else: - return self._deepest_section - -class Table: - """ Manage a table while traversing. - Maybe change to a mixin defining the visit/departs, but then - class Table internal variables are in the Translator. - """ - def __init__(self,latex_type,table_style): - self._latex_type = latex_type - self._table_style = table_style - self._open = 0 - # miscellaneous attributes - self._attrs = {} - self._col_width = [] - self._rowspan = [] - - def open(self): - self._open = 1 - self._col_specs = [] - self.caption = None - self._attrs = {} - self._in_head = 0 # maybe context with search - def close(self): - self._open = 0 - self._col_specs = None - self.caption = None - self._attrs = {} - def is_open(self): - return self._open - def used_packages(self): - if self._table_style == 'booktabs': - return '\\usepackage{booktabs}\n' - return '' - def get_latex_type(self): - return self._latex_type - - def set(self,attr,value): - self._attrs[attr] = value - def get(self,attr): - if self._attrs.has_key(attr): - return self._attrs[attr] - return None - def get_vertical_bar(self): - if self._table_style == 'standard': - return '|' - return '' - # horizontal lines are drawn below a row, because we. - def get_opening(self): - return '\\begin{%s}[c]' % self._latex_type - def get_closing(self): - line = "" - if self._table_style == 'booktabs': - line = '\\bottomrule\n' - elif self._table_style == 'standard': - lines = '\\hline\n' - return '%s\\end{%s}' % (line,self._latex_type) - - def visit_colspec(self,node): - self._col_specs.append(node) - - def get_colspecs(self): - """ - Return column specification for longtable. - - Assumes reST line length being 80 characters. - Table width is hairy. - - === === - ABC DEF - === === - - usually gets to narrow, therefore we add 1 (fiddlefactor). - """ - width = 80 - - total_width = 0.0 - # first see if we get too wide. - for node in self._col_specs: - colwidth = float(node['colwidth']+1) / width - total_width += colwidth - self._col_width = [] - self._rowspan = [] - # donot make it full linewidth - factor = 0.93 - if total_width > 1.0: - factor /= total_width - bar = self.get_vertical_bar() - latex_table_spec = "" - for node in self._col_specs: - colwidth = factor * float(node['colwidth']+1) / width - self._col_width.append(colwidth+0.005) - self._rowspan.append(0) - latex_table_spec += "%sp{%.2f\\locallinewidth}" % (bar,colwidth+0.005) - return latex_table_spec+bar - - def get_column_width(self): - """ return columnwidth for current cell (not multicell) - """ - return "%.2f\\locallinewidth" % self._col_width[self._cell_in_row-1] - - def visit_thead(self): - self._in_thead = 1 - if self._table_style == 'standard': - return ['\\hline\n'] - elif self._table_style == 'booktabs': - return ['\\toprule\n'] - return [] - def depart_thead(self): - a = [] - #if self._table_style == 'standard': - # a.append('\\hline\n') - if self._table_style == 'booktabs': - a.append('\\midrule\n') - a.append('\\endhead\n') - # for longtable one could add firsthead, foot and lastfoot - self._in_thead = 0 - return a - def visit_row(self): - self._cell_in_row = 0 - def depart_row(self): - res = [' \\\\\n'] - self._cell_in_row = None # remove cell counter - for i in range(len(self._rowspan)): - if (self._rowspan[i]>0): - self._rowspan[i] -= 1 - - if self._table_style == 'standard': - rowspans = [] - for i in range(len(self._rowspan)): - if (self._rowspan[i]<=0): - rowspans.append(i+1) - if len(rowspans)==len(self._rowspan): - res.append('\\hline\n') - else: - cline = '' - rowspans.reverse() - # TODO merge clines - while 1: - try: - c_start = rowspans.pop() - except: - break - cline += '\\cline{%d-%d}\n' % (c_start,c_start) - res.append(cline) - return res - - def set_rowspan(self,cell,value): - try: - self._rowspan[cell] = value - except: - pass - def get_rowspan(self,cell): - try: - return self._rowspan[cell] - except: - return 0 - def get_entry_number(self): - return self._cell_in_row - def visit_entry(self): - self._cell_in_row += 1 - - -class LaTeXTranslator(nodes.NodeVisitor): - - # When options are given to the documentclass, latex will pass them - # to other packages, as done with babel. - # Dummy settings might be taken from document settings - - latex_head = '\\documentclass[%s]{%s}\n' - encoding = '\\usepackage[%s]{inputenc}\n' - linking = '\\usepackage[colorlinks=%s,linkcolor=%s,urlcolor=%s]{hyperref}\n' - stylesheet = '\\input{%s}\n' - # add a generated on day , machine by user using docutils version. - generator = '%% generator Docutils: http://docutils.sourceforge.net/\n' - - # use latex tableofcontents or let docutils do it. - use_latex_toc = 0 - - # TODO: use mixins for different implementations. - # list environment for option-list. else tabularx - use_optionlist_for_option_list = 1 - # list environment for docinfo. else tabularx - use_optionlist_for_docinfo = 0 # NOT YET IN USE - - # Use compound enumerations (1.A.1.) - compound_enumerators = 0 - - # If using compound enumerations, include section information. - section_prefix_for_enumerators = 0 - - # This is the character that separates the section ("." subsection ...) - # prefix from the regular list enumerator. - section_enumerator_separator = '-' - - # default link color - hyperlink_color = "blue" - - def __init__(self, document): - nodes.NodeVisitor.__init__(self, document) - self.settings = settings = document.settings - self.latex_encoding = self.to_latex_encoding(settings.output_encoding) - self.use_latex_toc = settings.use_latex_toc - self.use_latex_docinfo = settings.use_latex_docinfo - self.use_latex_footnotes = settings.use_latex_footnotes - self._use_latex_citations = settings.use_latex_citations - self.hyperlink_color = settings.hyperlink_color - self.compound_enumerators = settings.compound_enumerators - self.font_encoding = settings.font_encoding - self.section_prefix_for_enumerators = ( - settings.section_prefix_for_enumerators) - self.section_enumerator_separator = ( - settings.section_enumerator_separator.replace('_', '\\_')) - if self.hyperlink_color == '0': - self.hyperlink_color = 'black' - self.colorlinks = 'false' - else: - self.colorlinks = 'true' - - # language: labels, bibliographic_fields, and author_separators. - # to allow writing labes for specific languages. - self.language = languages.get_language(settings.language_code) - self.babel = Babel(settings.language_code) - self.author_separator = self.language.author_separators[0] - self.d_options = self.settings.documentoptions - if self.babel.get_language(): - self.d_options += ',%s' % \ - self.babel.get_language() - - self.d_class = DocumentClass(settings.documentclass) - # object for a table while proccessing. - self.active_table = Table('longtable',settings.table_style) - - # HACK. Should have more sophisticated typearea handling. - if settings.documentclass.find('scr') == -1: - self.typearea = '\\usepackage[DIV12]{typearea}\n' - else: - if self.d_options.find('DIV') == -1 and self.d_options.find('BCOR') == -1: - self.typearea = '\\typearea{12}\n' - else: - self.typearea = '' - - if self.font_encoding == 'OT1': - fontenc_header = '' - elif self.font_encoding == '': - fontenc_header = '\\usepackage{ae}\n\\usepackage{aeguill}\n' - else: - fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) - input_encoding = self.encoding % self.latex_encoding - if self.settings.graphicx_option == '': - self.graphicx_package = '\\usepackage{graphicx}\n' - elif self.settings.graphicx_option.lower() == 'auto': - self.graphicx_package = '\n'.join( - ('%Check if we are compiling under latex or pdflatex', - '\\ifx\\pdftexversion\\undefined', - ' \\usepackage{graphicx}', - '\\else', - ' \\usepackage[pdftex]{graphicx}', - '\\fi\n')) - else: - self.graphicx_package = ( - '\\usepackage[%s]{graphicx}\n' % self.settings.graphicx_option) - - self.head_prefix = [ - self.latex_head % (self.d_options,self.settings.documentclass), - '\\usepackage{babel}\n', # language is in documents settings. - fontenc_header, - '\\usepackage{shortvrb}\n', # allows verb in footnotes. - input_encoding, - # * tabularx: for docinfo, automatic width of columns, always on one page. - '\\usepackage{tabularx}\n', - '\\usepackage{longtable}\n', - self.active_table.used_packages(), - # possible other packages. - # * fancyhdr - # * ltxtable is a combination of tabularx and longtable (pagebreaks). - # but ?? - # - # extra space between text in tables and the line above them - '\\setlength{\\extrarowheight}{2pt}\n', - '\\usepackage{amsmath}\n', # what fore amsmath. - self.graphicx_package, - '\\usepackage{color}\n', - '\\usepackage{multirow}\n', - '\\usepackage{ifthen}\n', # before hyperref! - self.linking % (self.colorlinks, self.hyperlink_color, self.hyperlink_color), - self.typearea, - self.generator, - # latex lengths - '\\newlength{\\admonitionwidth}\n', - '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' - # width for docinfo tablewidth - '\\newlength{\\docinfowidth}\n', - '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' - # linewidth of current environment, so tables are not wider - # than the sidebar: using locallinewidth seems to defer evaluation - # of linewidth, this is fixing it. - '\\newlength{\\locallinewidth}\n', - # will be set later. - ] - self.head_prefix.extend( latex_headings['optionlist_environment'] ) - self.head_prefix.extend( latex_headings['lineblock_environment'] ) - self.head_prefix.extend( latex_headings['footnote_floats'] ) - self.head_prefix.extend( latex_headings['some_commands'] ) - ## stylesheet is last: so it might be possible to overwrite defaults. - stylesheet = utils.get_stylesheet_reference(settings) - if stylesheet: - settings.record_dependencies.add(stylesheet) - self.head_prefix.append(self.stylesheet % (stylesheet)) - - if self.linking: # and maybe check for pdf - self.pdfinfo = [ ] - self.pdfauthor = None - # pdftitle, pdfsubject, pdfauthor, pdfkeywords, pdfcreator, pdfproducer - else: - self.pdfinfo = None - # NOTE: Latex wants a date and an author, rst puts this into - # docinfo, so normally we donot want latex author/date handling. - # latex article has its own handling of date and author, deactivate. - # So we always emit \title{...} \author{...} \date{...}, even if the - # "..." are empty strings. - self.head = [ ] - # separate title, so we can appen subtitle. - self.title = '' - # if use_latex_docinfo: collects lists of author/organization/contact/address lines - self.author_stack = [] - self.date = '' - - self.body_prefix = ['\\raggedbottom\n'] - self.body = [] - self.body_suffix = ['\n'] - self.section_level = 0 - self.context = [] - self.topic_classes = [] - # column specification for tables - self.table_caption = None - - # Flags to encode - # --------------- - # verbatim: to tell encode not to encode. - self.verbatim = 0 - # insert_newline: to tell encode to replace blanks by "~". - self.insert_none_breaking_blanks = 0 - # insert_newline: to tell encode to add latex newline. - self.insert_newline = 0 - # mbox_newline: to tell encode to add mbox and newline. - self.mbox_newline = 0 - - # enumeration is done by list environment. - self._enum_cnt = 0 - - # Stack of section counters so that we don't have to use_latex_toc. - # This will grow and shrink as processing occurs. - # Initialized for potential first-level sections. - self._section_number = [0] - - # The current stack of enumerations so that we can expand - # them into a compound enumeration - self._enumeration_counters = [] - - self._bibitems = [] - - # docinfo. - self.docinfo = None - # inside literal block: no quote mangling. - self.literal_block = 0 - self.literal_block_stack = [] - self.literal = 0 - # true when encoding in math mode - self.mathmode = 0 - - def to_latex_encoding(self,docutils_encoding): - """ - Translate docutils encoding name into latex's. - - Default fallback method is remove "-" and "_" chars from docutils_encoding. - - """ - tr = { "iso-8859-1": "latin1", # west european - "iso-8859-2": "latin2", # east european - "iso-8859-3": "latin3", # esperanto, maltese - "iso-8859-4": "latin4", # north european,scandinavian, baltic - "iso-8859-5": "iso88595", # cyrillic (ISO) - "iso-8859-9": "latin5", # turkish - "iso-8859-15": "latin9", # latin9, update to latin1. - "mac_cyrillic": "maccyr", # cyrillic (on Mac) - "windows-1251": "cp1251", # cyrillic (on Windows) - "koi8-r": "koi8-r", # cyrillic (Russian) - "koi8-u": "koi8-u", # cyrillic (Ukrainian) - "windows-1250": "cp1250", # - "windows-1252": "cp1252", # - "us-ascii": "ascii", # ASCII (US) - # unmatched encodings - #"": "applemac", - #"": "ansinew", # windows 3.1 ansi - #"": "ascii", # ASCII encoding for the range 32--127. - #"": "cp437", # dos latine us - #"": "cp850", # dos latin 1 - #"": "cp852", # dos latin 2 - #"": "decmulti", - #"": "latin10", - #"iso-8859-6": "" # arabic - #"iso-8859-7": "" # greek - #"iso-8859-8": "" # hebrew - #"iso-8859-10": "" # latin6, more complete iso-8859-4 - } - if tr.has_key(docutils_encoding.lower()): - return tr[docutils_encoding.lower()] - return docutils_encoding.translate(string.maketrans("",""),"_-").lower() - - def language_label(self, docutil_label): - return self.language.labels[docutil_label] - - latex_equivalents = { - u'\u00A0' : '~', - u'\u2013' : '{--}', - u'\u2014' : '{---}', - u'\u2018' : '`', - u'\u2019' : '\'', - u'\u201A' : ',', - u'\u201C' : '``', - u'\u201D' : '\'\'', - u'\u201E' : ',,', - u'\u2020' : '{\\dag}', - u'\u2021' : '{\\ddag}', - u'\u2026' : '{\\dots}', - u'\u2122' : '{\\texttrademark}', - u'\u21d4' : '{$\\Leftrightarrow$}', - } - - def unicode_to_latex(self,text): - # see LaTeX codec - # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 - # Only some special chracters are translated, for documents with many - # utf-8 chars one should use the LaTeX unicode package. - for uchar in self.latex_equivalents.keys(): - text = text.replace(uchar,self.latex_equivalents[uchar]) - return text - - def encode(self, text): - """ - Encode special characters in `text` & return. - # $ % & ~ _ ^ \ { } - Escaping with a backslash does not help with backslashes, ~ and ^. - - < > are only available in math-mode or tt font. (really ?) - $ starts math- mode. - AND quotes: - - """ - if self.verbatim: - return text - # compile the regexps once. do it here so one can see them. - # - # first the braces. - if not self.__dict__.has_key('encode_re_braces'): - self.encode_re_braces = re.compile(r'([{}])') - text = self.encode_re_braces.sub(r'{\\\1}',text) - if not self.__dict__.has_key('encode_re_bslash'): - # find backslash: except in the form '{\{}' or '{\}}'. - self.encode_re_bslash = re.compile(r'(?", '{\\textgreater}') - # then - text = text.replace("&", '{\\&}') - # the ^: - # * verb|^| does not work in mbox. - # * mathmode has wedge. hat{~} would also work. - # text = text.replace("^", '{\\ensuremath{^\\wedge}}') - text = text.replace("^", '{\\textasciicircum}') - text = text.replace("%", '{\\%}') - text = text.replace("#", '{\\#}') - text = text.replace("~", '{\\textasciitilde}') - # Separate compound characters, e.g. "--" to "-{}-". (The - # actual separation is done later; see below.) - separate_chars = '-' - if self.literal_block or self.literal: - # In monospace-font, we also separate ",,", "``" and "''" - # and some other characters which can't occur in - # non-literal text. - separate_chars += ',`\'"<>' - # pdflatex does not produce doublequotes for ngerman. - text = self.babel.double_quotes_in_tt(text) - if self.font_encoding == 'OT1': - # We're using OT1 font-encoding and have to replace - # underscore by underlined blank, because this has - # correct width. - text = text.replace('_', '{\\underline{ }}') - # And the tt-backslash doesn't work in OT1, so we use - # a mirrored slash. - text = text.replace('\\textbackslash', '\\reflectbox{/}') - else: - text = text.replace('_', '{\\_}') - else: - text = self.babel.quote_quotes(text) - text = text.replace("_", '{\\_}') - for char in separate_chars * 2: - # Do it twice ("* 2") becaues otherwise we would replace - # "---" by "-{}--". - text = text.replace(char + char, char + '{}' + char) - if self.insert_newline or self.literal_block: - # Insert a blank before the newline, to avoid - # ! LaTeX Error: There's no line here to end. - text = text.replace("\n", '~\\\\\n') - elif self.mbox_newline: - if self.literal_block: - closings = "}" * len(self.literal_block_stack) - openings = "".join(self.literal_block_stack) - else: - closings = "" - openings = "" - text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) - text = text.replace('[', '{[}').replace(']', '{]}') - if self.insert_none_breaking_blanks: - text = text.replace(' ', '~') - if self.latex_encoding != 'utf8': - text = self.unicode_to_latex(text) - return text - - def attval(self, text, - whitespace=re.compile('[\n\r\t\v\f]')): - """Cleanse, encode, and return attribute value text.""" - return self.encode(whitespace.sub(' ', text)) - - def astext(self): - if self.pdfinfo is not None: - if self.pdfauthor: - self.pdfinfo.append('pdfauthor={%s}' % self.pdfauthor) - if self.pdfinfo: - pdfinfo = '\\hypersetup{\n' + ',\n'.join(self.pdfinfo) + '\n}\n' - else: - pdfinfo = '' - head = '\\title{%s}\n\\author{%s}\n\\date{%s}\n' % \ - (self.title, - ' \\and\n'.join(['~\\\\\n'.join(author_lines) - for author_lines in self.author_stack]), - self.date) - return ''.join(self.head_prefix + [head] + self.head + [pdfinfo] - + self.body_prefix + self.body + self.body_suffix) - - def visit_Text(self, node): - self.body.append(self.encode(node.astext())) - - def depart_Text(self, node): - pass - - def visit_address(self, node): - self.visit_docinfo_item(node, 'address') - - def depart_address(self, node): - self.depart_docinfo_item(node) - - def visit_admonition(self, node, name=''): - self.body.append('\\begin{center}\\begin{sffamily}\n') - self.body.append('\\fbox{\\parbox{\\admonitionwidth}{\n') - if name: - self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); - self.body.append('\\vspace{2mm}\n') - - - def depart_admonition(self, node=None): - self.body.append('}}\n') # end parbox fbox - self.body.append('\\end{sffamily}\n\\end{center}\n'); - - def visit_attention(self, node): - self.visit_admonition(node, 'attention') - - def depart_attention(self, node): - self.depart_admonition() - - def visit_author(self, node): - self.visit_docinfo_item(node, 'author') - - def depart_author(self, node): - self.depart_docinfo_item(node) - - def visit_authors(self, node): - # not used: visit_author is called anyway for each author. - pass - - def depart_authors(self, node): - pass - - def visit_block_quote(self, node): - self.body.append( '\\begin{quote}\n') - - def depart_block_quote(self, node): - self.body.append( '\\end{quote}\n') - - def visit_bullet_list(self, node): - if 'contents' in self.topic_classes: - if not self.use_latex_toc: - self.body.append( '\\begin{list}{}{}\n' ) - else: - self.body.append( '\\begin{itemize}\n' ) - - def depart_bullet_list(self, node): - if 'contents' in self.topic_classes: - if not self.use_latex_toc: - self.body.append( '\\end{list}\n' ) - else: - self.body.append( '\\end{itemize}\n' ) - - # Imperfect superscript/subscript handling: mathmode italicizes - # all letters by default. - def visit_superscript(self, node): - self.body.append('$^{') - self.mathmode = 1 - - def depart_superscript(self, node): - self.body.append('}$') - self.mathmode = 0 - - def visit_subscript(self, node): - self.body.append('$_{') - self.mathmode = 1 - - def depart_subscript(self, node): - self.body.append('}$') - self.mathmode = 0 - - def visit_caption(self, node): - self.body.append( '\\caption{' ) - - def depart_caption(self, node): - self.body.append('}') - - def visit_caution(self, node): - self.visit_admonition(node, 'caution') - - def depart_caution(self, node): - self.depart_admonition() - - def visit_title_reference(self, node): - self.body.append( '\\titlereference{' ) - - def depart_title_reference(self, node): - self.body.append( '}' ) - - def visit_citation(self, node): - # TODO maybe use cite bibitems - if self._use_latex_citations: - self.context.append(len(self.body)) - else: - self.body.append('\\begin{figure}[b]') - for id in node['ids']: - self.body.append('\\hypertarget{%s}' % id) - - def depart_citation(self, node): - if self._use_latex_citations: - size = self.context.pop() - label = self.body[size] - text = ''.join(self.body[size+1:]) - del self.body[size:] - self._bibitems.append([label, text]) - else: - self.body.append('\\end{figure}\n') - - def visit_citation_reference(self, node): - if self._use_latex_citations: - self.body.append('\\cite{') - else: - href = '' - if node.has_key('refid'): - href = node['refid'] - elif node.has_key('refname'): - href = self.document.nameids[node['refname']] - self.body.append('[\\hyperlink{%s}{' % href) - - def depart_citation_reference(self, node): - if self._use_latex_citations: - self.body.append('}') - else: - self.body.append('}]') - - def visit_classifier(self, node): - self.body.append( '(\\textbf{' ) - - def depart_classifier(self, node): - self.body.append( '})\n' ) - - def visit_colspec(self, node): - self.active_table.visit_colspec(node) - - def depart_colspec(self, node): - pass - - def visit_comment(self, node): - # Escape end of line by a new comment start in comment text. - self.body.append('%% %s \n' % node.astext().replace('\n', '\n% ')) - raise nodes.SkipNode - - def visit_compound(self, node): - pass - - def depart_compound(self, node): - pass - - def visit_contact(self, node): - self.visit_docinfo_item(node, 'contact') - - def depart_contact(self, node): - self.depart_docinfo_item(node) - - def visit_container(self, node): - pass - - def depart_container(self, node): - pass - - def visit_copyright(self, node): - self.visit_docinfo_item(node, 'copyright') - - def depart_copyright(self, node): - self.depart_docinfo_item(node) - - def visit_danger(self, node): - self.visit_admonition(node, 'danger') - - def depart_danger(self, node): - self.depart_admonition() - - def visit_date(self, node): - self.visit_docinfo_item(node, 'date') - - def depart_date(self, node): - self.depart_docinfo_item(node) - - def visit_decoration(self, node): - pass - - def depart_decoration(self, node): - pass - - def visit_definition(self, node): - self.body.append('%[visit_definition]\n') - - def depart_definition(self, node): - self.body.append('\n') - self.body.append('%[depart_definition]\n') - - def visit_definition_list(self, node): - self.body.append( '\\begin{description}\n' ) - - def depart_definition_list(self, node): - self.body.append( '\\end{description}\n' ) - - def visit_definition_list_item(self, node): - self.body.append('%[visit_definition_list_item]\n') - - def depart_definition_list_item(self, node): - self.body.append('%[depart_definition_list_item]\n') - - def visit_description(self, node): - if self.use_optionlist_for_option_list: - self.body.append( ' ' ) - else: - self.body.append( ' & ' ) - - def depart_description(self, node): - pass - - def visit_docinfo(self, node): - self.docinfo = [] - self.docinfo.append('%' + '_'*75 + '\n') - self.docinfo.append('\\begin{center}\n') - self.docinfo.append('\\begin{tabularx}{\\docinfowidth}{lX}\n') - - def depart_docinfo(self, node): - self.docinfo.append('\\end{tabularx}\n') - self.docinfo.append('\\end{center}\n') - self.body = self.docinfo + self.body - # clear docinfo, so field names are no longer appended. - self.docinfo = None - - def visit_docinfo_item(self, node, name): - if name == 'author': - if not self.pdfinfo == None: - if not self.pdfauthor: - self.pdfauthor = self.attval(node.astext()) - else: - self.pdfauthor += self.author_separator + self.attval(node.astext()) - if self.use_latex_docinfo: - if name in ('author', 'organization', 'contact', 'address'): - # We attach these to the last author. If any of them precedes - # the first author, put them in a separate "author" group (for - # no better semantics). - if name == 'author' or not self.author_stack: - self.author_stack.append([]) - if name == 'address': # newlines are meaningful - self.insert_newline = 1 - text = self.encode(node.astext()) - self.insert_newline = 0 - else: - text = self.attval(node.astext()) - self.author_stack[-1].append(text) - raise nodes.SkipNode - elif name == 'date': - self.date = self.attval(node.astext()) - raise nodes.SkipNode - self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) - if name == 'address': - self.insert_newline = 1 - self.docinfo.append('{\\raggedright\n') - self.context.append(' } \\\\\n') - else: - self.context.append(' \\\\\n') - self.context.append(self.docinfo) - self.context.append(len(self.body)) - - def depart_docinfo_item(self, node): - size = self.context.pop() - dest = self.context.pop() - tail = self.context.pop() - tail = self.body[size:] + [tail] - del self.body[size:] - dest.extend(tail) - # for address we did set insert_newline - self.insert_newline = 0 - - def visit_doctest_block(self, node): - self.body.append( '\\begin{verbatim}' ) - self.verbatim = 1 - - def depart_doctest_block(self, node): - self.body.append( '\\end{verbatim}\n' ) - self.verbatim = 0 - - def visit_document(self, node): - self.body_prefix.append('\\begin{document}\n') - # titled document? - if self.use_latex_docinfo or len(node) and isinstance(node[0], nodes.title): - self.body_prefix.append('\\maketitle\n\n') - # alternative use titlepage environment. - # \begin{titlepage} - self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') - - def depart_document(self, node): - # TODO insertion point of bibliography should none automatic. - if self._use_latex_citations and len(self._bibitems)>0: - widest_label = "" - for bi in self._bibitems: - if len(widest_label) 14: - self.body.append('\\multicolumn{2}{l}{') - self.context.append('} \\\\\n ') - else: - self.context.append('') - self.body.append('\\texttt{') - # flag for first option - self.context.append(0) - - def depart_option_group(self, node): - self.context.pop() # the flag - if self.use_optionlist_for_option_list: - self.body.append('] ') - else: - self.body.append('}') - self.body.append(self.context.pop()) - - def visit_option_list(self, node): - self.body.append('% [option list]\n') - if self.use_optionlist_for_option_list: - self.body.append('\\begin{optionlist}{3cm}\n') - else: - self.body.append('\\begin{center}\n') - # BUG: use admwidth or make it relative to textwidth ? - self.body.append('\\begin{tabularx}{.9\\linewidth}{lX}\n') - - def depart_option_list(self, node): - if self.use_optionlist_for_option_list: - self.body.append('\\end{optionlist}\n') - else: - self.body.append('\\end{tabularx}\n') - self.body.append('\\end{center}\n') - - def visit_option_list_item(self, node): - pass - - def depart_option_list_item(self, node): - if not self.use_optionlist_for_option_list: - self.body.append('\\\\\n') - - def visit_option_string(self, node): - ##self.body.append(self.starttag(node, 'span', '', CLASS='option')) - pass - - def depart_option_string(self, node): - ##self.body.append('') - pass - - def visit_organization(self, node): - self.visit_docinfo_item(node, 'organization') - - def depart_organization(self, node): - self.depart_docinfo_item(node) - - def visit_paragraph(self, node): - index = node.parent.index(node) - if not ('contents' in self.topic_classes or - (isinstance(node.parent, nodes.compound) and - index > 0 and - not isinstance(node.parent[index - 1], nodes.paragraph) and - not isinstance(node.parent[index - 1], nodes.compound))): - self.body.append('\n') - - def depart_paragraph(self, node): - self.body.append('\n') - - def visit_problematic(self, node): - self.body.append('{\\color{red}\\bfseries{}') - - def depart_problematic(self, node): - self.body.append('}') - - def visit_raw(self, node): - if 'latex' in node.get('format', '').split(): - self.body.append(node.astext()) - raise nodes.SkipNode - - def visit_reference(self, node): - # BUG: hash_char "#" is trouble some in LaTeX. - # mbox and other environment do not like the '#'. - hash_char = '\\#' - if node.has_key('refuri'): - href = node['refuri'].replace('#',hash_char) - elif node.has_key('refid'): - href = hash_char + node['refid'] - elif node.has_key('refname'): - href = hash_char + self.document.nameids[node['refname']] - else: - raise AssertionError('Unknown reference.') - self.body.append('\\href{%s}{' % href) - - def depart_reference(self, node): - self.body.append('}') - - def visit_revision(self, node): - self.visit_docinfo_item(node, 'revision') - - def depart_revision(self, node): - self.depart_docinfo_item(node) - - def visit_section(self, node): - self.section_level += 1 - # Initialize counter for potential subsections: - self._section_number.append(0) - # Counter for this section's level (initialized by parent section): - self._section_number[self.section_level - 1] += 1 - - def depart_section(self, node): - # Remove counter for potential subsections: - self._section_number.pop() - self.section_level -= 1 - - def visit_sidebar(self, node): - # BUG: this is just a hack to make sidebars render something - self.body.append('\n\\setlength{\\locallinewidth}{0.9\\admonitionwidth}\n') - self.body.append('\\begin{center}\\begin{sffamily}\n') - self.body.append('\\fbox{\\colorbox[gray]{0.80}{\\parbox{\\admonitionwidth}{\n') - - def depart_sidebar(self, node): - self.body.append('}}}\n') # end parbox colorbox fbox - self.body.append('\\end{sffamily}\n\\end{center}\n'); - self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') - - - attribution_formats = {'dash': ('---', ''), - 'parentheses': ('(', ')'), - 'parens': ('(', ')'), - 'none': ('', '')} - - def visit_attribution(self, node): - prefix, suffix = self.attribution_formats[self.settings.attribution] - self.body.append('\n\\begin{flushright}\n') - self.body.append(prefix) - self.context.append(suffix) - - def depart_attribution(self, node): - self.body.append(self.context.pop() + '\n') - self.body.append('\\end{flushright}\n') - - def visit_status(self, node): - self.visit_docinfo_item(node, 'status') - - def depart_status(self, node): - self.depart_docinfo_item(node) - - def visit_strong(self, node): - self.body.append('\\textbf{') - self.literal_block_stack.append('\\textbf{') - - def depart_strong(self, node): - self.body.append('}') - self.literal_block_stack.pop() - - def visit_substitution_definition(self, node): - raise nodes.SkipNode - - def visit_substitution_reference(self, node): - self.unimplemented_visit(node) - - def visit_subtitle(self, node): - if isinstance(node.parent, nodes.sidebar): - self.body.append('~\\\\\n\\textbf{') - self.context.append('}\n\\smallskip\n') - elif isinstance(node.parent, nodes.document): - self.title = self.title + \ - '\\\\\n\\large{%s}\n' % self.encode(node.astext()) - raise nodes.SkipNode - elif isinstance(node.parent, nodes.section): - self.body.append('\\textbf{') - self.context.append('}\\vspace{0.2cm}\n\n\\noindent ') - - def depart_subtitle(self, node): - self.body.append(self.context.pop()) - - def visit_system_message(self, node): - pass - - def depart_system_message(self, node): - self.body.append('\n') - - def visit_table(self, node): - if self.active_table.is_open(): - print 'nested tables are not supported' - raise AssertionError - self.active_table.open() - self.body.append('\n' + self.active_table.get_opening()) - - def depart_table(self, node): - self.body.append(self.active_table.get_closing() + '\n') - self.active_table.close() - - def visit_target(self, node): - # BUG: why not (refuri or refid or refname) means not footnote ? - if not (node.has_key('refuri') or node.has_key('refid') - or node.has_key('refname')): - for id in node['ids']: - self.body.append('\\hypertarget{%s}{' % id) - self.context.append('}' * len(node['ids'])) - else: - self.context.append('') - - def depart_target(self, node): - self.body.append(self.context.pop()) - - def visit_tbody(self, node): - # BUG write preamble if not yet done (colspecs not []) - # for tables without heads. - if not self.active_table.get('preamble written'): - self.visit_thead(None) - # self.depart_thead(None) - - def depart_tbody(self, node): - pass - - def visit_term(self, node): - self.body.append('\\item[{') - - def depart_term(self, node): - # definition list term. - self.body.append('}] ') - - def visit_tgroup(self, node): - #self.body.append(self.starttag(node, 'colgroup')) - #self.context.append('\n') - pass - - def depart_tgroup(self, node): - pass - - def visit_thead(self, node): - self.body.append('{%s}\n' % self.active_table.get_colspecs()) - if self.active_table.caption: - self.body.append('\\caption{%s}\\\\\n' % self.active_table.caption) - self.active_table.set('preamble written',1) - # TODO longtable supports firsthead and lastfoot too. - self.body.extend(self.active_table.visit_thead()) - - def depart_thead(self, node): - # the table header written should be on every page - # => \endhead - self.body.extend(self.active_table.depart_thead()) - # and the firsthead => \endfirsthead - # BUG i want a "continued from previous page" on every not - # firsthead, but then we need the header twice. - # - # there is a \endfoot and \endlastfoot too. - # but we need the number of columns to - # self.body.append('\\multicolumn{%d}{c}{"..."}\n' % number_of_columns) - # self.body.append('\\hline\n\\endfoot\n') - # self.body.append('\\hline\n') - # self.body.append('\\endlastfoot\n') - - def visit_tip(self, node): - self.visit_admonition(node, 'tip') - - def depart_tip(self, node): - self.depart_admonition() - - def bookmark(self, node): - """Append latex href and pdfbookmarks for titles. - """ - if node.parent['ids']: - for id in node.parent['ids']: - self.body.append('\\hypertarget{%s}{}\n' % id) - if not self.use_latex_toc: - # BUG level depends on style. pdflatex allows level 0 to 3 - # ToC would be the only on level 0 so i choose to decrement the rest. - # "Table of contents" bookmark to see the ToC. To avoid this - # we set all zeroes to one. - l = self.section_level - if l>0: - l = l-1 - # pdftex does not like "_" subscripts in titles - text = self.encode(node.astext()) - for id in node.parent['ids']: - self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ - (l, text, id)) - - def visit_title(self, node): - """Only 3 section levels are supported by LaTeX article (AFAIR).""" - - if isinstance(node.parent, nodes.topic): - # section titles before the table of contents. - self.bookmark(node) - # BUG: latex chokes on center environment with "perhaps a missing item". - # so we use hfill. - self.body.append('\\subsubsection*{~\\hfill ') - # the closing brace for subsection. - self.context.append('\\hfill ~}\n') - # TODO: for admonition titles before the first section - # either specify every possible node or ... ? - elif isinstance(node.parent, nodes.sidebar) \ - or isinstance(node.parent, nodes.admonition): - self.body.append('\\textbf{\\large ') - self.context.append('}\n\\smallskip\n') - elif isinstance(node.parent, nodes.table): - # caption must be written after column spec - self.active_table.caption = self.encode(node.astext()) - raise nodes.SkipNode - elif self.section_level == 0: - # document title - self.title = self.encode(node.astext()) - if not self.pdfinfo == None: - self.pdfinfo.append( 'pdftitle={%s}' % self.encode(node.astext()) ) - raise nodes.SkipNode - else: - self.body.append('\n\n') - self.body.append('%' + '_' * 75) - self.body.append('\n\n') - self.bookmark(node) - - if self.use_latex_toc: - section_star = "" - else: - section_star = "*" - - section_name = self.d_class.section(self.section_level) - self.body.append('\\%s%s{' % (section_name, section_star)) - - self.context.append('}\n') - - def depart_title(self, node): - self.body.append(self.context.pop()) - - def visit_topic(self, node): - self.topic_classes = node['classes'] - if 'contents' in node['classes'] and self.use_latex_toc: - self.body.append('\\tableofcontents\n\n\\bigskip\n') - self.topic_classes = [] - raise nodes.SkipNode - - def visit_inline(self, node): # titlereference - self.body.append( '\\docutilsrole%s{' % node.get('class')) - - def depart_inline(self, node): - self.body.append( '}' ) - - def depart_topic(self, node): - self.topic_classes = [] - self.body.append('\n') - - def visit_rubric(self, node): - self.body.append('\\rubric{') - self.context.append('}\n') - - def depart_rubric(self, node): - self.body.append(self.context.pop()) - - def visit_transition(self, node): - self.body.append('\n\n') - self.body.append('%' + '_' * 75) - self.body.append('\n\\hspace*{\\fill}\\hrulefill\\hspace*{\\fill}') - self.body.append('\n\n') - - def depart_transition(self, node): - pass - - def visit_version(self, node): - self.visit_docinfo_item(node, 'version') - - def depart_version(self, node): - self.depart_docinfo_item(node) - - def visit_warning(self, node): - self.visit_admonition(node, 'warning') - - def depart_warning(self, node): - self.depart_admonition() - - def unimplemented_visit(self, node): - raise NotImplementedError('visiting unimplemented node type: %s' - % node.__class__.__name__) - -# def unknown_visit(self, node): -# def default_visit(self, node): - -# vim: set ts=4 et ai : diff --git a/docutils/writers/latex2e/__init__.py b/docutils/writers/latex2e/__init__.py new file mode 100644 index 000000000..695160dd4 --- /dev/null +++ b/docutils/writers/latex2e/__init__.py @@ -0,0 +1,2050 @@ +""" +:Author: Engelbert Gruber +:Contact: grubert@users.sourceforge.net +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +LaTeX2e document tree Writer. +""" + +__docformat__ = 'reStructuredText' + +# code contributions from several people included, thanks to all. +# some named: David Abrahams, Julien Letessier, Lele Gaifax, and others. +# +# convention deactivate code by two # e.g. ##. + +import sys +import time +import re +import string +from types import ListType +from docutils import frontend, nodes, languages, writers, utils + + +class Writer(writers.Writer): + + supported = ('latex','latex2e') + """Formats this writer supports.""" + + settings_spec = ( + 'LaTeX-Specific Options', + 'The LaTeX "--output-encoding" default is "latin-1:strict".', + (('Specify documentclass. Default is "article".', + ['--documentclass'], + {'default': 'article', }), + ('Specify document options. Multiple options can be given, ' + 'separated by commas. Default is "10pt,a4paper".', + ['--documentoptions'], + {'default': '10pt,a4paper', }), + ('Use LaTeX footnotes. LaTeX supports only numbered footnotes (does it?). ' + 'Default: no, uses figures.', + ['--use-latex-footnotes'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Format for footnote references: one of "superscript" or ' + '"brackets". Default is "superscript".', + ['--footnote-references'], + {'choices': ['superscript', 'brackets'], 'default': 'superscript', + 'metavar': '', + 'overrides': 'trim_footnote_reference_space'}), + ('Use LaTeX citations. ' + 'Default: no, uses figures which might get mixed with images.', + ['--use-latex-citations'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Format for block quote attributions: one of "dash" (em-dash ' + 'prefix), "parentheses"/"parens", or "none". Default is "dash".', + ['--attribution'], + {'choices': ['dash', 'parentheses', 'parens', 'none'], + 'default': 'dash', 'metavar': ''}), + ('Specify a stylesheet file. The file will be "input" by latex in ' + 'the document header. Default is no stylesheet (""). ' + 'Overrides --stylesheet-path.', + ['--stylesheet'], + {'default': '', 'metavar': '', + 'overrides': 'stylesheet_path'}), + ('Specify a stylesheet file, relative to the current working ' + 'directory. Overrides --stylesheet.', + ['--stylesheet-path'], + {'metavar': '', 'overrides': 'stylesheet'}), + ('Table of contents by docutils (default) or latex. Latex (writer) ' + 'supports only one ToC per document, but docutils does not write ' + 'pagenumbers.', + ['--use-latex-toc'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Let LaTeX print author and date, do not show it in docutils ' + 'document info.', + ['--use-latex-docinfo'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Color of any hyperlinks embedded in text ' + '(default: "blue", "0" to disable).', + ['--hyperlink-color'], {'default': 'blue'}), + ('Enable compound enumerators for nested enumerated lists ' + '(e.g. "1.2.a.ii"). Default: disabled.', + ['--compound-enumerators'], + {'default': None, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compound enumerators for nested enumerated lists. This is ' + 'the default.', + ['--no-compound-enumerators'], + {'action': 'store_false', 'dest': 'compound_enumerators'}), + ('Enable section ("." subsection ...) prefixes for compound ' + 'enumerators. This has no effect without --compound-enumerators. ' + 'Default: disabled.', + ['--section-prefix-for-enumerators'], + {'default': None, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable section prefixes for compound enumerators. ' + 'This is the default.', + ['--no-section-prefix-for-enumerators'], + {'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}), + ('Set the separator between section number and enumerator ' + 'for compound enumerated lists. Default is "-".', + ['--section-enumerator-separator'], + {'default': '-', 'metavar': ''}), + ('When possibile, use verbatim for literal-blocks. ' + 'Default is to always use the mbox environment.', + ['--use-verbatim-when-possible'], + {'default': 0, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Table style. "standard" with horizontal and vertical lines, ' + '"booktabs" (LaTeX booktabs style) only horizontal lines ' + 'above and below the table and below the header or "nolines". ' + 'Default: "standard"', + ['--table-style'], + {'choices': ['standard', 'booktabs','nolines'], 'default': 'standard', + 'metavar': ''}), + ('LaTeX graphicx package option. ' + 'Possible values are "dvips", "pdftex". "auto" includes LaTeX code ' + 'to use "pdftex" if processing with pdf(la)tex and dvips otherwise. ' + 'Default is no option.', + ['--graphicx-option'], + {'default': ''}), + ('LaTeX font encoding. ' + 'Possible values are "T1", "OT1", "" or some other fontenc option. ' + 'The font encoding influences available symbols, e.g. "<<" as one ' + 'character. Default is "" which leads to package "ae" (a T1 ' + 'emulation using CM fonts).', + ['--font-encoding'], + {'default': ''}), + ),) + + settings_defaults = {'output_encoding': 'latin-1'} + + relative_path_settings = ('stylesheet_path',) + + config_section = 'latex2e writer' + config_section_dependencies = ('writers',) + + output = None + """Final translated form of `document`.""" + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = LaTeXTranslator + + def translate(self): + visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + self.head_prefix = visitor.head_prefix + self.head = visitor.head + self.body_prefix = visitor.body_prefix + self.body = visitor.body + self.body_suffix = visitor.body_suffix + +""" +Notes on LaTeX +-------------- + +* latex does not support multiple tocs in one document. + (might be no limitation except for docutils documentation) + +* width + + * linewidth - width of a line in the local environment + * textwidth - the width of text on the page + + Maybe always use linewidth ? + + *Bug* inside a minipage a (e.g. Sidebar) the linewidth is + not changed, needs fix in docutils so that tables + are not too wide. + + So we add locallinewidth set it initially and + on entering sidebar and reset on exit. +""" + +class Babel: + """Language specifics for LaTeX.""" + # country code by a.schlock. + # partly manually converted from iso and babel stuff, dialects and some + _ISO639_TO_BABEL = { + 'no': 'norsk', #XXX added by hand ( forget about nynorsk?) + 'gd': 'scottish', #XXX added by hand + 'hu': 'magyar', #XXX added by hand + 'pt': 'portuguese',#XXX added by hand + 'sl': 'slovenian', + 'af': 'afrikaans', + 'bg': 'bulgarian', + 'br': 'breton', + 'ca': 'catalan', + 'cs': 'czech', + 'cy': 'welsh', + 'da': 'danish', + 'fr': 'french', + # french, francais, canadien, acadian + 'de': 'ngerman', #XXX rather than german + # ngerman, naustrian, german, germanb, austrian + 'el': 'greek', + 'en': 'english', + # english, USenglish, american, UKenglish, british, canadian + 'eo': 'esperanto', + 'es': 'spanish', + 'et': 'estonian', + 'eu': 'basque', + 'fi': 'finnish', + 'ga': 'irish', + 'gl': 'galician', + 'he': 'hebrew', + 'hr': 'croatian', + 'hu': 'hungarian', + 'is': 'icelandic', + 'it': 'italian', + 'la': 'latin', + 'nl': 'dutch', + 'pl': 'polish', + 'pt': 'portuguese', + 'ro': 'romanian', + 'ru': 'russian', + 'sk': 'slovak', + 'sr': 'serbian', + 'sv': 'swedish', + 'tr': 'turkish', + 'uk': 'ukrainian' + } + + def __init__(self,lang): + self.language = lang + # pdflatex does not produce double quotes for ngerman in tt. + self.double_quote_replacment = None + if re.search('^de',self.language): + #self.quotes = ("\"`", "\"'") + self.quotes = ('{\\glqq}', '{\\grqq}') + self.double_quote_replacment = "{\\dq}" + else: + self.quotes = ("``", "''") + self.quote_index = 0 + + def next_quote(self): + q = self.quotes[self.quote_index] + self.quote_index = (self.quote_index+1)%2 + return q + + def quote_quotes(self,text): + t = None + for part in text.split('"'): + if t == None: + t = part + else: + t += self.next_quote() + part + return t + + def double_quotes_in_tt (self,text): + if not self.double_quote_replacment: + return text + return text.replace('"', self.double_quote_replacment) + + def get_language(self): + if self._ISO639_TO_BABEL.has_key(self.language): + return self._ISO639_TO_BABEL[self.language] + else: + # support dialects. + l = self.language.split("_")[0] + if self._ISO639_TO_BABEL.has_key(l): + return self._ISO639_TO_BABEL[l] + return None + + +latex_headings = { + 'optionlist_environment' : [ + '\\newcommand{\\optionlistlabel}[1]{\\bf #1 \\hfill}\n' + '\\newenvironment{optionlist}[1]\n' + '{\\begin{list}{}\n' + ' {\\setlength{\\labelwidth}{#1}\n' + ' \\setlength{\\rightmargin}{1cm}\n' + ' \\setlength{\\leftmargin}{\\rightmargin}\n' + ' \\addtolength{\\leftmargin}{\\labelwidth}\n' + ' \\addtolength{\\leftmargin}{\\labelsep}\n' + ' \\renewcommand{\\makelabel}{\\optionlistlabel}}\n' + '}{\\end{list}}\n', + ], + 'lineblock_environment' : [ + '\\newlength{\\lineblockindentation}\n' + '\\setlength{\\lineblockindentation}{2.5em}\n' + '\\newenvironment{lineblock}[1]\n' + '{\\begin{list}{}\n' + ' {\\setlength{\\partopsep}{\\parskip}\n' + ' \\addtolength{\\partopsep}{\\baselineskip}\n' + ' \\topsep0pt\\itemsep0.15\\baselineskip\\parsep0pt\n' + ' \\leftmargin#1}\n' + ' \\raggedright}\n' + '{\\end{list}}\n' + ], + 'footnote_floats' : [ + '% begin: floats for footnotes tweaking.\n', + '\\setlength{\\floatsep}{0.5em}\n', + '\\setlength{\\textfloatsep}{\\fill}\n', + '\\addtolength{\\textfloatsep}{3em}\n', + '\\renewcommand{\\textfraction}{0.5}\n', + '\\renewcommand{\\topfraction}{0.5}\n', + '\\renewcommand{\\bottomfraction}{0.5}\n', + '\\setcounter{totalnumber}{50}\n', + '\\setcounter{topnumber}{50}\n', + '\\setcounter{bottomnumber}{50}\n', + '% end floats for footnotes\n', + ], + 'some_commands' : [ + '% some commands, that could be overwritten in the style file.\n' + '\\newcommand{\\rubric}[1]' + '{\\subsection*{~\\hfill {\\it #1} \\hfill ~}}\n' + '\\newcommand{\\titlereference}[1]{\\textsl{#1}}\n' + '% end of "some commands"\n', + ] + } + +class DocumentClass: + """Details of a LaTeX document class.""" + + # BUG: LaTeX has no deeper sections (actually paragrah is no + # section either). + # BUG: No support for unknown document classes. Make 'article' + # default? + _class_sections = { + 'book': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'scrbook': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'report': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'scrreprt': ( 'chapter', 'section', 'subsection', 'subsubsection' ), + 'article': ( 'section', 'subsection', 'subsubsection' ), + 'scrartcl': ( 'section', 'subsection', 'subsubsection' ), + } + _deepest_section = 'subsubsection' + + def __init__(self, document_class): + self.document_class = document_class + + def section(self, level): + """ Return the section name at the given level for the specific + document class. + + Level is 1,2,3..., as level 0 is the title.""" + + sections = self._class_sections[self.document_class] + if level <= len(sections): + return sections[level-1] + else: + return self._deepest_section + +class Table: + """ Manage a table while traversing. + Maybe change to a mixin defining the visit/departs, but then + class Table internal variables are in the Translator. + """ + def __init__(self,latex_type,table_style): + self._latex_type = latex_type + self._table_style = table_style + self._open = 0 + # miscellaneous attributes + self._attrs = {} + self._col_width = [] + self._rowspan = [] + + def open(self): + self._open = 1 + self._col_specs = [] + self.caption = None + self._attrs = {} + self._in_head = 0 # maybe context with search + def close(self): + self._open = 0 + self._col_specs = None + self.caption = None + self._attrs = {} + def is_open(self): + return self._open + def used_packages(self): + if self._table_style == 'booktabs': + return '\\usepackage{booktabs}\n' + return '' + def get_latex_type(self): + return self._latex_type + + def set(self,attr,value): + self._attrs[attr] = value + def get(self,attr): + if self._attrs.has_key(attr): + return self._attrs[attr] + return None + def get_vertical_bar(self): + if self._table_style == 'standard': + return '|' + return '' + # horizontal lines are drawn below a row, because we. + def get_opening(self): + return '\\begin{%s}[c]' % self._latex_type + def get_closing(self): + line = "" + if self._table_style == 'booktabs': + line = '\\bottomrule\n' + elif self._table_style == 'standard': + lines = '\\hline\n' + return '%s\\end{%s}' % (line,self._latex_type) + + def visit_colspec(self,node): + self._col_specs.append(node) + + def get_colspecs(self): + """ + Return column specification for longtable. + + Assumes reST line length being 80 characters. + Table width is hairy. + + === === + ABC DEF + === === + + usually gets to narrow, therefore we add 1 (fiddlefactor). + """ + width = 80 + + total_width = 0.0 + # first see if we get too wide. + for node in self._col_specs: + colwidth = float(node['colwidth']+1) / width + total_width += colwidth + self._col_width = [] + self._rowspan = [] + # donot make it full linewidth + factor = 0.93 + if total_width > 1.0: + factor /= total_width + bar = self.get_vertical_bar() + latex_table_spec = "" + for node in self._col_specs: + colwidth = factor * float(node['colwidth']+1) / width + self._col_width.append(colwidth+0.005) + self._rowspan.append(0) + latex_table_spec += "%sp{%.2f\\locallinewidth}" % (bar,colwidth+0.005) + return latex_table_spec+bar + + def get_column_width(self): + """ return columnwidth for current cell (not multicell) + """ + return "%.2f\\locallinewidth" % self._col_width[self._cell_in_row-1] + + def visit_thead(self): + self._in_thead = 1 + if self._table_style == 'standard': + return ['\\hline\n'] + elif self._table_style == 'booktabs': + return ['\\toprule\n'] + return [] + def depart_thead(self): + a = [] + #if self._table_style == 'standard': + # a.append('\\hline\n') + if self._table_style == 'booktabs': + a.append('\\midrule\n') + a.append('\\endhead\n') + # for longtable one could add firsthead, foot and lastfoot + self._in_thead = 0 + return a + def visit_row(self): + self._cell_in_row = 0 + def depart_row(self): + res = [' \\\\\n'] + self._cell_in_row = None # remove cell counter + for i in range(len(self._rowspan)): + if (self._rowspan[i]>0): + self._rowspan[i] -= 1 + + if self._table_style == 'standard': + rowspans = [] + for i in range(len(self._rowspan)): + if (self._rowspan[i]<=0): + rowspans.append(i+1) + if len(rowspans)==len(self._rowspan): + res.append('\\hline\n') + else: + cline = '' + rowspans.reverse() + # TODO merge clines + while 1: + try: + c_start = rowspans.pop() + except: + break + cline += '\\cline{%d-%d}\n' % (c_start,c_start) + res.append(cline) + return res + + def set_rowspan(self,cell,value): + try: + self._rowspan[cell] = value + except: + pass + def get_rowspan(self,cell): + try: + return self._rowspan[cell] + except: + return 0 + def get_entry_number(self): + return self._cell_in_row + def visit_entry(self): + self._cell_in_row += 1 + + +class LaTeXTranslator(nodes.NodeVisitor): + + # When options are given to the documentclass, latex will pass them + # to other packages, as done with babel. + # Dummy settings might be taken from document settings + + latex_head = '\\documentclass[%s]{%s}\n' + encoding = '\\usepackage[%s]{inputenc}\n' + linking = '\\usepackage[colorlinks=%s,linkcolor=%s,urlcolor=%s]{hyperref}\n' + stylesheet = '\\input{%s}\n' + # add a generated on day , machine by user using docutils version. + generator = '%% generator Docutils: http://docutils.sourceforge.net/\n' + + # use latex tableofcontents or let docutils do it. + use_latex_toc = 0 + + # TODO: use mixins for different implementations. + # list environment for option-list. else tabularx + use_optionlist_for_option_list = 1 + # list environment for docinfo. else tabularx + use_optionlist_for_docinfo = 0 # NOT YET IN USE + + # Use compound enumerations (1.A.1.) + compound_enumerators = 0 + + # If using compound enumerations, include section information. + section_prefix_for_enumerators = 0 + + # This is the character that separates the section ("." subsection ...) + # prefix from the regular list enumerator. + section_enumerator_separator = '-' + + # default link color + hyperlink_color = "blue" + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = settings = document.settings + self.latex_encoding = self.to_latex_encoding(settings.output_encoding) + self.use_latex_toc = settings.use_latex_toc + self.use_latex_docinfo = settings.use_latex_docinfo + self.use_latex_footnotes = settings.use_latex_footnotes + self._use_latex_citations = settings.use_latex_citations + self.hyperlink_color = settings.hyperlink_color + self.compound_enumerators = settings.compound_enumerators + self.font_encoding = settings.font_encoding + self.section_prefix_for_enumerators = ( + settings.section_prefix_for_enumerators) + self.section_enumerator_separator = ( + settings.section_enumerator_separator.replace('_', '\\_')) + if self.hyperlink_color == '0': + self.hyperlink_color = 'black' + self.colorlinks = 'false' + else: + self.colorlinks = 'true' + + # language: labels, bibliographic_fields, and author_separators. + # to allow writing labes for specific languages. + self.language = languages.get_language(settings.language_code) + self.babel = Babel(settings.language_code) + self.author_separator = self.language.author_separators[0] + self.d_options = self.settings.documentoptions + if self.babel.get_language(): + self.d_options += ',%s' % \ + self.babel.get_language() + + self.d_class = DocumentClass(settings.documentclass) + # object for a table while proccessing. + self.active_table = Table('longtable',settings.table_style) + + # HACK. Should have more sophisticated typearea handling. + if settings.documentclass.find('scr') == -1: + self.typearea = '\\usepackage[DIV12]{typearea}\n' + else: + if self.d_options.find('DIV') == -1 and self.d_options.find('BCOR') == -1: + self.typearea = '\\typearea{12}\n' + else: + self.typearea = '' + + if self.font_encoding == 'OT1': + fontenc_header = '' + elif self.font_encoding == '': + fontenc_header = '\\usepackage{ae}\n\\usepackage{aeguill}\n' + else: + fontenc_header = '\\usepackage[%s]{fontenc}\n' % (self.font_encoding,) + input_encoding = self.encoding % self.latex_encoding + if self.settings.graphicx_option == '': + self.graphicx_package = '\\usepackage{graphicx}\n' + elif self.settings.graphicx_option.lower() == 'auto': + self.graphicx_package = '\n'.join( + ('%Check if we are compiling under latex or pdflatex', + '\\ifx\\pdftexversion\\undefined', + ' \\usepackage{graphicx}', + '\\else', + ' \\usepackage[pdftex]{graphicx}', + '\\fi\n')) + else: + self.graphicx_package = ( + '\\usepackage[%s]{graphicx}\n' % self.settings.graphicx_option) + + self.head_prefix = [ + self.latex_head % (self.d_options,self.settings.documentclass), + '\\usepackage{babel}\n', # language is in documents settings. + fontenc_header, + '\\usepackage{shortvrb}\n', # allows verb in footnotes. + input_encoding, + # * tabularx: for docinfo, automatic width of columns, always on one page. + '\\usepackage{tabularx}\n', + '\\usepackage{longtable}\n', + self.active_table.used_packages(), + # possible other packages. + # * fancyhdr + # * ltxtable is a combination of tabularx and longtable (pagebreaks). + # but ?? + # + # extra space between text in tables and the line above them + '\\setlength{\\extrarowheight}{2pt}\n', + '\\usepackage{amsmath}\n', # what fore amsmath. + self.graphicx_package, + '\\usepackage{color}\n', + '\\usepackage{multirow}\n', + '\\usepackage{ifthen}\n', # before hyperref! + self.linking % (self.colorlinks, self.hyperlink_color, self.hyperlink_color), + self.typearea, + self.generator, + # latex lengths + '\\newlength{\\admonitionwidth}\n', + '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' + # width for docinfo tablewidth + '\\newlength{\\docinfowidth}\n', + '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' + # linewidth of current environment, so tables are not wider + # than the sidebar: using locallinewidth seems to defer evaluation + # of linewidth, this is fixing it. + '\\newlength{\\locallinewidth}\n', + # will be set later. + ] + self.head_prefix.extend( latex_headings['optionlist_environment'] ) + self.head_prefix.extend( latex_headings['lineblock_environment'] ) + self.head_prefix.extend( latex_headings['footnote_floats'] ) + self.head_prefix.extend( latex_headings['some_commands'] ) + ## stylesheet is last: so it might be possible to overwrite defaults. + stylesheet = utils.get_stylesheet_reference(settings) + if stylesheet: + settings.record_dependencies.add(stylesheet) + self.head_prefix.append(self.stylesheet % (stylesheet)) + + if self.linking: # and maybe check for pdf + self.pdfinfo = [ ] + self.pdfauthor = None + # pdftitle, pdfsubject, pdfauthor, pdfkeywords, pdfcreator, pdfproducer + else: + self.pdfinfo = None + # NOTE: Latex wants a date and an author, rst puts this into + # docinfo, so normally we donot want latex author/date handling. + # latex article has its own handling of date and author, deactivate. + # So we always emit \title{...} \author{...} \date{...}, even if the + # "..." are empty strings. + self.head = [ ] + # separate title, so we can appen subtitle. + self.title = '' + # if use_latex_docinfo: collects lists of author/organization/contact/address lines + self.author_stack = [] + self.date = '' + + self.body_prefix = ['\\raggedbottom\n'] + self.body = [] + self.body_suffix = ['\n'] + self.section_level = 0 + self.context = [] + self.topic_classes = [] + # column specification for tables + self.table_caption = None + + # Flags to encode + # --------------- + # verbatim: to tell encode not to encode. + self.verbatim = 0 + # insert_newline: to tell encode to replace blanks by "~". + self.insert_none_breaking_blanks = 0 + # insert_newline: to tell encode to add latex newline. + self.insert_newline = 0 + # mbox_newline: to tell encode to add mbox and newline. + self.mbox_newline = 0 + + # enumeration is done by list environment. + self._enum_cnt = 0 + + # Stack of section counters so that we don't have to use_latex_toc. + # This will grow and shrink as processing occurs. + # Initialized for potential first-level sections. + self._section_number = [0] + + # The current stack of enumerations so that we can expand + # them into a compound enumeration + self._enumeration_counters = [] + + self._bibitems = [] + + # docinfo. + self.docinfo = None + # inside literal block: no quote mangling. + self.literal_block = 0 + self.literal_block_stack = [] + self.literal = 0 + # true when encoding in math mode + self.mathmode = 0 + + def to_latex_encoding(self,docutils_encoding): + """ + Translate docutils encoding name into latex's. + + Default fallback method is remove "-" and "_" chars from docutils_encoding. + + """ + tr = { "iso-8859-1": "latin1", # west european + "iso-8859-2": "latin2", # east european + "iso-8859-3": "latin3", # esperanto, maltese + "iso-8859-4": "latin4", # north european,scandinavian, baltic + "iso-8859-5": "iso88595", # cyrillic (ISO) + "iso-8859-9": "latin5", # turkish + "iso-8859-15": "latin9", # latin9, update to latin1. + "mac_cyrillic": "maccyr", # cyrillic (on Mac) + "windows-1251": "cp1251", # cyrillic (on Windows) + "koi8-r": "koi8-r", # cyrillic (Russian) + "koi8-u": "koi8-u", # cyrillic (Ukrainian) + "windows-1250": "cp1250", # + "windows-1252": "cp1252", # + "us-ascii": "ascii", # ASCII (US) + # unmatched encodings + #"": "applemac", + #"": "ansinew", # windows 3.1 ansi + #"": "ascii", # ASCII encoding for the range 32--127. + #"": "cp437", # dos latine us + #"": "cp850", # dos latin 1 + #"": "cp852", # dos latin 2 + #"": "decmulti", + #"": "latin10", + #"iso-8859-6": "" # arabic + #"iso-8859-7": "" # greek + #"iso-8859-8": "" # hebrew + #"iso-8859-10": "" # latin6, more complete iso-8859-4 + } + if tr.has_key(docutils_encoding.lower()): + return tr[docutils_encoding.lower()] + return docutils_encoding.translate(string.maketrans("",""),"_-").lower() + + def language_label(self, docutil_label): + return self.language.labels[docutil_label] + + latex_equivalents = { + u'\u00A0' : '~', + u'\u2013' : '{--}', + u'\u2014' : '{---}', + u'\u2018' : '`', + u'\u2019' : '\'', + u'\u201A' : ',', + u'\u201C' : '``', + u'\u201D' : '\'\'', + u'\u201E' : ',,', + u'\u2020' : '{\\dag}', + u'\u2021' : '{\\ddag}', + u'\u2026' : '{\\dots}', + u'\u2122' : '{\\texttrademark}', + u'\u21d4' : '{$\\Leftrightarrow$}', + } + + def unicode_to_latex(self,text): + # see LaTeX codec + # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252124 + # Only some special chracters are translated, for documents with many + # utf-8 chars one should use the LaTeX unicode package. + for uchar in self.latex_equivalents.keys(): + text = text.replace(uchar,self.latex_equivalents[uchar]) + return text + + def encode(self, text): + """ + Encode special characters in `text` & return. + # $ % & ~ _ ^ \ { } + Escaping with a backslash does not help with backslashes, ~ and ^. + + < > are only available in math-mode or tt font. (really ?) + $ starts math- mode. + AND quotes: + + """ + if self.verbatim: + return text + # compile the regexps once. do it here so one can see them. + # + # first the braces. + if not self.__dict__.has_key('encode_re_braces'): + self.encode_re_braces = re.compile(r'([{}])') + text = self.encode_re_braces.sub(r'{\\\1}',text) + if not self.__dict__.has_key('encode_re_bslash'): + # find backslash: except in the form '{\{}' or '{\}}'. + self.encode_re_bslash = re.compile(r'(?", '{\\textgreater}') + # then + text = text.replace("&", '{\\&}') + # the ^: + # * verb|^| does not work in mbox. + # * mathmode has wedge. hat{~} would also work. + # text = text.replace("^", '{\\ensuremath{^\\wedge}}') + text = text.replace("^", '{\\textasciicircum}') + text = text.replace("%", '{\\%}') + text = text.replace("#", '{\\#}') + text = text.replace("~", '{\\textasciitilde}') + # Separate compound characters, e.g. "--" to "-{}-". (The + # actual separation is done later; see below.) + separate_chars = '-' + if self.literal_block or self.literal: + # In monospace-font, we also separate ",,", "``" and "''" + # and some other characters which can't occur in + # non-literal text. + separate_chars += ',`\'"<>' + # pdflatex does not produce doublequotes for ngerman. + text = self.babel.double_quotes_in_tt(text) + if self.font_encoding == 'OT1': + # We're using OT1 font-encoding and have to replace + # underscore by underlined blank, because this has + # correct width. + text = text.replace('_', '{\\underline{ }}') + # And the tt-backslash doesn't work in OT1, so we use + # a mirrored slash. + text = text.replace('\\textbackslash', '\\reflectbox{/}') + else: + text = text.replace('_', '{\\_}') + else: + text = self.babel.quote_quotes(text) + text = text.replace("_", '{\\_}') + for char in separate_chars * 2: + # Do it twice ("* 2") becaues otherwise we would replace + # "---" by "-{}--". + text = text.replace(char + char, char + '{}' + char) + if self.insert_newline or self.literal_block: + # Insert a blank before the newline, to avoid + # ! LaTeX Error: There's no line here to end. + text = text.replace("\n", '~\\\\\n') + elif self.mbox_newline: + if self.literal_block: + closings = "}" * len(self.literal_block_stack) + openings = "".join(self.literal_block_stack) + else: + closings = "" + openings = "" + text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings)) + text = text.replace('[', '{[}').replace(']', '{]}') + if self.insert_none_breaking_blanks: + text = text.replace(' ', '~') + if self.latex_encoding != 'utf8': + text = self.unicode_to_latex(text) + return text + + def attval(self, text, + whitespace=re.compile('[\n\r\t\v\f]')): + """Cleanse, encode, and return attribute value text.""" + return self.encode(whitespace.sub(' ', text)) + + def astext(self): + if self.pdfinfo is not None: + if self.pdfauthor: + self.pdfinfo.append('pdfauthor={%s}' % self.pdfauthor) + if self.pdfinfo: + pdfinfo = '\\hypersetup{\n' + ',\n'.join(self.pdfinfo) + '\n}\n' + else: + pdfinfo = '' + head = '\\title{%s}\n\\author{%s}\n\\date{%s}\n' % \ + (self.title, + ' \\and\n'.join(['~\\\\\n'.join(author_lines) + for author_lines in self.author_stack]), + self.date) + return ''.join(self.head_prefix + [head] + self.head + [pdfinfo] + + self.body_prefix + self.body + self.body_suffix) + + def visit_Text(self, node): + self.body.append(self.encode(node.astext())) + + def depart_Text(self, node): + pass + + def visit_address(self, node): + self.visit_docinfo_item(node, 'address') + + def depart_address(self, node): + self.depart_docinfo_item(node) + + def visit_admonition(self, node, name=''): + self.body.append('\\begin{center}\\begin{sffamily}\n') + self.body.append('\\fbox{\\parbox{\\admonitionwidth}{\n') + if name: + self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n'); + self.body.append('\\vspace{2mm}\n') + + + def depart_admonition(self, node=None): + self.body.append('}}\n') # end parbox fbox + self.body.append('\\end{sffamily}\n\\end{center}\n'); + + def visit_attention(self, node): + self.visit_admonition(node, 'attention') + + def depart_attention(self, node): + self.depart_admonition() + + def visit_author(self, node): + self.visit_docinfo_item(node, 'author') + + def depart_author(self, node): + self.depart_docinfo_item(node) + + def visit_authors(self, node): + # not used: visit_author is called anyway for each author. + pass + + def depart_authors(self, node): + pass + + def visit_block_quote(self, node): + self.body.append( '\\begin{quote}\n') + + def depart_block_quote(self, node): + self.body.append( '\\end{quote}\n') + + def visit_bullet_list(self, node): + if 'contents' in self.topic_classes: + if not self.use_latex_toc: + self.body.append( '\\begin{list}{}{}\n' ) + else: + self.body.append( '\\begin{itemize}\n' ) + + def depart_bullet_list(self, node): + if 'contents' in self.topic_classes: + if not self.use_latex_toc: + self.body.append( '\\end{list}\n' ) + else: + self.body.append( '\\end{itemize}\n' ) + + # Imperfect superscript/subscript handling: mathmode italicizes + # all letters by default. + def visit_superscript(self, node): + self.body.append('$^{') + self.mathmode = 1 + + def depart_superscript(self, node): + self.body.append('}$') + self.mathmode = 0 + + def visit_subscript(self, node): + self.body.append('$_{') + self.mathmode = 1 + + def depart_subscript(self, node): + self.body.append('}$') + self.mathmode = 0 + + def visit_caption(self, node): + self.body.append( '\\caption{' ) + + def depart_caption(self, node): + self.body.append('}') + + def visit_caution(self, node): + self.visit_admonition(node, 'caution') + + def depart_caution(self, node): + self.depart_admonition() + + def visit_title_reference(self, node): + self.body.append( '\\titlereference{' ) + + def depart_title_reference(self, node): + self.body.append( '}' ) + + def visit_citation(self, node): + # TODO maybe use cite bibitems + if self._use_latex_citations: + self.context.append(len(self.body)) + else: + self.body.append('\\begin{figure}[b]') + for id in node['ids']: + self.body.append('\\hypertarget{%s}' % id) + + def depart_citation(self, node): + if self._use_latex_citations: + size = self.context.pop() + label = self.body[size] + text = ''.join(self.body[size+1:]) + del self.body[size:] + self._bibitems.append([label, text]) + else: + self.body.append('\\end{figure}\n') + + def visit_citation_reference(self, node): + if self._use_latex_citations: + self.body.append('\\cite{') + else: + href = '' + if node.has_key('refid'): + href = node['refid'] + elif node.has_key('refname'): + href = self.document.nameids[node['refname']] + self.body.append('[\\hyperlink{%s}{' % href) + + def depart_citation_reference(self, node): + if self._use_latex_citations: + self.body.append('}') + else: + self.body.append('}]') + + def visit_classifier(self, node): + self.body.append( '(\\textbf{' ) + + def depart_classifier(self, node): + self.body.append( '})\n' ) + + def visit_colspec(self, node): + self.active_table.visit_colspec(node) + + def depart_colspec(self, node): + pass + + def visit_comment(self, node): + # Escape end of line by a new comment start in comment text. + self.body.append('%% %s \n' % node.astext().replace('\n', '\n% ')) + raise nodes.SkipNode + + def visit_compound(self, node): + pass + + def depart_compound(self, node): + pass + + def visit_contact(self, node): + self.visit_docinfo_item(node, 'contact') + + def depart_contact(self, node): + self.depart_docinfo_item(node) + + def visit_container(self, node): + pass + + def depart_container(self, node): + pass + + def visit_copyright(self, node): + self.visit_docinfo_item(node, 'copyright') + + def depart_copyright(self, node): + self.depart_docinfo_item(node) + + def visit_danger(self, node): + self.visit_admonition(node, 'danger') + + def depart_danger(self, node): + self.depart_admonition() + + def visit_date(self, node): + self.visit_docinfo_item(node, 'date') + + def depart_date(self, node): + self.depart_docinfo_item(node) + + def visit_decoration(self, node): + pass + + def depart_decoration(self, node): + pass + + def visit_definition(self, node): + self.body.append('%[visit_definition]\n') + + def depart_definition(self, node): + self.body.append('\n') + self.body.append('%[depart_definition]\n') + + def visit_definition_list(self, node): + self.body.append( '\\begin{description}\n' ) + + def depart_definition_list(self, node): + self.body.append( '\\end{description}\n' ) + + def visit_definition_list_item(self, node): + self.body.append('%[visit_definition_list_item]\n') + + def depart_definition_list_item(self, node): + self.body.append('%[depart_definition_list_item]\n') + + def visit_description(self, node): + if self.use_optionlist_for_option_list: + self.body.append( ' ' ) + else: + self.body.append( ' & ' ) + + def depart_description(self, node): + pass + + def visit_docinfo(self, node): + self.docinfo = [] + self.docinfo.append('%' + '_'*75 + '\n') + self.docinfo.append('\\begin{center}\n') + self.docinfo.append('\\begin{tabularx}{\\docinfowidth}{lX}\n') + + def depart_docinfo(self, node): + self.docinfo.append('\\end{tabularx}\n') + self.docinfo.append('\\end{center}\n') + self.body = self.docinfo + self.body + # clear docinfo, so field names are no longer appended. + self.docinfo = None + + def visit_docinfo_item(self, node, name): + if name == 'author': + if not self.pdfinfo == None: + if not self.pdfauthor: + self.pdfauthor = self.attval(node.astext()) + else: + self.pdfauthor += self.author_separator + self.attval(node.astext()) + if self.use_latex_docinfo: + if name in ('author', 'organization', 'contact', 'address'): + # We attach these to the last author. If any of them precedes + # the first author, put them in a separate "author" group (for + # no better semantics). + if name == 'author' or not self.author_stack: + self.author_stack.append([]) + if name == 'address': # newlines are meaningful + self.insert_newline = 1 + text = self.encode(node.astext()) + self.insert_newline = 0 + else: + text = self.attval(node.astext()) + self.author_stack[-1].append(text) + raise nodes.SkipNode + elif name == 'date': + self.date = self.attval(node.astext()) + raise nodes.SkipNode + self.docinfo.append('\\textbf{%s}: &\n\t' % self.language_label(name)) + if name == 'address': + self.insert_newline = 1 + self.docinfo.append('{\\raggedright\n') + self.context.append(' } \\\\\n') + else: + self.context.append(' \\\\\n') + self.context.append(self.docinfo) + self.context.append(len(self.body)) + + def depart_docinfo_item(self, node): + size = self.context.pop() + dest = self.context.pop() + tail = self.context.pop() + tail = self.body[size:] + [tail] + del self.body[size:] + dest.extend(tail) + # for address we did set insert_newline + self.insert_newline = 0 + + def visit_doctest_block(self, node): + self.body.append( '\\begin{verbatim}' ) + self.verbatim = 1 + + def depart_doctest_block(self, node): + self.body.append( '\\end{verbatim}\n' ) + self.verbatim = 0 + + def visit_document(self, node): + self.body_prefix.append('\\begin{document}\n') + # titled document? + if self.use_latex_docinfo or len(node) and isinstance(node[0], nodes.title): + self.body_prefix.append('\\maketitle\n\n') + # alternative use titlepage environment. + # \begin{titlepage} + self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') + + def depart_document(self, node): + # TODO insertion point of bibliography should none automatic. + if self._use_latex_citations and len(self._bibitems)>0: + widest_label = "" + for bi in self._bibitems: + if len(widest_label) 14: + self.body.append('\\multicolumn{2}{l}{') + self.context.append('} \\\\\n ') + else: + self.context.append('') + self.body.append('\\texttt{') + # flag for first option + self.context.append(0) + + def depart_option_group(self, node): + self.context.pop() # the flag + if self.use_optionlist_for_option_list: + self.body.append('] ') + else: + self.body.append('}') + self.body.append(self.context.pop()) + + def visit_option_list(self, node): + self.body.append('% [option list]\n') + if self.use_optionlist_for_option_list: + self.body.append('\\begin{optionlist}{3cm}\n') + else: + self.body.append('\\begin{center}\n') + # BUG: use admwidth or make it relative to textwidth ? + self.body.append('\\begin{tabularx}{.9\\linewidth}{lX}\n') + + def depart_option_list(self, node): + if self.use_optionlist_for_option_list: + self.body.append('\\end{optionlist}\n') + else: + self.body.append('\\end{tabularx}\n') + self.body.append('\\end{center}\n') + + def visit_option_list_item(self, node): + pass + + def depart_option_list_item(self, node): + if not self.use_optionlist_for_option_list: + self.body.append('\\\\\n') + + def visit_option_string(self, node): + ##self.body.append(self.starttag(node, 'span', '', CLASS='option')) + pass + + def depart_option_string(self, node): + ##self.body.append('') + pass + + def visit_organization(self, node): + self.visit_docinfo_item(node, 'organization') + + def depart_organization(self, node): + self.depart_docinfo_item(node) + + def visit_paragraph(self, node): + index = node.parent.index(node) + if not ('contents' in self.topic_classes or + (isinstance(node.parent, nodes.compound) and + index > 0 and + not isinstance(node.parent[index - 1], nodes.paragraph) and + not isinstance(node.parent[index - 1], nodes.compound))): + self.body.append('\n') + + def depart_paragraph(self, node): + self.body.append('\n') + + def visit_problematic(self, node): + self.body.append('{\\color{red}\\bfseries{}') + + def depart_problematic(self, node): + self.body.append('}') + + def visit_raw(self, node): + if 'latex' in node.get('format', '').split(): + self.body.append(node.astext()) + raise nodes.SkipNode + + def visit_reference(self, node): + # BUG: hash_char "#" is trouble some in LaTeX. + # mbox and other environment do not like the '#'. + hash_char = '\\#' + if node.has_key('refuri'): + href = node['refuri'].replace('#',hash_char) + elif node.has_key('refid'): + href = hash_char + node['refid'] + elif node.has_key('refname'): + href = hash_char + self.document.nameids[node['refname']] + else: + raise AssertionError('Unknown reference.') + self.body.append('\\href{%s}{' % href) + + def depart_reference(self, node): + self.body.append('}') + + def visit_revision(self, node): + self.visit_docinfo_item(node, 'revision') + + def depart_revision(self, node): + self.depart_docinfo_item(node) + + def visit_section(self, node): + self.section_level += 1 + # Initialize counter for potential subsections: + self._section_number.append(0) + # Counter for this section's level (initialized by parent section): + self._section_number[self.section_level - 1] += 1 + + def depart_section(self, node): + # Remove counter for potential subsections: + self._section_number.pop() + self.section_level -= 1 + + def visit_sidebar(self, node): + # BUG: this is just a hack to make sidebars render something + self.body.append('\n\\setlength{\\locallinewidth}{0.9\\admonitionwidth}\n') + self.body.append('\\begin{center}\\begin{sffamily}\n') + self.body.append('\\fbox{\\colorbox[gray]{0.80}{\\parbox{\\admonitionwidth}{\n') + + def depart_sidebar(self, node): + self.body.append('}}}\n') # end parbox colorbox fbox + self.body.append('\\end{sffamily}\n\\end{center}\n'); + self.body.append('\n\\setlength{\\locallinewidth}{\\linewidth}\n') + + + attribution_formats = {'dash': ('---', ''), + 'parentheses': ('(', ')'), + 'parens': ('(', ')'), + 'none': ('', '')} + + def visit_attribution(self, node): + prefix, suffix = self.attribution_formats[self.settings.attribution] + self.body.append('\n\\begin{flushright}\n') + self.body.append(prefix) + self.context.append(suffix) + + def depart_attribution(self, node): + self.body.append(self.context.pop() + '\n') + self.body.append('\\end{flushright}\n') + + def visit_status(self, node): + self.visit_docinfo_item(node, 'status') + + def depart_status(self, node): + self.depart_docinfo_item(node) + + def visit_strong(self, node): + self.body.append('\\textbf{') + self.literal_block_stack.append('\\textbf{') + + def depart_strong(self, node): + self.body.append('}') + self.literal_block_stack.pop() + + def visit_substitution_definition(self, node): + raise nodes.SkipNode + + def visit_substitution_reference(self, node): + self.unimplemented_visit(node) + + def visit_subtitle(self, node): + if isinstance(node.parent, nodes.sidebar): + self.body.append('~\\\\\n\\textbf{') + self.context.append('}\n\\smallskip\n') + elif isinstance(node.parent, nodes.document): + self.title = self.title + \ + '\\\\\n\\large{%s}\n' % self.encode(node.astext()) + raise nodes.SkipNode + elif isinstance(node.parent, nodes.section): + self.body.append('\\textbf{') + self.context.append('}\\vspace{0.2cm}\n\n\\noindent ') + + def depart_subtitle(self, node): + self.body.append(self.context.pop()) + + def visit_system_message(self, node): + pass + + def depart_system_message(self, node): + self.body.append('\n') + + def visit_table(self, node): + if self.active_table.is_open(): + print 'nested tables are not supported' + raise AssertionError + self.active_table.open() + self.body.append('\n' + self.active_table.get_opening()) + + def depart_table(self, node): + self.body.append(self.active_table.get_closing() + '\n') + self.active_table.close() + + def visit_target(self, node): + # BUG: why not (refuri or refid or refname) means not footnote ? + if not (node.has_key('refuri') or node.has_key('refid') + or node.has_key('refname')): + for id in node['ids']: + self.body.append('\\hypertarget{%s}{' % id) + self.context.append('}' * len(node['ids'])) + else: + self.context.append('') + + def depart_target(self, node): + self.body.append(self.context.pop()) + + def visit_tbody(self, node): + # BUG write preamble if not yet done (colspecs not []) + # for tables without heads. + if not self.active_table.get('preamble written'): + self.visit_thead(None) + # self.depart_thead(None) + + def depart_tbody(self, node): + pass + + def visit_term(self, node): + self.body.append('\\item[{') + + def depart_term(self, node): + # definition list term. + self.body.append('}] ') + + def visit_tgroup(self, node): + #self.body.append(self.starttag(node, 'colgroup')) + #self.context.append('\n') + pass + + def depart_tgroup(self, node): + pass + + def visit_thead(self, node): + self.body.append('{%s}\n' % self.active_table.get_colspecs()) + if self.active_table.caption: + self.body.append('\\caption{%s}\\\\\n' % self.active_table.caption) + self.active_table.set('preamble written',1) + # TODO longtable supports firsthead and lastfoot too. + self.body.extend(self.active_table.visit_thead()) + + def depart_thead(self, node): + # the table header written should be on every page + # => \endhead + self.body.extend(self.active_table.depart_thead()) + # and the firsthead => \endfirsthead + # BUG i want a "continued from previous page" on every not + # firsthead, but then we need the header twice. + # + # there is a \endfoot and \endlastfoot too. + # but we need the number of columns to + # self.body.append('\\multicolumn{%d}{c}{"..."}\n' % number_of_columns) + # self.body.append('\\hline\n\\endfoot\n') + # self.body.append('\\hline\n') + # self.body.append('\\endlastfoot\n') + + def visit_tip(self, node): + self.visit_admonition(node, 'tip') + + def depart_tip(self, node): + self.depart_admonition() + + def bookmark(self, node): + """Append latex href and pdfbookmarks for titles. + """ + if node.parent['ids']: + for id in node.parent['ids']: + self.body.append('\\hypertarget{%s}{}\n' % id) + if not self.use_latex_toc: + # BUG level depends on style. pdflatex allows level 0 to 3 + # ToC would be the only on level 0 so i choose to decrement the rest. + # "Table of contents" bookmark to see the ToC. To avoid this + # we set all zeroes to one. + l = self.section_level + if l>0: + l = l-1 + # pdftex does not like "_" subscripts in titles + text = self.encode(node.astext()) + for id in node.parent['ids']: + self.body.append('\\pdfbookmark[%d]{%s}{%s}\n' % \ + (l, text, id)) + + def visit_title(self, node): + """Only 3 section levels are supported by LaTeX article (AFAIR).""" + + if isinstance(node.parent, nodes.topic): + # section titles before the table of contents. + self.bookmark(node) + # BUG: latex chokes on center environment with "perhaps a missing item". + # so we use hfill. + self.body.append('\\subsubsection*{~\\hfill ') + # the closing brace for subsection. + self.context.append('\\hfill ~}\n') + # TODO: for admonition titles before the first section + # either specify every possible node or ... ? + elif isinstance(node.parent, nodes.sidebar) \ + or isinstance(node.parent, nodes.admonition): + self.body.append('\\textbf{\\large ') + self.context.append('}\n\\smallskip\n') + elif isinstance(node.parent, nodes.table): + # caption must be written after column spec + self.active_table.caption = self.encode(node.astext()) + raise nodes.SkipNode + elif self.section_level == 0: + # document title + self.title = self.encode(node.astext()) + if not self.pdfinfo == None: + self.pdfinfo.append( 'pdftitle={%s}' % self.encode(node.astext()) ) + raise nodes.SkipNode + else: + self.body.append('\n\n') + self.body.append('%' + '_' * 75) + self.body.append('\n\n') + self.bookmark(node) + + if self.use_latex_toc: + section_star = "" + else: + section_star = "*" + + section_name = self.d_class.section(self.section_level) + self.body.append('\\%s%s{' % (section_name, section_star)) + + self.context.append('}\n') + + def depart_title(self, node): + self.body.append(self.context.pop()) + + def visit_topic(self, node): + self.topic_classes = node['classes'] + if 'contents' in node['classes'] and self.use_latex_toc: + self.body.append('\\tableofcontents\n\n\\bigskip\n') + self.topic_classes = [] + raise nodes.SkipNode + + def visit_inline(self, node): # titlereference + self.body.append( '\\docutilsrole%s{' % node.get('class')) + + def depart_inline(self, node): + self.body.append( '}' ) + + def depart_topic(self, node): + self.topic_classes = [] + self.body.append('\n') + + def visit_rubric(self, node): + self.body.append('\\rubric{') + self.context.append('}\n') + + def depart_rubric(self, node): + self.body.append(self.context.pop()) + + def visit_transition(self, node): + self.body.append('\n\n') + self.body.append('%' + '_' * 75) + self.body.append('\n\\hspace*{\\fill}\\hrulefill\\hspace*{\\fill}') + self.body.append('\n\n') + + def depart_transition(self, node): + pass + + def visit_version(self, node): + self.visit_docinfo_item(node, 'version') + + def depart_version(self, node): + self.depart_docinfo_item(node) + + def visit_warning(self, node): + self.visit_admonition(node, 'warning') + + def depart_warning(self, node): + self.depart_admonition() + + def unimplemented_visit(self, node): + raise NotImplementedError('visiting unimplemented node type: %s' + % node.__class__.__name__) + +# def unknown_visit(self, node): +# def default_visit(self, node): + +# vim: set ts=4 et ai : diff --git a/docutils/writers/latex2e/latex2e.tex b/docutils/writers/latex2e/latex2e.tex new file mode 100644 index 000000000..6e041a14b --- /dev/null +++ b/docutils/writers/latex2e/latex2e.tex @@ -0,0 +1,74 @@ +% latex include file for docutils latex writer +% -------------------------------------------- +% +% CVS: $Id$ +% +% This is included at the end of the latex header in the generated file, +% to allow overwriting defaults, although this could get hairy. +% Generated files should process well standalone too, LaTeX might give a +% message about a missing file. + +% donot indent first line of paragraph. +\setlength{\parindent}{0pt} +\setlength{\parskip}{5pt plus 2pt minus 1pt} + +% sloppy +% ------ +% Less strict (opposite to default fussy) space size between words. Therefore +% less hyphenation. +\sloppy + +% fonts +% ----- +% times for pdf generation, gives smaller pdf files. +% +% But in standard postscript fonts: courier and times/helvetica do not fit. +% Maybe use pslatex. +\usepackage{times} + +% pagestyle +% --------- +% headings might put section titles in the page heading, but not if +% the table of contents is done by docutils. +% If pagestyle{headings} is used, \geometry{headheight=10pt,headsep=1pt} +% should be set too. +%\pagestyle{plain} +% +% or use fancyhdr (untested !) +%\usepackage{fancyhdr} +%\pagestyle{fancy} +%\addtolength{\headheight}{\\baselineskip} +%\renewcommand{\sectionmark}[1]{\markboth{#1}{}} +%\renewcommand{\subsectionmark}[1]{\markright{#1}} +%\fancyhf{} +%\fancyhead[LE,RO]{\\bfseries\\textsf{\Large\\thepage}} +%\fancyhead[LO]{\\textsf{\\footnotesize\\rightmark}} +%\fancyhead[RE]{\\textsc{\\textsf{\\footnotesize\leftmark}}} +%\\fancyfoot[LE,RO]{\\bfseries\\textsf{\scriptsize Docutils}} +%\fancyfoot[RE,LO]{\\textsf{\scriptsize\\today}} + +% geometry +% -------- +% = papersizes and margins +%\geometry{a4paper,twoside,tmargin=1.5cm, +% headheight=1cm,headsep=0.75cm} + +% Do section number display +% ------------------------- +%\makeatletter +%\def\@seccntformat#1{} +%\makeatother +% no numbers in toc +%\renewcommand{\numberline}[1]{} + + +% change maketitle +% ---------------- +%\renewcommand{\maketitle}{ +% \begin{titlepage} +% \begin{center} +% \textsf{TITLE \@title} \\ +% Date: \today +% \end{center} +% \end{titlepage} +%} diff --git a/docutils/writers/newlatex2e.py b/docutils/writers/newlatex2e.py deleted file mode 100644 index e3d0a738b..000000000 --- a/docutils/writers/newlatex2e.py +++ /dev/null @@ -1,788 +0,0 @@ -""" -:Author: Felix Wiemann -:Contact: Felix_Wiemann@ososo.de -:Revision: $Revision$ -:Date: $Date$ -:Copyright: This module has been placed in the public domain. - -LaTeX2e document tree Writer. -""" - -# Thanks to Engelbert Gruber and various contributors for the original -# LaTeX writer, some code and many ideas of which have been used for -# this writer. - -__docformat__ = 'reStructuredText' - - -import re -import os.path -from types import ListType - -import docutils -from docutils import nodes, writers, utils -from docutils.writers.support.newlatex2e import unicode_map -from docutils.transforms import writer_aux - - -class Writer(writers.Writer): - - supported = ('newlatex', 'newlatex2e') - """Formats this writer supports.""" - - default_stylesheet = 'base.tex' - - default_stylesheet_path = utils.relative_path( - os.path.join(os.getcwd(), 'dummy'), - os.path.join(writers.support_path, 'newlatex2e', default_stylesheet)) - - settings_spec = ( - 'LaTeX-Specific Options', - 'Note that this LaTeX writer is still EXPERIMENTAL. ' - 'You must specify the location of the tools/stylesheets/latex.tex ' - 'stylesheet file contained in the Docutils distribution tarball to ' - 'make the LaTeX output work.', - (('Specify a stylesheet file. The path is used verbatim to include ' - 'the file. Overrides --stylesheet-path.', - ['--stylesheet'], - {'default': '', 'metavar': '', - 'overrides': 'stylesheet_path'}), - ('Specify a stylesheet file, relative to the current working ' - 'directory. Overrides --stylesheet. Default: "%s"' - % default_stylesheet_path, - ['--stylesheet-path'], - {'metavar': '', 'overrides': 'stylesheet', - 'default': default_stylesheet_path}), - ('Specify a user stylesheet file. See --stylesheet.', - ['--user-stylesheet'], - {'default': '', 'metavar': '', - 'overrides': 'user_stylesheet_path'}), - ('Specify a user stylesheet file. See --stylesheet-path.', - ['--user-stylesheet-path'], - {'metavar': '', 'overrides': 'user_stylesheet'}) - ),) - - settings_defaults = { - # Many Unicode characters are provided by unicode_map.py. - 'output_encoding': 'ascii', - 'output_encoding_error_handler': 'strict', - # Since we are using superscript footnotes, it is necessary to - # trim whitespace in front of footnote references. - 'trim_footnote_reference_space': 1, - # Currently unsupported: - 'docinfo_xform': 0, - # During development: - 'traceback': 1 - } - - relative_path_settings = ('stylesheet_path', 'user_stylesheet_path') - - config_section = 'newlatex2e writer' - config_section_dependencies = ('writers',) - - output = None - """Final translated form of `document`.""" - - def get_transforms(self): - return writers.Writer.get_transforms(self) + [writer_aux.Compound] - - def __init__(self): - writers.Writer.__init__(self) - self.translator_class = LaTeXTranslator - - def translate(self): - visitor = self.translator_class(self.document) - self.document.walkabout(visitor) - assert not visitor.context, 'context not empty: %s' % visitor.context - self.output = visitor.astext() - self.head = visitor.header - self.body = visitor.body - - -class LaTeXException(Exception): - """ - Exception base class to for exceptions which influence the - automatic generation of LaTeX code. - """ - - -class SkipAttrParentLaTeX(LaTeXException): - """ - Do not generate \Dattr and \renewcommand{\Dparent}{...} for this - node. - - To be raised from before_... methods. - """ - - -class SkipParentLaTeX(LaTeXException): - """ - Do not generate \renewcommand{\DNparent}{...} for this node. - - To be raised from before_... methods. - """ - - -class LaTeXTranslator(nodes.SparseNodeVisitor): - - # Country code by a.schlock. - # Partly manually converted from iso and babel stuff. - iso639_to_babel = { - 'no': 'norsk', # added by hand - 'gd': 'scottish', # added by hand - 'sl': 'slovenian', - 'af': 'afrikaans', - 'bg': 'bulgarian', - 'br': 'breton', - 'ca': 'catalan', - 'cs': 'czech', - 'cy': 'welsh', - 'da': 'danish', - 'fr': 'french', - # french, francais, canadien, acadian - 'de': 'ngerman', - # ngerman, naustrian, german, germanb, austrian - 'el': 'greek', - 'en': 'english', - # english, USenglish, american, UKenglish, british, canadian - 'eo': 'esperanto', - 'es': 'spanish', - 'et': 'estonian', - 'eu': 'basque', - 'fi': 'finnish', - 'ga': 'irish', - 'gl': 'galician', - 'he': 'hebrew', - 'hr': 'croatian', - 'hu': 'hungarian', - 'is': 'icelandic', - 'it': 'italian', - 'la': 'latin', - 'nl': 'dutch', - 'pl': 'polish', - 'pt': 'portuguese', - 'ro': 'romanian', - 'ru': 'russian', - 'sk': 'slovak', - 'sr': 'serbian', - 'sv': 'swedish', - 'tr': 'turkish', - 'uk': 'ukrainian' - } - - # Start with left double quote. - left_quote = 1 - - def __init__(self, document): - nodes.NodeVisitor.__init__(self, document) - self.settings = document.settings - self.header = [] - self.body = [] - self.context = [] - self.stylesheet_path = utils.get_stylesheet_reference( - self.settings, os.path.join(os.getcwd(), 'dummy')) - if self.stylesheet_path: - self.settings.record_dependencies.add(self.stylesheet_path) - # This ugly hack will be cleaned up when refactoring the - # stylesheet mess. - self.settings.stylesheet = self.settings.user_stylesheet - self.settings.stylesheet_path = self.settings.user_stylesheet_path - self.user_stylesheet_path = utils.get_stylesheet_reference( - self.settings, os.path.join(os.getcwd(), 'dummy')) - if self.user_stylesheet_path: - self.settings.record_dependencies.add(self.user_stylesheet_path) - self.write_header() - - def write_header(self): - a = self.header.append - a('%% Generated by Docutils %s .' - % docutils.__version__) - a('') - a('% Docutils settings:') - lang = self.settings.language_code or '' - a(r'\providecommand{\Dlanguageiso}{%s}' % lang) - a(r'\providecommand{\Dlanguagebabel}{%s}' % self.iso639_to_babel.get( - lang, self.iso639_to_babel.get(lang.split('_')[0], ''))) - a('') - if self.user_stylesheet_path: - a('% User stylesheet:') - a(r'\input{%s}' % self.user_stylesheet_path) - a('% Docutils stylesheet:') - a(r'\input{%s}' % self.stylesheet_path) - a('') - a('% Default definitions for Docutils nodes:') - for node_name in nodes.node_class_names: - a(r'\providecommand{\DN%s}[1]{#1}' % node_name.replace('_', '')) - a('') - a('% Auxiliary definitions:') - a(r'\providecommand{\Dsetattr}[2]{}') - a(r'\providecommand{\Dparent}{} % variable') - a(r'\providecommand{\Dattr}[5]{#5}') - a(r'\providecommand{\Dattrlen}{} % variable') - a(r'\providecommand{\Dtitleastext}{x} % variable') - a(r'\providecommand{\Dsinglebackref}{} % variable') - a(r'\providecommand{\Dmultiplebackrefs}{} % variable') - a(r'\providecommand{\Dparagraphindented}{false} % variable') - a('\n\n') - - unicode_map = unicode_map.unicode_map # comprehensive Unicode map - # Fix problems with unimap.py. - unicode_map.update({ - # We have AE or T1 encoding, so "``" etc. work. The macros - # from unimap.py may *not* work. - u'\u201C': '{``}', - u'\u201D': "{''}", - u'\u201E': '{,,}', - }) - - character_map = { - '\\': r'{\textbackslash}', - '{': r'{\{}', - '}': r'{\}}', - '$': r'{\$}', - '&': r'{\&}', - '%': r'{\%}', - '#': r'{\#}', - '[': r'{[}', - ']': r'{]}', - '-': r'{-}', - '`': r'{`}', - "'": r"{'}", - ',': r'{,}', - '"': r'{"}', - '|': r'{\textbar}', - '<': r'{\textless}', - '>': r'{\textgreater}', - '^': r'{\textasciicircum}', - '~': r'{\textasciitilde}', - '_': r'{\Dtextunderscore}', - } - character_map.update(unicode_map) - #character_map.update(special_map) - - # `att_map` is for encoding attributes. According to - # , - # the following characters are special: # $ % & ~ _ ^ \ { } - # These work without special treatment in macro parameters: - # $, &, ~, _, ^ - att_map = {'#': '\\#', - '%': '\\%', - # We cannot do anything about backslashes. - '\\': '', - '{': '\\{', - '}': '\\}', - # The quotation mark may be redefined by babel. - '"': '"{}', - } - att_map.update(unicode_map) - - def encode(self, text, attval=None): - """ - Encode special characters in ``text`` and return it. - - If attval is true, preserve as much as possible verbatim (used - in attribute value encoding). If attval is 'width' or - 'height', `text` is interpreted as a length value. - """ - if attval in ('width', 'height'): - match = re.match(r'([0-9.]+)(\S*)$', text) - assert match, '%s="%s" must be a length' % (attval, text) - value, unit = match.groups() - if unit == '%': - value = str(float(value) / 100) - unit = r'\Drelativeunit' - elif unit in ('', 'px'): - # If \Dpixelunit is "pt", this gives the same notion - # of pixels as graphicx. - value = str(float(value) * 0.75) - unit = '\Dpixelunit' - return '%s%s' % (value, unit) - if attval: - get = self.att_map.get - else: - get = self.character_map.get - text = ''.join([get(c, c) for c in text]) - if (self.literal_block or self.inline_literal) and not attval: - # NB: We can have inline literals within literal blocks. - # Shrink '\r\n'. - text = text.replace('\r\n', '\n') - # Convert space. If "{ }~~~~~" is wrapped (at the - # brace-enclosed space "{ }"), the following non-breaking - # spaces ("~~~~") do *not* wind up at the beginning of the - # next line. Also note that, for some not-so-obvious - # reason, no hyphenation is done if the breaking space ("{ - # }") comes *after* the non-breaking spaces. - if self.literal_block: - # Replace newlines with real newlines. - text = text.replace('\n', '\mbox{}\\\\') - replace_fn = self.encode_replace_for_literal_block_spaces - else: - replace_fn = self.encode_replace_for_inline_literal_spaces - text = re.sub(r'\s+', replace_fn, text) - # Protect hyphens; if we don't, line breaks will be - # possible at the hyphens and even the \textnhtt macro - # from the hyphenat package won't change that. - text = text.replace('-', r'\mbox{-}') - text = text.replace("'", r'{\Dtextliteralsinglequote}') - return text - else: - if not attval: - # Replace space with single protected space. - text = re.sub(r'\s+', '{ }', text) - # Replace double quotes with macro calls. - L = [] - for part in text.split(self.character_map['"']): - if L: - # Insert quote. - L.append(self.left_quote and r'{\Dtextleftdblquote}' - or r'{\Dtextrightdblquote}') - self.left_quote = not self.left_quote - L.append(part) - return ''.join(L) - else: - return text - - def encode_replace_for_literal_block_spaces(self, match): - return '~' * len(match.group()) - - def encode_replace_for_inline_literal_spaces(self, match): - return '{ }' + '~' * (len(match.group()) - 1) - - def astext(self): - return '\n'.join(self.header) + (''.join(self.body)) - - def append(self, text, newline='%\n'): - """ - Append text, stripping newlines, producing nice LaTeX code. - """ - lines = [' ' * self.indentation_level + line + newline - for line in text.splitlines(0)] - self.body.append(''.join(lines)) - - def visit_Text(self, node): - self.append(self.encode(node.astext())) - - def depart_Text(self, node): - pass - - def is_indented(self, paragraph): - """Return true if `paragraph` should be first-line-indented.""" - assert isinstance(paragraph, nodes.paragraph) - siblings = [n for n in paragraph.parent if - self.is_visible(n) and not isinstance(n, nodes.Titular)] - index = siblings.index(paragraph) - if ('continued' in paragraph['classes'] or - index > 0 and isinstance(siblings[index-1], nodes.transition)): - return 0 - # Indent all but the first paragraphs. - return index > 0 - - def before_paragraph(self, node): - self.append(r'\renewcommand{\Dparagraphindented}{%s}' - % (self.is_indented(node) and 'true' or 'false')) - - def before_title(self, node): - self.append(r'\renewcommand{\Dtitleastext}{%s}' - % self.encode(node.astext())) - self.append(r'\renewcommand{\Dhassubtitle}{%s}' - % ((len(node.parent) > 2 and - isinstance(node.parent[1], nodes.subtitle)) - and 'true' or 'false')) - - def before_generated(self, node): - if 'sectnum' in node['classes']: - node[0] = node[0].strip() - - literal_block = 0 - - def visit_literal_block(self, node): - self.literal_block = 1 - - def depart_literal_block(self, node): - self.literal_block = 0 - - visit_doctest_block = visit_literal_block - depart_doctest_block = depart_literal_block - - inline_literal = 0 - - def visit_literal(self, node): - self.inline_literal += 1 - - def depart_literal(self, node): - self.inline_literal -= 1 - - def visit_comment(self, node): - self.append('\n'.join(['% ' + line for line - in node.astext().splitlines(0)]), newline='\n') - raise nodes.SkipChildren - - def before_topic(self, node): - if 'contents' in node['classes']: - for bullet_list in list(node.traverse(nodes.bullet_list)): - p = bullet_list.parent - if isinstance(p, nodes.list_item): - p.parent.insert(p.parent.index(p) + 1, bullet_list) - del p[1] - for paragraph in node.traverse(nodes.paragraph): - paragraph.attributes.update(paragraph[0].attributes) - paragraph[:] = paragraph[0] - paragraph.parent['tocrefid'] = paragraph['refid'] - node['contents'] = 1 - else: - node['contents'] = 0 - - bullet_list_level = 0 - - def visit_bullet_list(self, node): - self.append(r'\Dsetbullet{\labelitem%s}' % - ['i', 'ii', 'iii', 'iv'][min(self.bullet_list_level, 3)]) - self.bullet_list_level += 1 - - def depart_bullet_list(self, node): - self.bullet_list_level -= 1 - - enum_styles = {'arabic': 'arabic', 'loweralpha': 'alph', 'upperalpha': - 'Alph', 'lowerroman': 'roman', 'upperroman': 'Roman'} - - enum_counter = 0 - - def visit_enumerated_list(self, node): - # We create our own enumeration list environment. This allows - # to set the style and starting value and unlimited nesting. - # Maybe this can be moved to the stylesheet? - self.enum_counter += 1 - enum_prefix = self.encode(node['prefix']) - enum_suffix = self.encode(node['suffix']) - enum_type = '\\' + self.enum_styles.get(node['enumtype'], r'arabic') - start = node.get('start', 1) - 1 - counter = 'Denumcounter%d' % self.enum_counter - self.append(r'\Dmakeenumeratedlist{%s}{%s}{%s}{%s}{%s}{' - % (enum_prefix, enum_type, enum_suffix, counter, start)) - # for Emacs: } - - def depart_enumerated_list(self, node): - self.append('}') # for Emacs: { - - def before_list_item(self, node): - # XXX needs cleanup. - if (len(node) and (isinstance(node[-1], nodes.TextElement) or - isinstance(node[-1], nodes.Text)) and - node.parent.index(node) == len(node.parent) - 1): - node['lastitem'] = 'true' - - before_line = before_list_item - - def before_raw(self, node): - if 'latex' in node.get('format', '').split(): - # We're inserting the text in before_raw and thus outside - # of \DN... and \Dattr in order to make grouping with - # curly brackets work. - self.append(node.astext()) - raise nodes.SkipChildren - - def process_backlinks(self, node, type): - self.append(r'\renewcommand{\Dsinglebackref}{}') - self.append(r'\renewcommand{\Dmultiplebackrefs}{}') - if len(node['backrefs']) > 1: - refs = [] - for i in range(len(node['backrefs'])): - refs.append(r'\Dmulti%sbacklink{%s}{%s}' - % (type, node['backrefs'][i], i + 1)) - self.append(r'\renewcommand{\Dmultiplebackrefs}{(%s){ }}' - % ', '.join(refs)) - elif len(node['backrefs']) == 1: - self.append(r'\renewcommand{\Dsinglebackref}{%s}' - % node['backrefs'][0]) - - def visit_footnote(self, node): - self.process_backlinks(node, 'footnote') - - def visit_citation(self, node): - self.process_backlinks(node, 'citation') - - def before_table(self, node): - # A table contains exactly one tgroup. See before_tgroup. - pass - - def before_tgroup(self, node): - widths = [] - total_width = 0 - for i in range(int(node['cols'])): - assert isinstance(node[i], nodes.colspec) - widths.append(int(node[i]['colwidth']) + 1) - total_width += widths[-1] - del node[:len(widths)] - tablespec = '|' - for w in widths: - # 0.93 is probably wrong in many cases. XXX Find a - # solution which works *always*. - tablespec += r'p{%s\textwidth}|' % (0.93 * w / - max(total_width, 60)) - self.append(r'\Dmaketable{%s}{' % tablespec) - self.context.append('}') - raise SkipAttrParentLaTeX - - def depart_tgroup(self, node): - self.append(self.context.pop()) - - def before_row(self, node): - raise SkipAttrParentLaTeX - - def before_thead(self, node): - raise SkipAttrParentLaTeX - - def before_tbody(self, node): - raise SkipAttrParentLaTeX - - def is_simply_entry(self, node): - return (len(node) == 1 and isinstance(node[0], nodes.paragraph) or - len(node) == 0) - - def before_entry(self, node): - is_leftmost = 0 - if node.hasattr('morerows'): - self.document.reporter.severe('Rowspans are not supported.') - # Todo: Add empty cells below rowspanning cell and issue - # warning instead of severe. - if node.hasattr('morecols'): - # The author got a headache trying to implement - # multicolumn support. - if not self.is_simply_entry(node): - self.document.reporter.severe( - 'Colspanning table cells may only contain one paragraph.') - # Todo: Same as above. - # The number of columns this entry spans (as a string). - colspan = int(node['morecols']) + 1 - del node['morecols'] - else: - colspan = 1 - # Macro to call. - macro_name = r'\Dcolspan' - if node.parent.index(node) == 0: - # Leftmost column. - macro_name += 'left' - is_leftmost = 1 - if colspan > 1: - self.append('%s{%s}{' % (macro_name, colspan)) - self.context.append('}') - else: - # Do not add a multicolumn with colspan 1 beacuse we need - # at least one non-multicolumn cell per column to get the - # desired column widths, and we can only do colspans with - # cells consisting of only one paragraph. - if not is_leftmost: - self.append(r'\Dsubsequententry{') - self.context.append('}') - else: - self.context.append('') - if isinstance(node.parent.parent, nodes.thead): - node['tableheaderentry'] = 'true' - - # Don't add \renewcommand{\Dparent}{...} because there must - # not be any non-expandable commands in front of \multicolumn. - raise SkipParentLaTeX - - def depart_entry(self, node): - self.append(self.context.pop()) - - def before_substitution_definition(self, node): - raise nodes.SkipNode - - indentation_level = 0 - - def node_name(self, node): - return node.__class__.__name__.replace('_', '') - - # Attribute propagation order. - attribute_order = ['align', 'classes', 'ids'] - - def attribute_cmp(self, a1, a2): - """ - Compare attribute names `a1` and `a2`. Used in - propagate_attributes to determine propagation order. - - See built-in function `cmp` for return value. - """ - if a1 in self.attribute_order and a2 in self.attribute_order: - return cmp(self.attribute_order.index(a1), - self.attribute_order.index(a2)) - if (a1 in self.attribute_order) != (a2 in self.attribute_order): - # Attributes not in self.attribute_order come last. - return a1 in self.attribute_order and -1 or 1 - else: - return cmp(a1, a2) - - def propagate_attributes(self, node): - # Propagate attributes using \Dattr macros. - node_name = self.node_name(node) - attlist = [] - if isinstance(node, nodes.Element): - attlist = node.attlist() - attlist.sort(lambda pair1, pair2: self.attribute_cmp(pair1[0], - pair2[0])) - # `numatts` may be greater than len(attlist) due to list - # attributes. - numatts = 0 - pass_contents = self.pass_contents(node) - for key, value in attlist: - if isinstance(value, ListType): - self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) - for i in range(len(value)): - self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % - (i+1, key, self.encode(value[i], attval=key), - node_name)) - if not pass_contents: - self.append('}') - numatts += len(value) - else: - self.append(r'\Dattr{}{%s}{%s}{%s}{' % - (key, self.encode(unicode(value), attval=key), - node_name)) - if not pass_contents: - self.append('}') - numatts += 1 - if pass_contents: - self.context.append('}' * numatts) # for Emacs: { - else: - self.context.append('') - - def visit_docinfo(self, node): - raise NotImplementedError('Docinfo not yet implemented.') - - def visit_document(self, node): - document = node - # Move IDs into TextElements. This won't work for images. - # Need to review this. - for node in document.traverse(nodes.Element): - if node.has_key('ids') and not isinstance(node, - nodes.TextElement): - next_text_element = node.next_node(nodes.TextElement) - if next_text_element: - next_text_element['ids'].extend(node['ids']) - node['ids'] = [] - - def pass_contents(self, node): - r""" - Return true if the node contents should be passed in - parameters of \DN... and \Dattr. - """ - return not isinstance(node, (nodes.document, nodes.section)) - - def dispatch_visit(self, node): - skip_attr = skip_parent = 0 - # TreePruningException to be propagated. - tree_pruning_exception = None - if hasattr(self, 'before_' + node.__class__.__name__): - try: - getattr(self, 'before_' + node.__class__.__name__)(node) - except SkipParentLaTeX: - skip_parent = 1 - except SkipAttrParentLaTeX: - skip_attr = 1 - skip_parent = 1 - except nodes.SkipNode: - raise - except (nodes.SkipChildren, nodes.SkipSiblings), instance: - tree_pruning_exception = instance - except nodes.SkipDeparture: - raise NotImplementedError( - 'SkipDeparture not usable in LaTeX writer') - - if not isinstance(node, nodes.Text): - node_name = self.node_name(node) - # attribute_deleters will be appended to self.context. - attribute_deleters = [] - if not skip_parent and not isinstance(node, nodes.document): - self.append(r'\renewcommand{\Dparent}{%s}' - % self.node_name(node.parent)) - for name, value in node.attlist(): - if not isinstance(value, ListType) and not ':' in name: - macro = r'\DcurrentN%sA%s' % (node_name, name) - self.append(r'\def%s{%s}' % ( - macro, self.encode(unicode(value), attval=name))) - attribute_deleters.append(r'\let%s=\relax' % macro) - self.context.append('\n'.join(attribute_deleters)) - if self.pass_contents(node): - self.append(r'\DN%s{' % node_name) - self.context.append('}') - else: - self.append(r'\Dvisit%s' % node_name) - self.context.append(r'\Ddepart%s' % node_name) - self.indentation_level += 1 - if not skip_attr: - self.propagate_attributes(node) - else: - self.context.append('') - - if (isinstance(node, nodes.TextElement) and - not isinstance(node.parent, nodes.TextElement)): - # Reset current quote to left. - self.left_quote = 1 - - # Call visit_... method. - try: - nodes.SparseNodeVisitor.dispatch_visit(self, node) - except LaTeXException: - raise NotImplementedError( - 'visit_... methods must not raise LaTeXExceptions') - - if tree_pruning_exception: - # Propagate TreePruningException raised in before_... method. - raise tree_pruning_exception - - def is_invisible(self, node): - # Return true if node is invisible or moved away in the LaTeX - # rendering. - return (not isinstance(node, nodes.Text) and - (isinstance(node, nodes.Invisible) or - isinstance(node, nodes.footnote) or - isinstance(node, nodes.citation) or - # Assume raw nodes to be invisible. - isinstance(node, nodes.raw) or - # Floating image or figure. - node.get('align') in ('left', 'right'))) - - def is_visible(self, node): - return not self.is_invisible(node) - - def needs_space(self, node): - """Two nodes for which `needs_space` is true need auxiliary space.""" - # Return true if node is a visible block-level element. - return ((isinstance(node, nodes.Body) or - isinstance(node, nodes.topic)) and - not (self.is_invisible(node) or - isinstance(node.parent, nodes.TextElement))) - - def always_needs_space(self, node): - """ - Always add space around nodes for which `always_needs_space()` - is true, regardless of whether the other node needs space as - well. (E.g. transition next to section.) - """ - return isinstance(node, nodes.transition) - - def dispatch_departure(self, node): - # Call departure method. - nodes.SparseNodeVisitor.dispatch_departure(self, node) - - if not isinstance(node, nodes.Text): - # Close attribute and node handler call (\DN...{...}). - self.indentation_level -= 1 - self.append(self.context.pop() + self.context.pop()) - # Delete \Dcurrent... attribute macros. - self.append(self.context.pop()) - # Get next sibling. - next_node = node.next_node( - ascend=0, siblings=1, descend=0, - condition=self.is_visible) - # Insert space if necessary. - if (self.needs_space(node) and self.needs_space(next_node) or - self.always_needs_space(node) or - self.always_needs_space(next_node)): - if isinstance(node, nodes.paragraph) and isinstance(next_node, nodes.paragraph): - # Space between paragraphs. - self.append(r'\Dparagraphspace') - else: - # One of the elements is not a paragraph. - self.append(r'\Dauxiliaryspace') diff --git a/docutils/writers/newlatex2e/__init__.py b/docutils/writers/newlatex2e/__init__.py new file mode 100644 index 000000000..af397ba95 --- /dev/null +++ b/docutils/writers/newlatex2e/__init__.py @@ -0,0 +1,788 @@ +""" +:Author: Felix Wiemann +:Contact: Felix_Wiemann@ososo.de +:Revision: $Revision$ +:Date: $Date$ +:Copyright: This module has been placed in the public domain. + +LaTeX2e document tree Writer. +""" + +# Thanks to Engelbert Gruber and various contributors for the original +# LaTeX writer, some code and many ideas of which have been used for +# this writer. + +__docformat__ = 'reStructuredText' + + +import re +import os.path +from types import ListType + +import docutils +from docutils import nodes, writers, utils +from docutils.writers.newlatex2e import unicode_map +from docutils.transforms import writer_aux + + +class Writer(writers.Writer): + + supported = ('newlatex', 'newlatex2e') + """Formats this writer supports.""" + + default_stylesheet = 'base.tex' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(os.path.dirname(__file__), default_stylesheet)) + + settings_spec = ( + 'LaTeX-Specific Options', + 'Note that this LaTeX writer is still EXPERIMENTAL. ' + 'You must specify the location of the tools/stylesheets/latex.tex ' + 'stylesheet file contained in the Docutils distribution tarball to ' + 'make the LaTeX output work.', + (('Specify a stylesheet file. The path is used verbatim to include ' + 'the file. Overrides --stylesheet-path.', + ['--stylesheet'], + {'default': '', 'metavar': '', + 'overrides': 'stylesheet_path'}), + ('Specify a stylesheet file, relative to the current working ' + 'directory. Overrides --stylesheet. Default: "%s"' + % default_stylesheet_path, + ['--stylesheet-path'], + {'metavar': '', 'overrides': 'stylesheet', + 'default': default_stylesheet_path}), + ('Specify a user stylesheet file. See --stylesheet.', + ['--user-stylesheet'], + {'default': '', 'metavar': '', + 'overrides': 'user_stylesheet_path'}), + ('Specify a user stylesheet file. See --stylesheet-path.', + ['--user-stylesheet-path'], + {'metavar': '', 'overrides': 'user_stylesheet'}) + ),) + + settings_defaults = { + # Many Unicode characters are provided by unicode_map.py. + 'output_encoding': 'ascii', + 'output_encoding_error_handler': 'strict', + # Since we are using superscript footnotes, it is necessary to + # trim whitespace in front of footnote references. + 'trim_footnote_reference_space': 1, + # Currently unsupported: + 'docinfo_xform': 0, + # During development: + 'traceback': 1 + } + + relative_path_settings = ('stylesheet_path', 'user_stylesheet_path') + + config_section = 'newlatex2e writer' + config_section_dependencies = ('writers',) + + output = None + """Final translated form of `document`.""" + + def get_transforms(self): + return writers.Writer.get_transforms(self) + [writer_aux.Compound] + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = LaTeXTranslator + + def translate(self): + visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + assert not visitor.context, 'context not empty: %s' % visitor.context + self.output = visitor.astext() + self.head = visitor.header + self.body = visitor.body + + +class LaTeXException(Exception): + """ + Exception base class to for exceptions which influence the + automatic generation of LaTeX code. + """ + + +class SkipAttrParentLaTeX(LaTeXException): + """ + Do not generate \Dattr and \renewcommand{\Dparent}{...} for this + node. + + To be raised from before_... methods. + """ + + +class SkipParentLaTeX(LaTeXException): + """ + Do not generate \renewcommand{\DNparent}{...} for this node. + + To be raised from before_... methods. + """ + + +class LaTeXTranslator(nodes.SparseNodeVisitor): + + # Country code by a.schlock. + # Partly manually converted from iso and babel stuff. + iso639_to_babel = { + 'no': 'norsk', # added by hand + 'gd': 'scottish', # added by hand + 'sl': 'slovenian', + 'af': 'afrikaans', + 'bg': 'bulgarian', + 'br': 'breton', + 'ca': 'catalan', + 'cs': 'czech', + 'cy': 'welsh', + 'da': 'danish', + 'fr': 'french', + # french, francais, canadien, acadian + 'de': 'ngerman', + # ngerman, naustrian, german, germanb, austrian + 'el': 'greek', + 'en': 'english', + # english, USenglish, american, UKenglish, british, canadian + 'eo': 'esperanto', + 'es': 'spanish', + 'et': 'estonian', + 'eu': 'basque', + 'fi': 'finnish', + 'ga': 'irish', + 'gl': 'galician', + 'he': 'hebrew', + 'hr': 'croatian', + 'hu': 'hungarian', + 'is': 'icelandic', + 'it': 'italian', + 'la': 'latin', + 'nl': 'dutch', + 'pl': 'polish', + 'pt': 'portuguese', + 'ro': 'romanian', + 'ru': 'russian', + 'sk': 'slovak', + 'sr': 'serbian', + 'sv': 'swedish', + 'tr': 'turkish', + 'uk': 'ukrainian' + } + + # Start with left double quote. + left_quote = 1 + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = document.settings + self.header = [] + self.body = [] + self.context = [] + self.stylesheet_path = utils.get_stylesheet_reference( + self.settings, os.path.join(os.getcwd(), 'dummy')) + if self.stylesheet_path: + self.settings.record_dependencies.add(self.stylesheet_path) + # This ugly hack will be cleaned up when refactoring the + # stylesheet mess. + self.settings.stylesheet = self.settings.user_stylesheet + self.settings.stylesheet_path = self.settings.user_stylesheet_path + self.user_stylesheet_path = utils.get_stylesheet_reference( + self.settings, os.path.join(os.getcwd(), 'dummy')) + if self.user_stylesheet_path: + self.settings.record_dependencies.add(self.user_stylesheet_path) + self.write_header() + + def write_header(self): + a = self.header.append + a('%% Generated by Docutils %s .' + % docutils.__version__) + a('') + a('% Docutils settings:') + lang = self.settings.language_code or '' + a(r'\providecommand{\Dlanguageiso}{%s}' % lang) + a(r'\providecommand{\Dlanguagebabel}{%s}' % self.iso639_to_babel.get( + lang, self.iso639_to_babel.get(lang.split('_')[0], ''))) + a('') + if self.user_stylesheet_path: + a('% User stylesheet:') + a(r'\input{%s}' % self.user_stylesheet_path) + a('% Docutils stylesheet:') + a(r'\input{%s}' % self.stylesheet_path) + a('') + a('% Default definitions for Docutils nodes:') + for node_name in nodes.node_class_names: + a(r'\providecommand{\DN%s}[1]{#1}' % node_name.replace('_', '')) + a('') + a('% Auxiliary definitions:') + a(r'\providecommand{\Dsetattr}[2]{}') + a(r'\providecommand{\Dparent}{} % variable') + a(r'\providecommand{\Dattr}[5]{#5}') + a(r'\providecommand{\Dattrlen}{} % variable') + a(r'\providecommand{\Dtitleastext}{x} % variable') + a(r'\providecommand{\Dsinglebackref}{} % variable') + a(r'\providecommand{\Dmultiplebackrefs}{} % variable') + a(r'\providecommand{\Dparagraphindented}{false} % variable') + a('\n\n') + + unicode_map = unicode_map.unicode_map # comprehensive Unicode map + # Fix problems with unimap.py. + unicode_map.update({ + # We have AE or T1 encoding, so "``" etc. work. The macros + # from unimap.py may *not* work. + u'\u201C': '{``}', + u'\u201D': "{''}", + u'\u201E': '{,,}', + }) + + character_map = { + '\\': r'{\textbackslash}', + '{': r'{\{}', + '}': r'{\}}', + '$': r'{\$}', + '&': r'{\&}', + '%': r'{\%}', + '#': r'{\#}', + '[': r'{[}', + ']': r'{]}', + '-': r'{-}', + '`': r'{`}', + "'": r"{'}", + ',': r'{,}', + '"': r'{"}', + '|': r'{\textbar}', + '<': r'{\textless}', + '>': r'{\textgreater}', + '^': r'{\textasciicircum}', + '~': r'{\textasciitilde}', + '_': r'{\Dtextunderscore}', + } + character_map.update(unicode_map) + #character_map.update(special_map) + + # `att_map` is for encoding attributes. According to + # , + # the following characters are special: # $ % & ~ _ ^ \ { } + # These work without special treatment in macro parameters: + # $, &, ~, _, ^ + att_map = {'#': '\\#', + '%': '\\%', + # We cannot do anything about backslashes. + '\\': '', + '{': '\\{', + '}': '\\}', + # The quotation mark may be redefined by babel. + '"': '"{}', + } + att_map.update(unicode_map) + + def encode(self, text, attval=None): + """ + Encode special characters in ``text`` and return it. + + If attval is true, preserve as much as possible verbatim (used + in attribute value encoding). If attval is 'width' or + 'height', `text` is interpreted as a length value. + """ + if attval in ('width', 'height'): + match = re.match(r'([0-9.]+)(\S*)$', text) + assert match, '%s="%s" must be a length' % (attval, text) + value, unit = match.groups() + if unit == '%': + value = str(float(value) / 100) + unit = r'\Drelativeunit' + elif unit in ('', 'px'): + # If \Dpixelunit is "pt", this gives the same notion + # of pixels as graphicx. + value = str(float(value) * 0.75) + unit = '\Dpixelunit' + return '%s%s' % (value, unit) + if attval: + get = self.att_map.get + else: + get = self.character_map.get + text = ''.join([get(c, c) for c in text]) + if (self.literal_block or self.inline_literal) and not attval: + # NB: We can have inline literals within literal blocks. + # Shrink '\r\n'. + text = text.replace('\r\n', '\n') + # Convert space. If "{ }~~~~~" is wrapped (at the + # brace-enclosed space "{ }"), the following non-breaking + # spaces ("~~~~") do *not* wind up at the beginning of the + # next line. Also note that, for some not-so-obvious + # reason, no hyphenation is done if the breaking space ("{ + # }") comes *after* the non-breaking spaces. + if self.literal_block: + # Replace newlines with real newlines. + text = text.replace('\n', '\mbox{}\\\\') + replace_fn = self.encode_replace_for_literal_block_spaces + else: + replace_fn = self.encode_replace_for_inline_literal_spaces + text = re.sub(r'\s+', replace_fn, text) + # Protect hyphens; if we don't, line breaks will be + # possible at the hyphens and even the \textnhtt macro + # from the hyphenat package won't change that. + text = text.replace('-', r'\mbox{-}') + text = text.replace("'", r'{\Dtextliteralsinglequote}') + return text + else: + if not attval: + # Replace space with single protected space. + text = re.sub(r'\s+', '{ }', text) + # Replace double quotes with macro calls. + L = [] + for part in text.split(self.character_map['"']): + if L: + # Insert quote. + L.append(self.left_quote and r'{\Dtextleftdblquote}' + or r'{\Dtextrightdblquote}') + self.left_quote = not self.left_quote + L.append(part) + return ''.join(L) + else: + return text + + def encode_replace_for_literal_block_spaces(self, match): + return '~' * len(match.group()) + + def encode_replace_for_inline_literal_spaces(self, match): + return '{ }' + '~' * (len(match.group()) - 1) + + def astext(self): + return '\n'.join(self.header) + (''.join(self.body)) + + def append(self, text, newline='%\n'): + """ + Append text, stripping newlines, producing nice LaTeX code. + """ + lines = [' ' * self.indentation_level + line + newline + for line in text.splitlines(0)] + self.body.append(''.join(lines)) + + def visit_Text(self, node): + self.append(self.encode(node.astext())) + + def depart_Text(self, node): + pass + + def is_indented(self, paragraph): + """Return true if `paragraph` should be first-line-indented.""" + assert isinstance(paragraph, nodes.paragraph) + siblings = [n for n in paragraph.parent if + self.is_visible(n) and not isinstance(n, nodes.Titular)] + index = siblings.index(paragraph) + if ('continued' in paragraph['classes'] or + index > 0 and isinstance(siblings[index-1], nodes.transition)): + return 0 + # Indent all but the first paragraphs. + return index > 0 + + def before_paragraph(self, node): + self.append(r'\renewcommand{\Dparagraphindented}{%s}' + % (self.is_indented(node) and 'true' or 'false')) + + def before_title(self, node): + self.append(r'\renewcommand{\Dtitleastext}{%s}' + % self.encode(node.astext())) + self.append(r'\renewcommand{\Dhassubtitle}{%s}' + % ((len(node.parent) > 2 and + isinstance(node.parent[1], nodes.subtitle)) + and 'true' or 'false')) + + def before_generated(self, node): + if 'sectnum' in node['classes']: + node[0] = node[0].strip() + + literal_block = 0 + + def visit_literal_block(self, node): + self.literal_block = 1 + + def depart_literal_block(self, node): + self.literal_block = 0 + + visit_doctest_block = visit_literal_block + depart_doctest_block = depart_literal_block + + inline_literal = 0 + + def visit_literal(self, node): + self.inline_literal += 1 + + def depart_literal(self, node): + self.inline_literal -= 1 + + def visit_comment(self, node): + self.append('\n'.join(['% ' + line for line + in node.astext().splitlines(0)]), newline='\n') + raise nodes.SkipChildren + + def before_topic(self, node): + if 'contents' in node['classes']: + for bullet_list in list(node.traverse(nodes.bullet_list)): + p = bullet_list.parent + if isinstance(p, nodes.list_item): + p.parent.insert(p.parent.index(p) + 1, bullet_list) + del p[1] + for paragraph in node.traverse(nodes.paragraph): + paragraph.attributes.update(paragraph[0].attributes) + paragraph[:] = paragraph[0] + paragraph.parent['tocrefid'] = paragraph['refid'] + node['contents'] = 1 + else: + node['contents'] = 0 + + bullet_list_level = 0 + + def visit_bullet_list(self, node): + self.append(r'\Dsetbullet{\labelitem%s}' % + ['i', 'ii', 'iii', 'iv'][min(self.bullet_list_level, 3)]) + self.bullet_list_level += 1 + + def depart_bullet_list(self, node): + self.bullet_list_level -= 1 + + enum_styles = {'arabic': 'arabic', 'loweralpha': 'alph', 'upperalpha': + 'Alph', 'lowerroman': 'roman', 'upperroman': 'Roman'} + + enum_counter = 0 + + def visit_enumerated_list(self, node): + # We create our own enumeration list environment. This allows + # to set the style and starting value and unlimited nesting. + # Maybe this can be moved to the stylesheet? + self.enum_counter += 1 + enum_prefix = self.encode(node['prefix']) + enum_suffix = self.encode(node['suffix']) + enum_type = '\\' + self.enum_styles.get(node['enumtype'], r'arabic') + start = node.get('start', 1) - 1 + counter = 'Denumcounter%d' % self.enum_counter + self.append(r'\Dmakeenumeratedlist{%s}{%s}{%s}{%s}{%s}{' + % (enum_prefix, enum_type, enum_suffix, counter, start)) + # for Emacs: } + + def depart_enumerated_list(self, node): + self.append('}') # for Emacs: { + + def before_list_item(self, node): + # XXX needs cleanup. + if (len(node) and (isinstance(node[-1], nodes.TextElement) or + isinstance(node[-1], nodes.Text)) and + node.parent.index(node) == len(node.parent) - 1): + node['lastitem'] = 'true' + + before_line = before_list_item + + def before_raw(self, node): + if 'latex' in node.get('format', '').split(): + # We're inserting the text in before_raw and thus outside + # of \DN... and \Dattr in order to make grouping with + # curly brackets work. + self.append(node.astext()) + raise nodes.SkipChildren + + def process_backlinks(self, node, type): + self.append(r'\renewcommand{\Dsinglebackref}{}') + self.append(r'\renewcommand{\Dmultiplebackrefs}{}') + if len(node['backrefs']) > 1: + refs = [] + for i in range(len(node['backrefs'])): + refs.append(r'\Dmulti%sbacklink{%s}{%s}' + % (type, node['backrefs'][i], i + 1)) + self.append(r'\renewcommand{\Dmultiplebackrefs}{(%s){ }}' + % ', '.join(refs)) + elif len(node['backrefs']) == 1: + self.append(r'\renewcommand{\Dsinglebackref}{%s}' + % node['backrefs'][0]) + + def visit_footnote(self, node): + self.process_backlinks(node, 'footnote') + + def visit_citation(self, node): + self.process_backlinks(node, 'citation') + + def before_table(self, node): + # A table contains exactly one tgroup. See before_tgroup. + pass + + def before_tgroup(self, node): + widths = [] + total_width = 0 + for i in range(int(node['cols'])): + assert isinstance(node[i], nodes.colspec) + widths.append(int(node[i]['colwidth']) + 1) + total_width += widths[-1] + del node[:len(widths)] + tablespec = '|' + for w in widths: + # 0.93 is probably wrong in many cases. XXX Find a + # solution which works *always*. + tablespec += r'p{%s\textwidth}|' % (0.93 * w / + max(total_width, 60)) + self.append(r'\Dmaketable{%s}{' % tablespec) + self.context.append('}') + raise SkipAttrParentLaTeX + + def depart_tgroup(self, node): + self.append(self.context.pop()) + + def before_row(self, node): + raise SkipAttrParentLaTeX + + def before_thead(self, node): + raise SkipAttrParentLaTeX + + def before_tbody(self, node): + raise SkipAttrParentLaTeX + + def is_simply_entry(self, node): + return (len(node) == 1 and isinstance(node[0], nodes.paragraph) or + len(node) == 0) + + def before_entry(self, node): + is_leftmost = 0 + if node.hasattr('morerows'): + self.document.reporter.severe('Rowspans are not supported.') + # Todo: Add empty cells below rowspanning cell and issue + # warning instead of severe. + if node.hasattr('morecols'): + # The author got a headache trying to implement + # multicolumn support. + if not self.is_simply_entry(node): + self.document.reporter.severe( + 'Colspanning table cells may only contain one paragraph.') + # Todo: Same as above. + # The number of columns this entry spans (as a string). + colspan = int(node['morecols']) + 1 + del node['morecols'] + else: + colspan = 1 + # Macro to call. + macro_name = r'\Dcolspan' + if node.parent.index(node) == 0: + # Leftmost column. + macro_name += 'left' + is_leftmost = 1 + if colspan > 1: + self.append('%s{%s}{' % (macro_name, colspan)) + self.context.append('}') + else: + # Do not add a multicolumn with colspan 1 beacuse we need + # at least one non-multicolumn cell per column to get the + # desired column widths, and we can only do colspans with + # cells consisting of only one paragraph. + if not is_leftmost: + self.append(r'\Dsubsequententry{') + self.context.append('}') + else: + self.context.append('') + if isinstance(node.parent.parent, nodes.thead): + node['tableheaderentry'] = 'true' + + # Don't add \renewcommand{\Dparent}{...} because there must + # not be any non-expandable commands in front of \multicolumn. + raise SkipParentLaTeX + + def depart_entry(self, node): + self.append(self.context.pop()) + + def before_substitution_definition(self, node): + raise nodes.SkipNode + + indentation_level = 0 + + def node_name(self, node): + return node.__class__.__name__.replace('_', '') + + # Attribute propagation order. + attribute_order = ['align', 'classes', 'ids'] + + def attribute_cmp(self, a1, a2): + """ + Compare attribute names `a1` and `a2`. Used in + propagate_attributes to determine propagation order. + + See built-in function `cmp` for return value. + """ + if a1 in self.attribute_order and a2 in self.attribute_order: + return cmp(self.attribute_order.index(a1), + self.attribute_order.index(a2)) + if (a1 in self.attribute_order) != (a2 in self.attribute_order): + # Attributes not in self.attribute_order come last. + return a1 in self.attribute_order and -1 or 1 + else: + return cmp(a1, a2) + + def propagate_attributes(self, node): + # Propagate attributes using \Dattr macros. + node_name = self.node_name(node) + attlist = [] + if isinstance(node, nodes.Element): + attlist = node.attlist() + attlist.sort(lambda pair1, pair2: self.attribute_cmp(pair1[0], + pair2[0])) + # `numatts` may be greater than len(attlist) due to list + # attributes. + numatts = 0 + pass_contents = self.pass_contents(node) + for key, value in attlist: + if isinstance(value, ListType): + self.append(r'\renewcommand{\Dattrlen}{%s}' % len(value)) + for i in range(len(value)): + self.append(r'\Dattr{%s}{%s}{%s}{%s}{' % + (i+1, key, self.encode(value[i], attval=key), + node_name)) + if not pass_contents: + self.append('}') + numatts += len(value) + else: + self.append(r'\Dattr{}{%s}{%s}{%s}{' % + (key, self.encode(unicode(value), attval=key), + node_name)) + if not pass_contents: + self.append('}') + numatts += 1 + if pass_contents: + self.context.append('}' * numatts) # for Emacs: { + else: + self.context.append('') + + def visit_docinfo(self, node): + raise NotImplementedError('Docinfo not yet implemented.') + + def visit_document(self, node): + document = node + # Move IDs into TextElements. This won't work for images. + # Need to review this. + for node in document.traverse(nodes.Element): + if node.has_key('ids') and not isinstance(node, + nodes.TextElement): + next_text_element = node.next_node(nodes.TextElement) + if next_text_element: + next_text_element['ids'].extend(node['ids']) + node['ids'] = [] + + def pass_contents(self, node): + r""" + Return true if the node contents should be passed in + parameters of \DN... and \Dattr. + """ + return not isinstance(node, (nodes.document, nodes.section)) + + def dispatch_visit(self, node): + skip_attr = skip_parent = 0 + # TreePruningException to be propagated. + tree_pruning_exception = None + if hasattr(self, 'before_' + node.__class__.__name__): + try: + getattr(self, 'before_' + node.__class__.__name__)(node) + except SkipParentLaTeX: + skip_parent = 1 + except SkipAttrParentLaTeX: + skip_attr = 1 + skip_parent = 1 + except nodes.SkipNode: + raise + except (nodes.SkipChildren, nodes.SkipSiblings), instance: + tree_pruning_exception = instance + except nodes.SkipDeparture: + raise NotImplementedError( + 'SkipDeparture not usable in LaTeX writer') + + if not isinstance(node, nodes.Text): + node_name = self.node_name(node) + # attribute_deleters will be appended to self.context. + attribute_deleters = [] + if not skip_parent and not isinstance(node, nodes.document): + self.append(r'\renewcommand{\Dparent}{%s}' + % self.node_name(node.parent)) + for name, value in node.attlist(): + if not isinstance(value, ListType) and not ':' in name: + macro = r'\DcurrentN%sA%s' % (node_name, name) + self.append(r'\def%s{%s}' % ( + macro, self.encode(unicode(value), attval=name))) + attribute_deleters.append(r'\let%s=\relax' % macro) + self.context.append('\n'.join(attribute_deleters)) + if self.pass_contents(node): + self.append(r'\DN%s{' % node_name) + self.context.append('}') + else: + self.append(r'\Dvisit%s' % node_name) + self.context.append(r'\Ddepart%s' % node_name) + self.indentation_level += 1 + if not skip_attr: + self.propagate_attributes(node) + else: + self.context.append('') + + if (isinstance(node, nodes.TextElement) and + not isinstance(node.parent, nodes.TextElement)): + # Reset current quote to left. + self.left_quote = 1 + + # Call visit_... method. + try: + nodes.SparseNodeVisitor.dispatch_visit(self, node) + except LaTeXException: + raise NotImplementedError( + 'visit_... methods must not raise LaTeXExceptions') + + if tree_pruning_exception: + # Propagate TreePruningException raised in before_... method. + raise tree_pruning_exception + + def is_invisible(self, node): + # Return true if node is invisible or moved away in the LaTeX + # rendering. + return (not isinstance(node, nodes.Text) and + (isinstance(node, nodes.Invisible) or + isinstance(node, nodes.footnote) or + isinstance(node, nodes.citation) or + # Assume raw nodes to be invisible. + isinstance(node, nodes.raw) or + # Floating image or figure. + node.get('align') in ('left', 'right'))) + + def is_visible(self, node): + return not self.is_invisible(node) + + def needs_space(self, node): + """Two nodes for which `needs_space` is true need auxiliary space.""" + # Return true if node is a visible block-level element. + return ((isinstance(node, nodes.Body) or + isinstance(node, nodes.topic)) and + not (self.is_invisible(node) or + isinstance(node.parent, nodes.TextElement))) + + def always_needs_space(self, node): + """ + Always add space around nodes for which `always_needs_space()` + is true, regardless of whether the other node needs space as + well. (E.g. transition next to section.) + """ + return isinstance(node, nodes.transition) + + def dispatch_departure(self, node): + # Call departure method. + nodes.SparseNodeVisitor.dispatch_departure(self, node) + + if not isinstance(node, nodes.Text): + # Close attribute and node handler call (\DN...{...}). + self.indentation_level -= 1 + self.append(self.context.pop() + self.context.pop()) + # Delete \Dcurrent... attribute macros. + self.append(self.context.pop()) + # Get next sibling. + next_node = node.next_node( + ascend=0, siblings=1, descend=0, + condition=self.is_visible) + # Insert space if necessary. + if (self.needs_space(node) and self.needs_space(next_node) or + self.always_needs_space(node) or + self.always_needs_space(next_node)): + if isinstance(node, nodes.paragraph) and isinstance(next_node, nodes.paragraph): + # Space between paragraphs. + self.append(r'\Dparagraphspace') + else: + # One of the elements is not a paragraph. + self.append(r'\Dauxiliaryspace') diff --git a/docutils/writers/newlatex2e/base.tex b/docutils/writers/newlatex2e/base.tex new file mode 100644 index 000000000..231f3911f --- /dev/null +++ b/docutils/writers/newlatex2e/base.tex @@ -0,0 +1,1108 @@ +\makeatletter + +% Development notes at +% http://docutils.python-hosting.com/wiki/NewLatex + + +\providecommand{\Dprinting}{false} + + +\providecommand{\DSearly}{} +\providecommand{\DSlate}{} + +\providecommand{\Ddocumentclass}{scrartcl} +\providecommand{\Ddocumentoptions}{a4paper} + +\documentclass[\Ddocumentoptions]{\Ddocumentclass} + +\DSearly + + +\providecommand{\DSfontencoding}{ + % Set up font encoding. + % AE is a T1-emulation. It provides most characters and features + % as T1-encoded fonts but doesn't use ugly bitmap fonts. + \usepackage{ae} + % Provide the characters not contained in AE from EC bitmap fonts. + \usepackage{aecompl} + % Guillemets ("<<", ">>") in AE. + \usepackage{aeguill} +} + + +\providecommand{\DSsymbols}{% + % Fix up symbols. + % The Euro symbol in Computer Modern looks, um, funny. Let's get a + % proper Euro symbol. + \RequirePackage{eurosym}% + \renewcommand{\texteuro}{\euro}% +} + + +% Taken from +% +% and modified. Used with permission. +\providecommand{\Dprovidelength}[2]{% + \begingroup% + \escapechar\m@ne% + \xdef\@gtempa{{\string#1}}% + \endgroup% + \expandafter\@ifundefined\@gtempa% + {\newlength{#1}\setlength{#1}{#2}}% + {}% +} + +\providecommand{\Dprovidecounter}[1]{% + % Like \newcounter except that it doesn't crash if the counter + % already exists. + \@ifundefined{c@#1}{\newcounter{#1}}{} +} + +\Dprovidelength{\Dboxparindent}{\parindent} +\providecommand{\Dmakeboxminipage}[1]{% + % Make minipage for use in a box created by \Dmakefbox. + \begin{minipage}[t]{0.9\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% +} +\providecommand{\Dmakefbox}[1]{% + % Make a centered, framed box. Useful e.g. for admonitions. + \vspace{0.4\baselineskip}% + \begin{center}% + \fbox{\Dmakeboxminipage{#1}}% + \end{center}% + \vspace{0.4\baselineskip}% +} +\providecommand{\Dmakebox}[1]{% + % Make a centered, frameless box. Useful e.g. for block quotes. + % Do not use minipages here, but create pseudo-lists to allow + % page-breaking. (Don't use KOMA-script's addmargin environment + % because it messes up bullet lists.) + \Dmakelistenvironment{}{}{% + \setlength{\parskip}{0pt}% + \setlength{\parindent}{\Dboxparindent}% + \item{#1}% + }% +} + + +\RequirePackage{ifthen} +\providecommand{\Dfrenchspacing}{true} +\ifthenelse{\equal{\Dfrenchspacing}{true}}{\frenchspacing}{} + + +\Dprovidelength{\Dblocklevelvspace}{% + % Space between block-level elements other than paragraphs. + 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip% +} +\providecommand{\Dauxiliaryspace}{% + \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}% + \par\noindent% +} +\providecommand{\Dparagraphspace}{\par} +\providecommand{\Dneedvspace}{true} + + +\providecommand{\DSlinks}{ + % Targets and references. + \RequirePackage[colorlinks=false,pdfborder={0 0 0}]{hyperref} + + \providecommand{\Draisedlink}[1]{\Hy@raisedlink{##1}} + + % References. + % We're assuming here that the "refid" and "refuri" attributes occur + % only in inline context (in TextElements). + \providecommand{\DArefid}[5]{% + \ifthenelse{\equal{##4}{reference}}{% + \Dexplicitreference{\###3}{##5}% + }{% + % If this is not a target node (targets with refids are + % uninteresting and should be silently dropped). + \ifthenelse{\not\equal{##4}{target}}{% + % If this is a footnote reference, call special macro. + \ifthenelse{\equal{##4}{footnotereference}}{% + \Dimplicitfootnotereference{\###3}{##5}% + }{% + \ifthenelse{\equal{##4}{citationreference}}{% + \Dimplicitcitationreference{\###3}{##5}% + }{% + \Dimplicitreference{\###3}{##5}% + }% + }% + }{}% + }% + } + \providecommand{\DArefuri}[5]{% + \ifthenelse{\equal{##4}{target}}{% + % Hyperlink targets can (and should be) ignored because they are + % invisible. + }{% + % We only have explicit URI references, so one macro suffices. + \Durireference{##3}{##5}% + }% + } + % Targets. + \providecommand{\DAids}[5]{% + \label{##3}% + \ifthenelse{\equal{##4}{footnotereference}}{% + {% + \renewcommand{\HyperRaiseLinkDefault}{% + % Dirty hack to make backrefs to footnote references work. + % For some reason, \baselineskip is 0pt in fn references. + 0.5\Doriginalbaselineskip% + }% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + }{% + \Draisedlink{\hypertarget{##3}{}}##5% + }% + } + % Color in references. + \RequirePackage{color} + \providecommand{\Dimplicitreference}[2]{% + % Create implicit reference to ID. Implicit references occur + % e.g. in TOC-backlinks of section titles. Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{##2}% + } + \providecommand{\Dimplicitfootnotereference}[2]{% + % Ditto, but for the special case of footnotes. + % We want them to be rendered like explicit references. + \Dexplicitreference{##1}{##2}% + } + \providecommand{\Dimplicitcitationreference}[2]{% + % Ditto for citation references. + \Dimplicitfootnotereference{##1}{##2}% + } + \ifthenelse{\equal{\Dprinting}{true}}{ + \providecommand{\Dexplicitreferencecolor}{black} + }{ + \providecommand{\Dexplicitreferencecolor}{blue} + } + \providecommand{\Dexplicitreference}[2]{% + % Create explicit reference to ID, e.g. created with "foo_". + % Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{{\color{\Dexplicitreferencecolor}##2}}% + } + \providecommand{\Durireferencecolor}{\Dexplicitreferencecolor} + \providecommand{\Durireference}[2]{% + % Create reference to URI. Parameters: + % 1. Target. + % 2. Link text. + \href{##1}{{\color{\Durireferencecolor}##2}}% + } +} + + +\providecommand{\DSlanguage}{% + % Set up babel. + \ifthenelse{\equal{\Dlanguagebabel}{}}{}{ + \RequirePackage[\Dlanguagebabel]{babel} + } +} + + + + +\providecommand{\DAclasses}[5]{% + \Difdefined{DN#4C#3}{% + % Pass only contents, nothing else! + \csname DN#4C#3\endcsname{#5}% + }{% + \Difdefined{DC#3}{% + \csname DC#3\endcsname{#5}% + }{% + #5% + }% + }% +} + +\providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}} + +\providecommand{\Dattr}[5]{% + % Global attribute dispatcher. + % Parameters: + % 1. Attribute number. + % 2. Attribute name. + % 3. Attribute value. + % 4. Node name. + % 5. Node contents. + \Difdefined{DN#4A#2V#3}{% + \csname DN#4A#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DN#4A#2}{% + \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DA#2V#3}{% + \csname DA#2V#3\endcsname{#1}{#2}{#3}{#4}{#5}% + }{\Difdefined{DA#2}{% + \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}% + }{#5% + }}}}% +} + +\providecommand{\DNparagraph}[1]{% + \ifthenelse{\equal{\Dparagraphindented}{true}}{\indent}{\noindent}% + #1% +} +\providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}} +\providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}} +\providecommand{\Dtopictitle}[1]{% + \Difinsidetoc{\vspace{1em}\par}{}% + \noindent\Dformatboxtitle{#1}% + \ifthenelse{\equal{\Dhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}% + \par% +} +\providecommand{\Dtopicsubtitle}[1]{% + \noindent\Dformatboxsubtitle{#1}% + \vspace{1em}% + \par% +} +\providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}} +\providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}} +\providecommand{\Ddocumenttitle}[1]{% + \begin{center}{\Huge#1}\end{center}% + \ifthenelse{\equal{\Dhassubtitle}{true}}{\vspace{0.1cm}}{\vspace{1cm}}% +} +\providecommand{\Ddocumentsubtitle}[1]{% + \begin{center}{\huge#1}\end{center}% + \vspace{1cm}% +} +% Can be overwritten by user stylesheet. +\providecommand{\Dformatsectiontitle}[1]{#1} +\providecommand{\Dformatsectionsubtitle}[1]{\Dformatsectiontitle{#1}} +\providecommand{\Dbookmarksectiontitle}[1]{% + % Return text suitable for use in \section*, \subsection*, etc., + % containing a PDF bookmark. Parameter: The title (as node tree). + \Draisedlink{\Dpdfbookmark{\Dtitleastext}}% + #1% +} +\providecommand{\Dsectiontitlehook}[1]{#1} +\providecommand{\Dsectiontitle}[1]{% + \Dsectiontitlehook{% + \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}% + }% +} +\providecommand{\Ddispatchsectiontitle}[1]{% + \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{% + \Ddeepsectiontitle{#1}% + }{% + \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}% + }% +} +\providecommand{\Ddispatchsectionsubtitle}[1]{% + \Ddispatchsectiontitle{#1}% +} +\providecommand{\Dsectiontitlei}[1]{\section*{#1}} +\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}} +\providecommand{\Ddeepsectiontitle}[1]{% + % Anything below \subsubsection (like \paragraph or \subparagraph) + % is useless because it uses the same font. The only way to + % (visually) distinguish such deeply nested sections is to use + % section numbering. + \subsubsection*{#1}% +} +\providecommand{\Dsectionsubtitlehook}[1]{#1} +\Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em} +\providecommand{\Dsectionsubtitlescaling}{0.85} +\providecommand{\Dsectionsubtitle}[1]{% + \Dsectionsubtitlehook{% + % Move the subtitle nearer to the title. + \vspace{-\Dsectionsubtitleraisedistance}% + % Don't create a PDF bookmark. + \Ddispatchsectionsubtitle{% + \Dformatsectionsubtitle{\scalebox{\Dsectionsubtitlescaling}{#1}}% + }% + }% +} +% Boolean variable. +\providecommand{\Dhassubtitle}{false} +\providecommand{\DNtitle}[1]{% + \csname D\Dparent title\endcsname{#1}% +} +\providecommand{\DNsubtitle}[1]{% + \csname D\Dparent subtitle\endcsname{#1}% +} +\newcounter{Dpdfbookmarkid} +\setcounter{Dpdfbookmarkid}{0} +\providecommand{\Dpdfbookmark}[1]{% + % Temporarily decrement Desctionlevel counter. + \addtocounter{Dsectionlevel}{-1}% + %\typeout{\arabic{Dsectionlevel}}% + %\typeout{#1}% + %\typeout{docutils\roman{Dpdfbookmarkid}}% + %\typeout{}% + \pdfbookmark[\arabic{Dsectionlevel}]{#1}{docutils\arabic{Dpdfbookmarkid}}% + \addtocounter{Dsectionlevel}{1}% + \addtocounter{Dpdfbookmarkid}{1}% +} + +%\providecommand{\DNliteralblock}[1]{\begin{quote}\ttfamily\raggedright#1\end{quote}} +\providecommand{\DNliteralblock}[1]{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + \setlength{\leftmargin}{0pt}% + }{}% + \setlength{\rightmargin}{0pt}% + }{% + \raggedright\item\noindent\nohyphens{\textnhtt{#1\Dfinalstrut}}% + }% +} +\providecommand{\DNdoctestblock}[1]{% + % Treat doctest blocks the same as literal blocks. + \DNliteralblock{#1}% +} +\RequirePackage{hyphenat} +\providecommand{\DNliteral}[1]{\textnhtt{#1}} +\providecommand{\DNemphasis}[1]{\emph{#1}} +\providecommand{\DNstrong}[1]{\textbf{#1}} +\providecommand{\Dvisitdocument}{\begin{document}\noindent} +\providecommand{\Ddepartdocument}{\end{document}} +\providecommand{\DNtopic}[1]{% + \ifthenelse{\equal{\DcurrentNtopicAcontents}{1}}{% + \addtocounter{Dtoclevel}{1}% + \par\noindent% + #1% + \addtocounter{Dtoclevel}{-1}% + }{% + \par\noindent% + \Dmakebox{#1}% + }% +} +\providecommand{\Dformatrubric}[1]{\textbf{#1}} +\Dprovidelength{\Dprerubricspace}{0.3em} +\providecommand{\DNrubric}[1]{% + \vspace{\Dprerubricspace}\par\noindent\Dformatrubric{#1}\par% +} + +\providecommand{\Dbullet}{} +\providecommand{\Dsetbullet}[1]{\renewcommand{\Dbullet}{#1}} +\providecommand{\DNbulletlist}[1]{% + \Difinsidetoc{% + \Dtocbulletlist{#1}% + }{% + \Dmakelistenvironment{\Dbullet}{}{#1}% + }% +} +\renewcommand{\@pnumwidth}{2.2em} +\providecommand{\DNlistitem}[1]{% + \Difinsidetoc{% + \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{% + {% + \par\addvspace{1em}\noindent% + \sectfont% + #1\hfill\pageref{\DcurrentNlistitemAtocrefid}% + }% + }{% + \@dottedtocline{0}{\Dtocindent}{0em}{#1}{% + \pageref{\DcurrentNlistitemAtocrefid}% + }% + }% + }{% + \item{#1}% + }% +} +\providecommand{\DNenumeratedlist}[1]{#1} +\newcounter{Dsectionlevel} +\providecommand{\Dvisitsectionhook}{} +\providecommand{\Ddepartsectionhook}{} +\providecommand{\Dvisitsection}{% + \addtocounter{Dsectionlevel}{1}% + \Dvisitsectionhook% +} +\providecommand{\Ddepartsection}{% + \Ddepartsectionhook% + \addtocounter{Dsectionlevel}{-1}% +} + +% Using \_ will cause hyphenation after _ even in \textnhtt-typewriter +% because the hyphenat package redefines \_. So we use +% \textunderscore here. +\providecommand{\Dtextunderscore}{\textunderscore} + +\providecommand{\Dtextinlineliteralfirstspace}{{ }} +\providecommand{\Dtextinlineliteralsecondspace}{{~}} + +\Dprovidelength{\Dlistspacing}{0.8\baselineskip} + +\providecommand{\Dsetlistrightmargin}{% + \ifthenelse{\lengthtest{\linewidth>12em}}{% + % Equal margins. + \setlength{\rightmargin}{\leftmargin}% + }{% + % If the line is narrower than 10em, we don't remove any further + % space from the right. + \setlength{\rightmargin}{0pt}% + }% +} +\providecommand{\Dresetlistdepth}{false} +\Dprovidelength{\Doriginallabelsep}{\labelsep} +\providecommand{\Dmakelistenvironment}[3]{% + % Make list environment with support for unlimited nesting and with + % reasonable default lengths. Parameters: + % 1. Label (same as in list environment). + % 2. Spacing (same as in list environment). + % 3. List contents (contents of list environment). + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Unfortunately, vertical spacing doesn't work correctly when + % using lists inside tabular environments, so we use a minipage. + \begin{minipage}[t]{\linewidth}% + }{}% + {% + \renewcommand{\Dneedvspace}{false}% + % \parsep0.5\baselineskip + \renewcommand{\Dresetlistdepth}{false}% + \ifnum \@listdepth>5% + \protect\renewcommand{\Dresetlistdepth}{true}% + \@listdepth=5% + \fi% + \begin{list}{% + #1% + }{% + \setlength{\itemsep}{0pt}% + \setlength{\partopsep}{0pt}% + \setlength{\topsep}{0pt}% + % List should take 90% of total width. + \setlength{\leftmargin}{0.05\linewidth}% + \ifthenelse{\lengthtest{\leftmargin<1.8em}}{% + \setlength{\leftmargin}{1.8em}% + }{}% + \setlength{\labelsep}{\Doriginallabelsep}% + \Dsetlistrightmargin% + #2% + }{% + #3% + }% + \end{list}% + \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}% + }% + \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}% +} +\providecommand{\Dfinalstrut}{\@finalstrut\@arstrutbox} +\providecommand{\DAlastitem}[5]{#5\Dfinalstrut} + +\Dprovidelength{\Ditemsep}{0pt} +\providecommand{\Dmakeenumeratedlist}[6]{% + % Make enumerated list. + % Parameters: + % - prefix + % - type (\arabic, \roman, ...) + % - suffix + % - suggested counter name + % - start number - 1 + % - list contents + \newcounter{#4}% + \Dmakelistenvironment{#1#2{#4}#3}{% + % Use as much space as needed for the label. + \setlength{\labelwidth}{10em}% + % Reserve enough space so that the label doesn't go beyond the + % left margin of preceding paragraphs. Like that: + % + % A paragraph. + % + % 1. First item. + \setlength{\leftmargin}{2.5em}% + \Dsetlistrightmargin% + \setlength{\itemsep}{\Ditemsep}% + % Use counter recommended by Python module. + \usecounter{#4}% + % Set start value. + \addtocounter{#4}{#5}% + }{% + % The list contents. + #6% + }% +} + + +% Single quote in literal mode. \textquotesingle from package +% textcomp has wrong width when using package ae, so we use a normal +% single curly quote here. +\providecommand{\Dtextliteralsinglequote}{'} + + +% "Tabular lists" are field lists and options lists (not definition +% lists because there the term always appears on its own line). We'll +% use the terminology of field lists now ("field", "field name", +% "field body"), but the same is also analogously applicable to option +% lists. +% +% We want these lists to be breakable across pages. We cannot +% automatically get the narrowest possible size for the left column +% (i.e. the field names or option groups) because tabularx does not +% support multi-page tables, ltxtable needs to have the table in an +% external file and we don't want to clutter the user's directories +% with auxiliary files created by the filecontents environment, and +% ltablex is not included in teTeX. +% +% Thus we set a fixed length for the left column and use list +% environments. This also has the nice side effect that breaking is +% now possible anywhere, not just between fields. +% +% Note that we are creating a distinct list environment for each +% field. There is no macro for a whole tabular list! +\Dprovidelength{\Dtabularlistfieldnamewidth}{6em} +\Dprovidelength{\Dtabularlistfieldnamesep}{0.5em} +\providecommand{\Dinsidetabular}{false} +\providecommand{\Dsavefieldname}{} +\providecommand{\Dsavefieldbody}{} +\Dprovidelength{\Dusedfieldnamewidth}{0pt} +\Dprovidelength{\Drealfieldnamewidth}{0pt} +\providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}} +\providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}} +\Dprovidelength{\Dparskiptemp}{0pt} +\providecommand{\Dtabularlistfield}[1]{% + {% + % This only saves field name and field body in \Dsavefieldname and + % \Dsavefieldbody, resp. It does not insert any text into the + % document. + #1% + % Recalculate the real field name width everytime we encounter a + % tabular list field because it may have been changed using a + % "raw" node. + \setlength{\Drealfieldnamewidth}{\Dtabularlistfieldnamewidth}% + \addtolength{\Drealfieldnamewidth}{\Dtabularlistfieldnamesep}% + \Dmakelistenvironment{% + \makebox[\Drealfieldnamewidth][l]{\Dsavefieldname}% + }{% + \setlength{\labelwidth}{\Drealfieldnamewidth}% + \setlength{\leftmargin}{\Drealfieldnamewidth}% + \setlength{\rightmargin}{0pt}% + \setlength{\labelsep}{0pt}% + }{% + \item% + \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}% + \setlength{\Dparskiptemp}{\parskip}% + \ifthenelse{% + \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}% + }{% + \mbox{}\par% + \setlength{\parskip}{0pt}% + }{}% + \Dsavefieldbody% + \setlength{\parskip}{\Dparskiptemp}% + %XXX Why did we need this? + %\@finalstrut\@arstrutbox% + }% + \par% + }% +} + +\providecommand{\Dformatfieldname}[1]{\textbf{#1:}} +\providecommand{\DNfieldlist}[1]{#1} +\providecommand{\DNfield}[1]{\Dtabularlistfield{#1}} +\providecommand{\DNfieldname}[1]{% + \Dtabularlistfieldname{% + \Dformatfieldname{#1}% + }% +} +\providecommand{\DNfieldbody}[1]{\Dtabularlistfieldbody{#1}} + +\providecommand{\Dformatoptiongroup}[1]{% + % Format option group, e.g. "-f file, --input file". + \texttt{#1}% +} +\providecommand{\Dformatoption}[1]{% + % Format option, e.g. "-f file". + % Put into mbox to avoid line-breaking at spaces. + \mbox{#1}% +} +\providecommand{\Dformatoptionstring}[1]{% + % Format option string, e.g. "-f". + #1% +} +\providecommand{\Dformatoptionargument}[1]{% + % Format option argument, e.g. "file". + \textsl{#1}% +} +\providecommand{\Dformatoptiondescription}[1]{% + % Format option description, e.g. + % "\DNparagraph{Read input data from file.}" + #1% +} +\providecommand{\DNoptionlist}[1]{#1} +\providecommand{\Doptiongroupjoiner}{,{ }} +\providecommand{\Disfirstoption}{% + % Auxiliary macro indicating if a given option is the first child + % of its option group (if it's not, it has to preceded by + % \Doptiongroupjoiner). + false% +} +\providecommand{\DNoptionlistitem}[1]{% + \Dtabularlistfield{#1}% +} +\providecommand{\DNoptiongroup}[1]{% + \renewcommand{\Disfirstoption}{true}% + \Dtabularlistfieldname{\Dformatoptiongroup{#1}}% +} +\providecommand{\DNoption}[1]{% + % If this is not the first option in this option group, add a + % joiner. + \ifthenelse{\equal{\Disfirstoption}{true}}{% + \renewcommand{\Disfirstoption}{false}% + }{% + \Doptiongroupjoiner% + }% + \Dformatoption{#1}% +} +\providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}} +\providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}} +\providecommand{\DNdescription}[1]{% + \Dtabularlistfieldbody{\Dformatoptiondescription{#1}}% +} + +\providecommand{\DNdefinitionlist}[1]{% + \begin{description}% + \parskip0pt% + #1% + \end{description}% +} +\providecommand{\DNdefinitionlistitem}[1]{% + % LaTeX expects the label in square brackets; we provide an empty + % label. + \item[]#1% +} +\providecommand{\Dformatterm}[1]{#1} +\providecommand{\DNterm}[1]{\hspace{-5pt}\Dformatterm{#1}} +% I'm still not sure what's the best rendering for classifiers. The +% colon syntax is used by reStructuredText, so it's at least WYSIWYG. +% Use slanted text because italic would cause too much emphasis. +\providecommand{\Dformatclassifier}[1]{\textsl{#1}} +\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}} +\providecommand{\Dformatdefinition}[1]{#1} +\providecommand{\DNdefinition}[1]{\par\Dformatdefinition{#1}} + +\providecommand{\Dlineblockindentation}{2.5em} +\providecommand{\DNlineblock}[1]{% + \Dmakelistenvironment{}{% + \ifthenelse{\equal{\Dparent}{lineblock}}{% + % Parent is a line block, so indent. + \setlength{\leftmargin}{\Dlineblockindentation}% + }{% + % At top level; don't indent. + \setlength{\leftmargin}{0pt}% + }% + \setlength{\rightmargin}{0pt}% + \setlength{\parsep}{0pt}% + }{% + #1% + }% +} +\providecommand{\DNline}[1]{\item#1} + + +\providecommand{\DNtransition}{% + \raisebox{0.25em}{\parbox{\linewidth}{\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}}}% +} + + +\providecommand{\Dformatblockquote}[1]{% + % Format contents of block quote. + % This occurs in block-level context, so we cannot use \textsl. + {\slshape#1}% +} +\providecommand{\Dformatattribution}[1]{---\textup{#1}} +\providecommand{\DNblockquote}[1]{% + \Dmakebox{% + \Dformatblockquote{#1} + }% +} +\providecommand{\DNattribution}[1]{% + \par% + \begin{flushright}\Dformatattribution{#1}\end{flushright}% +} + + +% Sidebars: +\RequirePackage{picins} +% Vertical and horizontal margins. +\Dprovidelength{\Dsidebarvmargin}{0.5em} +\Dprovidelength{\Dsidebarhmargin}{1em} +% Padding (space between contents and frame). +\Dprovidelength{\Dsidebarpadding}{1em} +% Frame width. +\Dprovidelength{\Dsidebarframewidth}{2\fboxrule} +% Position ("l" or "r"). +\providecommand{\Dsidebarposition}{r} +% Width. +\Dprovidelength{\Dsidebarwidth}{0.45\linewidth} +\providecommand{\DNsidebar}[1]{ + \parpic[\Dsidebarposition]{% + \begin{minipage}[t]{\Dsidebarwidth}% + % Doing this with nested minipages is ugly, but I haven't found + % another way to place vertical space before and after the fbox. + \vspace{\Dsidebarvmargin}% + {% + \setlength{\fboxrule}{\Dsidebarframewidth}% + \setlength{\fboxsep}{\Dsidebarpadding}% + \fbox{% + \begin{minipage}[t]{\linewidth}% + \setlength{\parindent}{\Dboxparindent}% + #1% + \end{minipage}% + }% + }% + \vspace{\Dsidebarvmargin}% + \end{minipage}% + }% +} + + +% Citations and footnotes. +\providecommand{\Dformatfootnote}[1]{% + % Format footnote. + {% + \footnotesize#1% + % \par is necessary for LaTeX to adjust baselineskip to the + % changed font size. + \par% + }% +} +\providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}} +\Dprovidelength{\Doriginalbaselineskip}{0pt} +\providecommand{\DNfootnotereference}[1]{% + {% + % \baselineskip is 0pt in \textsuperscript, so we save it here. + \setlength{\Doriginalbaselineskip}{\baselineskip}% + \textsuperscript{#1}% + }% +} +\providecommand{\DNcitationreference}[1]{{[}#1{]}} +\Dprovidelength{\Dfootnotesep}{3.5pt} +\providecommand{\Dsetfootnotespacing}{% + % Spacing commands executed at the beginning of footnotes. + \setlength{\parindent}{0pt}% + \hspace{1em}% +} +\providecommand{\DNfootnote}[1]{% + % See ltfloat.dtx for details. + {% + \insert\footins{% + \vspace{\Dfootnotesep}% + \Dsetfootnotespacing% + \Dformatfootnote{#1}% + }% + }% +} +\providecommand{\DNcitation}[1]{\DNfootnote{#1}} +\providecommand{\Dformatfootnotelabel}[1]{% + % Keep \footnotesize in footnote labels (\textsuperscript would + % reduce the font size even more). + \textsuperscript{\footnotesize#1{ }}% +} +\providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }} +\providecommand{\Dformatmultiplebackrefs}[1]{% + % If in printing mode, do not write out multiple backrefs. + \ifthenelse{\equal{\Dprinting}{true}}{}{\textsl{#1}}% +} +\providecommand{\Dthislabel}{} +\providecommand{\DNlabel}[1]{% + \renewcommand{\Dthislabel}{#1} + \ifthenelse{\not\equal{\Dsinglebackref}{}}{% + \let\Doriginallabel=\Dthislabel% + \def\Dthislabel{% + \Dsinglefootnotebacklink{\Dsinglebackref}{\Doriginallabel}% + }% + }{}% + \ifthenelse{\equal{\Dparent}{footnote}}{% + % Footnote label. + \Dformatfootnotelabel{\Dthislabel}% + }{% + \ifthenelse{\equal{\Dparent}{citation}}{% + % Citation label. + \Dformatcitationlabel{\Dthislabel}% + }{}% + }% + % If there are multiple backrefs, add them now. + \Dformatmultiplebackrefs{\Dmultiplebackrefs}% +} +\providecommand{\Dsinglefootnotebacklink}[2]{% + % Create normal backlink of a footnote label. Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dmultifootnotebacklink}[2]{% + % Create generated backlink, as in (1, 2). Parameters: + % 1. ID. + % 2. Link text. + % Treat like a footnote reference. + \Dimplicitfootnotereference{\##1}{#2}% +} +\providecommand{\Dsinglecitationbacklink}[2]{\Dsinglefootnotebacklink{#1}{#2}} +\providecommand{\Dmulticitationbacklink}[2]{\Dmultifootnotebacklink{#1}{#2}} + + +\RequirePackage{longtable} +\providecommand{\Dmaketable}[2]{% + % Make table. Parameters: + % 1. Table spec (like "|p|p|"). + % 2. Table contents. + {% + \ifthenelse{\equal{\Dinsidetabular}{true}}{% + % Inside longtable; we cannot have nested longtables. + \begin{tabular}{#1}% + \hline% + #2% + \end{tabular}% + }{% + \renewcommand{\Dinsidetabular}{true}% + \begin{longtable}{#1}% + \hline% + #2% + \end{longtable}% + }% + }% +} +\providecommand{\DNthead}[1]{% + #1% + \endhead% +} +\providecommand{\DNrow}[1]{% + #1\tabularnewline% + \hline% +} +\providecommand{\Dinsidemulticolumn}{false} +\providecommand{\Dcompensatingmulticol}[3]{% + \multicolumn{#1}{#2}{% + {% + \renewcommand{\Dinsidemulticolumn}{true}% + % Compensate for weird missing vertical space at top of paragraph. + \raisebox{-2.5pt}{#3}% + }% + }% +} +\providecommand{\Dcolspan}[2]{% + % Take care of the morecols attribute (but incremented by 1). + &% + \Dcompensatingmulticol{#1}{l|}{#2}% +} +\providecommand{\Dcolspanleft}[2]{% + % Like \Dmorecols, but called for the leftmost entries in a table + % row. + \Dcompensatingmulticol{#1}{|l|}{#2}% +} +\providecommand{\Dsubsequententry}[1]{% + % +} +\providecommand{\DNentry}[1]{% + % The following sequence adds minimal vertical space above the top + % lines of the first cell paragraph, so that vertical space is + % balanced at the top and bottom of table cells. + \ifthenelse{\equal{\Dinsidemulticolumn}{false}}{% + \vspace{-1em}\vspace{-\parskip}\par% + }{}% + #1% + % No need to add an ampersand ("&"); that's done by \Dsubsequententry. +} +\providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}} +\providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}} + + +\providecommand{\DNsystemmessage}[1]{% + {% + \ifthenelse{\equal{\Dprinting}{false}}{\color{red}}{}% + \bfseries% + #1% + }% +} + + +\providecommand{\Dinsidehalign}{false} +\newsavebox{\Dalignedimagebox} +\Dprovidelength{\Dalignedimagewidth}{0pt} +\providecommand{\Dhalign}[2]{% + % Horizontally align the contents to the left or right so that the + % text flows around it. + % Parameters: + % 1. l or r + % 2. Contents. + \renewcommand{\Dinsidehalign}{true}% + % For some obscure reason \parpic consumes some vertical space. + \vspace{-3pt}% + % Now we do something *really* ugly, but this enables us to wrap the + % image in a minipage while still allowing tight frames when + % class=border (see \DNimageCborder). + \sbox{\Dalignedimagebox}{#2}% + \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}% + \parpic[#1]{% + \begin{minipage}[b]{\Dalignedimagewidth}% + % Compensate for previously added space, but not entirely. + \vspace*{2.0pt}% + \vspace*{\Dfloatimagetopmargin}% + \usebox{\Dalignedimagebox}% + \vspace*{1.5pt}% + \vspace*{\Dfloatimagebottommargin}% + \end{minipage}% + }% + \renewcommand{\Dinsidehalign}{false}% +} + + +\RequirePackage{graphicx} +% Maximum width of an image. +\providecommand{\Dimagemaxwidth}{\linewidth} +\providecommand{\Dfloatimagemaxwidth}{0.5\linewidth} +% Auxiliary variable. +\Dprovidelength{\Dcurrentimagewidth}{0pt} +\providecommand{\DNimageAalign}[5]{% + \ifthenelse{\equal{#3}{left}}{% + \Dhalign{l}{#5}% + }{% + \ifthenelse{\equal{#3}{right}}{% + \Dhalign{r}{#5}% + }{% + \ifthenelse{\equal{#3}{center}}{% + % Text floating around centered figures is a bad idea. Thus + % we use a center environment. Note that no extra space is + % added by the writer, so the space added by the center + % environment is fine. + \begin{center}#5\end{center}% + }{% + #5% + }% + }% + }% +} +% Base path for images. +\providecommand{\Dimagebase}{} +% Auxiliary command. Current image path. +\providecommand{\Dimagepath}{} +\providecommand{\DNimageAuri}[5]{% + % Insert image. We treat the URI like a path here. + \renewcommand{\Dimagepath}{\Dimagebase#3}% + \Difdefined{DcurrentNimageAwidth}{% + \Dwidthimage{\DcurrentNimageAwidth}{\Dimagepath}% + }{% + \Dsimpleimage{\Dimagepath}% + }% +} +\Dprovidelength{\Dfloatimagevmargin}{0pt} +\providecommand{\Dfloatimagetopmargin}{\Dfloatimagevmargin} +\providecommand{\Dfloatimagebottommargin}{\Dfloatimagevmargin} +\providecommand{\Dwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width. + % 2. Image path. + % Need to make bottom-alignment dependent on align attribute (add + % functional test first). Need to observe height attribute. + %\begin{minipage}[b]{#1}% + \includegraphics[width=#1,height=\textheight,keepaspectratio]{#2}% + %\end{minipage}% +} +\providecommand{\Dcurrentimagemaxwidth}{} +\providecommand{\Dsimpleimage}[1]{% + % Insert image, without much parametrization. + \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}% + \ifthenelse{\equal{\Dinsidehalign}{true}}{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dfloatimagemaxwidth}% + }{% + \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}% + }% + \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{% + \Dwidthimage{\Dcurrentimagemaxwidth}{#1}% + }{% + \Dwidthimage{\Dcurrentimagewidth}{#1}% + }% +} +\providecommand{\Dwidthimage}[2]{% + % Image with specified width. + % Parameters: + % 1. Image width. + % 2. Image path. + \Dwidthimage{#1}{#2}% +} + +% Figures. +\providecommand{\DNfigureAalign}[5]{% + % Hack to make it work Right Now. + %\def\DcurrentNimageAwidth{\DcurrentNfigureAwidth}% + % + %\def\DcurrentNimageAwidth{\linewidth}% + \DNimageAalign{#1}{#2}{#3}{#4}{% + \begin{minipage}[b]{0.4\linewidth}#5\end{minipage}}% + %\let\DcurrentNimageAwidth=\relax% + % + %\let\DcurrentNimageAwidth=\relax% +} +\providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}} +\providecommand{\DNlegend}[1]{\Dauxiliaryspace#1} + +\providecommand{\DCborder}[1]{\fbox{#1}} +% No padding between image and border. +\providecommand{\DNimageCborder}[1]{\frame{#1}} + + +% Need to replace with language-specific stuff. Maybe look at +% csquotes.sty and ask the author for permission to use parts of it. +\providecommand{\Dtextleftdblquote}{``} +\providecommand{\Dtextrightdblquote}{''} + +% Table of contents: +\Dprovidelength{\Dtocininitialsectnumwidth}{2.4em} +\Dprovidelength{\Dtocadditionalsectnumwidth}{0.7em} +% Level inside a table of contents. While this is at -1, we are not +% inside a TOC. +\Dprovidecounter{Dtoclevel}% +\setcounter{Dtoclevel}{-1} +\providecommand{\Dlocaltoc}{false}% +\providecommand{\DNtopicClocal}[1]{% + \renewcommand{\Dlocaltoc}{true}% + \addtolength{\Dtocsectnumwidth}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-2\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocindent}{2\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{-2\Dtocadditionalsectnumwidth}% + \renewcommand{\Dlocaltoc}{false}% +} +\Dprovidelength{\Dtocindent}{0pt}% +\Dprovidelength{\Dtocsectnumwidth}{\Dtocininitialsectnumwidth} +% Compensate for one additional TOC indentation space so that the +% top-level is unindented. +\addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth} +\addtolength{\Dtocindent}{-\Dtocsectnumwidth} +\providecommand{\Difinsidetoc}[2]{% + \ifthenelse{\not\equal{\theDtoclevel}{-1}}{#1}{#2}% +} +\providecommand{\DNgeneratedCsectnum}[1]{% + \Difinsidetoc{% + % Section number inside TOC. + \makebox[\Dtocsectnumwidth][l]{#1}% + }{% + % Section number inside section title. + #1\quad% + }% +} +\providecommand{\Dtocbulletlist}[1]{% + \addtocounter{Dtoclevel}{1}% + \addtolength{\Dtocindent}{\Dtocsectnumwidth}% + \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}% + #1% + \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}% + \addtolength{\Dtocindent}{-\Dtocsectnumwidth}% + \addtocounter{Dtoclevel}{-1}% +} + + +% For \Dpixelunit, the length value is pre-multiplied with 0.75, so by +% specifying "pt" we get the same notion of "pixel" as graphicx. +\providecommand{\Dpixelunit}{pt} +% Normally lengths are relative to the current linewidth. +\providecommand{\Drelativeunit}{\linewidth} + + +%\RequirePackage{fixmath} +%\RequirePackage{amsmath} + + +\DSfontencoding +\DSlanguage +\DSlinks +\DSsymbols +\DSlate + +\makeatother diff --git a/docutils/writers/newlatex2e/unicode_map.py b/docutils/writers/newlatex2e/unicode_map.py new file mode 100644 index 000000000..2998178f4 --- /dev/null +++ b/docutils/writers/newlatex2e/unicode_map.py @@ -0,0 +1,2371 @@ +# Author: Felix Wiemann +# Contact: Felix_Wiemann@ososo.de +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This file has been placed in the public domain. + +# This is a mapping of Unicode characters to LaTeX equivalents. +# The information has been extracted from +# , written by +# David Carlisle and Sebastian Rahtz. +# +# The extraction has been done by the "create_unimap.py" script +# located at . + +unicode_map = {u'\xa0': '$~$', +u'\xa1': '{\\textexclamdown}', +u'\xa2': '{\\textcent}', +u'\xa3': '{\\textsterling}', +u'\xa4': '{\\textcurrency}', +u'\xa5': '{\\textyen}', +u'\xa6': '{\\textbrokenbar}', +u'\xa7': '{\\textsection}', +u'\xa8': '{\\textasciidieresis}', +u'\xa9': '{\\textcopyright}', +u'\xaa': '{\\textordfeminine}', +u'\xab': '{\\guillemotleft}', +u'\xac': '$\\lnot$', +u'\xad': '$\\-$', +u'\xae': '{\\textregistered}', +u'\xaf': '{\\textasciimacron}', +u'\xb0': '{\\textdegree}', +u'\xb1': '$\\pm$', +u'\xb2': '${^2}$', +u'\xb3': '${^3}$', +u'\xb4': '{\\textasciiacute}', +u'\xb5': '$\\mathrm{\\mu}$', +u'\xb6': '{\\textparagraph}', +u'\xb7': '$\\cdot$', +u'\xb8': '{\\c{}}', +u'\xb9': '${^1}$', +u'\xba': '{\\textordmasculine}', +u'\xbb': '{\\guillemotright}', +u'\xbc': '{\\textonequarter}', +u'\xbd': '{\\textonehalf}', +u'\xbe': '{\\textthreequarters}', +u'\xbf': '{\\textquestiondown}', +u'\xc0': '{\\`{A}}', +u'\xc1': "{\\'{A}}", +u'\xc2': '{\\^{A}}', +u'\xc3': '{\\~{A}}', +u'\xc4': '{\\"{A}}', +u'\xc5': '{\\AA}', +u'\xc6': '{\\AE}', +u'\xc7': '{\\c{C}}', +u'\xc8': '{\\`{E}}', +u'\xc9': "{\\'{E}}", +u'\xca': '{\\^{E}}', +u'\xcb': '{\\"{E}}', +u'\xcc': '{\\`{I}}', +u'\xcd': "{\\'{I}}", +u'\xce': '{\\^{I}}', +u'\xcf': '{\\"{I}}', +u'\xd0': '{\\DH}', +u'\xd1': '{\\~{N}}', +u'\xd2': '{\\`{O}}', +u'\xd3': "{\\'{O}}", +u'\xd4': '{\\^{O}}', +u'\xd5': '{\\~{O}}', +u'\xd6': '{\\"{O}}', +u'\xd7': '{\\texttimes}', +u'\xd8': '{\\O}', +u'\xd9': '{\\`{U}}', +u'\xda': "{\\'{U}}", +u'\xdb': '{\\^{U}}', +u'\xdc': '{\\"{U}}', +u'\xdd': "{\\'{Y}}", +u'\xde': '{\\TH}', +u'\xdf': '{\\ss}', +u'\xe0': '{\\`{a}}', +u'\xe1': "{\\'{a}}", +u'\xe2': '{\\^{a}}', +u'\xe3': '{\\~{a}}', +u'\xe4': '{\\"{a}}', +u'\xe5': '{\\aa}', +u'\xe6': '{\\ae}', +u'\xe7': '{\\c{c}}', +u'\xe8': '{\\`{e}}', +u'\xe9': "{\\'{e}}", +u'\xea': '{\\^{e}}', +u'\xeb': '{\\"{e}}', +u'\xec': '{\\`{\\i}}', +u'\xed': "{\\'{\\i}}", +u'\xee': '{\\^{\\i}}', +u'\xef': '{\\"{\\i}}', +u'\xf0': '{\\dh}', +u'\xf1': '{\\~{n}}', +u'\xf2': '{\\`{o}}', +u'\xf3': "{\\'{o}}", +u'\xf4': '{\\^{o}}', +u'\xf5': '{\\~{o}}', +u'\xf6': '{\\"{o}}', +u'\xf7': '$\\div$', +u'\xf8': '{\\o}', +u'\xf9': '{\\`{u}}', +u'\xfa': "{\\'{u}}", +u'\xfb': '{\\^{u}}', +u'\xfc': '{\\"{u}}', +u'\xfd': "{\\'{y}}", +u'\xfe': '{\\th}', +u'\xff': '{\\"{y}}', +u'\u0100': '{\\={A}}', +u'\u0101': '{\\={a}}', +u'\u0102': '{\\u{A}}', +u'\u0103': '{\\u{a}}', +u'\u0104': '{\\k{A}}', +u'\u0105': '{\\k{a}}', +u'\u0106': "{\\'{C}}", +u'\u0107': "{\\'{c}}", +u'\u0108': '{\\^{C}}', +u'\u0109': '{\\^{c}}', +u'\u010a': '{\\.{C}}', +u'\u010b': '{\\.{c}}', +u'\u010c': '{\\v{C}}', +u'\u010d': '{\\v{c}}', +u'\u010e': '{\\v{D}}', +u'\u010f': '{\\v{d}}', +u'\u0110': '{\\DJ}', +u'\u0111': '{\\dj}', +u'\u0112': '{\\={E}}', +u'\u0113': '{\\={e}}', +u'\u0114': '{\\u{E}}', +u'\u0115': '{\\u{e}}', +u'\u0116': '{\\.{E}}', +u'\u0117': '{\\.{e}}', +u'\u0118': '{\\k{E}}', +u'\u0119': '{\\k{e}}', +u'\u011a': '{\\v{E}}', +u'\u011b': '{\\v{e}}', +u'\u011c': '{\\^{G}}', +u'\u011d': '{\\^{g}}', +u'\u011e': '{\\u{G}}', +u'\u011f': '{\\u{g}}', +u'\u0120': '{\\.{G}}', +u'\u0121': '{\\.{g}}', +u'\u0122': '{\\c{G}}', +u'\u0123': '{\\c{g}}', +u'\u0124': '{\\^{H}}', +u'\u0125': '{\\^{h}}', +u'\u0126': '{{\\fontencoding{LELA}\\selectfont\\char40}}', +u'\u0127': '$\\Elzxh$', +u'\u0128': '{\\~{I}}', +u'\u0129': '{\\~{\\i}}', +u'\u012a': '{\\={I}}', +u'\u012b': '{\\={\\i}}', +u'\u012c': '{\\u{I}}', +u'\u012d': '{\\u{\\i}}', +u'\u012e': '{\\k{I}}', +u'\u012f': '{\\k{i}}', +u'\u0130': '{\\.{I}}', +u'\u0131': '{\\i}', +u'\u0132': '{IJ}', +u'\u0133': '{ij}', +u'\u0134': '{\\^{J}}', +u'\u0135': '{\\^{\\j}}', +u'\u0136': '{\\c{K}}', +u'\u0137': '{\\c{k}}', +u'\u0138': '{{\\fontencoding{LELA}\\selectfont\\char91}}', +u'\u0139': "{\\'{L}}", +u'\u013a': "{\\'{l}}", +u'\u013b': '{\\c{L}}', +u'\u013c': '{\\c{l}}', +u'\u013d': '{\\v{L}}', +u'\u013e': '{\\v{l}}', +u'\u013f': '{{\\fontencoding{LELA}\\selectfont\\char201}}', +u'\u0140': '{{\\fontencoding{LELA}\\selectfont\\char202}}', +u'\u0141': '{\\L}', +u'\u0142': '{\\l}', +u'\u0143': "{\\'{N}}", +u'\u0144': "{\\'{n}}", +u'\u0145': '{\\c{N}}', +u'\u0146': '{\\c{n}}', +u'\u0147': '{\\v{N}}', +u'\u0148': '{\\v{n}}', +u'\u0149': "{'n}", +u'\u014a': '{\\NG}', +u'\u014b': '{\\ng}', +u'\u014c': '{\\={O}}', +u'\u014d': '{\\={o}}', +u'\u014e': '{\\u{O}}', +u'\u014f': '{\\u{o}}', +u'\u0150': '{\\H{O}}', +u'\u0151': '{\\H{o}}', +u'\u0152': '{\\OE}', +u'\u0153': '{\\oe}', +u'\u0154': "{\\'{R}}", +u'\u0155': "{\\'{r}}", +u'\u0156': '{\\c{R}}', +u'\u0157': '{\\c{r}}', +u'\u0158': '{\\v{R}}', +u'\u0159': '{\\v{r}}', +u'\u015a': "{\\'{S}}", +u'\u015b': "{\\'{s}}", +u'\u015c': '{\\^{S}}', +u'\u015d': '{\\^{s}}', +u'\u015e': '{\\c{S}}', +u'\u015f': '{\\c{s}}', +u'\u0160': '{\\v{S}}', +u'\u0161': '{\\v{s}}', +u'\u0162': '{\\c{T}}', +u'\u0163': '{\\c{t}}', +u'\u0164': '{\\v{T}}', +u'\u0165': '{\\v{t}}', +u'\u0166': '{{\\fontencoding{LELA}\\selectfont\\char47}}', +u'\u0167': '{{\\fontencoding{LELA}\\selectfont\\char63}}', +u'\u0168': '{\\~{U}}', +u'\u0169': '{\\~{u}}', +u'\u016a': '{\\={U}}', +u'\u016b': '{\\={u}}', +u'\u016c': '{\\u{U}}', +u'\u016d': '{\\u{u}}', +u'\u016e': '{\\r{U}}', +u'\u016f': '{\\r{u}}', +u'\u0170': '{\\H{U}}', +u'\u0171': '{\\H{u}}', +u'\u0172': '{\\k{U}}', +u'\u0173': '{\\k{u}}', +u'\u0174': '{\\^{W}}', +u'\u0175': '{\\^{w}}', +u'\u0176': '{\\^{Y}}', +u'\u0177': '{\\^{y}}', +u'\u0178': '{\\"{Y}}', +u'\u0179': "{\\'{Z}}", +u'\u017a': "{\\'{z}}", +u'\u017b': '{\\.{Z}}', +u'\u017c': '{\\.{z}}', +u'\u017d': '{\\v{Z}}', +u'\u017e': '{\\v{z}}', +u'\u0192': '$f$', +u'\u0195': '{\\texthvlig}', +u'\u019e': '{\\textnrleg}', +u'\u01aa': '$\\eth$', +u'\u01ba': '{{\\fontencoding{LELA}\\selectfont\\char195}}', +u'\u01c2': '{\\textdoublepipe}', +u'\u01f5': "{\\'{g}}", +u'\u0250': '$\\Elztrna$', +u'\u0252': '$\\Elztrnsa$', +u'\u0254': '$\\Elzopeno$', +u'\u0256': '$\\Elzrtld$', +u'\u0258': '{{\\fontencoding{LEIP}\\selectfont\\char61}}', +u'\u0259': '$\\Elzschwa$', +u'\u025b': '$\\varepsilon$', +u'\u0261': '{g}', +u'\u0263': '$\\Elzpgamma$', +u'\u0264': '$\\Elzpbgam$', +u'\u0265': '$\\Elztrnh$', +u'\u026c': '$\\Elzbtdl$', +u'\u026d': '$\\Elzrtll$', +u'\u026f': '$\\Elztrnm$', +u'\u0270': '$\\Elztrnmlr$', +u'\u0271': '$\\Elzltlmr$', +u'\u0272': '{\\Elzltln}', +u'\u0273': '$\\Elzrtln$', +u'\u0277': '$\\Elzclomeg$', +u'\u0278': '{\\textphi}', +u'\u0279': '$\\Elztrnr$', +u'\u027a': '$\\Elztrnrl$', +u'\u027b': '$\\Elzrttrnr$', +u'\u027c': '$\\Elzrl$', +u'\u027d': '$\\Elzrtlr$', +u'\u027e': '$\\Elzfhr$', +u'\u027f': '{{\\fontencoding{LEIP}\\selectfont\\char202}}', +u'\u0282': '$\\Elzrtls$', +u'\u0283': '$\\Elzesh$', +u'\u0287': '$\\Elztrnt$', +u'\u0288': '$\\Elzrtlt$', +u'\u028a': '$\\Elzpupsil$', +u'\u028b': '$\\Elzpscrv$', +u'\u028c': '$\\Elzinvv$', +u'\u028d': '$\\Elzinvw$', +u'\u028e': '$\\Elztrny$', +u'\u0290': '$\\Elzrtlz$', +u'\u0292': '$\\Elzyogh$', +u'\u0294': '$\\Elzglst$', +u'\u0295': '$\\Elzreglst$', +u'\u0296': '$\\Elzinglst$', +u'\u029e': '{\\textturnk}', +u'\u02a4': '$\\Elzdyogh$', +u'\u02a7': '$\\Elztesh$', +u'\u02bc': "{'}", +u'\u02c7': '{\\textasciicaron}', +u'\u02c8': '$\\Elzverts$', +u'\u02cc': '$\\Elzverti$', +u'\u02d0': '$\\Elzlmrk$', +u'\u02d1': '$\\Elzhlmrk$', +u'\u02d2': '$\\Elzsbrhr$', +u'\u02d3': '$\\Elzsblhr$', +u'\u02d4': '$\\Elzrais$', +u'\u02d5': '$\\Elzlow$', +u'\u02d8': '{\\textasciibreve}', +u'\u02d9': '{\\textperiodcentered}', +u'\u02da': '{\\r{}}', +u'\u02db': '{\\k{}}', +u'\u02dc': '{\\texttildelow}', +u'\u02dd': '{\\H{}}', +u'\u02e5': '{\\tone{55}}', +u'\u02e6': '{\\tone{44}}', +u'\u02e7': '{\\tone{33}}', +u'\u02e8': '{\\tone{22}}', +u'\u02e9': '{\\tone{11}}', +u'\u0300': '{\\`}', +u'\u0301': "{\\'}", +u'\u0302': '{\\^}', +u'\u0303': '{\\~}', +u'\u0304': '{\\=}', +u'\u0306': '{\\u}', +u'\u0307': '{\\.}', +u'\u0308': '{\\"}', +u'\u030a': '{\\r}', +u'\u030b': '{\\H}', +u'\u030c': '{\\v}', +u'\u030f': '{\\cyrchar\\C}', +u'\u0311': '{{\\fontencoding{LECO}\\selectfont\\char177}}', +u'\u0318': '{{\\fontencoding{LECO}\\selectfont\\char184}}', +u'\u0319': '{{\\fontencoding{LECO}\\selectfont\\char185}}', +u'\u0321': '$\\Elzpalh$', +u'\u0322': '{\\Elzrh}', +u'\u0327': '{\\c}', +u'\u0328': '{\\k}', +u'\u032a': '$\\Elzsbbrg$', +u'\u032b': '{{\\fontencoding{LECO}\\selectfont\\char203}}', +u'\u032f': '{{\\fontencoding{LECO}\\selectfont\\char207}}', +u'\u0335': '{\\Elzxl}', +u'\u0336': '{\\Elzbar}', +u'\u0337': '{{\\fontencoding{LECO}\\selectfont\\char215}}', +u'\u0338': '{{\\fontencoding{LECO}\\selectfont\\char216}}', +u'\u033a': '{{\\fontencoding{LECO}\\selectfont\\char218}}', +u'\u033b': '{{\\fontencoding{LECO}\\selectfont\\char219}}', +u'\u033c': '{{\\fontencoding{LECO}\\selectfont\\char220}}', +u'\u033d': '{{\\fontencoding{LECO}\\selectfont\\char221}}', +u'\u0361': '{{\\fontencoding{LECO}\\selectfont\\char225}}', +u'\u0386': "{\\'{A}}", +u'\u0388': "{\\'{E}}", +u'\u0389': "{\\'{H}}", +u'\u038a': "{\\'{}{I}}", +u'\u038c': "{\\'{}O}", +u'\u038e': "$\\mathrm{'Y}$", +u'\u038f': "$\\mathrm{'\\Omega}$", +u'\u0390': '$\\acute{\\ddot{\\iota}}$', +u'\u0391': '$\\Alpha$', +u'\u0392': '$\\Beta$', +u'\u0393': '$\\Gamma$', +u'\u0394': '$\\Delta$', +u'\u0395': '$\\Epsilon$', +u'\u0396': '$\\Zeta$', +u'\u0397': '$\\Eta$', +u'\u0398': '$\\Theta$', +u'\u0399': '$\\Iota$', +u'\u039a': '$\\Kappa$', +u'\u039b': '$\\Lambda$', +u'\u039c': '$M$', +u'\u039d': '$N$', +u'\u039e': '$\\Xi$', +u'\u039f': '$O$', +u'\u03a0': '$\\Pi$', +u'\u03a1': '$\\Rho$', +u'\u03a3': '$\\Sigma$', +u'\u03a4': '$\\Tau$', +u'\u03a5': '$\\Upsilon$', +u'\u03a6': '$\\Phi$', +u'\u03a7': '$\\Chi$', +u'\u03a8': '$\\Psi$', +u'\u03a9': '$\\Omega$', +u'\u03aa': '$\\mathrm{\\ddot{I}}$', +u'\u03ab': '$\\mathrm{\\ddot{Y}}$', +u'\u03ac': "{\\'{$\\alpha$}}", +u'\u03ad': '$\\acute{\\epsilon}$', +u'\u03ae': '$\\acute{\\eta}$', +u'\u03af': '$\\acute{\\iota}$', +u'\u03b0': '$\\acute{\\ddot{\\upsilon}}$', +u'\u03b1': '$\\alpha$', +u'\u03b2': '$\\beta$', +u'\u03b3': '$\\gamma$', +u'\u03b4': '$\\delta$', +u'\u03b5': '$\\epsilon$', +u'\u03b6': '$\\zeta$', +u'\u03b7': '$\\eta$', +u'\u03b8': '{\\texttheta}', +u'\u03b9': '$\\iota$', +u'\u03ba': '$\\kappa$', +u'\u03bb': '$\\lambda$', +u'\u03bc': '$\\mu$', +u'\u03bd': '$\\nu$', +u'\u03be': '$\\xi$', +u'\u03bf': '$o$', +u'\u03c0': '$\\pi$', +u'\u03c1': '$\\rho$', +u'\u03c2': '$\\varsigma$', +u'\u03c3': '$\\sigma$', +u'\u03c4': '$\\tau$', +u'\u03c5': '$\\upsilon$', +u'\u03c6': '$\\varphi$', +u'\u03c7': '$\\chi$', +u'\u03c8': '$\\psi$', +u'\u03c9': '$\\omega$', +u'\u03ca': '$\\ddot{\\iota}$', +u'\u03cb': '$\\ddot{\\upsilon}$', +u'\u03cc': "{\\'{o}}", +u'\u03cd': '$\\acute{\\upsilon}$', +u'\u03ce': '$\\acute{\\omega}$', +u'\u03d0': '{\\Pisymbol{ppi022}{87}}', +u'\u03d1': '{\\textvartheta}', +u'\u03d2': '$\\Upsilon$', +u'\u03d5': '$\\phi$', +u'\u03d6': '$\\varpi$', +u'\u03da': '$\\Stigma$', +u'\u03dc': '$\\Digamma$', +u'\u03dd': '$\\digamma$', +u'\u03de': '$\\Koppa$', +u'\u03e0': '$\\Sampi$', +u'\u03f0': '$\\varkappa$', +u'\u03f1': '$\\varrho$', +u'\u03f4': '{\\textTheta}', +u'\u03f6': '$\\backepsilon$', +u'\u0401': '{\\cyrchar\\CYRYO}', +u'\u0402': '{\\cyrchar\\CYRDJE}', +u'\u0403': "{\\cyrchar{\\'\\CYRG}}", +u'\u0404': '{\\cyrchar\\CYRIE}', +u'\u0405': '{\\cyrchar\\CYRDZE}', +u'\u0406': '{\\cyrchar\\CYRII}', +u'\u0407': '{\\cyrchar\\CYRYI}', +u'\u0408': '{\\cyrchar\\CYRJE}', +u'\u0409': '{\\cyrchar\\CYRLJE}', +u'\u040a': '{\\cyrchar\\CYRNJE}', +u'\u040b': '{\\cyrchar\\CYRTSHE}', +u'\u040c': "{\\cyrchar{\\'\\CYRK}}", +u'\u040e': '{\\cyrchar\\CYRUSHRT}', +u'\u040f': '{\\cyrchar\\CYRDZHE}', +u'\u0410': '{\\cyrchar\\CYRA}', +u'\u0411': '{\\cyrchar\\CYRB}', +u'\u0412': '{\\cyrchar\\CYRV}', +u'\u0413': '{\\cyrchar\\CYRG}', +u'\u0414': '{\\cyrchar\\CYRD}', +u'\u0415': '{\\cyrchar\\CYRE}', +u'\u0416': '{\\cyrchar\\CYRZH}', +u'\u0417': '{\\cyrchar\\CYRZ}', +u'\u0418': '{\\cyrchar\\CYRI}', +u'\u0419': '{\\cyrchar\\CYRISHRT}', +u'\u041a': '{\\cyrchar\\CYRK}', +u'\u041b': '{\\cyrchar\\CYRL}', +u'\u041c': '{\\cyrchar\\CYRM}', +u'\u041d': '{\\cyrchar\\CYRN}', +u'\u041e': '{\\cyrchar\\CYRO}', +u'\u041f': '{\\cyrchar\\CYRP}', +u'\u0420': '{\\cyrchar\\CYRR}', +u'\u0421': '{\\cyrchar\\CYRS}', +u'\u0422': '{\\cyrchar\\CYRT}', +u'\u0423': '{\\cyrchar\\CYRU}', +u'\u0424': '{\\cyrchar\\CYRF}', +u'\u0425': '{\\cyrchar\\CYRH}', +u'\u0426': '{\\cyrchar\\CYRC}', +u'\u0427': '{\\cyrchar\\CYRCH}', +u'\u0428': '{\\cyrchar\\CYRSH}', +u'\u0429': '{\\cyrchar\\CYRSHCH}', +u'\u042a': '{\\cyrchar\\CYRHRDSN}', +u'\u042b': '{\\cyrchar\\CYRERY}', +u'\u042c': '{\\cyrchar\\CYRSFTSN}', +u'\u042d': '{\\cyrchar\\CYREREV}', +u'\u042e': '{\\cyrchar\\CYRYU}', +u'\u042f': '{\\cyrchar\\CYRYA}', +u'\u0430': '{\\cyrchar\\cyra}', +u'\u0431': '{\\cyrchar\\cyrb}', +u'\u0432': '{\\cyrchar\\cyrv}', +u'\u0433': '{\\cyrchar\\cyrg}', +u'\u0434': '{\\cyrchar\\cyrd}', +u'\u0435': '{\\cyrchar\\cyre}', +u'\u0436': '{\\cyrchar\\cyrzh}', +u'\u0437': '{\\cyrchar\\cyrz}', +u'\u0438': '{\\cyrchar\\cyri}', +u'\u0439': '{\\cyrchar\\cyrishrt}', +u'\u043a': '{\\cyrchar\\cyrk}', +u'\u043b': '{\\cyrchar\\cyrl}', +u'\u043c': '{\\cyrchar\\cyrm}', +u'\u043d': '{\\cyrchar\\cyrn}', +u'\u043e': '{\\cyrchar\\cyro}', +u'\u043f': '{\\cyrchar\\cyrp}', +u'\u0440': '{\\cyrchar\\cyrr}', +u'\u0441': '{\\cyrchar\\cyrs}', +u'\u0442': '{\\cyrchar\\cyrt}', +u'\u0443': '{\\cyrchar\\cyru}', +u'\u0444': '{\\cyrchar\\cyrf}', +u'\u0445': '{\\cyrchar\\cyrh}', +u'\u0446': '{\\cyrchar\\cyrc}', +u'\u0447': '{\\cyrchar\\cyrch}', +u'\u0448': '{\\cyrchar\\cyrsh}', +u'\u0449': '{\\cyrchar\\cyrshch}', +u'\u044a': '{\\cyrchar\\cyrhrdsn}', +u'\u044b': '{\\cyrchar\\cyrery}', +u'\u044c': '{\\cyrchar\\cyrsftsn}', +u'\u044d': '{\\cyrchar\\cyrerev}', +u'\u044e': '{\\cyrchar\\cyryu}', +u'\u044f': '{\\cyrchar\\cyrya}', +u'\u0451': '{\\cyrchar\\cyryo}', +u'\u0452': '{\\cyrchar\\cyrdje}', +u'\u0453': "{\\cyrchar{\\'\\cyrg}}", +u'\u0454': '{\\cyrchar\\cyrie}', +u'\u0455': '{\\cyrchar\\cyrdze}', +u'\u0456': '{\\cyrchar\\cyrii}', +u'\u0457': '{\\cyrchar\\cyryi}', +u'\u0458': '{\\cyrchar\\cyrje}', +u'\u0459': '{\\cyrchar\\cyrlje}', +u'\u045a': '{\\cyrchar\\cyrnje}', +u'\u045b': '{\\cyrchar\\cyrtshe}', +u'\u045c': "{\\cyrchar{\\'\\cyrk}}", +u'\u045e': '{\\cyrchar\\cyrushrt}', +u'\u045f': '{\\cyrchar\\cyrdzhe}', +u'\u0460': '{\\cyrchar\\CYROMEGA}', +u'\u0461': '{\\cyrchar\\cyromega}', +u'\u0462': '{\\cyrchar\\CYRYAT}', +u'\u0464': '{\\cyrchar\\CYRIOTE}', +u'\u0465': '{\\cyrchar\\cyriote}', +u'\u0466': '{\\cyrchar\\CYRLYUS}', +u'\u0467': '{\\cyrchar\\cyrlyus}', +u'\u0468': '{\\cyrchar\\CYRIOTLYUS}', +u'\u0469': '{\\cyrchar\\cyriotlyus}', +u'\u046a': '{\\cyrchar\\CYRBYUS}', +u'\u046c': '{\\cyrchar\\CYRIOTBYUS}', +u'\u046d': '{\\cyrchar\\cyriotbyus}', +u'\u046e': '{\\cyrchar\\CYRKSI}', +u'\u046f': '{\\cyrchar\\cyrksi}', +u'\u0470': '{\\cyrchar\\CYRPSI}', +u'\u0471': '{\\cyrchar\\cyrpsi}', +u'\u0472': '{\\cyrchar\\CYRFITA}', +u'\u0474': '{\\cyrchar\\CYRIZH}', +u'\u0478': '{\\cyrchar\\CYRUK}', +u'\u0479': '{\\cyrchar\\cyruk}', +u'\u047a': '{\\cyrchar\\CYROMEGARND}', +u'\u047b': '{\\cyrchar\\cyromegarnd}', +u'\u047c': '{\\cyrchar\\CYROMEGATITLO}', +u'\u047d': '{\\cyrchar\\cyromegatitlo}', +u'\u047e': '{\\cyrchar\\CYROT}', +u'\u047f': '{\\cyrchar\\cyrot}', +u'\u0480': '{\\cyrchar\\CYRKOPPA}', +u'\u0481': '{\\cyrchar\\cyrkoppa}', +u'\u0482': '{\\cyrchar\\cyrthousands}', +u'\u0488': '{\\cyrchar\\cyrhundredthousands}', +u'\u0489': '{\\cyrchar\\cyrmillions}', +u'\u048c': '{\\cyrchar\\CYRSEMISFTSN}', +u'\u048d': '{\\cyrchar\\cyrsemisftsn}', +u'\u048e': '{\\cyrchar\\CYRRTICK}', +u'\u048f': '{\\cyrchar\\cyrrtick}', +u'\u0490': '{\\cyrchar\\CYRGUP}', +u'\u0491': '{\\cyrchar\\cyrgup}', +u'\u0492': '{\\cyrchar\\CYRGHCRS}', +u'\u0493': '{\\cyrchar\\cyrghcrs}', +u'\u0494': '{\\cyrchar\\CYRGHK}', +u'\u0495': '{\\cyrchar\\cyrghk}', +u'\u0496': '{\\cyrchar\\CYRZHDSC}', +u'\u0497': '{\\cyrchar\\cyrzhdsc}', +u'\u0498': '{\\cyrchar\\CYRZDSC}', +u'\u0499': '{\\cyrchar\\cyrzdsc}', +u'\u049a': '{\\cyrchar\\CYRKDSC}', +u'\u049b': '{\\cyrchar\\cyrkdsc}', +u'\u049c': '{\\cyrchar\\CYRKVCRS}', +u'\u049d': '{\\cyrchar\\cyrkvcrs}', +u'\u049e': '{\\cyrchar\\CYRKHCRS}', +u'\u049f': '{\\cyrchar\\cyrkhcrs}', +u'\u04a0': '{\\cyrchar\\CYRKBEAK}', +u'\u04a1': '{\\cyrchar\\cyrkbeak}', +u'\u04a2': '{\\cyrchar\\CYRNDSC}', +u'\u04a3': '{\\cyrchar\\cyrndsc}', +u'\u04a4': '{\\cyrchar\\CYRNG}', +u'\u04a5': '{\\cyrchar\\cyrng}', +u'\u04a6': '{\\cyrchar\\CYRPHK}', +u'\u04a7': '{\\cyrchar\\cyrphk}', +u'\u04a8': '{\\cyrchar\\CYRABHHA}', +u'\u04a9': '{\\cyrchar\\cyrabhha}', +u'\u04aa': '{\\cyrchar\\CYRSDSC}', +u'\u04ab': '{\\cyrchar\\cyrsdsc}', +u'\u04ac': '{\\cyrchar\\CYRTDSC}', +u'\u04ad': '{\\cyrchar\\cyrtdsc}', +u'\u04ae': '{\\cyrchar\\CYRY}', +u'\u04af': '{\\cyrchar\\cyry}', +u'\u04b0': '{\\cyrchar\\CYRYHCRS}', +u'\u04b1': '{\\cyrchar\\cyryhcrs}', +u'\u04b2': '{\\cyrchar\\CYRHDSC}', +u'\u04b3': '{\\cyrchar\\cyrhdsc}', +u'\u04b4': '{\\cyrchar\\CYRTETSE}', +u'\u04b5': '{\\cyrchar\\cyrtetse}', +u'\u04b6': '{\\cyrchar\\CYRCHRDSC}', +u'\u04b7': '{\\cyrchar\\cyrchrdsc}', +u'\u04b8': '{\\cyrchar\\CYRCHVCRS}', +u'\u04b9': '{\\cyrchar\\cyrchvcrs}', +u'\u04ba': '{\\cyrchar\\CYRSHHA}', +u'\u04bb': '{\\cyrchar\\cyrshha}', +u'\u04bc': '{\\cyrchar\\CYRABHCH}', +u'\u04bd': '{\\cyrchar\\cyrabhch}', +u'\u04be': '{\\cyrchar\\CYRABHCHDSC}', +u'\u04bf': '{\\cyrchar\\cyrabhchdsc}', +u'\u04c0': '{\\cyrchar\\CYRpalochka}', +u'\u04c3': '{\\cyrchar\\CYRKHK}', +u'\u04c4': '{\\cyrchar\\cyrkhk}', +u'\u04c7': '{\\cyrchar\\CYRNHK}', +u'\u04c8': '{\\cyrchar\\cyrnhk}', +u'\u04cb': '{\\cyrchar\\CYRCHLDSC}', +u'\u04cc': '{\\cyrchar\\cyrchldsc}', +u'\u04d4': '{\\cyrchar\\CYRAE}', +u'\u04d5': '{\\cyrchar\\cyrae}', +u'\u04d8': '{\\cyrchar\\CYRSCHWA}', +u'\u04d9': '{\\cyrchar\\cyrschwa}', +u'\u04e0': '{\\cyrchar\\CYRABHDZE}', +u'\u04e1': '{\\cyrchar\\cyrabhdze}', +u'\u04e8': '{\\cyrchar\\CYROTLD}', +u'\u04e9': '{\\cyrchar\\cyrotld}', +u'\u2002': '{\\hspace{0.6em}}', +u'\u2003': '{\\hspace{1em}}', +u'\u2004': '{\\hspace{0.33em}}', +u'\u2005': '{\\hspace{0.25em}}', +u'\u2006': '{\\hspace{0.166em}}', +u'\u2007': '{\\hphantom{0}}', +u'\u2008': '{\\hphantom{,}}', +u'\u2009': '{\\hspace{0.167em}}', +u'\u200a': '$\\mkern1mu$', +u'\u2010': '{-}', +u'\u2013': '{\\textendash}', +u'\u2014': '{\\textemdash}', +u'\u2015': '{\\rule{1em}{1pt}}', +u'\u2016': '$\\Vert$', +u'\u2018': '{`}', +u'\u2019': "{'}", +u'\u201a': '{,}', +u'\u201b': '$\\Elzreapos$', +u'\u201c': '{\\textquotedblleft}', +u'\u201d': '{\\textquotedblright}', +u'\u201e': '{,,}', +u'\u2020': '{\\textdagger}', +u'\u2021': '{\\textdaggerdbl}', +u'\u2022': '{\\textbullet}', +u'\u2024': '{.}', +u'\u2025': '{..}', +u'\u2026': '{\\ldots}', +u'\u2030': '{\\textperthousand}', +u'\u2031': '{\\textpertenthousand}', +u'\u2032': "${'}$", +u'\u2033': "${''}$", +u'\u2034': "${'''}$", +u'\u2035': '$\\backprime$', +u'\u2039': '{\\guilsinglleft}', +u'\u203a': '{\\guilsinglright}', +u'\u2057': "$''''$", +u'\u205f': '{\\mkern4mu}', +u'\u2060': '{\\nolinebreak}', +u'\u20a7': '{\\ensuremath{\\Elzpes}}', +u'\u20ac': '{\\mbox{\\texteuro}}', +u'\u20db': '$\\dddot$', +u'\u20dc': '$\\ddddot$', +u'\u2102': '$\\mathbb{C}$', +u'\u210a': '{\\mathscr{g}}', +u'\u210b': '$\\mathscr{H}$', +u'\u210c': '$\\mathfrak{H}$', +u'\u210d': '$\\mathbb{H}$', +u'\u210f': '$\\hslash$', +u'\u2110': '$\\mathscr{I}$', +u'\u2111': '$\\mathfrak{I}$', +u'\u2112': '$\\mathscr{L}$', +u'\u2113': '$\\mathscr{l}$', +u'\u2115': '$\\mathbb{N}$', +u'\u2116': '{\\cyrchar\\textnumero}', +u'\u2118': '$\\wp$', +u'\u2119': '$\\mathbb{P}$', +u'\u211a': '$\\mathbb{Q}$', +u'\u211b': '$\\mathscr{R}$', +u'\u211c': '$\\mathfrak{R}$', +u'\u211d': '$\\mathbb{R}$', +u'\u211e': '$\\Elzxrat$', +u'\u2122': '{\\texttrademark}', +u'\u2124': '$\\mathbb{Z}$', +u'\u2126': '$\\Omega$', +u'\u2127': '$\\mho$', +u'\u2128': '$\\mathfrak{Z}$', +u'\u2129': '$\\ElsevierGlyph{2129}$', +u'\u212b': '{\\AA}', +u'\u212c': '$\\mathscr{B}$', +u'\u212d': '$\\mathfrak{C}$', +u'\u212f': '$\\mathscr{e}$', +u'\u2130': '$\\mathscr{E}$', +u'\u2131': '$\\mathscr{F}$', +u'\u2133': '$\\mathscr{M}$', +u'\u2134': '$\\mathscr{o}$', +u'\u2135': '$\\aleph$', +u'\u2136': '$\\beth$', +u'\u2137': '$\\gimel$', +u'\u2138': '$\\daleth$', +u'\u2153': '$\\textfrac{1}{3}$', +u'\u2154': '$\\textfrac{2}{3}$', +u'\u2155': '$\\textfrac{1}{5}$', +u'\u2156': '$\\textfrac{2}{5}$', +u'\u2157': '$\\textfrac{3}{5}$', +u'\u2158': '$\\textfrac{4}{5}$', +u'\u2159': '$\\textfrac{1}{6}$', +u'\u215a': '$\\textfrac{5}{6}$', +u'\u215b': '$\\textfrac{1}{8}$', +u'\u215c': '$\\textfrac{3}{8}$', +u'\u215d': '$\\textfrac{5}{8}$', +u'\u215e': '$\\textfrac{7}{8}$', +u'\u2190': '$\\leftarrow$', +u'\u2191': '$\\uparrow$', +u'\u2192': '$\\rightarrow$', +u'\u2193': '$\\downarrow$', +u'\u2194': '$\\leftrightarrow$', +u'\u2195': '$\\updownarrow$', +u'\u2196': '$\\nwarrow$', +u'\u2197': '$\\nearrow$', +u'\u2198': '$\\searrow$', +u'\u2199': '$\\swarrow$', +u'\u219a': '$\\nleftarrow$', +u'\u219b': '$\\nrightarrow$', +u'\u219c': '$\\arrowwaveright$', +u'\u219d': '$\\arrowwaveright$', +u'\u219e': '$\\twoheadleftarrow$', +u'\u21a0': '$\\twoheadrightarrow$', +u'\u21a2': '$\\leftarrowtail$', +u'\u21a3': '$\\rightarrowtail$', +u'\u21a6': '$\\mapsto$', +u'\u21a9': '$\\hookleftarrow$', +u'\u21aa': '$\\hookrightarrow$', +u'\u21ab': '$\\looparrowleft$', +u'\u21ac': '$\\looparrowright$', +u'\u21ad': '$\\leftrightsquigarrow$', +u'\u21ae': '$\\nleftrightarrow$', +u'\u21b0': '$\\Lsh$', +u'\u21b1': '$\\Rsh$', +u'\u21b3': '$\\ElsevierGlyph{21B3}$', +u'\u21b6': '$\\curvearrowleft$', +u'\u21b7': '$\\curvearrowright$', +u'\u21ba': '$\\circlearrowleft$', +u'\u21bb': '$\\circlearrowright$', +u'\u21bc': '$\\leftharpoonup$', +u'\u21bd': '$\\leftharpoondown$', +u'\u21be': '$\\upharpoonright$', +u'\u21bf': '$\\upharpoonleft$', +u'\u21c0': '$\\rightharpoonup$', +u'\u21c1': '$\\rightharpoondown$', +u'\u21c2': '$\\downharpoonright$', +u'\u21c3': '$\\downharpoonleft$', +u'\u21c4': '$\\rightleftarrows$', +u'\u21c5': '$\\dblarrowupdown$', +u'\u21c6': '$\\leftrightarrows$', +u'\u21c7': '$\\leftleftarrows$', +u'\u21c8': '$\\upuparrows$', +u'\u21c9': '$\\rightrightarrows$', +u'\u21ca': '$\\downdownarrows$', +u'\u21cb': '$\\leftrightharpoons$', +u'\u21cc': '$\\rightleftharpoons$', +u'\u21cd': '$\\nLeftarrow$', +u'\u21ce': '$\\nLeftrightarrow$', +u'\u21cf': '$\\nRightarrow$', +u'\u21d0': '$\\Leftarrow$', +u'\u21d1': '$\\Uparrow$', +u'\u21d2': '$\\Rightarrow$', +u'\u21d3': '$\\Downarrow$', +u'\u21d4': '$\\Leftrightarrow$', +u'\u21d5': '$\\Updownarrow$', +u'\u21da': '$\\Lleftarrow$', +u'\u21db': '$\\Rrightarrow$', +u'\u21dd': '$\\rightsquigarrow$', +u'\u21f5': '$\\DownArrowUpArrow$', +u'\u2200': '$\\forall$', +u'\u2201': '$\\complement$', +u'\u2202': '$\\partial$', +u'\u2203': '$\\exists$', +u'\u2204': '$\\nexists$', +u'\u2205': '$\\varnothing$', +u'\u2207': '$\\nabla$', +u'\u2208': '$\\in$', +u'\u2209': '$\\not\\in$', +u'\u220b': '$\\ni$', +u'\u220c': '$\\not\\ni$', +u'\u220f': '$\\prod$', +u'\u2210': '$\\coprod$', +u'\u2211': '$\\sum$', +u'\u2212': '{-}', +u'\u2213': '$\\mp$', +u'\u2214': '$\\dotplus$', +u'\u2216': '$\\setminus$', +u'\u2217': '${_\\ast}$', +u'\u2218': '$\\circ$', +u'\u2219': '$\\bullet$', +u'\u221a': '$\\surd$', +u'\u221d': '$\\propto$', +u'\u221e': '$\\infty$', +u'\u221f': '$\\rightangle$', +u'\u2220': '$\\angle$', +u'\u2221': '$\\measuredangle$', +u'\u2222': '$\\sphericalangle$', +u'\u2223': '$\\mid$', +u'\u2224': '$\\nmid$', +u'\u2225': '$\\parallel$', +u'\u2226': '$\\nparallel$', +u'\u2227': '$\\wedge$', +u'\u2228': '$\\vee$', +u'\u2229': '$\\cap$', +u'\u222a': '$\\cup$', +u'\u222b': '$\\int$', +u'\u222c': '$\\int\\!\\int$', +u'\u222d': '$\\int\\!\\int\\!\\int$', +u'\u222e': '$\\oint$', +u'\u222f': '$\\surfintegral$', +u'\u2230': '$\\volintegral$', +u'\u2231': '$\\clwintegral$', +u'\u2232': '$\\ElsevierGlyph{2232}$', +u'\u2233': '$\\ElsevierGlyph{2233}$', +u'\u2234': '$\\therefore$', +u'\u2235': '$\\because$', +u'\u2237': '$\\Colon$', +u'\u2238': '$\\ElsevierGlyph{2238}$', +u'\u223a': '$\\mathbin{{:}\\!\\!{-}\\!\\!{:}}$', +u'\u223b': '$\\homothetic$', +u'\u223c': '$\\sim$', +u'\u223d': '$\\backsim$', +u'\u223e': '$\\lazysinv$', +u'\u2240': '$\\wr$', +u'\u2241': '$\\not\\sim$', +u'\u2242': '$\\ElsevierGlyph{2242}$', +u'\u2243': '$\\simeq$', +u'\u2244': '$\\not\\simeq$', +u'\u2245': '$\\cong$', +u'\u2246': '$\\approxnotequal$', +u'\u2247': '$\\not\\cong$', +u'\u2248': '$\\approx$', +u'\u2249': '$\\not\\approx$', +u'\u224a': '$\\approxeq$', +u'\u224b': '$\\tildetrpl$', +u'\u224c': '$\\allequal$', +u'\u224d': '$\\asymp$', +u'\u224e': '$\\Bumpeq$', +u'\u224f': '$\\bumpeq$', +u'\u2250': '$\\doteq$', +u'\u2251': '$\\doteqdot$', +u'\u2252': '$\\fallingdotseq$', +u'\u2253': '$\\risingdotseq$', +u'\u2254': '{:=}', +u'\u2255': '$=:$', +u'\u2256': '$\\eqcirc$', +u'\u2257': '$\\circeq$', +u'\u2259': '$\\estimates$', +u'\u225a': '$\\ElsevierGlyph{225A}$', +u'\u225b': '$\\starequal$', +u'\u225c': '$\\triangleq$', +u'\u225f': '$\\ElsevierGlyph{225F}$', +u'\u2260': '$\\not =$', +u'\u2261': '$\\equiv$', +u'\u2262': '$\\not\\equiv$', +u'\u2264': '$\\leq$', +u'\u2265': '$\\geq$', +u'\u2266': '$\\leqq$', +u'\u2267': '$\\geqq$', +u'\u2268': '$\\lneqq$', +u'\u2269': '$\\gneqq$', +u'\u226a': '$\\ll$', +u'\u226b': '$\\gg$', +u'\u226c': '$\\between$', +u'\u226d': '$\\not\\kern-0.3em\\times$', +u'\u226e': '$\\not<$', +u'\u226f': '$\\not>$', +u'\u2270': '$\\not\\leq$', +u'\u2271': '$\\not\\geq$', +u'\u2272': '$\\lessequivlnt$', +u'\u2273': '$\\greaterequivlnt$', +u'\u2274': '$\\ElsevierGlyph{2274}$', +u'\u2275': '$\\ElsevierGlyph{2275}$', +u'\u2276': '$\\lessgtr$', +u'\u2277': '$\\gtrless$', +u'\u2278': '$\\notlessgreater$', +u'\u2279': '$\\notgreaterless$', +u'\u227a': '$\\prec$', +u'\u227b': '$\\succ$', +u'\u227c': '$\\preccurlyeq$', +u'\u227d': '$\\succcurlyeq$', +u'\u227e': '$\\precapprox$', +u'\u227f': '$\\succapprox$', +u'\u2280': '$\\not\\prec$', +u'\u2281': '$\\not\\succ$', +u'\u2282': '$\\subset$', +u'\u2283': '$\\supset$', +u'\u2284': '$\\not\\subset$', +u'\u2285': '$\\not\\supset$', +u'\u2286': '$\\subseteq$', +u'\u2287': '$\\supseteq$', +u'\u2288': '$\\not\\subseteq$', +u'\u2289': '$\\not\\supseteq$', +u'\u228a': '$\\subsetneq$', +u'\u228b': '$\\supsetneq$', +u'\u228e': '$\\uplus$', +u'\u228f': '$\\sqsubset$', +u'\u2290': '$\\sqsupset$', +u'\u2291': '$\\sqsubseteq$', +u'\u2292': '$\\sqsupseteq$', +u'\u2293': '$\\sqcap$', +u'\u2294': '$\\sqcup$', +u'\u2295': '$\\oplus$', +u'\u2296': '$\\ominus$', +u'\u2297': '$\\otimes$', +u'\u2298': '$\\oslash$', +u'\u2299': '$\\odot$', +u'\u229a': '$\\circledcirc$', +u'\u229b': '$\\circledast$', +u'\u229d': '$\\circleddash$', +u'\u229e': '$\\boxplus$', +u'\u229f': '$\\boxminus$', +u'\u22a0': '$\\boxtimes$', +u'\u22a1': '$\\boxdot$', +u'\u22a2': '$\\vdash$', +u'\u22a3': '$\\dashv$', +u'\u22a4': '$\\top$', +u'\u22a5': '$\\perp$', +u'\u22a7': '$\\truestate$', +u'\u22a8': '$\\forcesextra$', +u'\u22a9': '$\\Vdash$', +u'\u22aa': '$\\Vvdash$', +u'\u22ab': '$\\VDash$', +u'\u22ac': '$\\nvdash$', +u'\u22ad': '$\\nvDash$', +u'\u22ae': '$\\nVdash$', +u'\u22af': '$\\nVDash$', +u'\u22b2': '$\\vartriangleleft$', +u'\u22b3': '$\\vartriangleright$', +u'\u22b4': '$\\trianglelefteq$', +u'\u22b5': '$\\trianglerighteq$', +u'\u22b6': '$\\original$', +u'\u22b7': '$\\image$', +u'\u22b8': '$\\multimap$', +u'\u22b9': '$\\hermitconjmatrix$', +u'\u22ba': '$\\intercal$', +u'\u22bb': '$\\veebar$', +u'\u22be': '$\\rightanglearc$', +u'\u22c0': '$\\ElsevierGlyph{22C0}$', +u'\u22c1': '$\\ElsevierGlyph{22C1}$', +u'\u22c2': '$\\bigcap$', +u'\u22c3': '$\\bigcup$', +u'\u22c4': '$\\diamond$', +u'\u22c5': '$\\cdot$', +u'\u22c6': '$\\star$', +u'\u22c7': '$\\divideontimes$', +u'\u22c8': '$\\bowtie$', +u'\u22c9': '$\\ltimes$', +u'\u22ca': '$\\rtimes$', +u'\u22cb': '$\\leftthreetimes$', +u'\u22cc': '$\\rightthreetimes$', +u'\u22cd': '$\\backsimeq$', +u'\u22ce': '$\\curlyvee$', +u'\u22cf': '$\\curlywedge$', +u'\u22d0': '$\\Subset$', +u'\u22d1': '$\\Supset$', +u'\u22d2': '$\\Cap$', +u'\u22d3': '$\\Cup$', +u'\u22d4': '$\\pitchfork$', +u'\u22d6': '$\\lessdot$', +u'\u22d7': '$\\gtrdot$', +u'\u22d8': '$\\verymuchless$', +u'\u22d9': '$\\verymuchgreater$', +u'\u22da': '$\\lesseqgtr$', +u'\u22db': '$\\gtreqless$', +u'\u22de': '$\\curlyeqprec$', +u'\u22df': '$\\curlyeqsucc$', +u'\u22e2': '$\\not\\sqsubseteq$', +u'\u22e3': '$\\not\\sqsupseteq$', +u'\u22e5': '$\\Elzsqspne$', +u'\u22e6': '$\\lnsim$', +u'\u22e7': '$\\gnsim$', +u'\u22e8': '$\\precedesnotsimilar$', +u'\u22e9': '$\\succnsim$', +u'\u22ea': '$\\ntriangleleft$', +u'\u22eb': '$\\ntriangleright$', +u'\u22ec': '$\\ntrianglelefteq$', +u'\u22ed': '$\\ntrianglerighteq$', +u'\u22ee': '$\\vdots$', +u'\u22ef': '$\\cdots$', +u'\u22f0': '$\\upslopeellipsis$', +u'\u22f1': '$\\downslopeellipsis$', +u'\u2305': '{\\barwedge}', +u'\u2306': '$\\perspcorrespond$', +u'\u2308': '$\\lceil$', +u'\u2309': '$\\rceil$', +u'\u230a': '$\\lfloor$', +u'\u230b': '$\\rfloor$', +u'\u2315': '$\\recorder$', +u'\u2316': '$\\mathchar"2208$', +u'\u231c': '$\\ulcorner$', +u'\u231d': '$\\urcorner$', +u'\u231e': '$\\llcorner$', +u'\u231f': '$\\lrcorner$', +u'\u2322': '$\\frown$', +u'\u2323': '$\\smile$', +u'\u2329': '$\\langle$', +u'\u232a': '$\\rangle$', +u'\u233d': '$\\ElsevierGlyph{E838}$', +u'\u23a3': '$\\Elzdlcorn$', +u'\u23b0': '$\\lmoustache$', +u'\u23b1': '$\\rmoustache$', +u'\u2423': '{\\textvisiblespace}', +u'\u2460': '{\\ding{172}}', +u'\u2461': '{\\ding{173}}', +u'\u2462': '{\\ding{174}}', +u'\u2463': '{\\ding{175}}', +u'\u2464': '{\\ding{176}}', +u'\u2465': '{\\ding{177}}', +u'\u2466': '{\\ding{178}}', +u'\u2467': '{\\ding{179}}', +u'\u2468': '{\\ding{180}}', +u'\u2469': '{\\ding{181}}', +u'\u24c8': '$\\circledS$', +u'\u2506': '$\\Elzdshfnc$', +u'\u2519': '$\\Elzsqfnw$', +u'\u2571': '$\\diagup$', +u'\u25a0': '{\\ding{110}}', +u'\u25a1': '$\\square$', +u'\u25aa': '$\\blacksquare$', +u'\u25ad': '$\\fbox{~~}$', +u'\u25af': '$\\Elzvrecto$', +u'\u25b1': '$\\ElsevierGlyph{E381}$', +u'\u25b2': '{\\ding{115}}', +u'\u25b3': '$\\bigtriangleup$', +u'\u25b4': '$\\blacktriangle$', +u'\u25b5': '$\\vartriangle$', +u'\u25b8': '$\\blacktriangleright$', +u'\u25b9': '$\\triangleright$', +u'\u25bc': '{\\ding{116}}', +u'\u25bd': '$\\bigtriangledown$', +u'\u25be': '$\\blacktriangledown$', +u'\u25bf': '$\\triangledown$', +u'\u25c2': '$\\blacktriangleleft$', +u'\u25c3': '$\\triangleleft$', +u'\u25c6': '{\\ding{117}}', +u'\u25ca': '$\\lozenge$', +u'\u25cb': '$\\bigcirc$', +u'\u25cf': '{\\ding{108}}', +u'\u25d0': '$\\Elzcirfl$', +u'\u25d1': '$\\Elzcirfr$', +u'\u25d2': '$\\Elzcirfb$', +u'\u25d7': '{\\ding{119}}', +u'\u25d8': '$\\Elzrvbull$', +u'\u25e7': '$\\Elzsqfl$', +u'\u25e8': '$\\Elzsqfr$', +u'\u25ea': '$\\Elzsqfse$', +u'\u25ef': '$\\bigcirc$', +u'\u2605': '{\\ding{72}}', +u'\u2606': '{\\ding{73}}', +u'\u260e': '{\\ding{37}}', +u'\u261b': '{\\ding{42}}', +u'\u261e': '{\\ding{43}}', +u'\u263e': '{\\rightmoon}', +u'\u263f': '{\\mercury}', +u'\u2640': '{\\venus}', +u'\u2642': '{\\male}', +u'\u2643': '{\\jupiter}', +u'\u2644': '{\\saturn}', +u'\u2645': '{\\uranus}', +u'\u2646': '{\\neptune}', +u'\u2647': '{\\pluto}', +u'\u2648': '{\\aries}', +u'\u2649': '{\\taurus}', +u'\u264a': '{\\gemini}', +u'\u264b': '{\\cancer}', +u'\u264c': '{\\leo}', +u'\u264d': '{\\virgo}', +u'\u264e': '{\\libra}', +u'\u264f': '{\\scorpio}', +u'\u2650': '{\\sagittarius}', +u'\u2651': '{\\capricornus}', +u'\u2652': '{\\aquarius}', +u'\u2653': '{\\pisces}', +u'\u2660': '{\\ding{171}}', +u'\u2662': '$\\diamond$', +u'\u2663': '{\\ding{168}}', +u'\u2665': '{\\ding{170}}', +u'\u2666': '{\\ding{169}}', +u'\u2669': '{\\quarternote}', +u'\u266a': '{\\eighthnote}', +u'\u266d': '$\\flat$', +u'\u266e': '$\\natural$', +u'\u266f': '$\\sharp$', +u'\u2701': '{\\ding{33}}', +u'\u2702': '{\\ding{34}}', +u'\u2703': '{\\ding{35}}', +u'\u2704': '{\\ding{36}}', +u'\u2706': '{\\ding{38}}', +u'\u2707': '{\\ding{39}}', +u'\u2708': '{\\ding{40}}', +u'\u2709': '{\\ding{41}}', +u'\u270c': '{\\ding{44}}', +u'\u270d': '{\\ding{45}}', +u'\u270e': '{\\ding{46}}', +u'\u270f': '{\\ding{47}}', +u'\u2710': '{\\ding{48}}', +u'\u2711': '{\\ding{49}}', +u'\u2712': '{\\ding{50}}', +u'\u2713': '{\\ding{51}}', +u'\u2714': '{\\ding{52}}', +u'\u2715': '{\\ding{53}}', +u'\u2716': '{\\ding{54}}', +u'\u2717': '{\\ding{55}}', +u'\u2718': '{\\ding{56}}', +u'\u2719': '{\\ding{57}}', +u'\u271a': '{\\ding{58}}', +u'\u271b': '{\\ding{59}}', +u'\u271c': '{\\ding{60}}', +u'\u271d': '{\\ding{61}}', +u'\u271e': '{\\ding{62}}', +u'\u271f': '{\\ding{63}}', +u'\u2720': '{\\ding{64}}', +u'\u2721': '{\\ding{65}}', +u'\u2722': '{\\ding{66}}', +u'\u2723': '{\\ding{67}}', +u'\u2724': '{\\ding{68}}', +u'\u2725': '{\\ding{69}}', +u'\u2726': '{\\ding{70}}', +u'\u2727': '{\\ding{71}}', +u'\u2729': '{\\ding{73}}', +u'\u272a': '{\\ding{74}}', +u'\u272b': '{\\ding{75}}', +u'\u272c': '{\\ding{76}}', +u'\u272d': '{\\ding{77}}', +u'\u272e': '{\\ding{78}}', +u'\u272f': '{\\ding{79}}', +u'\u2730': '{\\ding{80}}', +u'\u2731': '{\\ding{81}}', +u'\u2732': '{\\ding{82}}', +u'\u2733': '{\\ding{83}}', +u'\u2734': '{\\ding{84}}', +u'\u2735': '{\\ding{85}}', +u'\u2736': '{\\ding{86}}', +u'\u2737': '{\\ding{87}}', +u'\u2738': '{\\ding{88}}', +u'\u2739': '{\\ding{89}}', +u'\u273a': '{\\ding{90}}', +u'\u273b': '{\\ding{91}}', +u'\u273c': '{\\ding{92}}', +u'\u273d': '{\\ding{93}}', +u'\u273e': '{\\ding{94}}', +u'\u273f': '{\\ding{95}}', +u'\u2740': '{\\ding{96}}', +u'\u2741': '{\\ding{97}}', +u'\u2742': '{\\ding{98}}', +u'\u2743': '{\\ding{99}}', +u'\u2744': '{\\ding{100}}', +u'\u2745': '{\\ding{101}}', +u'\u2746': '{\\ding{102}}', +u'\u2747': '{\\ding{103}}', +u'\u2748': '{\\ding{104}}', +u'\u2749': '{\\ding{105}}', +u'\u274a': '{\\ding{106}}', +u'\u274b': '{\\ding{107}}', +u'\u274d': '{\\ding{109}}', +u'\u274f': '{\\ding{111}}', +u'\u2750': '{\\ding{112}}', +u'\u2751': '{\\ding{113}}', +u'\u2752': '{\\ding{114}}', +u'\u2756': '{\\ding{118}}', +u'\u2758': '{\\ding{120}}', +u'\u2759': '{\\ding{121}}', +u'\u275a': '{\\ding{122}}', +u'\u275b': '{\\ding{123}}', +u'\u275c': '{\\ding{124}}', +u'\u275d': '{\\ding{125}}', +u'\u275e': '{\\ding{126}}', +u'\u2761': '{\\ding{161}}', +u'\u2762': '{\\ding{162}}', +u'\u2763': '{\\ding{163}}', +u'\u2764': '{\\ding{164}}', +u'\u2765': '{\\ding{165}}', +u'\u2766': '{\\ding{166}}', +u'\u2767': '{\\ding{167}}', +u'\u2776': '{\\ding{182}}', +u'\u2777': '{\\ding{183}}', +u'\u2778': '{\\ding{184}}', +u'\u2779': '{\\ding{185}}', +u'\u277a': '{\\ding{186}}', +u'\u277b': '{\\ding{187}}', +u'\u277c': '{\\ding{188}}', +u'\u277d': '{\\ding{189}}', +u'\u277e': '{\\ding{190}}', +u'\u277f': '{\\ding{191}}', +u'\u2780': '{\\ding{192}}', +u'\u2781': '{\\ding{193}}', +u'\u2782': '{\\ding{194}}', +u'\u2783': '{\\ding{195}}', +u'\u2784': '{\\ding{196}}', +u'\u2785': '{\\ding{197}}', +u'\u2786': '{\\ding{198}}', +u'\u2787': '{\\ding{199}}', +u'\u2788': '{\\ding{200}}', +u'\u2789': '{\\ding{201}}', +u'\u278a': '{\\ding{202}}', +u'\u278b': '{\\ding{203}}', +u'\u278c': '{\\ding{204}}', +u'\u278d': '{\\ding{205}}', +u'\u278e': '{\\ding{206}}', +u'\u278f': '{\\ding{207}}', +u'\u2790': '{\\ding{208}}', +u'\u2791': '{\\ding{209}}', +u'\u2792': '{\\ding{210}}', +u'\u2793': '{\\ding{211}}', +u'\u2794': '{\\ding{212}}', +u'\u2798': '{\\ding{216}}', +u'\u2799': '{\\ding{217}}', +u'\u279a': '{\\ding{218}}', +u'\u279b': '{\\ding{219}}', +u'\u279c': '{\\ding{220}}', +u'\u279d': '{\\ding{221}}', +u'\u279e': '{\\ding{222}}', +u'\u279f': '{\\ding{223}}', +u'\u27a0': '{\\ding{224}}', +u'\u27a1': '{\\ding{225}}', +u'\u27a2': '{\\ding{226}}', +u'\u27a3': '{\\ding{227}}', +u'\u27a4': '{\\ding{228}}', +u'\u27a5': '{\\ding{229}}', +u'\u27a6': '{\\ding{230}}', +u'\u27a7': '{\\ding{231}}', +u'\u27a8': '{\\ding{232}}', +u'\u27a9': '{\\ding{233}}', +u'\u27aa': '{\\ding{234}}', +u'\u27ab': '{\\ding{235}}', +u'\u27ac': '{\\ding{236}}', +u'\u27ad': '{\\ding{237}}', +u'\u27ae': '{\\ding{238}}', +u'\u27af': '{\\ding{239}}', +u'\u27b1': '{\\ding{241}}', +u'\u27b2': '{\\ding{242}}', +u'\u27b3': '{\\ding{243}}', +u'\u27b4': '{\\ding{244}}', +u'\u27b5': '{\\ding{245}}', +u'\u27b6': '{\\ding{246}}', +u'\u27b7': '{\\ding{247}}', +u'\u27b8': '{\\ding{248}}', +u'\u27b9': '{\\ding{249}}', +u'\u27ba': '{\\ding{250}}', +u'\u27bb': '{\\ding{251}}', +u'\u27bc': '{\\ding{252}}', +u'\u27bd': '{\\ding{253}}', +u'\u27be': '{\\ding{254}}', +u'\u27f5': '$\\longleftarrow$', +u'\u27f6': '$\\longrightarrow$', +u'\u27f7': '$\\longleftrightarrow$', +u'\u27f8': '$\\Longleftarrow$', +u'\u27f9': '$\\Longrightarrow$', +u'\u27fa': '$\\Longleftrightarrow$', +u'\u27fc': '$\\longmapsto$', +u'\u27ff': '$\\sim\\joinrel\\leadsto$', +u'\u2905': '$\\ElsevierGlyph{E212}$', +u'\u2912': '$\\UpArrowBar$', +u'\u2913': '$\\DownArrowBar$', +u'\u2923': '$\\ElsevierGlyph{E20C}$', +u'\u2924': '$\\ElsevierGlyph{E20D}$', +u'\u2925': '$\\ElsevierGlyph{E20B}$', +u'\u2926': '$\\ElsevierGlyph{E20A}$', +u'\u2927': '$\\ElsevierGlyph{E211}$', +u'\u2928': '$\\ElsevierGlyph{E20E}$', +u'\u2929': '$\\ElsevierGlyph{E20F}$', +u'\u292a': '$\\ElsevierGlyph{E210}$', +u'\u2933': '$\\ElsevierGlyph{E21C}$', +u'\u2936': '$\\ElsevierGlyph{E21A}$', +u'\u2937': '$\\ElsevierGlyph{E219}$', +u'\u2940': '$\\Elolarr$', +u'\u2941': '$\\Elorarr$', +u'\u2942': '$\\ElzRlarr$', +u'\u2944': '$\\ElzrLarr$', +u'\u2947': '$\\Elzrarrx$', +u'\u294e': '$\\LeftRightVector$', +u'\u294f': '$\\RightUpDownVector$', +u'\u2950': '$\\DownLeftRightVector$', +u'\u2951': '$\\LeftUpDownVector$', +u'\u2952': '$\\LeftVectorBar$', +u'\u2953': '$\\RightVectorBar$', +u'\u2954': '$\\RightUpVectorBar$', +u'\u2955': '$\\RightDownVectorBar$', +u'\u2956': '$\\DownLeftVectorBar$', +u'\u2957': '$\\DownRightVectorBar$', +u'\u2958': '$\\LeftUpVectorBar$', +u'\u2959': '$\\LeftDownVectorBar$', +u'\u295a': '$\\LeftTeeVector$', +u'\u295b': '$\\RightTeeVector$', +u'\u295c': '$\\RightUpTeeVector$', +u'\u295d': '$\\RightDownTeeVector$', +u'\u295e': '$\\DownLeftTeeVector$', +u'\u295f': '$\\DownRightTeeVector$', +u'\u2960': '$\\LeftUpTeeVector$', +u'\u2961': '$\\LeftDownTeeVector$', +u'\u296e': '$\\UpEquilibrium$', +u'\u296f': '$\\ReverseUpEquilibrium$', +u'\u2970': '$\\RoundImplies$', +u'\u297c': '$\\ElsevierGlyph{E214}$', +u'\u297d': '$\\ElsevierGlyph{E215}$', +u'\u2980': '$\\Elztfnc$', +u'\u2985': '$\\ElsevierGlyph{3018}$', +u'\u2986': '$\\Elroang$', +u'\u2993': '$<\\kern-0.58em($', +u'\u2994': '$\\ElsevierGlyph{E291}$', +u'\u2999': '$\\Elzddfnc$', +u'\u299c': '$\\Angle$', +u'\u29a0': '$\\Elzlpargt$', +u'\u29b5': '$\\ElsevierGlyph{E260}$', +u'\u29b6': '$\\ElsevierGlyph{E61B}$', +u'\u29ca': '$\\ElzLap$', +u'\u29cb': '$\\Elzdefas$', +u'\u29cf': '$\\LeftTriangleBar$', +u'\u29d0': '$\\RightTriangleBar$', +u'\u29dc': '$\\ElsevierGlyph{E372}$', +u'\u29eb': '$\\blacklozenge$', +u'\u29f4': '$\\RuleDelayed$', +u'\u2a04': '$\\Elxuplus$', +u'\u2a05': '$\\ElzThr$', +u'\u2a06': '$\\Elxsqcup$', +u'\u2a07': '$\\ElzInf$', +u'\u2a08': '$\\ElzSup$', +u'\u2a0d': '$\\ElzCint$', +u'\u2a0f': '$\\clockoint$', +u'\u2a10': '$\\ElsevierGlyph{E395}$', +u'\u2a16': '$\\sqrint$', +u'\u2a25': '$\\ElsevierGlyph{E25A}$', +u'\u2a2a': '$\\ElsevierGlyph{E25B}$', +u'\u2a2d': '$\\ElsevierGlyph{E25C}$', +u'\u2a2e': '$\\ElsevierGlyph{E25D}$', +u'\u2a2f': '$\\ElzTimes$', +u'\u2a34': '$\\ElsevierGlyph{E25E}$', +u'\u2a35': '$\\ElsevierGlyph{E25E}$', +u'\u2a3c': '$\\ElsevierGlyph{E259}$', +u'\u2a3f': '$\\amalg$', +u'\u2a53': '$\\ElzAnd$', +u'\u2a54': '$\\ElzOr$', +u'\u2a55': '$\\ElsevierGlyph{E36E}$', +u'\u2a56': '$\\ElOr$', +u'\u2a5e': '$\\perspcorrespond$', +u'\u2a5f': '$\\Elzminhat$', +u'\u2a63': '$\\ElsevierGlyph{225A}$', +u'\u2a6e': '$\\stackrel{*}{=}$', +u'\u2a75': '$\\Equal$', +u'\u2a7d': '$\\leqslant$', +u'\u2a7e': '$\\geqslant$', +u'\u2a85': '$\\lessapprox$', +u'\u2a86': '$\\gtrapprox$', +u'\u2a87': '$\\lneq$', +u'\u2a88': '$\\gneq$', +u'\u2a89': '$\\lnapprox$', +u'\u2a8a': '$\\gnapprox$', +u'\u2a8b': '$\\lesseqqgtr$', +u'\u2a8c': '$\\gtreqqless$', +u'\u2a95': '$\\eqslantless$', +u'\u2a96': '$\\eqslantgtr$', +u'\u2a9d': '$\\Pisymbol{ppi020}{117}$', +u'\u2a9e': '$\\Pisymbol{ppi020}{105}$', +u'\u2aa1': '$\\NestedLessLess$', +u'\u2aa2': '$\\NestedGreaterGreater$', +u'\u2aaf': '$\\preceq$', +u'\u2ab0': '$\\succeq$', +u'\u2ab5': '$\\precneqq$', +u'\u2ab6': '$\\succneqq$', +u'\u2ab7': '$\\precapprox$', +u'\u2ab8': '$\\succapprox$', +u'\u2ab9': '$\\precnapprox$', +u'\u2aba': '$\\succnapprox$', +u'\u2ac5': '$\\subseteqq$', +u'\u2ac6': '$\\supseteqq$', +u'\u2acb': '$\\subsetneqq$', +u'\u2acc': '$\\supsetneqq$', +u'\u2aeb': '$\\ElsevierGlyph{E30D}$', +u'\u2af6': '$\\Elztdcol$', +u'\u2afd': '${{/}\\!\\!{/}}$', +u'\u300a': '$\\ElsevierGlyph{300A}$', +u'\u300b': '$\\ElsevierGlyph{300B}$', +u'\u3018': '$\\ElsevierGlyph{3018}$', +u'\u3019': '$\\ElsevierGlyph{3019}$', +u'\u301a': '$\\openbracketleft$', +u'\u301b': '$\\openbracketright$', +u'\ufb00': '{ff}', +u'\ufb01': '{fi}', +u'\ufb02': '{fl}', +u'\ufb03': '{ffi}', +u'\ufb04': '{ffl}', +u'\U0001d400': '$\\mathbf{A}$', +u'\U0001d401': '$\\mathbf{B}$', +u'\U0001d402': '$\\mathbf{C}$', +u'\U0001d403': '$\\mathbf{D}$', +u'\U0001d404': '$\\mathbf{E}$', +u'\U0001d405': '$\\mathbf{F}$', +u'\U0001d406': '$\\mathbf{G}$', +u'\U0001d407': '$\\mathbf{H}$', +u'\U0001d408': '$\\mathbf{I}$', +u'\U0001d409': '$\\mathbf{J}$', +u'\U0001d40a': '$\\mathbf{K}$', +u'\U0001d40b': '$\\mathbf{L}$', +u'\U0001d40c': '$\\mathbf{M}$', +u'\U0001d40d': '$\\mathbf{N}$', +u'\U0001d40e': '$\\mathbf{O}$', +u'\U0001d40f': '$\\mathbf{P}$', +u'\U0001d410': '$\\mathbf{Q}$', +u'\U0001d411': '$\\mathbf{R}$', +u'\U0001d412': '$\\mathbf{S}$', +u'\U0001d413': '$\\mathbf{T}$', +u'\U0001d414': '$\\mathbf{U}$', +u'\U0001d415': '$\\mathbf{V}$', +u'\U0001d416': '$\\mathbf{W}$', +u'\U0001d417': '$\\mathbf{X}$', +u'\U0001d418': '$\\mathbf{Y}$', +u'\U0001d419': '$\\mathbf{Z}$', +u'\U0001d41a': '$\\mathbf{a}$', +u'\U0001d41b': '$\\mathbf{b}$', +u'\U0001d41c': '$\\mathbf{c}$', +u'\U0001d41d': '$\\mathbf{d}$', +u'\U0001d41e': '$\\mathbf{e}$', +u'\U0001d41f': '$\\mathbf{f}$', +u'\U0001d420': '$\\mathbf{g}$', +u'\U0001d421': '$\\mathbf{h}$', +u'\U0001d422': '$\\mathbf{i}$', +u'\U0001d423': '$\\mathbf{j}$', +u'\U0001d424': '$\\mathbf{k}$', +u'\U0001d425': '$\\mathbf{l}$', +u'\U0001d426': '$\\mathbf{m}$', +u'\U0001d427': '$\\mathbf{n}$', +u'\U0001d428': '$\\mathbf{o}$', +u'\U0001d429': '$\\mathbf{p}$', +u'\U0001d42a': '$\\mathbf{q}$', +u'\U0001d42b': '$\\mathbf{r}$', +u'\U0001d42c': '$\\mathbf{s}$', +u'\U0001d42d': '$\\mathbf{t}$', +u'\U0001d42e': '$\\mathbf{u}$', +u'\U0001d42f': '$\\mathbf{v}$', +u'\U0001d430': '$\\mathbf{w}$', +u'\U0001d431': '$\\mathbf{x}$', +u'\U0001d432': '$\\mathbf{y}$', +u'\U0001d433': '$\\mathbf{z}$', +u'\U0001d434': '$\\mathsl{A}$', +u'\U0001d435': '$\\mathsl{B}$', +u'\U0001d436': '$\\mathsl{C}$', +u'\U0001d437': '$\\mathsl{D}$', +u'\U0001d438': '$\\mathsl{E}$', +u'\U0001d439': '$\\mathsl{F}$', +u'\U0001d43a': '$\\mathsl{G}$', +u'\U0001d43b': '$\\mathsl{H}$', +u'\U0001d43c': '$\\mathsl{I}$', +u'\U0001d43d': '$\\mathsl{J}$', +u'\U0001d43e': '$\\mathsl{K}$', +u'\U0001d43f': '$\\mathsl{L}$', +u'\U0001d440': '$\\mathsl{M}$', +u'\U0001d441': '$\\mathsl{N}$', +u'\U0001d442': '$\\mathsl{O}$', +u'\U0001d443': '$\\mathsl{P}$', +u'\U0001d444': '$\\mathsl{Q}$', +u'\U0001d445': '$\\mathsl{R}$', +u'\U0001d446': '$\\mathsl{S}$', +u'\U0001d447': '$\\mathsl{T}$', +u'\U0001d448': '$\\mathsl{U}$', +u'\U0001d449': '$\\mathsl{V}$', +u'\U0001d44a': '$\\mathsl{W}$', +u'\U0001d44b': '$\\mathsl{X}$', +u'\U0001d44c': '$\\mathsl{Y}$', +u'\U0001d44d': '$\\mathsl{Z}$', +u'\U0001d44e': '$\\mathsl{a}$', +u'\U0001d44f': '$\\mathsl{b}$', +u'\U0001d450': '$\\mathsl{c}$', +u'\U0001d451': '$\\mathsl{d}$', +u'\U0001d452': '$\\mathsl{e}$', +u'\U0001d453': '$\\mathsl{f}$', +u'\U0001d454': '$\\mathsl{g}$', +u'\U0001d456': '$\\mathsl{i}$', +u'\U0001d457': '$\\mathsl{j}$', +u'\U0001d458': '$\\mathsl{k}$', +u'\U0001d459': '$\\mathsl{l}$', +u'\U0001d45a': '$\\mathsl{m}$', +u'\U0001d45b': '$\\mathsl{n}$', +u'\U0001d45c': '$\\mathsl{o}$', +u'\U0001d45d': '$\\mathsl{p}$', +u'\U0001d45e': '$\\mathsl{q}$', +u'\U0001d45f': '$\\mathsl{r}$', +u'\U0001d460': '$\\mathsl{s}$', +u'\U0001d461': '$\\mathsl{t}$', +u'\U0001d462': '$\\mathsl{u}$', +u'\U0001d463': '$\\mathsl{v}$', +u'\U0001d464': '$\\mathsl{w}$', +u'\U0001d465': '$\\mathsl{x}$', +u'\U0001d466': '$\\mathsl{y}$', +u'\U0001d467': '$\\mathsl{z}$', +u'\U0001d468': '$\\mathbit{A}$', +u'\U0001d469': '$\\mathbit{B}$', +u'\U0001d46a': '$\\mathbit{C}$', +u'\U0001d46b': '$\\mathbit{D}$', +u'\U0001d46c': '$\\mathbit{E}$', +u'\U0001d46d': '$\\mathbit{F}$', +u'\U0001d46e': '$\\mathbit{G}$', +u'\U0001d46f': '$\\mathbit{H}$', +u'\U0001d470': '$\\mathbit{I}$', +u'\U0001d471': '$\\mathbit{J}$', +u'\U0001d472': '$\\mathbit{K}$', +u'\U0001d473': '$\\mathbit{L}$', +u'\U0001d474': '$\\mathbit{M}$', +u'\U0001d475': '$\\mathbit{N}$', +u'\U0001d476': '$\\mathbit{O}$', +u'\U0001d477': '$\\mathbit{P}$', +u'\U0001d478': '$\\mathbit{Q}$', +u'\U0001d479': '$\\mathbit{R}$', +u'\U0001d47a': '$\\mathbit{S}$', +u'\U0001d47b': '$\\mathbit{T}$', +u'\U0001d47c': '$\\mathbit{U}$', +u'\U0001d47d': '$\\mathbit{V}$', +u'\U0001d47e': '$\\mathbit{W}$', +u'\U0001d47f': '$\\mathbit{X}$', +u'\U0001d480': '$\\mathbit{Y}$', +u'\U0001d481': '$\\mathbit{Z}$', +u'\U0001d482': '$\\mathbit{a}$', +u'\U0001d483': '$\\mathbit{b}$', +u'\U0001d484': '$\\mathbit{c}$', +u'\U0001d485': '$\\mathbit{d}$', +u'\U0001d486': '$\\mathbit{e}$', +u'\U0001d487': '$\\mathbit{f}$', +u'\U0001d488': '$\\mathbit{g}$', +u'\U0001d489': '$\\mathbit{h}$', +u'\U0001d48a': '$\\mathbit{i}$', +u'\U0001d48b': '$\\mathbit{j}$', +u'\U0001d48c': '$\\mathbit{k}$', +u'\U0001d48d': '$\\mathbit{l}$', +u'\U0001d48e': '$\\mathbit{m}$', +u'\U0001d48f': '$\\mathbit{n}$', +u'\U0001d490': '$\\mathbit{o}$', +u'\U0001d491': '$\\mathbit{p}$', +u'\U0001d492': '$\\mathbit{q}$', +u'\U0001d493': '$\\mathbit{r}$', +u'\U0001d494': '$\\mathbit{s}$', +u'\U0001d495': '$\\mathbit{t}$', +u'\U0001d496': '$\\mathbit{u}$', +u'\U0001d497': '$\\mathbit{v}$', +u'\U0001d498': '$\\mathbit{w}$', +u'\U0001d499': '$\\mathbit{x}$', +u'\U0001d49a': '$\\mathbit{y}$', +u'\U0001d49b': '$\\mathbit{z}$', +u'\U0001d49c': '$\\mathscr{A}$', +u'\U0001d49e': '$\\mathscr{C}$', +u'\U0001d49f': '$\\mathscr{D}$', +u'\U0001d4a2': '$\\mathscr{G}$', +u'\U0001d4a5': '$\\mathscr{J}$', +u'\U0001d4a6': '$\\mathscr{K}$', +u'\U0001d4a9': '$\\mathscr{N}$', +u'\U0001d4aa': '$\\mathscr{O}$', +u'\U0001d4ab': '$\\mathscr{P}$', +u'\U0001d4ac': '$\\mathscr{Q}$', +u'\U0001d4ae': '$\\mathscr{S}$', +u'\U0001d4af': '$\\mathscr{T}$', +u'\U0001d4b0': '$\\mathscr{U}$', +u'\U0001d4b1': '$\\mathscr{V}$', +u'\U0001d4b2': '$\\mathscr{W}$', +u'\U0001d4b3': '$\\mathscr{X}$', +u'\U0001d4b4': '$\\mathscr{Y}$', +u'\U0001d4b5': '$\\mathscr{Z}$', +u'\U0001d4b6': '$\\mathscr{a}$', +u'\U0001d4b7': '$\\mathscr{b}$', +u'\U0001d4b8': '$\\mathscr{c}$', +u'\U0001d4b9': '$\\mathscr{d}$', +u'\U0001d4bb': '$\\mathscr{f}$', +u'\U0001d4bd': '$\\mathscr{h}$', +u'\U0001d4be': '$\\mathscr{i}$', +u'\U0001d4bf': '$\\mathscr{j}$', +u'\U0001d4c0': '$\\mathscr{k}$', +u'\U0001d4c1': '$\\mathscr{l}$', +u'\U0001d4c2': '$\\mathscr{m}$', +u'\U0001d4c3': '$\\mathscr{n}$', +u'\U0001d4c5': '$\\mathscr{p}$', +u'\U0001d4c6': '$\\mathscr{q}$', +u'\U0001d4c7': '$\\mathscr{r}$', +u'\U0001d4c8': '$\\mathscr{s}$', +u'\U0001d4c9': '$\\mathscr{t}$', +u'\U0001d4ca': '$\\mathscr{u}$', +u'\U0001d4cb': '$\\mathscr{v}$', +u'\U0001d4cc': '$\\mathscr{w}$', +u'\U0001d4cd': '$\\mathscr{x}$', +u'\U0001d4ce': '$\\mathscr{y}$', +u'\U0001d4cf': '$\\mathscr{z}$', +u'\U0001d4d0': '$\\mathmit{A}$', +u'\U0001d4d1': '$\\mathmit{B}$', +u'\U0001d4d2': '$\\mathmit{C}$', +u'\U0001d4d3': '$\\mathmit{D}$', +u'\U0001d4d4': '$\\mathmit{E}$', +u'\U0001d4d5': '$\\mathmit{F}$', +u'\U0001d4d6': '$\\mathmit{G}$', +u'\U0001d4d7': '$\\mathmit{H}$', +u'\U0001d4d8': '$\\mathmit{I}$', +u'\U0001d4d9': '$\\mathmit{J}$', +u'\U0001d4da': '$\\mathmit{K}$', +u'\U0001d4db': '$\\mathmit{L}$', +u'\U0001d4dc': '$\\mathmit{M}$', +u'\U0001d4dd': '$\\mathmit{N}$', +u'\U0001d4de': '$\\mathmit{O}$', +u'\U0001d4df': '$\\mathmit{P}$', +u'\U0001d4e0': '$\\mathmit{Q}$', +u'\U0001d4e1': '$\\mathmit{R}$', +u'\U0001d4e2': '$\\mathmit{S}$', +u'\U0001d4e3': '$\\mathmit{T}$', +u'\U0001d4e4': '$\\mathmit{U}$', +u'\U0001d4e5': '$\\mathmit{V}$', +u'\U0001d4e6': '$\\mathmit{W}$', +u'\U0001d4e7': '$\\mathmit{X}$', +u'\U0001d4e8': '$\\mathmit{Y}$', +u'\U0001d4e9': '$\\mathmit{Z}$', +u'\U0001d4ea': '$\\mathmit{a}$', +u'\U0001d4eb': '$\\mathmit{b}$', +u'\U0001d4ec': '$\\mathmit{c}$', +u'\U0001d4ed': '$\\mathmit{d}$', +u'\U0001d4ee': '$\\mathmit{e}$', +u'\U0001d4ef': '$\\mathmit{f}$', +u'\U0001d4f0': '$\\mathmit{g}$', +u'\U0001d4f1': '$\\mathmit{h}$', +u'\U0001d4f2': '$\\mathmit{i}$', +u'\U0001d4f3': '$\\mathmit{j}$', +u'\U0001d4f4': '$\\mathmit{k}$', +u'\U0001d4f5': '$\\mathmit{l}$', +u'\U0001d4f6': '$\\mathmit{m}$', +u'\U0001d4f7': '$\\mathmit{n}$', +u'\U0001d4f8': '$\\mathmit{o}$', +u'\U0001d4f9': '$\\mathmit{p}$', +u'\U0001d4fa': '$\\mathmit{q}$', +u'\U0001d4fb': '$\\mathmit{r}$', +u'\U0001d4fc': '$\\mathmit{s}$', +u'\U0001d4fd': '$\\mathmit{t}$', +u'\U0001d4fe': '$\\mathmit{u}$', +u'\U0001d4ff': '$\\mathmit{v}$', +u'\U0001d500': '$\\mathmit{w}$', +u'\U0001d501': '$\\mathmit{x}$', +u'\U0001d502': '$\\mathmit{y}$', +u'\U0001d503': '$\\mathmit{z}$', +u'\U0001d504': '$\\mathfrak{A}$', +u'\U0001d505': '$\\mathfrak{B}$', +u'\U0001d507': '$\\mathfrak{D}$', +u'\U0001d508': '$\\mathfrak{E}$', +u'\U0001d509': '$\\mathfrak{F}$', +u'\U0001d50a': '$\\mathfrak{G}$', +u'\U0001d50d': '$\\mathfrak{J}$', +u'\U0001d50e': '$\\mathfrak{K}$', +u'\U0001d50f': '$\\mathfrak{L}$', +u'\U0001d510': '$\\mathfrak{M}$', +u'\U0001d511': '$\\mathfrak{N}$', +u'\U0001d512': '$\\mathfrak{O}$', +u'\U0001d513': '$\\mathfrak{P}$', +u'\U0001d514': '$\\mathfrak{Q}$', +u'\U0001d516': '$\\mathfrak{S}$', +u'\U0001d517': '$\\mathfrak{T}$', +u'\U0001d518': '$\\mathfrak{U}$', +u'\U0001d519': '$\\mathfrak{V}$', +u'\U0001d51a': '$\\mathfrak{W}$', +u'\U0001d51b': '$\\mathfrak{X}$', +u'\U0001d51c': '$\\mathfrak{Y}$', +u'\U0001d51e': '$\\mathfrak{a}$', +u'\U0001d51f': '$\\mathfrak{b}$', +u'\U0001d520': '$\\mathfrak{c}$', +u'\U0001d521': '$\\mathfrak{d}$', +u'\U0001d522': '$\\mathfrak{e}$', +u'\U0001d523': '$\\mathfrak{f}$', +u'\U0001d524': '$\\mathfrak{g}$', +u'\U0001d525': '$\\mathfrak{h}$', +u'\U0001d526': '$\\mathfrak{i}$', +u'\U0001d527': '$\\mathfrak{j}$', +u'\U0001d528': '$\\mathfrak{k}$', +u'\U0001d529': '$\\mathfrak{l}$', +u'\U0001d52a': '$\\mathfrak{m}$', +u'\U0001d52b': '$\\mathfrak{n}$', +u'\U0001d52c': '$\\mathfrak{o}$', +u'\U0001d52d': '$\\mathfrak{p}$', +u'\U0001d52e': '$\\mathfrak{q}$', +u'\U0001d52f': '$\\mathfrak{r}$', +u'\U0001d530': '$\\mathfrak{s}$', +u'\U0001d531': '$\\mathfrak{t}$', +u'\U0001d532': '$\\mathfrak{u}$', +u'\U0001d533': '$\\mathfrak{v}$', +u'\U0001d534': '$\\mathfrak{w}$', +u'\U0001d535': '$\\mathfrak{x}$', +u'\U0001d536': '$\\mathfrak{y}$', +u'\U0001d537': '$\\mathfrak{z}$', +u'\U0001d538': '$\\mathbb{A}$', +u'\U0001d539': '$\\mathbb{B}$', +u'\U0001d53b': '$\\mathbb{D}$', +u'\U0001d53c': '$\\mathbb{E}$', +u'\U0001d53d': '$\\mathbb{F}$', +u'\U0001d53e': '$\\mathbb{G}$', +u'\U0001d540': '$\\mathbb{I}$', +u'\U0001d541': '$\\mathbb{J}$', +u'\U0001d542': '$\\mathbb{K}$', +u'\U0001d543': '$\\mathbb{L}$', +u'\U0001d544': '$\\mathbb{M}$', +u'\U0001d546': '$\\mathbb{O}$', +u'\U0001d54a': '$\\mathbb{S}$', +u'\U0001d54b': '$\\mathbb{T}$', +u'\U0001d54c': '$\\mathbb{U}$', +u'\U0001d54d': '$\\mathbb{V}$', +u'\U0001d54e': '$\\mathbb{W}$', +u'\U0001d54f': '$\\mathbb{X}$', +u'\U0001d550': '$\\mathbb{Y}$', +u'\U0001d552': '$\\mathbb{a}$', +u'\U0001d553': '$\\mathbb{b}$', +u'\U0001d554': '$\\mathbb{c}$', +u'\U0001d555': '$\\mathbb{d}$', +u'\U0001d556': '$\\mathbb{e}$', +u'\U0001d557': '$\\mathbb{f}$', +u'\U0001d558': '$\\mathbb{g}$', +u'\U0001d559': '$\\mathbb{h}$', +u'\U0001d55a': '$\\mathbb{i}$', +u'\U0001d55b': '$\\mathbb{j}$', +u'\U0001d55c': '$\\mathbb{k}$', +u'\U0001d55d': '$\\mathbb{l}$', +u'\U0001d55e': '$\\mathbb{m}$', +u'\U0001d55f': '$\\mathbb{n}$', +u'\U0001d560': '$\\mathbb{o}$', +u'\U0001d561': '$\\mathbb{p}$', +u'\U0001d562': '$\\mathbb{q}$', +u'\U0001d563': '$\\mathbb{r}$', +u'\U0001d564': '$\\mathbb{s}$', +u'\U0001d565': '$\\mathbb{t}$', +u'\U0001d566': '$\\mathbb{u}$', +u'\U0001d567': '$\\mathbb{v}$', +u'\U0001d568': '$\\mathbb{w}$', +u'\U0001d569': '$\\mathbb{x}$', +u'\U0001d56a': '$\\mathbb{y}$', +u'\U0001d56b': '$\\mathbb{z}$', +u'\U0001d56c': '$\\mathslbb{A}$', +u'\U0001d56d': '$\\mathslbb{B}$', +u'\U0001d56e': '$\\mathslbb{C}$', +u'\U0001d56f': '$\\mathslbb{D}$', +u'\U0001d570': '$\\mathslbb{E}$', +u'\U0001d571': '$\\mathslbb{F}$', +u'\U0001d572': '$\\mathslbb{G}$', +u'\U0001d573': '$\\mathslbb{H}$', +u'\U0001d574': '$\\mathslbb{I}$', +u'\U0001d575': '$\\mathslbb{J}$', +u'\U0001d576': '$\\mathslbb{K}$', +u'\U0001d577': '$\\mathslbb{L}$', +u'\U0001d578': '$\\mathslbb{M}$', +u'\U0001d579': '$\\mathslbb{N}$', +u'\U0001d57a': '$\\mathslbb{O}$', +u'\U0001d57b': '$\\mathslbb{P}$', +u'\U0001d57c': '$\\mathslbb{Q}$', +u'\U0001d57d': '$\\mathslbb{R}$', +u'\U0001d57e': '$\\mathslbb{S}$', +u'\U0001d57f': '$\\mathslbb{T}$', +u'\U0001d580': '$\\mathslbb{U}$', +u'\U0001d581': '$\\mathslbb{V}$', +u'\U0001d582': '$\\mathslbb{W}$', +u'\U0001d583': '$\\mathslbb{X}$', +u'\U0001d584': '$\\mathslbb{Y}$', +u'\U0001d585': '$\\mathslbb{Z}$', +u'\U0001d586': '$\\mathslbb{a}$', +u'\U0001d587': '$\\mathslbb{b}$', +u'\U0001d588': '$\\mathslbb{c}$', +u'\U0001d589': '$\\mathslbb{d}$', +u'\U0001d58a': '$\\mathslbb{e}$', +u'\U0001d58b': '$\\mathslbb{f}$', +u'\U0001d58c': '$\\mathslbb{g}$', +u'\U0001d58d': '$\\mathslbb{h}$', +u'\U0001d58e': '$\\mathslbb{i}$', +u'\U0001d58f': '$\\mathslbb{j}$', +u'\U0001d590': '$\\mathslbb{k}$', +u'\U0001d591': '$\\mathslbb{l}$', +u'\U0001d592': '$\\mathslbb{m}$', +u'\U0001d593': '$\\mathslbb{n}$', +u'\U0001d594': '$\\mathslbb{o}$', +u'\U0001d595': '$\\mathslbb{p}$', +u'\U0001d596': '$\\mathslbb{q}$', +u'\U0001d597': '$\\mathslbb{r}$', +u'\U0001d598': '$\\mathslbb{s}$', +u'\U0001d599': '$\\mathslbb{t}$', +u'\U0001d59a': '$\\mathslbb{u}$', +u'\U0001d59b': '$\\mathslbb{v}$', +u'\U0001d59c': '$\\mathslbb{w}$', +u'\U0001d59d': '$\\mathslbb{x}$', +u'\U0001d59e': '$\\mathslbb{y}$', +u'\U0001d59f': '$\\mathslbb{z}$', +u'\U0001d5a0': '$\\mathsf{A}$', +u'\U0001d5a1': '$\\mathsf{B}$', +u'\U0001d5a2': '$\\mathsf{C}$', +u'\U0001d5a3': '$\\mathsf{D}$', +u'\U0001d5a4': '$\\mathsf{E}$', +u'\U0001d5a5': '$\\mathsf{F}$', +u'\U0001d5a6': '$\\mathsf{G}$', +u'\U0001d5a7': '$\\mathsf{H}$', +u'\U0001d5a8': '$\\mathsf{I}$', +u'\U0001d5a9': '$\\mathsf{J}$', +u'\U0001d5aa': '$\\mathsf{K}$', +u'\U0001d5ab': '$\\mathsf{L}$', +u'\U0001d5ac': '$\\mathsf{M}$', +u'\U0001d5ad': '$\\mathsf{N}$', +u'\U0001d5ae': '$\\mathsf{O}$', +u'\U0001d5af': '$\\mathsf{P}$', +u'\U0001d5b0': '$\\mathsf{Q}$', +u'\U0001d5b1': '$\\mathsf{R}$', +u'\U0001d5b2': '$\\mathsf{S}$', +u'\U0001d5b3': '$\\mathsf{T}$', +u'\U0001d5b4': '$\\mathsf{U}$', +u'\U0001d5b5': '$\\mathsf{V}$', +u'\U0001d5b6': '$\\mathsf{W}$', +u'\U0001d5b7': '$\\mathsf{X}$', +u'\U0001d5b8': '$\\mathsf{Y}$', +u'\U0001d5b9': '$\\mathsf{Z}$', +u'\U0001d5ba': '$\\mathsf{a}$', +u'\U0001d5bb': '$\\mathsf{b}$', +u'\U0001d5bc': '$\\mathsf{c}$', +u'\U0001d5bd': '$\\mathsf{d}$', +u'\U0001d5be': '$\\mathsf{e}$', +u'\U0001d5bf': '$\\mathsf{f}$', +u'\U0001d5c0': '$\\mathsf{g}$', +u'\U0001d5c1': '$\\mathsf{h}$', +u'\U0001d5c2': '$\\mathsf{i}$', +u'\U0001d5c3': '$\\mathsf{j}$', +u'\U0001d5c4': '$\\mathsf{k}$', +u'\U0001d5c5': '$\\mathsf{l}$', +u'\U0001d5c6': '$\\mathsf{m}$', +u'\U0001d5c7': '$\\mathsf{n}$', +u'\U0001d5c8': '$\\mathsf{o}$', +u'\U0001d5c9': '$\\mathsf{p}$', +u'\U0001d5ca': '$\\mathsf{q}$', +u'\U0001d5cb': '$\\mathsf{r}$', +u'\U0001d5cc': '$\\mathsf{s}$', +u'\U0001d5cd': '$\\mathsf{t}$', +u'\U0001d5ce': '$\\mathsf{u}$', +u'\U0001d5cf': '$\\mathsf{v}$', +u'\U0001d5d0': '$\\mathsf{w}$', +u'\U0001d5d1': '$\\mathsf{x}$', +u'\U0001d5d2': '$\\mathsf{y}$', +u'\U0001d5d3': '$\\mathsf{z}$', +u'\U0001d5d4': '$\\mathsfbf{A}$', +u'\U0001d5d5': '$\\mathsfbf{B}$', +u'\U0001d5d6': '$\\mathsfbf{C}$', +u'\U0001d5d7': '$\\mathsfbf{D}$', +u'\U0001d5d8': '$\\mathsfbf{E}$', +u'\U0001d5d9': '$\\mathsfbf{F}$', +u'\U0001d5da': '$\\mathsfbf{G}$', +u'\U0001d5db': '$\\mathsfbf{H}$', +u'\U0001d5dc': '$\\mathsfbf{I}$', +u'\U0001d5dd': '$\\mathsfbf{J}$', +u'\U0001d5de': '$\\mathsfbf{K}$', +u'\U0001d5df': '$\\mathsfbf{L}$', +u'\U0001d5e0': '$\\mathsfbf{M}$', +u'\U0001d5e1': '$\\mathsfbf{N}$', +u'\U0001d5e2': '$\\mathsfbf{O}$', +u'\U0001d5e3': '$\\mathsfbf{P}$', +u'\U0001d5e4': '$\\mathsfbf{Q}$', +u'\U0001d5e5': '$\\mathsfbf{R}$', +u'\U0001d5e6': '$\\mathsfbf{S}$', +u'\U0001d5e7': '$\\mathsfbf{T}$', +u'\U0001d5e8': '$\\mathsfbf{U}$', +u'\U0001d5e9': '$\\mathsfbf{V}$', +u'\U0001d5ea': '$\\mathsfbf{W}$', +u'\U0001d5eb': '$\\mathsfbf{X}$', +u'\U0001d5ec': '$\\mathsfbf{Y}$', +u'\U0001d5ed': '$\\mathsfbf{Z}$', +u'\U0001d5ee': '$\\mathsfbf{a}$', +u'\U0001d5ef': '$\\mathsfbf{b}$', +u'\U0001d5f0': '$\\mathsfbf{c}$', +u'\U0001d5f1': '$\\mathsfbf{d}$', +u'\U0001d5f2': '$\\mathsfbf{e}$', +u'\U0001d5f3': '$\\mathsfbf{f}$', +u'\U0001d5f4': '$\\mathsfbf{g}$', +u'\U0001d5f5': '$\\mathsfbf{h}$', +u'\U0001d5f6': '$\\mathsfbf{i}$', +u'\U0001d5f7': '$\\mathsfbf{j}$', +u'\U0001d5f8': '$\\mathsfbf{k}$', +u'\U0001d5f9': '$\\mathsfbf{l}$', +u'\U0001d5fa': '$\\mathsfbf{m}$', +u'\U0001d5fb': '$\\mathsfbf{n}$', +u'\U0001d5fc': '$\\mathsfbf{o}$', +u'\U0001d5fd': '$\\mathsfbf{p}$', +u'\U0001d5fe': '$\\mathsfbf{q}$', +u'\U0001d5ff': '$\\mathsfbf{r}$', +u'\U0001d600': '$\\mathsfbf{s}$', +u'\U0001d601': '$\\mathsfbf{t}$', +u'\U0001d602': '$\\mathsfbf{u}$', +u'\U0001d603': '$\\mathsfbf{v}$', +u'\U0001d604': '$\\mathsfbf{w}$', +u'\U0001d605': '$\\mathsfbf{x}$', +u'\U0001d606': '$\\mathsfbf{y}$', +u'\U0001d607': '$\\mathsfbf{z}$', +u'\U0001d608': '$\\mathsfsl{A}$', +u'\U0001d609': '$\\mathsfsl{B}$', +u'\U0001d60a': '$\\mathsfsl{C}$', +u'\U0001d60b': '$\\mathsfsl{D}$', +u'\U0001d60c': '$\\mathsfsl{E}$', +u'\U0001d60d': '$\\mathsfsl{F}$', +u'\U0001d60e': '$\\mathsfsl{G}$', +u'\U0001d60f': '$\\mathsfsl{H}$', +u'\U0001d610': '$\\mathsfsl{I}$', +u'\U0001d611': '$\\mathsfsl{J}$', +u'\U0001d612': '$\\mathsfsl{K}$', +u'\U0001d613': '$\\mathsfsl{L}$', +u'\U0001d614': '$\\mathsfsl{M}$', +u'\U0001d615': '$\\mathsfsl{N}$', +u'\U0001d616': '$\\mathsfsl{O}$', +u'\U0001d617': '$\\mathsfsl{P}$', +u'\U0001d618': '$\\mathsfsl{Q}$', +u'\U0001d619': '$\\mathsfsl{R}$', +u'\U0001d61a': '$\\mathsfsl{S}$', +u'\U0001d61b': '$\\mathsfsl{T}$', +u'\U0001d61c': '$\\mathsfsl{U}$', +u'\U0001d61d': '$\\mathsfsl{V}$', +u'\U0001d61e': '$\\mathsfsl{W}$', +u'\U0001d61f': '$\\mathsfsl{X}$', +u'\U0001d620': '$\\mathsfsl{Y}$', +u'\U0001d621': '$\\mathsfsl{Z}$', +u'\U0001d622': '$\\mathsfsl{a}$', +u'\U0001d623': '$\\mathsfsl{b}$', +u'\U0001d624': '$\\mathsfsl{c}$', +u'\U0001d625': '$\\mathsfsl{d}$', +u'\U0001d626': '$\\mathsfsl{e}$', +u'\U0001d627': '$\\mathsfsl{f}$', +u'\U0001d628': '$\\mathsfsl{g}$', +u'\U0001d629': '$\\mathsfsl{h}$', +u'\U0001d62a': '$\\mathsfsl{i}$', +u'\U0001d62b': '$\\mathsfsl{j}$', +u'\U0001d62c': '$\\mathsfsl{k}$', +u'\U0001d62d': '$\\mathsfsl{l}$', +u'\U0001d62e': '$\\mathsfsl{m}$', +u'\U0001d62f': '$\\mathsfsl{n}$', +u'\U0001d630': '$\\mathsfsl{o}$', +u'\U0001d631': '$\\mathsfsl{p}$', +u'\U0001d632': '$\\mathsfsl{q}$', +u'\U0001d633': '$\\mathsfsl{r}$', +u'\U0001d634': '$\\mathsfsl{s}$', +u'\U0001d635': '$\\mathsfsl{t}$', +u'\U0001d636': '$\\mathsfsl{u}$', +u'\U0001d637': '$\\mathsfsl{v}$', +u'\U0001d638': '$\\mathsfsl{w}$', +u'\U0001d639': '$\\mathsfsl{x}$', +u'\U0001d63a': '$\\mathsfsl{y}$', +u'\U0001d63b': '$\\mathsfsl{z}$', +u'\U0001d63c': '$\\mathsfbfsl{A}$', +u'\U0001d63d': '$\\mathsfbfsl{B}$', +u'\U0001d63e': '$\\mathsfbfsl{C}$', +u'\U0001d63f': '$\\mathsfbfsl{D}$', +u'\U0001d640': '$\\mathsfbfsl{E}$', +u'\U0001d641': '$\\mathsfbfsl{F}$', +u'\U0001d642': '$\\mathsfbfsl{G}$', +u'\U0001d643': '$\\mathsfbfsl{H}$', +u'\U0001d644': '$\\mathsfbfsl{I}$', +u'\U0001d645': '$\\mathsfbfsl{J}$', +u'\U0001d646': '$\\mathsfbfsl{K}$', +u'\U0001d647': '$\\mathsfbfsl{L}$', +u'\U0001d648': '$\\mathsfbfsl{M}$', +u'\U0001d649': '$\\mathsfbfsl{N}$', +u'\U0001d64a': '$\\mathsfbfsl{O}$', +u'\U0001d64b': '$\\mathsfbfsl{P}$', +u'\U0001d64c': '$\\mathsfbfsl{Q}$', +u'\U0001d64d': '$\\mathsfbfsl{R}$', +u'\U0001d64e': '$\\mathsfbfsl{S}$', +u'\U0001d64f': '$\\mathsfbfsl{T}$', +u'\U0001d650': '$\\mathsfbfsl{U}$', +u'\U0001d651': '$\\mathsfbfsl{V}$', +u'\U0001d652': '$\\mathsfbfsl{W}$', +u'\U0001d653': '$\\mathsfbfsl{X}$', +u'\U0001d654': '$\\mathsfbfsl{Y}$', +u'\U0001d655': '$\\mathsfbfsl{Z}$', +u'\U0001d656': '$\\mathsfbfsl{a}$', +u'\U0001d657': '$\\mathsfbfsl{b}$', +u'\U0001d658': '$\\mathsfbfsl{c}$', +u'\U0001d659': '$\\mathsfbfsl{d}$', +u'\U0001d65a': '$\\mathsfbfsl{e}$', +u'\U0001d65b': '$\\mathsfbfsl{f}$', +u'\U0001d65c': '$\\mathsfbfsl{g}$', +u'\U0001d65d': '$\\mathsfbfsl{h}$', +u'\U0001d65e': '$\\mathsfbfsl{i}$', +u'\U0001d65f': '$\\mathsfbfsl{j}$', +u'\U0001d660': '$\\mathsfbfsl{k}$', +u'\U0001d661': '$\\mathsfbfsl{l}$', +u'\U0001d662': '$\\mathsfbfsl{m}$', +u'\U0001d663': '$\\mathsfbfsl{n}$', +u'\U0001d664': '$\\mathsfbfsl{o}$', +u'\U0001d665': '$\\mathsfbfsl{p}$', +u'\U0001d666': '$\\mathsfbfsl{q}$', +u'\U0001d667': '$\\mathsfbfsl{r}$', +u'\U0001d668': '$\\mathsfbfsl{s}$', +u'\U0001d669': '$\\mathsfbfsl{t}$', +u'\U0001d66a': '$\\mathsfbfsl{u}$', +u'\U0001d66b': '$\\mathsfbfsl{v}$', +u'\U0001d66c': '$\\mathsfbfsl{w}$', +u'\U0001d66d': '$\\mathsfbfsl{x}$', +u'\U0001d66e': '$\\mathsfbfsl{y}$', +u'\U0001d66f': '$\\mathsfbfsl{z}$', +u'\U0001d670': '$\\mathtt{A}$', +u'\U0001d671': '$\\mathtt{B}$', +u'\U0001d672': '$\\mathtt{C}$', +u'\U0001d673': '$\\mathtt{D}$', +u'\U0001d674': '$\\mathtt{E}$', +u'\U0001d675': '$\\mathtt{F}$', +u'\U0001d676': '$\\mathtt{G}$', +u'\U0001d677': '$\\mathtt{H}$', +u'\U0001d678': '$\\mathtt{I}$', +u'\U0001d679': '$\\mathtt{J}$', +u'\U0001d67a': '$\\mathtt{K}$', +u'\U0001d67b': '$\\mathtt{L}$', +u'\U0001d67c': '$\\mathtt{M}$', +u'\U0001d67d': '$\\mathtt{N}$', +u'\U0001d67e': '$\\mathtt{O}$', +u'\U0001d67f': '$\\mathtt{P}$', +u'\U0001d680': '$\\mathtt{Q}$', +u'\U0001d681': '$\\mathtt{R}$', +u'\U0001d682': '$\\mathtt{S}$', +u'\U0001d683': '$\\mathtt{T}$', +u'\U0001d684': '$\\mathtt{U}$', +u'\U0001d685': '$\\mathtt{V}$', +u'\U0001d686': '$\\mathtt{W}$', +u'\U0001d687': '$\\mathtt{X}$', +u'\U0001d688': '$\\mathtt{Y}$', +u'\U0001d689': '$\\mathtt{Z}$', +u'\U0001d68a': '$\\mathtt{a}$', +u'\U0001d68b': '$\\mathtt{b}$', +u'\U0001d68c': '$\\mathtt{c}$', +u'\U0001d68d': '$\\mathtt{d}$', +u'\U0001d68e': '$\\mathtt{e}$', +u'\U0001d68f': '$\\mathtt{f}$', +u'\U0001d690': '$\\mathtt{g}$', +u'\U0001d691': '$\\mathtt{h}$', +u'\U0001d692': '$\\mathtt{i}$', +u'\U0001d693': '$\\mathtt{j}$', +u'\U0001d694': '$\\mathtt{k}$', +u'\U0001d695': '$\\mathtt{l}$', +u'\U0001d696': '$\\mathtt{m}$', +u'\U0001d697': '$\\mathtt{n}$', +u'\U0001d698': '$\\mathtt{o}$', +u'\U0001d699': '$\\mathtt{p}$', +u'\U0001d69a': '$\\mathtt{q}$', +u'\U0001d69b': '$\\mathtt{r}$', +u'\U0001d69c': '$\\mathtt{s}$', +u'\U0001d69d': '$\\mathtt{t}$', +u'\U0001d69e': '$\\mathtt{u}$', +u'\U0001d69f': '$\\mathtt{v}$', +u'\U0001d6a0': '$\\mathtt{w}$', +u'\U0001d6a1': '$\\mathtt{x}$', +u'\U0001d6a2': '$\\mathtt{y}$', +u'\U0001d6a3': '$\\mathtt{z}$', +u'\U0001d6a8': '$\\mathbf{\\Alpha}$', +u'\U0001d6a9': '$\\mathbf{\\Beta}$', +u'\U0001d6aa': '$\\mathbf{\\Gamma}$', +u'\U0001d6ab': '$\\mathbf{\\Delta}$', +u'\U0001d6ac': '$\\mathbf{\\Epsilon}$', +u'\U0001d6ad': '$\\mathbf{\\Zeta}$', +u'\U0001d6ae': '$\\mathbf{\\Eta}$', +u'\U0001d6af': '$\\mathbf{\\Theta}$', +u'\U0001d6b0': '$\\mathbf{\\Iota}$', +u'\U0001d6b1': '$\\mathbf{\\Kappa}$', +u'\U0001d6b2': '$\\mathbf{\\Lambda}$', +u'\U0001d6b3': '$M$', +u'\U0001d6b4': '$N$', +u'\U0001d6b5': '$\\mathbf{\\Xi}$', +u'\U0001d6b6': '$O$', +u'\U0001d6b7': '$\\mathbf{\\Pi}$', +u'\U0001d6b8': '$\\mathbf{\\Rho}$', +u'\U0001d6b9': '{\\mathbf{\\vartheta}}', +u'\U0001d6ba': '$\\mathbf{\\Sigma}$', +u'\U0001d6bb': '$\\mathbf{\\Tau}$', +u'\U0001d6bc': '$\\mathbf{\\Upsilon}$', +u'\U0001d6bd': '$\\mathbf{\\Phi}$', +u'\U0001d6be': '$\\mathbf{\\Chi}$', +u'\U0001d6bf': '$\\mathbf{\\Psi}$', +u'\U0001d6c0': '$\\mathbf{\\Omega}$', +u'\U0001d6c1': '$\\mathbf{\\nabla}$', +u'\U0001d6c2': '$\\mathbf{\\Alpha}$', +u'\U0001d6c3': '$\\mathbf{\\Beta}$', +u'\U0001d6c4': '$\\mathbf{\\Gamma}$', +u'\U0001d6c5': '$\\mathbf{\\Delta}$', +u'\U0001d6c6': '$\\mathbf{\\Epsilon}$', +u'\U0001d6c7': '$\\mathbf{\\Zeta}$', +u'\U0001d6c8': '$\\mathbf{\\Eta}$', +u'\U0001d6c9': '$\\mathbf{\\theta}$', +u'\U0001d6ca': '$\\mathbf{\\Iota}$', +u'\U0001d6cb': '$\\mathbf{\\Kappa}$', +u'\U0001d6cc': '$\\mathbf{\\Lambda}$', +u'\U0001d6cd': '$M$', +u'\U0001d6ce': '$N$', +u'\U0001d6cf': '$\\mathbf{\\Xi}$', +u'\U0001d6d0': '$O$', +u'\U0001d6d1': '$\\mathbf{\\Pi}$', +u'\U0001d6d2': '$\\mathbf{\\Rho}$', +u'\U0001d6d3': '$\\mathbf{\\varsigma}$', +u'\U0001d6d4': '$\\mathbf{\\Sigma}$', +u'\U0001d6d5': '$\\mathbf{\\Tau}$', +u'\U0001d6d6': '$\\mathbf{\\Upsilon}$', +u'\U0001d6d7': '$\\mathbf{\\Phi}$', +u'\U0001d6d8': '$\\mathbf{\\Chi}$', +u'\U0001d6d9': '$\\mathbf{\\Psi}$', +u'\U0001d6da': '$\\mathbf{\\Omega}$', +u'\U0001d6db': '$\\partial$', +u'\U0001d6dc': '$\\in$', +u'\U0001d6dd': '{\\mathbf{\\vartheta}}', +u'\U0001d6de': '{\\mathbf{\\varkappa}}', +u'\U0001d6df': '{\\mathbf{\\phi}}', +u'\U0001d6e0': '{\\mathbf{\\varrho}}', +u'\U0001d6e1': '{\\mathbf{\\varpi}}', +u'\U0001d6e2': '$\\mathsl{\\Alpha}$', +u'\U0001d6e3': '$\\mathsl{\\Beta}$', +u'\U0001d6e4': '$\\mathsl{\\Gamma}$', +u'\U0001d6e5': '$\\mathsl{\\Delta}$', +u'\U0001d6e6': '$\\mathsl{\\Epsilon}$', +u'\U0001d6e7': '$\\mathsl{\\Zeta}$', +u'\U0001d6e8': '$\\mathsl{\\Eta}$', +u'\U0001d6e9': '$\\mathsl{\\Theta}$', +u'\U0001d6ea': '$\\mathsl{\\Iota}$', +u'\U0001d6eb': '$\\mathsl{\\Kappa}$', +u'\U0001d6ec': '$\\mathsl{\\Lambda}$', +u'\U0001d6ed': '$M$', +u'\U0001d6ee': '$N$', +u'\U0001d6ef': '$\\mathsl{\\Xi}$', +u'\U0001d6f0': '$O$', +u'\U0001d6f1': '$\\mathsl{\\Pi}$', +u'\U0001d6f2': '$\\mathsl{\\Rho}$', +u'\U0001d6f3': '{\\mathsl{\\vartheta}}', +u'\U0001d6f4': '$\\mathsl{\\Sigma}$', +u'\U0001d6f5': '$\\mathsl{\\Tau}$', +u'\U0001d6f6': '$\\mathsl{\\Upsilon}$', +u'\U0001d6f7': '$\\mathsl{\\Phi}$', +u'\U0001d6f8': '$\\mathsl{\\Chi}$', +u'\U0001d6f9': '$\\mathsl{\\Psi}$', +u'\U0001d6fa': '$\\mathsl{\\Omega}$', +u'\U0001d6fb': '$\\mathsl{\\nabla}$', +u'\U0001d6fc': '$\\mathsl{\\Alpha}$', +u'\U0001d6fd': '$\\mathsl{\\Beta}$', +u'\U0001d6fe': '$\\mathsl{\\Gamma}$', +u'\U0001d6ff': '$\\mathsl{\\Delta}$', +u'\U0001d700': '$\\mathsl{\\Epsilon}$', +u'\U0001d701': '$\\mathsl{\\Zeta}$', +u'\U0001d702': '$\\mathsl{\\Eta}$', +u'\U0001d703': '$\\mathsl{\\Theta}$', +u'\U0001d704': '$\\mathsl{\\Iota}$', +u'\U0001d705': '$\\mathsl{\\Kappa}$', +u'\U0001d706': '$\\mathsl{\\Lambda}$', +u'\U0001d707': '$M$', +u'\U0001d708': '$N$', +u'\U0001d709': '$\\mathsl{\\Xi}$', +u'\U0001d70a': '$O$', +u'\U0001d70b': '$\\mathsl{\\Pi}$', +u'\U0001d70c': '$\\mathsl{\\Rho}$', +u'\U0001d70d': '$\\mathsl{\\varsigma}$', +u'\U0001d70e': '$\\mathsl{\\Sigma}$', +u'\U0001d70f': '$\\mathsl{\\Tau}$', +u'\U0001d710': '$\\mathsl{\\Upsilon}$', +u'\U0001d711': '$\\mathsl{\\Phi}$', +u'\U0001d712': '$\\mathsl{\\Chi}$', +u'\U0001d713': '$\\mathsl{\\Psi}$', +u'\U0001d714': '$\\mathsl{\\Omega}$', +u'\U0001d715': '$\\partial$', +u'\U0001d716': '$\\in$', +u'\U0001d717': '{\\mathsl{\\vartheta}}', +u'\U0001d718': '{\\mathsl{\\varkappa}}', +u'\U0001d719': '{\\mathsl{\\phi}}', +u'\U0001d71a': '{\\mathsl{\\varrho}}', +u'\U0001d71b': '{\\mathsl{\\varpi}}', +u'\U0001d71c': '$\\mathbit{\\Alpha}$', +u'\U0001d71d': '$\\mathbit{\\Beta}$', +u'\U0001d71e': '$\\mathbit{\\Gamma}$', +u'\U0001d71f': '$\\mathbit{\\Delta}$', +u'\U0001d720': '$\\mathbit{\\Epsilon}$', +u'\U0001d721': '$\\mathbit{\\Zeta}$', +u'\U0001d722': '$\\mathbit{\\Eta}$', +u'\U0001d723': '$\\mathbit{\\Theta}$', +u'\U0001d724': '$\\mathbit{\\Iota}$', +u'\U0001d725': '$\\mathbit{\\Kappa}$', +u'\U0001d726': '$\\mathbit{\\Lambda}$', +u'\U0001d727': '$M$', +u'\U0001d728': '$N$', +u'\U0001d729': '$\\mathbit{\\Xi}$', +u'\U0001d72a': '$O$', +u'\U0001d72b': '$\\mathbit{\\Pi}$', +u'\U0001d72c': '$\\mathbit{\\Rho}$', +u'\U0001d72d': '{\\mathbit{O}}', +u'\U0001d72e': '$\\mathbit{\\Sigma}$', +u'\U0001d72f': '$\\mathbit{\\Tau}$', +u'\U0001d730': '$\\mathbit{\\Upsilon}$', +u'\U0001d731': '$\\mathbit{\\Phi}$', +u'\U0001d732': '$\\mathbit{\\Chi}$', +u'\U0001d733': '$\\mathbit{\\Psi}$', +u'\U0001d734': '$\\mathbit{\\Omega}$', +u'\U0001d735': '$\\mathbit{\\nabla}$', +u'\U0001d736': '$\\mathbit{\\Alpha}$', +u'\U0001d737': '$\\mathbit{\\Beta}$', +u'\U0001d738': '$\\mathbit{\\Gamma}$', +u'\U0001d739': '$\\mathbit{\\Delta}$', +u'\U0001d73a': '$\\mathbit{\\Epsilon}$', +u'\U0001d73b': '$\\mathbit{\\Zeta}$', +u'\U0001d73c': '$\\mathbit{\\Eta}$', +u'\U0001d73d': '$\\mathbit{\\Theta}$', +u'\U0001d73e': '$\\mathbit{\\Iota}$', +u'\U0001d73f': '$\\mathbit{\\Kappa}$', +u'\U0001d740': '$\\mathbit{\\Lambda}$', +u'\U0001d741': '$M$', +u'\U0001d742': '$N$', +u'\U0001d743': '$\\mathbit{\\Xi}$', +u'\U0001d744': '$O$', +u'\U0001d745': '$\\mathbit{\\Pi}$', +u'\U0001d746': '$\\mathbit{\\Rho}$', +u'\U0001d747': '$\\mathbit{\\varsigma}$', +u'\U0001d748': '$\\mathbit{\\Sigma}$', +u'\U0001d749': '$\\mathbit{\\Tau}$', +u'\U0001d74a': '$\\mathbit{\\Upsilon}$', +u'\U0001d74b': '$\\mathbit{\\Phi}$', +u'\U0001d74c': '$\\mathbit{\\Chi}$', +u'\U0001d74d': '$\\mathbit{\\Psi}$', +u'\U0001d74e': '$\\mathbit{\\Omega}$', +u'\U0001d74f': '$\\partial$', +u'\U0001d750': '$\\in$', +u'\U0001d751': '{\\mathbit{\\vartheta}}', +u'\U0001d752': '{\\mathbit{\\varkappa}}', +u'\U0001d753': '{\\mathbit{\\phi}}', +u'\U0001d754': '{\\mathbit{\\varrho}}', +u'\U0001d755': '{\\mathbit{\\varpi}}', +u'\U0001d756': '$\\mathsfbf{\\Alpha}$', +u'\U0001d757': '$\\mathsfbf{\\Beta}$', +u'\U0001d758': '$\\mathsfbf{\\Gamma}$', +u'\U0001d759': '$\\mathsfbf{\\Delta}$', +u'\U0001d75a': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d75b': '$\\mathsfbf{\\Zeta}$', +u'\U0001d75c': '$\\mathsfbf{\\Eta}$', +u'\U0001d75d': '$\\mathsfbf{\\Theta}$', +u'\U0001d75e': '$\\mathsfbf{\\Iota}$', +u'\U0001d75f': '$\\mathsfbf{\\Kappa}$', +u'\U0001d760': '$\\mathsfbf{\\Lambda}$', +u'\U0001d761': '$M$', +u'\U0001d762': '$N$', +u'\U0001d763': '$\\mathsfbf{\\Xi}$', +u'\U0001d764': '$O$', +u'\U0001d765': '$\\mathsfbf{\\Pi}$', +u'\U0001d766': '$\\mathsfbf{\\Rho}$', +u'\U0001d767': '{\\mathsfbf{\\vartheta}}', +u'\U0001d768': '$\\mathsfbf{\\Sigma}$', +u'\U0001d769': '$\\mathsfbf{\\Tau}$', +u'\U0001d76a': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d76b': '$\\mathsfbf{\\Phi}$', +u'\U0001d76c': '$\\mathsfbf{\\Chi}$', +u'\U0001d76d': '$\\mathsfbf{\\Psi}$', +u'\U0001d76e': '$\\mathsfbf{\\Omega}$', +u'\U0001d76f': '$\\mathsfbf{\\nabla}$', +u'\U0001d770': '$\\mathsfbf{\\Alpha}$', +u'\U0001d771': '$\\mathsfbf{\\Beta}$', +u'\U0001d772': '$\\mathsfbf{\\Gamma}$', +u'\U0001d773': '$\\mathsfbf{\\Delta}$', +u'\U0001d774': '$\\mathsfbf{\\Epsilon}$', +u'\U0001d775': '$\\mathsfbf{\\Zeta}$', +u'\U0001d776': '$\\mathsfbf{\\Eta}$', +u'\U0001d777': '$\\mathsfbf{\\Theta}$', +u'\U0001d778': '$\\mathsfbf{\\Iota}$', +u'\U0001d779': '$\\mathsfbf{\\Kappa}$', +u'\U0001d77a': '$\\mathsfbf{\\Lambda}$', +u'\U0001d77b': '$M$', +u'\U0001d77c': '$N$', +u'\U0001d77d': '$\\mathsfbf{\\Xi}$', +u'\U0001d77e': '$O$', +u'\U0001d77f': '$\\mathsfbf{\\Pi}$', +u'\U0001d780': '$\\mathsfbf{\\Rho}$', +u'\U0001d781': '$\\mathsfbf{\\varsigma}$', +u'\U0001d782': '$\\mathsfbf{\\Sigma}$', +u'\U0001d783': '$\\mathsfbf{\\Tau}$', +u'\U0001d784': '$\\mathsfbf{\\Upsilon}$', +u'\U0001d785': '$\\mathsfbf{\\Phi}$', +u'\U0001d786': '$\\mathsfbf{\\Chi}$', +u'\U0001d787': '$\\mathsfbf{\\Psi}$', +u'\U0001d788': '$\\mathsfbf{\\Omega}$', +u'\U0001d789': '$\\partial$', +u'\U0001d78a': '$\\in$', +u'\U0001d78b': '{\\mathsfbf{\\vartheta}}', +u'\U0001d78c': '{\\mathsfbf{\\varkappa}}', +u'\U0001d78d': '{\\mathsfbf{\\phi}}', +u'\U0001d78e': '{\\mathsfbf{\\varrho}}', +u'\U0001d78f': '{\\mathsfbf{\\varpi}}', +u'\U0001d790': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d791': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d792': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d793': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d794': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d795': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d796': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d797': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d798': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d799': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d79a': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d79b': '$M$', +u'\U0001d79c': '$N$', +u'\U0001d79d': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d79e': '$O$', +u'\U0001d79f': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7a0': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7a1': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7a2': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7a3': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7a4': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7a5': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7a6': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7a7': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7a8': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7a9': '$\\mathsfbfsl{\\nabla}$', +u'\U0001d7aa': '$\\mathsfbfsl{\\Alpha}$', +u'\U0001d7ab': '$\\mathsfbfsl{\\Beta}$', +u'\U0001d7ac': '$\\mathsfbfsl{\\Gamma}$', +u'\U0001d7ad': '$\\mathsfbfsl{\\Delta}$', +u'\U0001d7ae': '$\\mathsfbfsl{\\Epsilon}$', +u'\U0001d7af': '$\\mathsfbfsl{\\Zeta}$', +u'\U0001d7b0': '$\\mathsfbfsl{\\Eta}$', +u'\U0001d7b1': '$\\mathsfbfsl{\\vartheta}$', +u'\U0001d7b2': '$\\mathsfbfsl{\\Iota}$', +u'\U0001d7b3': '$\\mathsfbfsl{\\Kappa}$', +u'\U0001d7b4': '$\\mathsfbfsl{\\Lambda}$', +u'\U0001d7b5': '$M$', +u'\U0001d7b6': '$N$', +u'\U0001d7b7': '$\\mathsfbfsl{\\Xi}$', +u'\U0001d7b8': '$O$', +u'\U0001d7b9': '$\\mathsfbfsl{\\Pi}$', +u'\U0001d7ba': '$\\mathsfbfsl{\\Rho}$', +u'\U0001d7bb': '$\\mathsfbfsl{\\varsigma}$', +u'\U0001d7bc': '$\\mathsfbfsl{\\Sigma}$', +u'\U0001d7bd': '$\\mathsfbfsl{\\Tau}$', +u'\U0001d7be': '$\\mathsfbfsl{\\Upsilon}$', +u'\U0001d7bf': '$\\mathsfbfsl{\\Phi}$', +u'\U0001d7c0': '$\\mathsfbfsl{\\Chi}$', +u'\U0001d7c1': '$\\mathsfbfsl{\\Psi}$', +u'\U0001d7c2': '$\\mathsfbfsl{\\Omega}$', +u'\U0001d7c3': '$\\partial$', +u'\U0001d7c4': '$\\in$', +u'\U0001d7c5': '{\\mathsfbfsl{\\vartheta}}', +u'\U0001d7c6': '{\\mathsfbfsl{\\varkappa}}', +u'\U0001d7c7': '{\\mathsfbfsl{\\phi}}', +u'\U0001d7c8': '{\\mathsfbfsl{\\varrho}}', +u'\U0001d7c9': '{\\mathsfbfsl{\\varpi}}', +u'\U0001d7ce': '$\\mathbf{0}$', +u'\U0001d7cf': '$\\mathbf{1}$', +u'\U0001d7d0': '$\\mathbf{2}$', +u'\U0001d7d1': '$\\mathbf{3}$', +u'\U0001d7d2': '$\\mathbf{4}$', +u'\U0001d7d3': '$\\mathbf{5}$', +u'\U0001d7d4': '$\\mathbf{6}$', +u'\U0001d7d5': '$\\mathbf{7}$', +u'\U0001d7d6': '$\\mathbf{8}$', +u'\U0001d7d7': '$\\mathbf{9}$', +u'\U0001d7d8': '$\\mathbb{0}$', +u'\U0001d7d9': '$\\mathbb{1}$', +u'\U0001d7da': '$\\mathbb{2}$', +u'\U0001d7db': '$\\mathbb{3}$', +u'\U0001d7dc': '$\\mathbb{4}$', +u'\U0001d7dd': '$\\mathbb{5}$', +u'\U0001d7de': '$\\mathbb{6}$', +u'\U0001d7df': '$\\mathbb{7}$', +u'\U0001d7e0': '$\\mathbb{8}$', +u'\U0001d7e1': '$\\mathbb{9}$', +u'\U0001d7e2': '$\\mathsf{0}$', +u'\U0001d7e3': '$\\mathsf{1}$', +u'\U0001d7e4': '$\\mathsf{2}$', +u'\U0001d7e5': '$\\mathsf{3}$', +u'\U0001d7e6': '$\\mathsf{4}$', +u'\U0001d7e7': '$\\mathsf{5}$', +u'\U0001d7e8': '$\\mathsf{6}$', +u'\U0001d7e9': '$\\mathsf{7}$', +u'\U0001d7ea': '$\\mathsf{8}$', +u'\U0001d7eb': '$\\mathsf{9}$', +u'\U0001d7ec': '$\\mathsfbf{0}$', +u'\U0001d7ed': '$\\mathsfbf{1}$', +u'\U0001d7ee': '$\\mathsfbf{2}$', +u'\U0001d7ef': '$\\mathsfbf{3}$', +u'\U0001d7f0': '$\\mathsfbf{4}$', +u'\U0001d7f1': '$\\mathsfbf{5}$', +u'\U0001d7f2': '$\\mathsfbf{6}$', +u'\U0001d7f3': '$\\mathsfbf{7}$', +u'\U0001d7f4': '$\\mathsfbf{8}$', +u'\U0001d7f5': '$\\mathsfbf{9}$', +u'\U0001d7f6': '$\\mathtt{0}$', +u'\U0001d7f7': '$\\mathtt{1}$', +u'\U0001d7f8': '$\\mathtt{2}$', +u'\U0001d7f9': '$\\mathtt{3}$', +u'\U0001d7fa': '$\\mathtt{4}$', +u'\U0001d7fb': '$\\mathtt{5}$', +u'\U0001d7fc': '$\\mathtt{6}$', +u'\U0001d7fd': '$\\mathtt{7}$', +u'\U0001d7fe': '$\\mathtt{8}$', +u'\U0001d7ff': '$\\mathtt{9}$'} diff --git a/docutils/writers/pep_html.py b/docutils/writers/pep_html.py deleted file mode 100644 index 1fdc36f30..000000000 --- a/docutils/writers/pep_html.py +++ /dev/null @@ -1,108 +0,0 @@ -# Author: David Goodger -# Contact: goodger@users.sourceforge.net -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -PEP HTML Writer. -""" - -__docformat__ = 'reStructuredText' - - -import sys -import os -import os.path -import docutils -from docutils import frontend, nodes, utils, writers -from docutils.writers import html4css1 - - -class Writer(html4css1.Writer): - - default_stylesheet = 'pep_html/pep.css' - - default_stylesheet_path = utils.relative_path( - os.path.join(os.getcwd(), 'dummy'), - os.path.join(writers.support_path, default_stylesheet)) - - default_template = 'pep_html/template.txt' - - default_template_path = utils.relative_path( - os.path.join(os.getcwd(), 'dummy'), - os.path.join(writers.support_path, default_template)) - - settings_spec = html4css1.Writer.settings_spec + ( - 'PEP/HTML-Specific Options', - 'The default value for the --stylesheet-path option (defined in ' - 'HTML-Specific Options above) is "%s" for the PEP/HTML writer.' - % default_stylesheet_path, - (('Specify a template file. Default is "%s".' % default_template_path, - ['--template'], - {'default': default_template_path, 'metavar': ''}), - ('Python\'s home URL. Default is "http://www.python.org".', - ['--python-home'], - {'default': 'http://www.python.org', 'metavar': ''}), - ('Home URL prefix for PEPs. Default is "." (current directory).', - ['--pep-home'], - {'default': '.', 'metavar': ''}), - # For testing. - (frontend.SUPPRESS_HELP, - ['--no-random'], - {'action': 'store_true', 'validator': frontend.validate_boolean}),)) - - settings_default_overrides = {'stylesheet_path': default_stylesheet_path} - - relative_path_settings = (html4css1.Writer.relative_path_settings - + ('template',)) - - config_section = 'pep_html writer' - config_section_dependencies = ('writers', 'html4css1 writer') - - def __init__(self): - html4css1.Writer.__init__(self) - self.translator_class = HTMLTranslator - - def translate(self): - html4css1.Writer.translate(self) - settings = self.document.settings - template = open(settings.template).read() - # Substitutions dict for template: - subs = {} - subs['encoding'] = settings.output_encoding - subs['version'] = docutils.__version__ - subs['stylesheet'] = ''.join(self.stylesheet) - pyhome = settings.python_home - subs['pyhome'] = pyhome - subs['pephome'] = settings.pep_home - if pyhome == '..': - subs['pepindex'] = '.' - else: - subs['pepindex'] = pyhome + '/peps' - index = self.document.first_child_matching_class(nodes.field_list) - header = self.document[index] - pepnum = header[0][1].astext() - subs['pep'] = pepnum - if settings.no_random: - subs['banner'] = 0 - else: - import random - subs['banner'] = random.randrange(64) - try: - subs['pepnum'] = '%04i' % int(pepnum) - except ValueError: - subs['pepnum'] = pepnum - subs['title'] = header[1][1].astext() - subs['body'] = ''.join( - self.body_pre_docinfo + self.docinfo + self.body) - subs['body_suffix'] = ''.join(self.body_suffix) - self.output = template % subs - - -class HTMLTranslator(html4css1.HTMLTranslator): - - def depart_field_list(self, node): - html4css1.HTMLTranslator.depart_field_list(self, node) - if 'rfc2822' in node['classes']: - self.body.append('
    \n') diff --git a/docutils/writers/pep_html/__init__.py b/docutils/writers/pep_html/__init__.py new file mode 100644 index 000000000..a672e1c6d --- /dev/null +++ b/docutils/writers/pep_html/__init__.py @@ -0,0 +1,108 @@ +# Author: David Goodger +# Contact: goodger@users.sourceforge.net +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +PEP HTML Writer. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os +import os.path +import docutils +from docutils import frontend, nodes, utils, writers +from docutils.writers import html4css1 + + +class Writer(html4css1.Writer): + + default_stylesheet = 'pep.css' + + default_stylesheet_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(os.path.dirname(__file__), default_stylesheet)) + + default_template = 'template.txt' + + default_template_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(os.path.dirname(__file__), default_template)) + + settings_spec = html4css1.Writer.settings_spec + ( + 'PEP/HTML-Specific Options', + 'The default value for the --stylesheet-path option (defined in ' + 'HTML-Specific Options above) is "%s" for the PEP/HTML writer.' + % default_stylesheet_path, + (('Specify a template file. Default is "%s".' % default_template_path, + ['--template'], + {'default': default_template_path, 'metavar': ''}), + ('Python\'s home URL. Default is "http://www.python.org".', + ['--python-home'], + {'default': 'http://www.python.org', 'metavar': ''}), + ('Home URL prefix for PEPs. Default is "." (current directory).', + ['--pep-home'], + {'default': '.', 'metavar': ''}), + # For testing. + (frontend.SUPPRESS_HELP, + ['--no-random'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + + settings_default_overrides = {'stylesheet_path': default_stylesheet_path} + + relative_path_settings = (html4css1.Writer.relative_path_settings + + ('template',)) + + config_section = 'pep_html writer' + config_section_dependencies = ('writers', 'html4css1 writer') + + def __init__(self): + html4css1.Writer.__init__(self) + self.translator_class = HTMLTranslator + + def translate(self): + html4css1.Writer.translate(self) + settings = self.document.settings + template = open(settings.template).read() + # Substitutions dict for template: + subs = {} + subs['encoding'] = settings.output_encoding + subs['version'] = docutils.__version__ + subs['stylesheet'] = ''.join(self.stylesheet) + pyhome = settings.python_home + subs['pyhome'] = pyhome + subs['pephome'] = settings.pep_home + if pyhome == '..': + subs['pepindex'] = '.' + else: + subs['pepindex'] = pyhome + '/peps' + index = self.document.first_child_matching_class(nodes.field_list) + header = self.document[index] + pepnum = header[0][1].astext() + subs['pep'] = pepnum + if settings.no_random: + subs['banner'] = 0 + else: + import random + subs['banner'] = random.randrange(64) + try: + subs['pepnum'] = '%04i' % int(pepnum) + except ValueError: + subs['pepnum'] = pepnum + subs['title'] = header[1][1].astext() + subs['body'] = ''.join( + self.body_pre_docinfo + self.docinfo + self.body) + subs['body_suffix'] = ''.join(self.body_suffix) + self.output = template % subs + + +class HTMLTranslator(html4css1.HTMLTranslator): + + def depart_field_list(self, node): + html4css1.HTMLTranslator.depart_field_list(self, node) + if 'rfc2822' in node['classes']: + self.body.append('
    \n') diff --git a/docutils/writers/pep_html/pep.css b/docutils/writers/pep_html/pep.css new file mode 100644 index 000000000..014d3e423 --- /dev/null +++ b/docutils/writers/pep_html/pep.css @@ -0,0 +1,348 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date$ +:version: $Revision$ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the PEP HTML output of Docutils. +*/ + +/* "! important" is used here to override other ``margin-top`` and + ``margin-bottom`` styles that are later in the stylesheet or + more specific. See http://www.w3.org/TR/CSS1#the-cascade */ +.first { + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +.navigation { + width: 100% ; + background: #99ccff ; + margin-top: 0px ; + margin-bottom: 0px } + +.navigation .navicon { + width: 150px ; + height: 35px } + +.navigation .textlinks { + padding-left: 1em ; + text-align: left } + +.navigation td, .navigation th { + padding-left: 0em ; + padding-right: 0em ; + vertical-align: middle } + +.rfc2822 { + margin-top: 0.5em ; + margin-left: 0.5em ; + margin-right: 0.5em ; + margin-bottom: 0em } + +.rfc2822 td { + text-align: left } + +.rfc2822 th.field-name { + text-align: right ; + font-family: sans-serif ; + padding-right: 0.5em ; + font-weight: bold ; + margin-bottom: 0em } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +body { + margin: 0px ; + margin-bottom: 1em ; + padding: 0px } + +dl.docutils dd { + margin-bottom: 0.5em } + +div.section { + margin-left: 1em ; + margin-right: 1em ; + margin-bottom: 1.5em } + +div.section div.section { + margin-left: 0em ; + margin-right: 0em ; + margin-top: 1.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em ; + margin-right: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.footer { + margin-left: 1em ; + margin-right: 1em } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1 { + font-family: sans-serif ; + font-size: large } + +h2 { + font-family: sans-serif ; + font-size: medium } + +h3 { + font-family: sans-serif ; + font-size: small } + +h4 { + font-family: sans-serif ; + font-style: italic ; + font-size: small } + +h5 { + font-family: sans-serif; + font-size: x-small } + +h6 { + font-family: sans-serif; + font-style: italic ; + font-size: x-small } + +hr.docutils { + width: 75% } + +img.align-left { + clear: left } + +img.align-right { + clear: right } + +img.borderless { + border: 0 } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-family: sans-serif ; + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid 1px gray; + margin-left: 1px } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid 1px black; + margin-left: 1px } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +td.num { + text-align: right } + +th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } diff --git a/docutils/writers/pep_html/template.txt b/docutils/writers/pep_html/template.txt new file mode 100644 index 000000000..6f96977e8 --- /dev/null +++ b/docutils/writers/pep_html/template.txt @@ -0,0 +1,28 @@ + + + + + + + + PEP %(pep)s -- %(title)s + %(stylesheet)s + + + + +
    +%(body)s +%(body_suffix)s diff --git a/docutils/writers/s5_html.py b/docutils/writers/s5_html.py deleted file mode 100644 index 1a25abc82..000000000 --- a/docutils/writers/s5_html.py +++ /dev/null @@ -1,321 +0,0 @@ -# Author: Chris Liechti -# Contact: cliechti@gmx.net -# Author: David Goodger -# Contact: goodger@python.org -# Revision: $Revision$ -# Date: $Date$ -# Copyright: This module has been placed in the public domain. - -""" -S5/HTML Slideshow Writer. -""" - -__docformat__ = 'reStructuredText' - - -import sys -import os -import re -import docutils -from docutils import frontend, nodes, utils, writers -from docutils.writers import html4css1 -from docutils.parsers.rst import directives - -support_path = utils.relative_path( - os.path.join(os.getcwd(), 'dummy'), - os.path.join(writers.support_path, 's5_html')) - -def find_theme(name): - # Where else to look for a theme? - # Check working dir? Destination dir? Config dir? Plugins dir? - path = os.path.join(support_path, name) - if not os.path.isdir(path): - raise docutils.ApplicationError('Theme directory not found: %r' % name) - return path - - -class Writer(html4css1.Writer): - - settings_spec = html4css1.Writer.settings_spec + ( - 'S5 Slideshow Specific Options', - 'For the S5/HTML writer, the --no-toc-backlinks option ' - '(defined in General Docutils Options above) is the default, ' - 'and should not be changed.', - (('Specify an installed S5 theme by name. Overrides --theme-url. ' - 'The default theme name is "default". The theme files will be ' - 'copied into a "ui/" directory, in the same directory as the ' - 'destination file (output HTML). Note that existing theme files ' - 'will not be overwritten (unless --overwrite-theme-files is used).', - ['--theme'], - {'default': 'default', 'metavar': '', - 'overrides': 'theme_url'}), - ('Specify an S5 theme URL. The destination file (output HTML) will ' - 'link to this theme; nothing will be copied. Overrides --theme.', - ['--theme-url'], - {'metavar': '', 'overrides': 'theme'}), - ('Allow existing theme files in the ``ui/`` directory to be ' - 'overwritten. The default is not to overwrite theme files.', - ['--overwrite-theme-files'], - {'action': 'store_true'}), - ('Keep existing theme files in the ``ui/`` directory; do not ' - 'overwrite any. This is the default.', - ['--keep-theme-files'], - {'dest': 'overwrite_theme_files', 'action': 'store_false'}), - ('Enable the current slide indicator ("1 / 15"). ' - 'The default is to disable it.', - ['--current-slide'], - {'action': 'store_true'}), - ('Disable the current slide indicator. This is the default.', - ['--no-current-slide'], - {'dest': 'current_slide', 'action': 'store_false'}),)) - - settings_default_overrides = {'toc_backlinks': 0} - - config_section = 's5_html writer' - config_section_dependencies = ('writers', 'html4css1 writer') - - def __init__(self): - html4css1.Writer.__init__(self) - self.translator_class = S5HTMLTranslator - - -class S5HTMLTranslator(html4css1.HTMLTranslator): - - doctype = ( - '\n') - - s5_stylesheet_template = """\ - - - - - - - - -\n""" - - disable_current_slide = """ -\n""" - - layout_template = """\ -
    -
    -
    - - -
    \n""" -#
    -#
    -#
    -#
    - - default_theme = 'default' - """Name of the default theme.""" - - base_theme_file = '__base__' - """Name of the file containing the name of the base theme.""" - - direct_theme_files = ( - 'slides.css', 'outline.css', 'print.css', 'opera.css', 'slides.js') - """Names of theme files directly linked to in the output HTML""" - - indirect_theme_files = ( - 's5-core.css', 'framing.css', 'pretty.css', 'blank.gif', 'iepngfix.htc') - """Names of files used indirectly; imported or used by files in - `direct_theme_files`.""" - - required_theme_files = indirect_theme_files + direct_theme_files - """Names of mandatory theme files.""" - - def __init__(self, *args): - html4css1.HTMLTranslator.__init__(self, *args) - #insert S5-specific stylesheet and script stuff: - self.theme_file_path = None - self.setup_theme() - self.stylesheet.append(self.s5_stylesheet_template - % {'path': self.theme_file_path}) - if not self.document.settings.current_slide: - self.stylesheet.append(self.disable_current_slide) - self.add_meta('\n') - self.s5_footer = [] - self.s5_header = [] - self.section_count = 0 - self.theme_files_copied = None - - def setup_theme(self): - if self.document.settings.theme: - self.copy_theme() - elif self.document.settings.theme_url: - self.theme_file_path = self.document.settings.theme_url - else: - raise docutils.ApplicationError( - 'No theme specified for S5/HTML writer.') - - def copy_theme(self): - """ - Locate & copy theme files. - - A theme may be explicitly based on another theme via a '__base__' - file. The default base theme is 'default'. Files are accumulated - from the specified theme, any base themes, and 'default'. - """ - settings = self.document.settings - path = find_theme(settings.theme) - theme_paths = [path] - self.theme_files_copied = {} - required_files_copied = {} - # This is a link (URL) in HTML, so we use "/", not os.sep: - self.theme_file_path = '%s/%s' % ('ui', settings.theme) - if settings._destination: - dest = os.path.join( - os.path.dirname(settings._destination), 'ui', settings.theme) - if not os.path.isdir(dest): - os.makedirs(dest) - else: - # no destination, so we can't copy the theme - return - default = 0 - while path: - for f in os.listdir(path): # copy all files from each theme - if f == self.base_theme_file: - continue # ... except the "__base__" file - if ( self.copy_file(f, path, dest) - and f in self.required_theme_files): - required_files_copied[f] = 1 - if default: - break # "default" theme has no base theme - # Find the "__base__" file in theme directory: - base_theme_file = os.path.join(path, self.base_theme_file) - # If it exists, read it and record the theme path: - if os.path.isfile(base_theme_file): - lines = open(base_theme_file).readlines() - for line in lines: - line = line.strip() - if line and not line.startswith('#'): - path = find_theme(line) - if path in theme_paths: # check for duplicates (cycles) - path = None # if found, use default base - else: - theme_paths.append(path) - break - else: # no theme name found - path = None # use default base - else: # no base theme file found - path = None # use default base - if not path: - path = find_theme(self.default_theme) - theme_paths.append(path) - default = 1 - if len(required_files_copied) != len(self.required_theme_files): - # Some required files weren't found & couldn't be copied. - required = list(self.required_theme_files) - for f in required_files_copied.keys(): - required.remove(f) - raise docutils.ApplicationError( - 'Theme files not found: %s' - % ', '.join(['%r' % f for f in required])) - - files_to_skip_pattern = re.compile(r'~$|\.bak$|#$|\.cvsignore$') - - def copy_file(self, name, source_dir, dest_dir): - """ - Copy file `name` from `source_dir` to `dest_dir`. - Return 1 if the file exists in either `source_dir` or `dest_dir`. - """ - source = os.path.join(source_dir, name) - dest = os.path.join(dest_dir, name) - if self.theme_files_copied.has_key(dest): - return 1 - else: - self.theme_files_copied[dest] = 1 - if os.path.isfile(source): - if self.files_to_skip_pattern.search(source): - return None - settings = self.document.settings - if os.path.exists(dest) and not settings.overwrite_theme_files: - settings.record_dependencies.add(dest) - else: - src_file = open(source, 'rb') - src_data = src_file.read() - src_file.close() - dest_file = open(dest, 'wb') - dest_file.write(src_data.replace( - 'ui/default', dest_dir[dest_dir.rfind('ui/'):])) - dest_file.close() - settings.record_dependencies.add(source) - return 1 - if os.path.isfile(dest): - return 1 - - def depart_document(self, node): - header = ''.join(self.s5_header) - footer = ''.join(self.s5_footer) - title = ''.join(self.html_title).replace('

    ', '

    ') - layout = self.layout_template % {'header': header, - 'title': title, - 'footer': footer} - self.fragment.extend(self.body) - self.body_prefix.extend(layout) - self.body_prefix.append('
    \n') - self.body_prefix.append( - self.starttag({'classes': ['slide'], 'ids': ['slide0']}, 'div')) - if not self.section_count: - self.body.append('
    \n') - self.body_suffix.insert(0, '

    \n') - # skip content-type meta tag with interpolated charset value: - self.html_head.extend(self.head[1:]) - self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo - + self.docinfo + self.body - + self.body_suffix[:-1]) - - def depart_footer(self, node): - start = self.context.pop() - self.s5_footer.append('

    ') - self.s5_footer.extend(self.body[start:]) - self.s5_footer.append('

    ') - del self.body[start:] - - def depart_header(self, node): - start = self.context.pop() - header = ['\n') - del self.body[start:] - self.s5_header.extend(header) - - def visit_section(self, node): - if not self.section_count: - self.body.append('\n\n') - self.section_count += 1 - self.section_level += 1 - if self.section_level > 1: - # dummy for matching div's - self.body.append(self.starttag(node, 'div', CLASS='section')) - else: - self.body.append(self.starttag(node, 'div', CLASS='slide')) - - def visit_subtitle(self, node): - if isinstance(node.parent, nodes.section): - level = self.section_level + self.initial_header_level - 1 - if level == 1: - level = 2 - tag = 'h%s' % level - self.body.append(self.starttag(node, tag, '')) - self.context.append('\n' % tag) - else: - html4css1.HTMLTranslator.visit_subtitle(self, node) - - def visit_title(self, node, move_ids=0): - html4css1.HTMLTranslator.visit_title(self, node, move_ids=move_ids) diff --git a/docutils/writers/s5_html/__init__.py b/docutils/writers/s5_html/__init__.py new file mode 100644 index 000000000..39c958887 --- /dev/null +++ b/docutils/writers/s5_html/__init__.py @@ -0,0 +1,322 @@ +# Author: Chris Liechti +# Contact: cliechti@gmx.net +# Author: David Goodger +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +S5/HTML Slideshow Writer. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os +import re +import docutils +from docutils import frontend, nodes, utils +from docutils.writers import html4css1 +from docutils.parsers.rst import directives + +themes_dir_path = utils.relative_path( + os.path.join(os.getcwd(), 'dummy'), + os.path.join(os.path.dirname(__file__), 'themes')) + +def find_theme(name): + # Where else to look for a theme? + # Check working dir? Destination dir? Config dir? Plugins dir? + path = os.path.join(themes_dir_path, name) + if not os.path.isdir(path): + raise docutils.ApplicationError('Theme directory not found: %r (path: %r)' + % (name, path)) + return path + + +class Writer(html4css1.Writer): + + settings_spec = html4css1.Writer.settings_spec + ( + 'S5 Slideshow Specific Options', + 'For the S5/HTML writer, the --no-toc-backlinks option ' + '(defined in General Docutils Options above) is the default, ' + 'and should not be changed.', + (('Specify an installed S5 theme by name. Overrides --theme-url. ' + 'The default theme name is "default". The theme files will be ' + 'copied into a "ui/" directory, in the same directory as the ' + 'destination file (output HTML). Note that existing theme files ' + 'will not be overwritten (unless --overwrite-theme-files is used).', + ['--theme'], + {'default': 'default', 'metavar': '', + 'overrides': 'theme_url'}), + ('Specify an S5 theme URL. The destination file (output HTML) will ' + 'link to this theme; nothing will be copied. Overrides --theme.', + ['--theme-url'], + {'metavar': '', 'overrides': 'theme'}), + ('Allow existing theme files in the ``ui/`` directory to be ' + 'overwritten. The default is not to overwrite theme files.', + ['--overwrite-theme-files'], + {'action': 'store_true'}), + ('Keep existing theme files in the ``ui/`` directory; do not ' + 'overwrite any. This is the default.', + ['--keep-theme-files'], + {'dest': 'overwrite_theme_files', 'action': 'store_false'}), + ('Enable the current slide indicator ("1 / 15"). ' + 'The default is to disable it.', + ['--current-slide'], + {'action': 'store_true'}), + ('Disable the current slide indicator. This is the default.', + ['--no-current-slide'], + {'dest': 'current_slide', 'action': 'store_false'}),)) + + settings_default_overrides = {'toc_backlinks': 0} + + config_section = 's5_html writer' + config_section_dependencies = ('writers', 'html4css1 writer') + + def __init__(self): + html4css1.Writer.__init__(self) + self.translator_class = S5HTMLTranslator + + +class S5HTMLTranslator(html4css1.HTMLTranslator): + + doctype = ( + '\n') + + s5_stylesheet_template = """\ + + + + + + + + +\n""" + + disable_current_slide = """ +\n""" + + layout_template = """\ +
    +
    +
    + + +
    \n""" +#
    +#
    +#
    +#
    + + default_theme = 'default' + """Name of the default theme.""" + + base_theme_file = '__base__' + """Name of the file containing the name of the base theme.""" + + direct_theme_files = ( + 'slides.css', 'outline.css', 'print.css', 'opera.css', 'slides.js') + """Names of theme files directly linked to in the output HTML""" + + indirect_theme_files = ( + 's5-core.css', 'framing.css', 'pretty.css', 'blank.gif', 'iepngfix.htc') + """Names of files used indirectly; imported or used by files in + `direct_theme_files`.""" + + required_theme_files = indirect_theme_files + direct_theme_files + """Names of mandatory theme files.""" + + def __init__(self, *args): + html4css1.HTMLTranslator.__init__(self, *args) + #insert S5-specific stylesheet and script stuff: + self.theme_file_path = None + self.setup_theme() + self.stylesheet.append(self.s5_stylesheet_template + % {'path': self.theme_file_path}) + if not self.document.settings.current_slide: + self.stylesheet.append(self.disable_current_slide) + self.add_meta('\n') + self.s5_footer = [] + self.s5_header = [] + self.section_count = 0 + self.theme_files_copied = None + + def setup_theme(self): + if self.document.settings.theme: + self.copy_theme() + elif self.document.settings.theme_url: + self.theme_file_path = self.document.settings.theme_url + else: + raise docutils.ApplicationError( + 'No theme specified for S5/HTML writer.') + + def copy_theme(self): + """ + Locate & copy theme files. + + A theme may be explicitly based on another theme via a '__base__' + file. The default base theme is 'default'. Files are accumulated + from the specified theme, any base themes, and 'default'. + """ + settings = self.document.settings + path = find_theme(settings.theme) + theme_paths = [path] + self.theme_files_copied = {} + required_files_copied = {} + # This is a link (URL) in HTML, so we use "/", not os.sep: + self.theme_file_path = '%s/%s' % ('ui', settings.theme) + if settings._destination: + dest = os.path.join( + os.path.dirname(settings._destination), 'ui', settings.theme) + if not os.path.isdir(dest): + os.makedirs(dest) + else: + # no destination, so we can't copy the theme + return + default = 0 + while path: + for f in os.listdir(path): # copy all files from each theme + if f == self.base_theme_file: + continue # ... except the "__base__" file + if ( self.copy_file(f, path, dest) + and f in self.required_theme_files): + required_files_copied[f] = 1 + if default: + break # "default" theme has no base theme + # Find the "__base__" file in theme directory: + base_theme_file = os.path.join(path, self.base_theme_file) + # If it exists, read it and record the theme path: + if os.path.isfile(base_theme_file): + lines = open(base_theme_file).readlines() + for line in lines: + line = line.strip() + if line and not line.startswith('#'): + path = find_theme(line) + if path in theme_paths: # check for duplicates (cycles) + path = None # if found, use default base + else: + theme_paths.append(path) + break + else: # no theme name found + path = None # use default base + else: # no base theme file found + path = None # use default base + if not path: + path = find_theme(self.default_theme) + theme_paths.append(path) + default = 1 + if len(required_files_copied) != len(self.required_theme_files): + # Some required files weren't found & couldn't be copied. + required = list(self.required_theme_files) + for f in required_files_copied.keys(): + required.remove(f) + raise docutils.ApplicationError( + 'Theme files not found: %s' + % ', '.join(['%r' % f for f in required])) + + files_to_skip_pattern = re.compile(r'~$|\.bak$|#$|\.cvsignore$') + + def copy_file(self, name, source_dir, dest_dir): + """ + Copy file `name` from `source_dir` to `dest_dir`. + Return 1 if the file exists in either `source_dir` or `dest_dir`. + """ + source = os.path.join(source_dir, name) + dest = os.path.join(dest_dir, name) + if self.theme_files_copied.has_key(dest): + return 1 + else: + self.theme_files_copied[dest] = 1 + if os.path.isfile(source): + if self.files_to_skip_pattern.search(source): + return None + settings = self.document.settings + if os.path.exists(dest) and not settings.overwrite_theme_files: + settings.record_dependencies.add(dest) + else: + src_file = open(source, 'rb') + src_data = src_file.read() + src_file.close() + dest_file = open(dest, 'wb') + dest_file.write(src_data.replace( + 'ui/default', dest_dir[dest_dir.rfind('ui/'):])) + dest_file.close() + settings.record_dependencies.add(source) + return 1 + if os.path.isfile(dest): + return 1 + + def depart_document(self, node): + header = ''.join(self.s5_header) + footer = ''.join(self.s5_footer) + title = ''.join(self.html_title).replace('

    ', '

    ') + layout = self.layout_template % {'header': header, + 'title': title, + 'footer': footer} + self.fragment.extend(self.body) + self.body_prefix.extend(layout) + self.body_prefix.append('
    \n') + self.body_prefix.append( + self.starttag({'classes': ['slide'], 'ids': ['slide0']}, 'div')) + if not self.section_count: + self.body.append('
    \n') + self.body_suffix.insert(0, '\n') + # skip content-type meta tag with interpolated charset value: + self.html_head.extend(self.head[1:]) + self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo + + self.docinfo + self.body + + self.body_suffix[:-1]) + + def depart_footer(self, node): + start = self.context.pop() + self.s5_footer.append('

    ') + self.s5_footer.extend(self.body[start:]) + self.s5_footer.append('

    ') + del self.body[start:] + + def depart_header(self, node): + start = self.context.pop() + header = ['\n') + del self.body[start:] + self.s5_header.extend(header) + + def visit_section(self, node): + if not self.section_count: + self.body.append('\n\n') + self.section_count += 1 + self.section_level += 1 + if self.section_level > 1: + # dummy for matching div's + self.body.append(self.starttag(node, 'div', CLASS='section')) + else: + self.body.append(self.starttag(node, 'div', CLASS='slide')) + + def visit_subtitle(self, node): + if isinstance(node.parent, nodes.section): + level = self.section_level + self.initial_header_level - 1 + if level == 1: + level = 2 + tag = 'h%s' % level + self.body.append(self.starttag(node, tag, '')) + self.context.append('\n' % tag) + else: + html4css1.HTMLTranslator.visit_subtitle(self, node) + + def visit_title(self, node, move_ids=0): + html4css1.HTMLTranslator.visit_title(self, node, move_ids=move_ids) diff --git a/docutils/writers/s5_html/themes/README.txt b/docutils/writers/s5_html/themes/README.txt new file mode 100644 index 000000000..2e01b51ee --- /dev/null +++ b/docutils/writers/s5_html/themes/README.txt @@ -0,0 +1,6 @@ +Except where otherwise noted (default/iepngfix.htc), all files in this +directory have been released into the Public Domain. + +These files are based on files from S5 1.1, released into the Public +Domain by Eric Meyer. For further details, please see +http://www.meyerweb.com/eric/tools/s5/credits.html. diff --git a/docutils/writers/s5_html/themes/big-black/__base__ b/docutils/writers/s5_html/themes/big-black/__base__ new file mode 100644 index 000000000..f08be9ad5 --- /dev/null +++ b/docutils/writers/s5_html/themes/big-black/__base__ @@ -0,0 +1,2 @@ +# base theme of this theme: +big-white diff --git a/docutils/writers/s5_html/themes/big-black/big_inverse/framing.css b/docutils/writers/s5_html/themes/big-black/big_inverse/framing.css new file mode 100644 index 000000000..5a31113fb --- /dev/null +++ b/docutils/writers/s5_html/themes/big-black/big_inverse/framing.css @@ -0,0 +1,25 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; z-index: 1;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.1em 4% 4%; z-index: 2;} +/* list-style: none;} */ +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/s5_html/themes/big-black/framing.css b/docutils/writers/s5_html/themes/big-black/framing.css new file mode 100644 index 000000000..5a31113fb --- /dev/null +++ b/docutils/writers/s5_html/themes/big-black/framing.css @@ -0,0 +1,25 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; z-index: 1;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.1em 4% 4%; z-index: 2;} +/* list-style: none;} */ +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/s5_html/themes/big-black/pretty.css b/docutils/writers/s5_html/themes/big-black/pretty.css new file mode 100644 index 000000000..91a85dec2 --- /dev/null +++ b/docutils/writers/s5_html/themes/big-black/pretty.css @@ -0,0 +1,111 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: black; color: white;} +:link, :visited {text-decoration: none; color: cyan;} +#controls :active {color: #888 !important;} +#controls :focus {outline: 1px dotted #CCC;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;} +.slide h2 {font-size: 110%;} +.slide h3 {font-size: 105%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #888; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: black; color: #CCC;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #AAA; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0; + font-size: 150%; white-space: normal; background: transparent;} +#slide0 h2 {font: 110%; font-style: italic; color: gray;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #FCC;} + +.incremental, .incremental *, .incremental *:after { + color: black; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: lime;} + +.print-block, .print-inline {display: none;} + +.huge {font-size: 150%;} +.big {font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +div.sidebar {background-color: black;} + +pre.literal-block, pre.doctest-block {background-color: black;} + +tt.docutils {background-color: black;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/s5_html/themes/big-white/framing.css b/docutils/writers/s5_html/themes/big-white/framing.css new file mode 100644 index 000000000..cd343432b --- /dev/null +++ b/docutils/writers/s5_html/themes/big-white/framing.css @@ -0,0 +1,24 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#footer {display:none;} +.slide {top: 0; width: 92%; padding: 0.25em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/s5_html/themes/big-white/pretty.css b/docutils/writers/s5_html/themes/big-white/pretty.css new file mode 100644 index 000000000..8ecb1dd65 --- /dev/null +++ b/docutils/writers/s5_html/themes/big-white/pretty.css @@ -0,0 +1,109 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;} +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;} +.slide h2 {font-size: 110%;} +.slide h3 {font-size: 105%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #005; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #444; + font-family: sans-serif; font-weight: bold;} + +#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0; + font-size: 150%; white-space: normal; background: transparent;} +#slide0 h2 {font: 110%; font-style: italic; color: gray;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after { + color: white; visibility: visible; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-size: 150%;} +.big {font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 0.5em 0 0.5em 1em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/s5_html/themes/default/blank.gif b/docutils/writers/s5_html/themes/default/blank.gif new file mode 100644 index 000000000..75b945d25 Binary files /dev/null and b/docutils/writers/s5_html/themes/default/blank.gif differ diff --git a/docutils/writers/s5_html/themes/default/framing.css b/docutils/writers/s5_html/themes/default/framing.css new file mode 100644 index 000000000..c4727f303 --- /dev/null +++ b/docutils/writers/s5_html/themes/default/framing.css @@ -0,0 +1,25 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {position: fixed; top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docutils/writers/s5_html/themes/default/iepngfix.htc b/docutils/writers/s5_html/themes/default/iepngfix.htc new file mode 100644 index 000000000..9f3d628b5 --- /dev/null +++ b/docutils/writers/s5_html/themes/default/iepngfix.htc @@ -0,0 +1,42 @@ + + + + + \ No newline at end of file diff --git a/docutils/writers/s5_html/themes/default/opera.css b/docutils/writers/s5_html/themes/default/opera.css new file mode 100644 index 000000000..c9d1148be --- /dev/null +++ b/docutils/writers/s5_html/themes/default/opera.css @@ -0,0 +1,8 @@ +/* This file has been placed in the public domain. */ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff --git a/docutils/writers/s5_html/themes/default/outline.css b/docutils/writers/s5_html/themes/default/outline.css new file mode 100644 index 000000000..cb3588d5a --- /dev/null +++ b/docutils/writers/s5_html/themes/default/outline.css @@ -0,0 +1,21 @@ +/* This file has been placed in the public domain. */ +/* Don't change this unless you want the layout stuff to show up in the + outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0.75em; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block, .print-inline {display: none;} diff --git a/docutils/writers/s5_html/themes/default/pretty.css b/docutils/writers/s5_html/themes/default/pretty.css new file mode 100644 index 000000000..f83ca2bf5 --- /dev/null +++ b/docutils/writers/s5_html/themes/default/pretty.css @@ -0,0 +1,122 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black;} +/* Replace the background style above with the style below (and again for + div#header) for a graphic: */ +/* background: white url(bodybg.gif) -16px 0 no-repeat; */ +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin: 0 0 0.5em 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#header, div#footer {background: #005; color: #AAB; font-family: sans-serif;} +/* background: #005 url(bodybg.gif) -16px 0 no-repeat; */ +div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {position: absolute; top: 0.45em; z-index: 1; + margin: 0; padding-left: 0.7em; white-space: nowrap; + font: bold 150% sans-serif; color: #DDE; background: #005;} +.slide h2 {font: bold 120%/1em sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #005; border: none; color: #779; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #449; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 1.5em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; color: #000; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after {visibility: visible; + color: white; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.print-block, .print-inline {display: none;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.borderless, .borderless td {border: 0;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docutils/writers/s5_html/themes/default/print.css b/docutils/writers/s5_html/themes/default/print.css new file mode 100644 index 000000000..76e6352ee --- /dev/null +++ b/docutils/writers/s5_html/themes/default/print.css @@ -0,0 +1,33 @@ +/* This file has been placed in the public domain. */ +/* The following rule is necessary to have all slides appear in print! + DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} +.extra {background: transparent !important;} +div.extra, pre.extra, .example {font-size: 10pt; color: #333;} +ul.extra a {font-weight: bold;} +p.example {display: none;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; + font-style: italic;} +#footer h2, #controls {display: none;} + +.handout {border-left: solid #BBB; padding-left: 0.5em;} + +.print-block {display: block !important;} +.print-inline {display: inline !important;} + +/* The following rule keeps the layout stuff out of print. + Remove at your own risk! */ +.layout, .layout * {display: none !important;} diff --git a/docutils/writers/s5_html/themes/default/s5-core.css b/docutils/writers/s5_html/themes/default/s5-core.css new file mode 100644 index 000000000..6965f5e8f --- /dev/null +++ b/docutils/writers/s5_html/themes/default/s5-core.css @@ -0,0 +1,11 @@ +/* This file has been placed in the public domain. */ +/* Do not edit or override these styles! + The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff --git a/docutils/writers/s5_html/themes/default/slides.css b/docutils/writers/s5_html/themes/default/slides.css new file mode 100644 index 000000000..82bdc0ee0 --- /dev/null +++ b/docutils/writers/s5_html/themes/default/slides.css @@ -0,0 +1,10 @@ +/* This file has been placed in the public domain. */ + +/* required to make the slide show run at all */ +@import url(s5-core.css); + +/* sets basic placement and size of slide components */ +@import url(framing.css); + +/* styles that make the slides look good */ +@import url(pretty.css); diff --git a/docutils/writers/s5_html/themes/default/slides.js b/docutils/writers/s5_html/themes/default/slides.js new file mode 100644 index 000000000..f0f81bbf8 --- /dev/null +++ b/docutils/writers/s5_html/themes/default/slides.js @@ -0,0 +1,559 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// Modified for Docutils (http://docutils.sf.net) by David Goodger +// $Revision$ +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for +// information about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var slideIDs = new Array(); +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + if (obj.getAttribute('id')) { + slideIDs[n] = obj.getAttribute('id'); + } + else { + obj.setAttribute('id',did); + slideIDs[n] = did; + } + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + var footer_nodes; + var vis = 'visible'; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + footer_nodes = document.getElementById('footer').childNodes; + } else { + cs = document.currentSlide; + footer = document.footer.childNodes; + } + cs.innerHTML = '' + snum + '<\/span> ' + + '\/<\/span> ' + + '' + (smax-1) + '<\/span>'; + if (snum == 0) { + vis = 'hidden'; + } + cs.style.visibility = vis; + for (var i = 0; i < footer_nodes.length; i++) { + if (footer_nodes[i].nodeType == 1) { + footer_nodes[i].style.visibility = vis; + } + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = slideIDs[snum]; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = slideIDs[snum]; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById(slideIDs[0]); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = document.getElementById(hash); + if (target) { + for (var i = 0; i < slideIDs.length; i++) { + if (target.id == slideIDs[i]) return i; + } + } + return null; +} + +function slideJump() { + if (window.location.hash == null || window.location.hash == '') { + currentSlide(); + return; + } + if (window.location.hash == null) return; + var dest = null; + dest = findSlide(window.location.hash.slice(1)); + if (dest == null) { + dest = 0; + } + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#.+'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i' + + '